diff options
1359 files changed, 88320 insertions, 69269 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index b24a36beef..2dad253288 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -6,7 +6,7 @@ env: GODOT_BASE_BRANCH: master SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes SCONS_CACHE_LIMIT: 4096 - ANDROID_NDK_VERSION: 21.1.6352462 + ANDROID_NDK_VERSION: 21.4.7075529 jobs: android-template: @@ -29,7 +29,7 @@ jobs: with: java-version: 8 - - name: Install Android NDK r21 + - name: Install Android NDK run: | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install 'ndk;${{env.ANDROID_NDK_VERSION}}' diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 0982d768d6..b4bbaaacb1 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -144,7 +144,7 @@ jobs: scons --version # We should always be explicit with our flags usage here since it's gonna be sure to always set those flags - # [Workaround] SwiftShader doesn't support tesselation, so we skip Godot check about it + # [Workaround] SwiftShader doesn't support tessellation, so we skip Godot check about it - name: Compilation env: SCONS_CACHE: ${{github.workspace}}/.scons_cache/ diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index b7cc127226..d1db449ab0 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -46,7 +46,7 @@ jobs: - name: Configuring Python packages run: | python -c "import sys; print(sys.version)" - python -m pip install scons pywin32 + python -m pip install scons python --version scons --version @@ -102,7 +102,7 @@ jobs: - name: Configuring Python packages run: | python -c "import sys; print(sys.version)" - python -m pip install scons pywin32 + python -m pip install scons python --version scons --version @@ -68,6 +68,7 @@ Kanabenki <lucien.menassol@gmail.com> <18357657+Kanabenki@users.noreply.github.c Kelly Thomas <kelly.thomas@hotmail.com.au> Kongfa Waroros <gongpha@hotmail.com> K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com> +kleonc <9283098+kleonc@users.noreply.github.com> <kleonc@users.noreply.github.com> Leon Krause <lk@leonkrause.com> <eska@eska.me> Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com> Liz Haas <27thLiz@gmail.com> @@ -94,6 +95,7 @@ Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com> Nils ANDRÉ-CHANG <nils@nilsand.re> Nils ANDRÉ-CHANG <nils@nilsand.re> <nils.andre.chang@gmail.com> Nuno Donato <nunodonato@gmail.com> <n.donato@estrelasustentavel.pt> +Pawel Kowal <pkowal1982@gmail.com> Pedro J. Estébanez <pedrojrulez@gmail.com> <RandomShaper@users.noreply.github.com> Paul Batty <p_batty@hotmail.co.uk> Paul Batty <p_batty@hotmail.co.uk> <Paulb23@users.noreply.github.com> diff --git a/AUTHORS.md b/AUTHORS.md index 7c5eb0c56b..0aacde20e8 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -109,6 +109,7 @@ name is available. Julian Murgia (StraToN) Justo Delgado (mrcdk) Kelly Thomas (KellyThomas) + kleonc Kongfa Waroros (gongpha) Kostadin Damyanov (Max-Might) K. S. Ernest (iFire) Lee (fire) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index cfd983bb0a..b2a930a4bb 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -55,6 +55,14 @@ Comment: Godot Engine logo Copyright: 2017, Andrea Calabró License: CC-BY-4.0 +Files: ./core/math/convex_hull.cpp + ./core/math/convex_hull.h +Comment: Bullet Continuous Collision Detection and Physics Library +Copyright: 2011, Ole Kniemeyer, MAXON, www.maxon.net + 2007-2021, Juan Linietsky, Ariel Manzur. + 2014-2021, Godot Engine contributors. +License: Expat and Zlib + Files: ./modules/fbx/fbx_parser/ Comment: Open Asset Import Library (FBX parser) Copyright: 2006-2020, assimp team @@ -131,8 +139,8 @@ Comment: doctest Copyright: 2016-2020, Viktor Kirilov License: Expat -Files: ./thirdparty/embree-aarch64/ -Comment: Embree-aarch64 +Files: ./thirdparty/embree/ +Comment: Embree Copyright: 2009-2021 Intel Corporation License: Apache-2.0 @@ -352,6 +360,12 @@ Comment: SMAZ Copyright: 2006-2009, Salvatore Sanfilippo License: BSD-3-clause +Files: ./thirdparty/misc/smolv.cpp + ./thirdparty/misc/smolv.h +Comment: SMOL-V +Copyright: 2016-2020, Aras Pranckevicius +License: public-domain or Unlicense or Expat + Files: ./thirdparty/misc/stb_rect_pack.h ./thirdparty/misc/stb_vorbis.c Comment: stb libraries @@ -7,7 +7,7 @@ support of generous donors. The ways to donate to the project, as well as details on how the funds are used, are described on [Godot's website](https://godotengine.org/donate). -The following is a list of the current monthly donors, to be have their +The following is a list of the current monthly donors, who will have their generous deed immortalized in the next stable release of Godot Engine. ## Platinum sponsors @@ -23,8 +23,7 @@ generous deed immortalized in the next stable release of Godot Engine. ## Silver sponsors ASIFA-Hollywood <https://www.asifa-hollywood.org> - Moonwards <https://www.moonwards.com> - Zenva Academy <https://academy.zenva.com> + LITSLINK <https://litslink.com> ## Bronze sponsors @@ -32,7 +31,10 @@ generous deed immortalized in the next stable release of Godot Engine. Garry Newman Gordon MacPherson Hunter Dickson + Kitcat490 Kyle Szklenski + Moonwards <https://www.moonwards.com> + TrampolineTales <http://trampolinetales.com> ## Mini sponsors @@ -40,6 +42,7 @@ generous deed immortalized in the next stable release of Godot Engine. Alejandro Saucedo alex brown Andrew Dunai + Angry Skull anti666 Ben Nolan blurp @@ -56,7 +59,6 @@ generous deed immortalized in the next stable release of Godot Engine. Gamechuck GameDev.net Hein-Pieter van Braam - Jacob McKenney Jasper Brooks Javary Co. Jeffery Chiu @@ -65,11 +67,13 @@ generous deed immortalized in the next stable release of Godot Engine. Justin Arnold Kamil Brzezinski Marcel Kräml + Marek Belski Matthieu Huvé Maxim Karsten Mike King Nathan Warden Neal Gompa (Conan Kudo) + Ninja_5tyl3 Patrick Horn Patrick Schmidt Péter Magyar @@ -86,8 +90,10 @@ generous deed immortalized in the next stable release of Godot Engine. ## Gold donors Acheron + Adam Brown albinaask Alvaro A Baena R + Andres Hernandez Asher Glick Barugon Carlo Cabanilla @@ -131,6 +137,7 @@ generous deed immortalized in the next stable release of Godot Engine. Sarksus Scott B Sean + segfault-god Sergey Sofox Taylor Ritenour @@ -150,13 +157,13 @@ generous deed immortalized in the next stable release of Godot Engine. Alexey Dyadchenko Alex Khayrullin alice gambrell - Andreas Funke Andrew Cunningham Antanas Paskauskas Antoni Batchelli Arisaka Mayuki Arthur S. Muszynski Ben Botwin + Björn Hjorth Brandon Hawkinson Caleb Sizemore Can Eris @@ -166,6 +173,7 @@ generous deed immortalized in the next stable release of Godot Engine. Chris Petrich Chris Serino Christian Leth Jeppesen + Container7 Craig Ostrin Craig Smith Cristopher @@ -174,6 +182,7 @@ generous deed immortalized in the next stable release of Godot Engine. Darrian Little Dennis Belfrage Dev To be curious + Dietrich Schuetz Digital Denizen Dimitri Nüscheler Donn Eddy @@ -183,6 +192,7 @@ generous deed immortalized in the next stable release of Godot Engine. Eugenio Hugo Salgüero Jáñez EXUREI flesk + foxydevloper F S Gabrielius VaiÅ¡kÅ«nas Gary Hulst @@ -196,12 +206,15 @@ generous deed immortalized in the next stable release of Godot Engine. Hu Hund Jake Burga James Couzens + Jan Sælid Jared Jared White + Jeppe Zapp Jesús Chicharro Joel Fivat Joel Höglund Johnathan Kupferer + John Knight Jose Malheiro Jose Manuel Muñoz Perez Joseph Crane @@ -218,6 +231,7 @@ generous deed immortalized in the next stable release of Godot Engine. Kelteseth kickmaniac kinfox + Kis Levente Lorand Kos Lachie Lain Ballard @@ -226,12 +240,9 @@ generous deed immortalized in the next stable release of Godot Engine. Leo Fidel R Liban Liam Smyth Luc-Frédéric Langis - Åukasz Nowak MadScientistCarl - Marcelo Dornbusch Lopes Marcus Dobler Marcus Richter - Marek Belski Mark Barrett Martin Eigel Martin Kotz @@ -241,6 +252,7 @@ generous deed immortalized in the next stable release of Godot Engine. Matthias Toepp medecau Michael + Michael Bordießer-Krauth Michael Dürwald Michael Policastro MightyPossum @@ -257,7 +269,9 @@ generous deed immortalized in the next stable release of Godot Engine. Pavel Kotlyar Pedro Silva Pete Goodwin + Peter Richmond Petr Malac + Petrus Prinsloo PhaineOfCatz pl Raymond Harris @@ -265,6 +279,7 @@ generous deed immortalized in the next stable release of Godot Engine. Rene Tailleur Rhodochrone Ricardo Alcantara + Rob Robert Larnach Robert Willes Rob McInroy @@ -300,11 +315,10 @@ generous deed immortalized in the next stable release of Godot Engine. Vincent Cloutier Vlad Ceru Opran VoidPointer - voxelv + Winston Wojciech Chojnacki xzibiting Yuancheng Zhang - Zhou Tuizhi Zie Weaver Zoran Kukulj @@ -313,7 +327,6 @@ generous deed immortalized in the next stable release of Godot Engine. 1D_Inc Abraham Haskins Adam - Adam Brown Adam Brunnmeier Adam Carr Adam Long @@ -322,6 +335,7 @@ generous deed immortalized in the next stable release of Godot Engine. Adam Smeltzer Adam SzymaÅ„ski Adisibio + Adrien de Pierres Agar3s - Giovanny Beltrán Agustinus Arya Ahmet Kalyoncu @@ -339,6 +353,7 @@ generous deed immortalized in the next stable release of Godot Engine. Alexandre Beaudoin alex clavelle Alex (Well Done Games) + alks Allan Davis Allen Schade Anders Marstein Kruke @@ -351,14 +366,15 @@ generous deed immortalized in the next stable release of Godot Engine. Anthony Avina Anton Bouwer aomimezura11 - AP Condomines Arch Toasty Arda Erol Armin Preiml Arseniy M + Arthur Brainville Ashley Claymore Astier Mickael Aubrey Falconer + aurelien condomines AzulCrescent Balázs Batári Bartosz Bielecki @@ -387,11 +403,13 @@ generous deed immortalized in the next stable release of Godot Engine. Carl van der Geest Carwyn Edwards Cas Brugman + Casey Cassidy James Cédric Givord Chad Steadman Charles Alston Chris Chapin + Chris Jagusch Chris Langford Christian Clavet Christian Mauduit @@ -454,7 +472,6 @@ generous deed immortalized in the next stable release of Godot Engine. Gary Thomas George Marques georgios katsanakis - GFizz Greg Lincoln Greg Olson Greyson Richey @@ -466,6 +483,7 @@ generous deed immortalized in the next stable release of Godot Engine. Hal A helija Heribert Hirth + Houdini Blueprints Hunter Jones Ian Williams Iiari @@ -487,6 +505,7 @@ generous deed immortalized in the next stable release of Godot Engine. Jan Vetulani JARKKO PARVIAINEN Jason Bolton + Jason Malcolm-Herzmark Jason Uechi Jeff Hungerford Jennifer Graves @@ -500,6 +519,7 @@ generous deed immortalized in the next stable release of Godot Engine. Jonas Rudlang Jonas Yamazaki Jonatan R + Jonathan Bieber Jonathan G Jon Bonazza Jon Oakes @@ -535,9 +555,9 @@ generous deed immortalized in the next stable release of Godot Engine. Kiri Jolly Kjetil Haugland Konstantin Goncharov - Kridsada Thanabulpong Kristian Nygaard Jensen KsyTek Games + kt kycho Kyle Jacobs Kyuppin @@ -565,14 +585,15 @@ generous deed immortalized in the next stable release of Godot Engine. Martin Holas Martin Trbola Marvin + MatÄ›j Drábek Mathieu Matt Edwards Matthew Booe Matt Sylvia + Maverick C. Max Fiedler Maxime Blade Maxwell - Megasploot Melissa Mears Merlyn Morgan-Graham mewin @@ -588,9 +609,12 @@ generous deed immortalized in the next stable release of Godot Engine. Mike Cunningham Mitchell J. Wagner MJacred + ModularMind Molinghu Molly Jameson + MoltenGears MrAZIE + Mrjemandem Nathan Fish Nathaniel nee @@ -599,7 +623,7 @@ generous deed immortalized in the next stable release of Godot Engine. Neil Wang Nerdforge Nerdyninja - Nicholas + Nicholas Orlowski Nick Macholl Niclas Eriksen Nicolas Goll-Perrier @@ -612,6 +636,7 @@ generous deed immortalized in the next stable release of Godot Engine. OKV Oleg Reva Oleksandr Kryvonos + Olle Soprani Omar Delarosa Oriol Muñoz Princep Oscar Domingo @@ -620,20 +645,20 @@ generous deed immortalized in the next stable release of Godot Engine. Paul Gieske PaweÅ‚ Kowal PaweÅ‚ Åyczkowski + p_brighenti Peter Höglund - Peter Richmond - Petrus Prinsloo Philip Cohoe Philip Ludington (MrPhil) Pierre Caye Piotr Góral + pj Point08 Preethi Vaidyanathan pwab + Rackat Rad Cat Rafa Laguna Raffaele Aramo - Rami Hanano RAMupgrade Remi Rampin Rémi Verschelde @@ -653,14 +678,12 @@ generous deed immortalized in the next stable release of Godot Engine. Sam Caulfield Sam Edson Samuele Zolfanelli - scapegoat57 Scott D. Yelich Scott Longley Sean Lynch Sebastian Michailidis SeongWan Kim Sergey - Sergiy Onenko Shane Shane Sicienski Shane Spoor @@ -679,15 +702,17 @@ generous deed immortalized in the next stable release of Godot Engine. summerblind Sung soo Choi Svenne Krap + SxP tadashi endo - tannhauser_gate Tarch Terry + the9thdude Theodore Lindsey TheVoiceInMyHead thomas Thomas Bechtold Thomas Detoy + Thomas Hermansen Thomas Horwath Tim Drumheller Tim Erskine @@ -697,7 +722,6 @@ generous deed immortalized in the next stable release of Godot Engine. Tobias Bradtke Tom Coxon Toni Duran - Tony Zhao Torgeir Lilleskog Torsten Crass toupeira @@ -718,6 +742,7 @@ generous deed immortalized in the next stable release of Godot Engine. Vi Watch Vladimir Savin Vladislav Smirnov + VojtÄ›ch Vytenis NaruÅ¡is waka nya Wayne Haak @@ -729,9 +754,9 @@ generous deed immortalized in the next stable release of Godot Engine. Wyatt Goodin x1212 xenomat + Yan Shi Yegor Smirnov Zak Stephens - Ðльдар Будагов è•æƒŸå… ## Bronze donors diff --git a/core/SCsub b/core/SCsub index 21829553a7..e3ba46be02 100644 --- a/core/SCsub +++ b/core/SCsub @@ -12,25 +12,28 @@ import os txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" if "SCRIPT_AES256_ENCRYPTION_KEY" in os.environ: - e = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"] - txt = "" + key = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"] ec_valid = True - if len(e) != 64: + if len(key) != 64: ec_valid = False else: - - for i in range(len(e) >> 1): + txt = "" + for i in range(len(key) >> 1): if i > 0: txt += "," - txts = "0x" + e[i * 2 : i * 2 + 2] + txts = "0x" + key[i * 2 : i * 2 + 2] try: int(txts, 16) except Exception: ec_valid = False txt += txts if not ec_valid: - txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" - print("Invalid AES256 encryption key, not 64 bits hex: " + e) + print("Error: Invalid AES256 encryption key, not 64 hexadecimal characters: '" + key + "'.") + print( + "Unset 'SCRIPT_AES256_ENCRYPTION_KEY' in your environment " + "or make sure that it contains exactly 64 hexadecimal characters." + ) + Exit(255) # NOTE: It is safe to generate this file here, since this is still executed serially with open("script_encryption_key.gen.cpp", "w") as f: @@ -56,6 +59,7 @@ thirdparty_misc_sources = [ "pcg.cpp", "polypartition.cpp", "clipper.cpp", + "smolv.cpp", ] thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources] env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources) diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 2360d66438..c43e32868c 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -31,6 +31,7 @@ #include "engine.h" #include "core/authors.gen.h" +#include "core/config/project_settings.h" #include "core/donors.gen.h" #include "core/license.gen.h" #include "core/version.h" @@ -210,6 +211,13 @@ void Engine::get_singletons(List<Singleton> *p_singletons) { } } +void Engine::set_shader_cache_path(const String &p_path) { + shader_cache_path = p_path; +} +String Engine::get_shader_cache_path() const { + return shader_cache_path; +} + Engine *Engine::singleton = nullptr; Engine *Engine::get_singleton() { diff --git a/core/config/engine.h b/core/config/engine.h index a9080e3dfd..276da1c7ea 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -72,6 +72,8 @@ private: static Engine *singleton; + String shader_cache_path; + public: static Engine *get_singleton(); @@ -121,6 +123,9 @@ public: Dictionary get_license_info() const; String get_license_text() const; + void set_shader_cache_path(const String &p_path); + String get_shader_cache_path() const; + bool is_abort_on_gpu_errors_enabled() const; bool is_validation_layers_enabled() const; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 0d699cdacb..53d13f7429 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1114,7 +1114,8 @@ ProjectSettings::ProjectSettings() { _add_builtin_input_map(); - custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor"); + // Keep the enum values in sync with the `DisplayServer::ScreenOrientation` enum. + custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::INT, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor"); custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); GLOBAL_DEF("physics/2d/run_on_thread", false); GLOBAL_DEF("physics/3d/run_on_thread", false); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 84d8d0d4d3..05265c41ad 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -390,7 +390,7 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { unsigned int hour = ((datetime.has(HOUR_KEY)) ? static_cast<unsigned int>(datetime[HOUR_KEY]) : 0); unsigned int day = ((datetime.has(DAY_KEY)) ? static_cast<unsigned int>(datetime[DAY_KEY]) : 1); unsigned int month = ((datetime.has(MONTH_KEY)) ? static_cast<unsigned int>(datetime[MONTH_KEY]) : 1); - unsigned int year = ((datetime.has(YEAR_KEY)) ? static_cast<unsigned int>(datetime[YEAR_KEY]) : 0); + unsigned int year = ((datetime.has(YEAR_KEY)) ? static_cast<unsigned int>(datetime[YEAR_KEY]) : 1970); /// How many days come before each month (0-12) static const unsigned short int DAYS_PAST_THIS_YEAR_TABLE[2][13] = { @@ -401,15 +401,14 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { }; ERR_FAIL_COND_V_MSG(second > 59, 0, "Invalid second value of: " + itos(second) + "."); - ERR_FAIL_COND_V_MSG(minute > 59, 0, "Invalid minute value of: " + itos(minute) + "."); - ERR_FAIL_COND_V_MSG(hour > 23, 0, "Invalid hour value of: " + itos(hour) + "."); - + ERR_FAIL_COND_V_MSG(year == 0, 0, "Years before 1 AD are not supported. Value passed: " + itos(year) + "."); ERR_FAIL_COND_V_MSG(month > 12 || month == 0, 0, "Invalid month value of: " + itos(month) + "."); - // Do this check after month is tested as valid - ERR_FAIL_COND_V_MSG(day > MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1] || day == 0, 0, "Invalid day value of '" + itos(day) + "' which is larger than '" + itos(MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1]) + "' or 0."); + unsigned int days_in_month = MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1]; + ERR_FAIL_COND_V_MSG(day == 0 || day > days_in_month, 0, "Invalid day value of: " + itos(day) + ". It should be comprised between 1 and " + itos(days_in_month) + " for month " + itos(month) + "."); + // Calculate all the seconds from months past in this year uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month - 1] * SECONDS_PER_DAY; @@ -1259,6 +1258,7 @@ String _File::get_path_absolute() const { void _File::seek(int64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); + ERR_FAIL_COND_MSG(p_position < 0, "Seek position must be a positive integer."); f->seek(p_position); } @@ -1267,14 +1267,14 @@ void _File::seek_end(int64_t p_position) { f->seek_end(p_position); } -int64_t _File::get_position() const { +uint64_t _File::get_position() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); return f->get_position(); } -int64_t _File::get_len() const { +uint64_t _File::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); - return f->get_len(); + return f->get_length(); } bool _File::eof_reached() const { @@ -1317,7 +1317,7 @@ real_t _File::get_real() const { return f->get_real(); } -Vector<uint8_t> _File::get_buffer(int p_length) const { +Vector<uint8_t> _File::get_buffer(int64_t p_length) const { Vector<uint8_t> data; ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use."); @@ -1330,8 +1330,7 @@ Vector<uint8_t> _File::get_buffer(int p_length) const { ERR_FAIL_COND_V_MSG(err != OK, data, "Can't resize data to " + itos(p_length) + " elements."); uint8_t *w = data.ptrw(); - int len = f->get_buffer(&w[0], p_length); - ERR_FAIL_COND_V(len < 0, Vector<uint8_t>()); + int64_t len = f->get_buffer(&w[0], p_length); if (len < p_length) { data.resize(len); @@ -1344,7 +1343,7 @@ String _File::get_as_text() const { ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use."); String text; - size_t original_pos = f->get_position(); + uint64_t original_pos = f->get_position(); f->seek(0); String l = get_line(); @@ -1473,7 +1472,7 @@ void _File::store_csv_line(const Vector<String> &p_values, const String &p_delim void _File::store_buffer(const Vector<uint8_t> &p_buffer) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); - int len = p_buffer.size(); + uint64_t len = p_buffer.size(); if (len == 0) { return; } @@ -1537,7 +1536,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("seek", "position"), &_File::seek); ClassDB::bind_method(D_METHOD("seek_end", "position"), &_File::seek_end, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_position"), &_File::get_position); - ClassDB::bind_method(D_METHOD("get_len"), &_File::get_len); + ClassDB::bind_method(D_METHOD("get_length"), &_File::get_length); ClassDB::bind_method(D_METHOD("eof_reached"), &_File::eof_reached); ClassDB::bind_method(D_METHOD("get_8"), &_File::get_8); ClassDB::bind_method(D_METHOD("get_16"), &_File::get_16); @@ -1546,7 +1545,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("get_float"), &_File::get_float); ClassDB::bind_method(D_METHOD("get_double"), &_File::get_double); ClassDB::bind_method(D_METHOD("get_real"), &_File::get_real); - ClassDB::bind_method(D_METHOD("get_buffer", "len"), &_File::get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "length"), &_File::get_buffer); ClassDB::bind_method(D_METHOD("get_line"), &_File::get_line); ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text); @@ -1617,11 +1616,11 @@ bool _Directory::is_open() const { return d && dir_open; } -Error _Directory::list_dir_begin(bool p_skip_navigational, bool p_skip_hidden) { +Error _Directory::list_dir_begin(bool p_show_navigational, bool p_show_hidden) { ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); - _list_skip_navigational = p_skip_navigational; - _list_skip_hidden = p_skip_hidden; + _list_skip_navigational = !p_show_navigational; + _list_skip_hidden = !p_show_hidden; return d->list_dir_begin(); } @@ -1721,9 +1720,9 @@ bool _Directory::dir_exists(String p_dir) { return d->dir_exists(p_dir); } -int _Directory::get_space_left() { - ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); - return d->get_space_left() / 1024 * 1024; //return value in megabytes, given binding is int +uint64_t _Directory::get_space_left() { + ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use."); + return d->get_space_left() / 1024 * 1024; // Truncate to closest MiB. } Error _Directory::copy(String p_from, String p_to) { @@ -1759,7 +1758,7 @@ Error _Directory::remove(String p_name) { void _Directory::_bind_methods() { ClassDB::bind_method(D_METHOD("open", "path"), &_Directory::open); - ClassDB::bind_method(D_METHOD("list_dir_begin", "skip_navigational", "skip_hidden"), &_Directory::list_dir_begin, DEFVAL(false), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("list_dir_begin", "show_navigational", "show_hidden"), &_Directory::list_dir_begin, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_next"), &_Directory::get_next); ClassDB::bind_method(D_METHOD("current_is_dir"), &_Directory::current_is_dir); ClassDB::bind_method(D_METHOD("list_dir_end"), &_Directory::list_dir_end); diff --git a/core/core_bind.h b/core/core_bind.h index 3920116ca4..8253040a12 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -390,8 +390,8 @@ public: void seek(int64_t p_position); // Seek to a given position. void seek_end(int64_t p_position = 0); // Seek from the end of file. - int64_t get_position() const; // Get position in the file. - int64_t get_len() const; // Get size of the file. + uint64_t get_position() const; // Get position in the file. + uint64_t get_length() const; // Get size of the file. bool eof_reached() const; // Reading passed EOF. @@ -406,7 +406,7 @@ public: Variant get_var(bool p_allow_objects = false) const; - Vector<uint8_t> get_buffer(int p_length) const; // Get an array of bytes. + Vector<uint8_t> get_buffer(int64_t p_length) const; // Get an array of bytes. String get_line() const; Vector<String> get_csv_line(const String &p_delim = ",") const; String get_as_text() const; @@ -467,7 +467,7 @@ public: bool is_open() const; - Error list_dir_begin(bool p_skip_navigational = false, bool p_skip_hidden = false); // This starts dir listing. + Error list_dir_begin(bool p_show_navigational = false, bool p_show_hidden = false); // This starts dir listing. String get_next(); bool current_is_dir() const; @@ -486,7 +486,7 @@ public: bool file_exists(String p_file); bool dir_exists(String p_dir); - int get_space_left(); + uint64_t get_space_left(); Error copy(String p_from, String p_to); Error rename(String p_from, String p_to); diff --git a/core/core_constants.cpp b/core/core_constants.cpp index f40928350a..a0a41015dc 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -161,7 +161,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(KEY_PAGEUP); BIND_CORE_ENUM_CONSTANT(KEY_PAGEDOWN); BIND_CORE_ENUM_CONSTANT(KEY_SHIFT); - BIND_CORE_ENUM_CONSTANT(KEY_CONTROL); + BIND_CORE_ENUM_CONSTANT(KEY_CTRL); BIND_CORE_ENUM_CONSTANT(KEY_META); BIND_CORE_ENUM_CONSTANT(KEY_ALT); BIND_CORE_ENUM_CONSTANT(KEY_CAPSLOCK); diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index 1dd7e268a5..ab368471e4 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -183,7 +183,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { print_line("Error: Unknown option " + key); } else { // Allow explicit tab character - String value = key_value.right(value_pos + 1).replace("\\t", "\t"); + String value = key_value.substr(value_pos + 1).replace("\\t", "\t"); options[key] = value; } @@ -348,7 +348,7 @@ Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) { } breakpoint.first = script_debugger->breakpoint_find_source(breakpoint_part.left(last_colon).strip_edges()); - breakpoint.second = breakpoint_part.right(last_colon).strip_edges().to_int(); + breakpoint.second = breakpoint_part.substr(last_colon).strip_edges().to_int(); return breakpoint; } diff --git a/core/input/input.cpp b/core/input/input.cpp index 2304c05bf8..6eafec087d 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -1262,16 +1262,16 @@ void Input::parse_mapping(String p_mapping) { } else if (output[0] == '-') { output_range = NEGATIVE_HALF_AXIS; } - output = output.right(1); + output = output.substr(1); } JoyAxisRange input_range = FULL_AXIS; if (input[0] == '+') { input_range = POSITIVE_HALF_AXIS; - input = input.right(1); + input = input.substr(1); } else if (input[0] == '-') { input_range = NEGATIVE_HALF_AXIS; - input = input.right(1); + input = input.substr(1); } bool invert_axis = false; if (input[input.length() - 1] == '~') { @@ -1299,11 +1299,11 @@ void Input::parse_mapping(String p_mapping) { switch (input[0]) { case 'b': binding.inputType = TYPE_BUTTON; - binding.input.button = input.right(1).to_int(); + binding.input.button = input.substr(1).to_int(); break; case 'a': binding.inputType = TYPE_AXIS; - binding.input.axis.axis = input.right(1).to_int(); + binding.input.axis.axis = input.substr(1).to_int(); binding.input.axis.range = input_range; binding.input.axis.invert = invert_axis; break; @@ -1312,7 +1312,7 @@ void Input::parse_mapping(String p_mapping) { String(entry[idx] + "\nInvalid hat input: " + input)); binding.inputType = TYPE_HAT; binding.input.hat.hat = input.substr(1, 1).to_int(); - binding.input.hat.hat_mask = static_cast<HatMask>(input.right(3).to_int()); + binding.input.hat.hat_mask = static_cast<HatMask>(input.substr(3).to_int()); break; default: ERR_CONTINUE_MSG(true, String(entry[idx] + "\nUnrecognised input string: " + input)); diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 46629d742e..6f063c217f 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -147,66 +147,66 @@ bool InputEventWithModifiers::is_storing_command() const { return store_command; } -void InputEventWithModifiers::set_shift(bool p_enabled) { - shift = p_enabled; +void InputEventWithModifiers::set_shift_pressed(bool p_enabled) { + shift_pressed = p_enabled; } -bool InputEventWithModifiers::get_shift() const { - return shift; +bool InputEventWithModifiers::is_shift_pressed() const { + return shift_pressed; } -void InputEventWithModifiers::set_alt(bool p_enabled) { - alt = p_enabled; +void InputEventWithModifiers::set_alt_pressed(bool p_enabled) { + alt_pressed = p_enabled; } -bool InputEventWithModifiers::get_alt() const { - return alt; +bool InputEventWithModifiers::is_alt_pressed() const { + return alt_pressed; } -void InputEventWithModifiers::set_control(bool p_enabled) { - control = p_enabled; +void InputEventWithModifiers::set_ctrl_pressed(bool p_enabled) { + ctrl_pressed = p_enabled; } -bool InputEventWithModifiers::get_control() const { - return control; +bool InputEventWithModifiers::is_ctrl_pressed() const { + return ctrl_pressed; } -void InputEventWithModifiers::set_metakey(bool p_enabled) { - meta = p_enabled; +void InputEventWithModifiers::set_meta_pressed(bool p_enabled) { + meta_pressed = p_enabled; } -bool InputEventWithModifiers::get_metakey() const { - return meta; +bool InputEventWithModifiers::is_meta_pressed() const { + return meta_pressed; } -void InputEventWithModifiers::set_command(bool p_enabled) { - command = p_enabled; +void InputEventWithModifiers::set_command_pressed(bool p_enabled) { + command_pressed = p_enabled; } -bool InputEventWithModifiers::get_command() const { - return command; +bool InputEventWithModifiers::is_command_pressed() const { + return command_pressed; } void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModifiers *event) { - set_alt(event->get_alt()); - set_shift(event->get_shift()); - set_control(event->get_control()); - set_metakey(event->get_metakey()); + set_alt_pressed(event->is_alt_pressed()); + set_shift_pressed(event->is_shift_pressed()); + set_ctrl_pressed(event->is_ctrl_pressed()); + set_meta_pressed(event->is_meta_pressed()); } String InputEventWithModifiers::as_text() const { Vector<String> mod_names; - if (get_control()) { - mod_names.push_back(find_keycode_name(KEY_CONTROL)); + if (is_ctrl_pressed()) { + mod_names.push_back(find_keycode_name(KEY_CTRL)); } - if (get_shift()) { + if (is_shift_pressed()) { mod_names.push_back(find_keycode_name(KEY_SHIFT)); } - if (get_alt()) { + if (is_alt_pressed()) { mod_names.push_back(find_keycode_name(KEY_ALT)); } - if (get_metakey()) { + if (is_meta_pressed()) { mod_names.push_back(find_keycode_name(KEY_META)); } @@ -225,27 +225,27 @@ void InputEventWithModifiers::_bind_methods() { ClassDB::bind_method(D_METHOD("set_store_command", "enable"), &InputEventWithModifiers::set_store_command); ClassDB::bind_method(D_METHOD("is_storing_command"), &InputEventWithModifiers::is_storing_command); - ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt); - ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt); + ClassDB::bind_method(D_METHOD("set_alt_pressed", "pressed"), &InputEventWithModifiers::set_alt_pressed); + ClassDB::bind_method(D_METHOD("is_alt_pressed"), &InputEventWithModifiers::is_alt_pressed); - ClassDB::bind_method(D_METHOD("set_shift", "enable"), &InputEventWithModifiers::set_shift); - ClassDB::bind_method(D_METHOD("get_shift"), &InputEventWithModifiers::get_shift); + ClassDB::bind_method(D_METHOD("set_shift_pressed", "pressed"), &InputEventWithModifiers::set_shift_pressed); + ClassDB::bind_method(D_METHOD("is_shift_pressed"), &InputEventWithModifiers::is_shift_pressed); - ClassDB::bind_method(D_METHOD("set_control", "enable"), &InputEventWithModifiers::set_control); - ClassDB::bind_method(D_METHOD("get_control"), &InputEventWithModifiers::get_control); + ClassDB::bind_method(D_METHOD("set_ctrl_pressed", "pressed"), &InputEventWithModifiers::set_ctrl_pressed); + ClassDB::bind_method(D_METHOD("is_ctrl_pressed"), &InputEventWithModifiers::is_ctrl_pressed); - ClassDB::bind_method(D_METHOD("set_metakey", "enable"), &InputEventWithModifiers::set_metakey); - ClassDB::bind_method(D_METHOD("get_metakey"), &InputEventWithModifiers::get_metakey); + ClassDB::bind_method(D_METHOD("set_meta_pressed", "pressed"), &InputEventWithModifiers::set_meta_pressed); + ClassDB::bind_method(D_METHOD("is_meta_pressed"), &InputEventWithModifiers::is_meta_pressed); - ClassDB::bind_method(D_METHOD("set_command", "enable"), &InputEventWithModifiers::set_command); - ClassDB::bind_method(D_METHOD("get_command"), &InputEventWithModifiers::get_command); + ClassDB::bind_method(D_METHOD("set_command_pressed", "pressed"), &InputEventWithModifiers::set_command_pressed); + ClassDB::bind_method(D_METHOD("is_command_pressed"), &InputEventWithModifiers::is_command_pressed); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "store_command"), "set_store_command", "is_storing_command"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alt"), "set_alt", "get_alt"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shift"), "set_shift", "get_shift"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "control"), "set_control", "get_control"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta"), "set_metakey", "get_metakey"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "command"), "set_command", "get_command"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alt_pressed"), "set_alt_pressed", "is_alt_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shift_pressed"), "set_shift_pressed", "is_shift_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ctrl_pressed"), "set_ctrl_pressed", "is_ctrl_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_pressed"), "set_meta_pressed", "is_meta_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "command_pressed"), "set_command_pressed", "is_command_pressed"); } void InputEventWithModifiers::_validate_property(PropertyInfo &property) const { @@ -253,18 +253,18 @@ void InputEventWithModifiers::_validate_property(PropertyInfo &property) const { // If we only want to Store "Command". #ifdef APPLE_STYLE_KEYS // Don't store "Meta" on Mac. - if (property.name == "meta") { + if (property.name == "meta_pressed") { property.usage ^= PROPERTY_USAGE_STORAGE; } #else - // Don't store "Control". - if (property.name == "control") { + // Don't store "Ctrl". + if (property.name == "ctrl_pressed") { property.usage ^= PROPERTY_USAGE_STORAGE; } #endif } else { - // We don't want to store command, only control or meta (on mac). - if (property.name == "command") { + // We don't want to store command, only ctrl or meta (on mac). + if (property.name == "command_pressed") { property.usage ^= PROPERTY_USAGE_STORAGE; } } @@ -314,16 +314,16 @@ bool InputEventKey::is_echo() const { uint32_t InputEventKey::get_keycode_with_modifiers() const { uint32_t sc = keycode; - if (get_control()) { + if (is_ctrl_pressed()) { sc |= KEY_MASK_CTRL; } - if (get_alt()) { + if (is_alt_pressed()) { sc |= KEY_MASK_ALT; } - if (get_shift()) { + if (is_shift_pressed()) { sc |= KEY_MASK_SHIFT; } - if (get_metakey()) { + if (is_meta_pressed()) { sc |= KEY_MASK_META; } @@ -332,16 +332,16 @@ uint32_t InputEventKey::get_keycode_with_modifiers() const { uint32_t InputEventKey::get_physical_keycode_with_modifiers() const { uint32_t sc = physical_keycode; - if (get_control()) { + if (is_ctrl_pressed()) { sc |= KEY_MASK_CTRL; } - if (get_alt()) { + if (is_alt_pressed()) { sc |= KEY_MASK_ALT; } - if (get_shift()) { + if (is_shift_pressed()) { sc |= KEY_MASK_SHIFT; } - if (get_metakey()) { + if (is_meta_pressed()) { sc |= KEY_MASK_META; } @@ -372,16 +372,16 @@ String InputEventKey::to_string() { String kc = ""; String physical = "false"; if (keycode == 0) { - kc = itos(physical_keycode) + " " + keycode_get_string(physical_keycode); + kc = itos(physical_keycode) + " (" + keycode_get_string(physical_keycode) + ")"; physical = "true"; } else { - kc = itos(keycode) + " " + keycode_get_string(keycode); + kc = itos(keycode) + " (" + keycode_get_string(keycode) + ")"; } String mods = InputEventWithModifiers::as_text(); - mods = mods == "" ? TTR("None") : mods; + mods = mods == "" ? TTR("none") : mods; - return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", kc, mods, physical, p, e); + return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, pressed=%s, echo=%s", kc, mods, physical, p, e); } Ref<InputEventKey> InputEventKey::create_reference(uint32_t p_keycode) { @@ -391,19 +391,19 @@ Ref<InputEventKey> InputEventKey::create_reference(uint32_t p_keycode) { ie->set_unicode(p_keycode & KEY_CODE_MASK); if (p_keycode & KEY_MASK_SHIFT) { - ie->set_shift(true); + ie->set_shift_pressed(true); } if (p_keycode & KEY_MASK_ALT) { - ie->set_alt(true); + ie->set_alt_pressed(true); } if (p_keycode & KEY_MASK_CTRL) { - ie->set_control(true); + ie->set_ctrl_pressed(true); } if (p_keycode & KEY_MASK_CMD) { - ie->set_command(true); + ie->set_command_pressed(true); } if (p_keycode & KEY_MASK_META) { - ie->set_metakey(true); + ie->set_meta_pressed(true); } return ie; @@ -667,11 +667,11 @@ String InputEventMouseButton::to_string() { } String mods = InputEventWithModifiers::as_text(); - mods = mods == "" ? TTR("None") : mods; + mods = mods == "" ? TTR("none") : mods; // Work around the fact vformat can only take 5 substitutions but 6 need to be passed. - String index_and_mods = vformat("button_index=%s mods=%s", button_index, mods); - return vformat("InputEventMouseButton: %s pressed=%s position=(%s) button_mask=%s double_click=%s", index_and_mods, p, String(get_position()), itos(get_button_mask()), d); + String index_and_mods = vformat("button_index=%s, mods=%s", button_index, mods); + return vformat("InputEventMouseButton: %s, pressed=%s, position=(%s), button_mask=%d, double_click=%s", index_and_mods, p, String(get_position()), get_button_mask(), d); } void InputEventMouseButton::_bind_methods() { @@ -780,7 +780,9 @@ String InputEventMouseMotion::to_string() { break; } - return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + ")"; + // Work around the fact vformat can only take 5 substitutions but 6 need to be passed. + String mask_and_position = vformat("button_mask=%s, position=(%s)", button_mask_string, String(get_position())); + return vformat("InputEventMouseMotion: %s, relative=(%s), speed=(%s), pressure=%.2f, tilt=(%s)", mask_and_position, String(get_relative()), String(get_speed()), get_pressure(), String(get_tilt())); } bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { @@ -801,19 +803,19 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) { return false; } - if (get_shift() != motion->get_shift()) { + if (is_shift_pressed() != motion->is_shift_pressed()) { return false; } - if (get_control() != motion->get_control()) { + if (is_ctrl_pressed() != motion->is_ctrl_pressed()) { return false; } - if (get_alt() != motion->get_alt()) { + if (is_alt_pressed() != motion->is_alt_pressed()) { return false; } - if (get_metakey() != motion->get_metakey()) { + if (is_meta_pressed() != motion->is_meta_pressed()) { return false; } @@ -918,11 +920,11 @@ static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = { String InputEventJoypadMotion::as_text() const { String desc = axis < JOY_AXIS_MAX ? RTR(_joy_axis_descriptions[axis]) : TTR("Unknown Joypad Axis"); - return vformat(TTR("Joypad Motion on Axis %s (%s) with Value %s"), itos(axis), desc, String(Variant(axis_value))); + return vformat(TTR("Joypad Motion on Axis %d (%s) with Value %.2f"), axis, desc, axis_value); } String InputEventJoypadMotion::to_string() { - return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value)); + return vformat("InputEventJoypadMotion: axis=%d, axis_value=%.2f", axis, axis_value); } void InputEventJoypadMotion::_bind_methods() { @@ -1033,7 +1035,8 @@ String InputEventJoypadButton::as_text() const { } String InputEventJoypadButton::to_string() { - return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure)); + String p = pressed ? "true" : "false"; + return vformat("InputEventJoypadButton: button_index=%d, pressed=%s, pressure=%.2f", button_index, p, pressure); } Ref<InputEventJoypadButton> InputEventJoypadButton::create_reference(int p_btn_index) { @@ -1104,7 +1107,8 @@ String InputEventScreenTouch::as_text() const { } String InputEventScreenTouch::to_string() { - return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")"; + String p = pressed ? "true" : "false"; + return vformat("InputEventScreenTouch: index=%d, pressed=%s, position=(%s)", index, p, String(get_position())); } void InputEventScreenTouch::_bind_methods() { @@ -1177,7 +1181,7 @@ String InputEventScreenDrag::as_text() const { } String InputEventScreenDrag::to_string() { - return "InputEventScreenDrag : index=" + itos(index) + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")"; + return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), speed=(%s)", index, String(get_position()), String(get_relative()), String(get_speed())); } void InputEventScreenDrag::_bind_methods() { @@ -1264,7 +1268,8 @@ String InputEventAction::as_text() const { } String InputEventAction::to_string() { - return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false"); + String p = pressed ? "true" : "false"; + return vformat("InputEventAction: action=\"%s\", pressed=%s", action, p); } void InputEventAction::_bind_methods() { @@ -1331,7 +1336,7 @@ String InputEventMagnifyGesture::as_text() const { } String InputEventMagnifyGesture::to_string() { - return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")"; + return vformat("InputEventMagnifyGesture: factor=%.2f, position=(%s)", factor, String(get_position())); } void InputEventMagnifyGesture::_bind_methods() { @@ -1371,7 +1376,7 @@ String InputEventPanGesture::as_text() const { } String InputEventPanGesture::to_string() { - return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")"; + return vformat("InputEventPanGesture: delta=(%s), position=(%s)", String(get_delta()), String(get_position())); } void InputEventPanGesture::_bind_methods() { @@ -1452,7 +1457,7 @@ String InputEventMIDI::as_text() const { } String InputEventMIDI::to_string() { - return vformat("InputEvenMIDI: channel=%s message=%s pitch=%s velocity=%s pressure=%s", itos(channel), itos(message), itos(pitch), itos(velocity), itos(pressure)); + return vformat("InputEventMIDI: channel=%d, message=%d, pitch=%d, velocity=%d, pressure=%d", channel, message, pitch, velocity, pressure); } void InputEventMIDI::_bind_methods() { diff --git a/core/input/input_event.h b/core/input/input_event.h index 5a33ee7b9c..eed0d79326 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -170,21 +170,21 @@ class InputEventWithModifiers : public InputEventFromWindow { bool store_command = true; - bool shift = false; - bool alt = false; + bool shift_pressed = false; + bool alt_pressed = false; #ifdef APPLE_STYLE_KEYS union { - bool command; - bool meta = false; //< windows/mac key + bool command_pressed; + bool meta_pressed = false; //< windows/mac key }; - bool control = false; + bool ctrl_pressed = false; #else union { - bool command; //< windows/mac key - bool control = false; + bool command_pressed; //< windows/mac key + bool ctrl_pressed = false; }; - bool meta = false; //< windows/mac key + bool meta_pressed = false; //< windows/mac key #endif protected: @@ -195,20 +195,20 @@ public: void set_store_command(bool p_enabled); bool is_storing_command() const; - void set_shift(bool p_enabled); - bool get_shift() const; + void set_shift_pressed(bool p_pressed); + bool is_shift_pressed() const; - void set_alt(bool p_enabled); - bool get_alt() const; + void set_alt_pressed(bool p_pressed); + bool is_alt_pressed() const; - void set_control(bool p_enabled); - bool get_control() const; + void set_ctrl_pressed(bool p_pressed); + bool is_ctrl_pressed() const; - void set_metakey(bool p_enabled); - bool get_metakey() const; + void set_meta_pressed(bool p_pressed); + bool is_meta_pressed() const; - void set_command(bool p_enabled); - bool get_command() const; + void set_command_pressed(bool p_pressed); + bool is_command_pressed() const; void set_modifiers_from_event(const InputEventWithModifiers *event); diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 7421909650..a43ad4ed7d 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -166,7 +166,7 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object."); ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action)); if (_find_event(input_map[p_action], p_event, true)) { - return; // Already addded. + return; // Already added. } input_map[p_action].inputs.push_back(p_event); @@ -353,6 +353,7 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_text_scroll_down", TTRC("Scroll Down") }, { "ui_text_scroll_down.OSX", TTRC("Scroll Down") }, { "ui_text_select_all", TTRC("Select All") }, + { "ui_text_select_word_under_caret", TTRC("Select Word Under Caret") }, { "ui_text_toggle_insert_mode", TTRC("Toggle Insert Mode") }, { "ui_graph_duplicate", TTRC("Duplicate Nodes") }, { "ui_graph_delete", TTRC("Delete Nodes") }, @@ -651,6 +652,10 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() { default_builtin_cache.insert("ui_text_select_all", inputs); inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_D | KEY_MASK_CMD)); + default_builtin_cache.insert("ui_text_select_word_under_caret", inputs); + + inputs = List<Ref<InputEvent>>(); inputs.push_back(InputEventKey::create_reference(KEY_INSERT)); default_builtin_cache.insert("ui_text_toggle_insert_mode", inputs); diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index b2440629e3..e54c947340 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -32,7 +32,7 @@ #include "core/string/print_string.h" -void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) { +void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, uint32_t p_block_size) { magic = p_magic.ascii().get_data(); if (magic.length() > 4) { magic = magic.substr(0, 4); @@ -67,10 +67,10 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) { ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted."); } read_total = f->get_32(); - int bc = (read_total / block_size) + 1; - int acc_ofs = f->get_position() + bc * 4; - int max_bs = 0; - for (int i = 0; i < bc; i++) { + uint32_t bc = (read_total / block_size) + 1; + uint64_t acc_ofs = f->get_position() + bc * 4; + uint32_t max_bs = 0; + for (uint32_t i = 0; i < bc; i++) { ReadBlock rb; rb.offset = acc_ofs; rb.csize = f->get_32(); @@ -148,15 +148,15 @@ void FileAccessCompressed::close() { f->store_32(cmode); //write compression mode 4 f->store_32(block_size); //write block size 4 f->store_32(write_max); //max amount of data written 4 - int bc = (write_max / block_size) + 1; + uint32_t bc = (write_max / block_size) + 1; - for (int i = 0; i < bc; i++) { + for (uint32_t i = 0; i < bc; i++) { f->store_32(0); //compressed sizes, will update later } Vector<int> block_sizes; - for (int i = 0; i < bc; i++) { - int bl = i == (bc - 1) ? write_max % block_size : block_size; + for (uint32_t i = 0; i < bc; i++) { + uint32_t bl = i == (bc - 1) ? write_max % block_size : block_size; uint8_t *bp = &write_ptr[i * block_size]; Vector<uint8_t> cblock; @@ -168,7 +168,7 @@ void FileAccessCompressed::close() { } f->seek(16); //ok write block sizes - for (int i = 0; i < bc; i++) { + for (uint32_t i = 0; i < bc; i++) { f->store_32(block_sizes[i]); } f->seek_end(); @@ -190,8 +190,9 @@ bool FileAccessCompressed::is_open() const { return f != nullptr; } -void FileAccessCompressed::seek(size_t p_position) { +void FileAccessCompressed::seek(uint64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); + if (writing) { ERR_FAIL_COND(p_position > write_max); @@ -204,7 +205,7 @@ void FileAccessCompressed::seek(size_t p_position) { } else { at_end = false; read_eof = false; - int block_idx = p_position / block_size; + uint32_t block_idx = p_position / block_size; if (block_idx != read_block) { read_block = block_idx; f->seek(read_blocks[read_block].offset); @@ -227,7 +228,7 @@ void FileAccessCompressed::seek_end(int64_t p_position) { } } -size_t FileAccessCompressed::get_position() const { +uint64_t FileAccessCompressed::get_position() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); if (writing) { return write_pos; @@ -236,7 +237,7 @@ size_t FileAccessCompressed::get_position() const { } } -size_t FileAccessCompressed::get_len() const { +uint64_t FileAccessCompressed::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); if (writing) { return write_max; @@ -285,9 +286,8 @@ uint8_t FileAccessCompressed::get_8() const { return ret; } -int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessCompressed::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use."); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); @@ -296,7 +296,7 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const { return 0; } - for (int i = 0; i < p_length; i++) { + for (uint64_t i = 0; i < p_length; i++) { p_dst[i] = read_ptr[read_pos]; read_pos++; if (read_pos >= read_block_size) { diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 118d05ea57..19e4f241dd 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -37,34 +37,34 @@ class FileAccessCompressed : public FileAccess { Compression::Mode cmode = Compression::MODE_ZSTD; bool writing = false; - uint32_t write_pos = 0; + uint64_t write_pos = 0; uint8_t *write_ptr = nullptr; uint32_t write_buffer_size = 0; - uint32_t write_max = 0; + uint64_t write_max = 0; uint32_t block_size = 0; mutable bool read_eof = false; mutable bool at_end = false; struct ReadBlock { - int csize; - int offset; + uint32_t csize; + uint64_t offset; }; mutable Vector<uint8_t> comp_buffer; uint8_t *read_ptr = nullptr; - mutable int read_block = 0; - int read_block_count = 0; - mutable int read_block_size = 0; - mutable int read_pos = 0; + mutable uint32_t read_block = 0; + uint32_t read_block_count = 0; + mutable uint32_t read_block_size = 0; + mutable uint64_t read_pos = 0; Vector<ReadBlock> read_blocks; - uint32_t read_total = 0; + uint64_t read_total = 0; String magic = "GCMP"; mutable Vector<uint8_t> buffer; FileAccess *f = nullptr; public: - void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, int p_block_size = 4096); + void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, uint32_t p_block_size = 4096); Error open_after_magic(FileAccess *p_base); @@ -72,15 +72,15 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 13377a3a25..b9514c8c8b 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -69,14 +69,14 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 } base = p_base->get_position(); - ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT); - uint32_t ds = length; + ERR_FAIL_COND_V(p_base->get_length() < base + length, ERR_FILE_CORRUPT); + uint64_t ds = length; if (ds % 16) { ds += 16 - (ds % 16); } data.resize(ds); - uint32_t blen = p_base->get_buffer(data.ptrw(), ds); + uint64_t blen = p_base->get_buffer(data.ptrw(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); { @@ -141,7 +141,7 @@ void FileAccessEncrypted::release() { void FileAccessEncrypted::_release() { if (writing) { Vector<uint8_t> compressed; - size_t len = data.size(); + uint64_t len = data.size(); if (len % 16) { len += 16 - (len % 16); } @@ -198,9 +198,9 @@ String FileAccessEncrypted::get_path_absolute() const { } } -void FileAccessEncrypted::seek(size_t p_position) { - if (p_position > (size_t)data.size()) { - p_position = data.size(); +void FileAccessEncrypted::seek(uint64_t p_position) { + if (p_position > get_length()) { + p_position = get_length(); } pos = p_position; @@ -208,14 +208,14 @@ void FileAccessEncrypted::seek(size_t p_position) { } void FileAccessEncrypted::seek_end(int64_t p_position) { - seek(data.size() + p_position); + seek(get_length() + p_position); } -size_t FileAccessEncrypted::get_position() const { +uint64_t FileAccessEncrypted::get_position() const { return pos; } -size_t FileAccessEncrypted::get_len() const { +uint64_t FileAccessEncrypted::get_length() const { return data.size(); } @@ -225,7 +225,7 @@ bool FileAccessEncrypted::eof_reached() const { uint8_t FileAccessEncrypted::get_8() const { ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode."); - if (pos >= data.size()) { + if (pos >= get_length()) { eofed = true; return 0; } @@ -235,13 +235,12 @@ uint8_t FileAccessEncrypted::get_8() const { return b; } -int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessEncrypted::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); - int to_copy = MIN(p_length, data.size() - pos); - for (int i = 0; i < to_copy; i++) { + uint64_t to_copy = MIN(p_length, get_length() - pos); + for (uint64_t i = 0; i < to_copy; i++) { p_dst[i] = data[pos++]; } @@ -256,16 +255,16 @@ Error FileAccessEncrypted::get_error() const { return eofed ? ERR_FILE_EOF : OK; } -void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessEncrypted::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); - if (pos < data.size()) { - for (int i = 0; i < p_length; i++) { + if (pos < get_length()) { + for (uint64_t i = 0; i < p_length; i++) { store_8(p_src[i]); } - } else if (pos == data.size()) { + } else if (pos == get_length()) { data.resize(pos + p_length); - for (int i = 0; i < p_length; i++) { + for (uint64_t i = 0; i < p_length; i++) { data.write[pos + i] = p_src[i]; } pos += p_length; @@ -281,10 +280,10 @@ void FileAccessEncrypted::flush() { void FileAccessEncrypted::store_8(uint8_t p_dest) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); - if (pos < data.size()) { + if (pos < get_length()) { data.write[pos] = p_dest; pos++; - } else if (pos == data.size()) { + } else if (pos == get_length()) { data.push_back(p_dest); pos++; } diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 969052d04f..00f14099f9 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -47,10 +47,10 @@ private: Vector<uint8_t> key; bool writing = false; FileAccess *file = nullptr; - size_t base = 0; - size_t length = 0; + uint64_t base = 0; + uint64_t length = 0; Vector<uint8_t> data; - mutable int pos = 0; + mutable uint64_t pos = 0; mutable bool eofed = false; bool use_magic = true; @@ -68,21 +68,21 @@ public: virtual String get_path() const; /// returns the path for the current open file virtual String get_path_absolute() const; /// returns the absolute path for the current open file - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index af155a77a8..0114ab1765 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -71,7 +71,7 @@ bool FileAccessMemory::file_exists(const String &p_name) { return files && (files->find(name) != nullptr); } -Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) { +Error FileAccessMemory::open_custom(const uint8_t *p_data, uint64_t p_len) { data = (uint8_t *)p_data; length = p_len; pos = 0; @@ -102,7 +102,7 @@ bool FileAccessMemory::is_open() const { return data != nullptr; } -void FileAccessMemory::seek(size_t p_position) { +void FileAccessMemory::seek(uint64_t p_position) { ERR_FAIL_COND(!data); pos = p_position; } @@ -112,12 +112,12 @@ void FileAccessMemory::seek_end(int64_t p_position) { pos = length + p_position; } -size_t FileAccessMemory::get_position() const { +uint64_t FileAccessMemory::get_position() const { ERR_FAIL_COND_V(!data, 0); return pos; } -size_t FileAccessMemory::get_len() const { +uint64_t FileAccessMemory::get_length() const { ERR_FAIL_COND_V(!data, 0); return length; } @@ -136,13 +136,12 @@ uint8_t FileAccessMemory::get_8() const { return ret; } -int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessMemory::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!data, -1); - int left = length - pos; - int read = MIN(p_length, left); + uint64_t left = length - pos; + uint64_t read = MIN(p_length, left); if (read < p_length) { WARN_PRINT("Reading less data than requested"); @@ -168,9 +167,9 @@ void FileAccessMemory::store_8(uint8_t p_byte) { data[pos++] = p_byte; } -void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) { - int left = length - pos; - int write = MIN(p_length, left); +void FileAccessMemory::store_buffer(const uint8_t *p_src, uint64_t p_length) { + uint64_t left = length - pos; + uint64_t write = MIN(p_length, left); if (write < p_length) { WARN_PRINT("Writing less data than requested"); } diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 0e3b0ad7b1..4157531d01 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -35,8 +35,8 @@ class FileAccessMemory : public FileAccess { uint8_t *data = nullptr; - int length = 0; - mutable int pos = 0; + uint64_t length = 0; + mutable uint64_t pos = 0; static FileAccess *create(); @@ -44,27 +44,27 @@ public: static void register_file(String p_name, Vector<uint8_t> p_data); static void cleanup(); - virtual Error open_custom(const uint8_t *p_data, int p_len); ///< open a file + virtual Error open_custom(const uint8_t *p_data, uint64_t p_len); ///< open a file virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; ///< get an array of bytes virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_byte); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 4cc73bcd22..63a8f9c5b6 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -126,7 +126,7 @@ void FileAccessNetworkClient::_thread_func() { if (status != OK) { fa->_respond(0, Error(status)); } else { - uint64_t len = get_64(); + int64_t len = get_64(); fa->_respond(len, Error(status)); } @@ -135,7 +135,7 @@ void FileAccessNetworkClient::_thread_func() { } break; case FileAccessNetwork::RESPONSE_DATA: { int64_t offset = get_64(); - uint32_t len = get_32(); + int32_t len = get_32(); Vector<uint8_t> block; block.resize(len); @@ -219,13 +219,13 @@ FileAccessNetworkClient::~FileAccessNetworkClient() { thread.wait_to_finish(); } -void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) { - int page = p_offset / page_size; +void FileAccessNetwork::_set_block(uint64_t p_offset, const Vector<uint8_t> &p_block) { + int32_t page = p_offset / page_size; ERR_FAIL_INDEX(page, pages.size()); if (page < pages.size() - 1) { ERR_FAIL_COND(p_block.size() != page_size); } else { - ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size))); + ERR_FAIL_COND((uint64_t)p_block.size() != total_size % page_size); } { @@ -240,7 +240,7 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) } } -void FileAccessNetwork::_respond(size_t p_len, Error p_status) { +void FileAccessNetwork::_respond(uint64_t p_len, Error p_status) { DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status)); response = p_status; if (response != OK) { @@ -248,7 +248,7 @@ void FileAccessNetwork::_respond(size_t p_len, Error p_status) { } opened = true; total_size = p_len; - int pc = ((total_size - 1) / page_size) + 1; + int32_t pc = ((total_size - 1) / page_size) + 1; pages.resize(pc); } @@ -307,8 +307,9 @@ bool FileAccessNetwork::is_open() const { return opened; } -void FileAccessNetwork::seek(size_t p_position) { +void FileAccessNetwork::seek(uint64_t p_position) { ERR_FAIL_COND_MSG(!opened, "File must be opened before use."); + eof_flag = p_position > total_size; if (p_position >= total_size) { @@ -322,12 +323,12 @@ void FileAccessNetwork::seek_end(int64_t p_position) { seek(total_size + p_position); } -size_t FileAccessNetwork::get_position() const { +uint64_t FileAccessNetwork::get_position() const { ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use."); return pos; } -size_t FileAccessNetwork::get_len() const { +uint64_t FileAccessNetwork::get_length() const { ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use."); return total_size; } @@ -343,7 +344,7 @@ uint8_t FileAccessNetwork::get_8() const { return v; } -void FileAccessNetwork::_queue_page(int p_page) const { +void FileAccessNetwork::_queue_page(int32_t p_page) const { if (p_page >= pages.size()) { return; } @@ -354,7 +355,7 @@ void FileAccessNetwork::_queue_page(int p_page) const { FileAccessNetworkClient::BlockRequest br; br.id = id; - br.offset = size_t(p_page) * page_size; + br.offset = (uint64_t)p_page * page_size; br.size = page_size; nc->block_requests.push_back(br); pages.write[p_page].queued = true; @@ -365,11 +366,9 @@ void FileAccessNetwork::_queue_page(int p_page) const { } } -int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessNetwork::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); - //bool eof=false; if (pos + p_length > total_size) { eof_flag = true; } @@ -377,18 +376,16 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { p_length = total_size - pos; } - //FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; - uint8_t *buff = last_page_buff; - for (int i = 0; i < p_length; i++) { - int page = pos / page_size; + for (uint64_t i = 0; i < p_length; i++) { + int32_t page = pos / page_size; if (page != last_page) { buffer_mutex.lock(); if (pages[page].buffer.is_empty()) { waiting_on_page = page; - for (int j = 0; j < read_ahead; j++) { + for (int32_t j = 0; j < read_ahead; j++) { _queue_page(page + j); } buffer_mutex.unlock(); @@ -396,10 +393,9 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { page_sem.wait(); DEBUG_PRINT("done"); } else { - for (int j = 0; j < read_ahead; j++) { + for (int32_t j = 0; j < read_ahead; j++) { _queue_page(page + j); } - //queue pages buffer_mutex.unlock(); } diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 1f5de3e5dd..94b66c2480 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -40,9 +40,9 @@ class FileAccessNetwork; class FileAccessNetworkClient { struct BlockRequest { - int id; + int32_t id; uint64_t offset; - int size; + int32_t size; }; List<BlockRequest> block_requests; @@ -54,17 +54,17 @@ class FileAccessNetworkClient { Mutex blockrequest_mutex; Map<int, FileAccessNetwork *> accesses; Ref<StreamPeerTCP> client; - int last_id = 0; - int lockcount = 0; + int32_t last_id = 0; + int32_t lockcount = 0; Vector<uint8_t> block; void _thread_func(); static void _thread_func(void *s); - void put_32(int p_32); + void put_32(int32_t p_32); void put_64(int64_t p_64); - int get_32(); + int32_t get_32(); int64_t get_64(); void lock_mutex(); void unlock_mutex(); @@ -86,15 +86,15 @@ class FileAccessNetwork : public FileAccess { Semaphore page_sem; Mutex buffer_mutex; bool opened = false; - size_t total_size; - mutable size_t pos = 0; - int id; + uint64_t total_size; + mutable uint64_t pos = 0; + int32_t id; mutable bool eof_flag = false; - mutable int last_page = -1; + mutable int32_t last_page = -1; mutable uint8_t *last_page_buff = nullptr; - int page_size; - int read_ahead; + int32_t page_size; + int32_t read_ahead; mutable int waiting_on_page = -1; @@ -110,9 +110,9 @@ class FileAccessNetwork : public FileAccess { uint64_t exists_modtime; friend class FileAccessNetworkClient; - void _queue_page(int p_page) const; - void _respond(size_t p_len, Error p_status); - void _set_block(int p_offset, const Vector<uint8_t> &p_block); + void _queue_page(int32_t p_page) const; + void _respond(uint64_t p_len, Error p_status); + void _set_block(uint64_t p_offset, const Vector<uint8_t> &p_block); public: enum Command { @@ -134,15 +134,15 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e24dc40166..e9983ece47 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -36,7 +36,7 @@ #include <stdio.h> -Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_offset) { +Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) { for (int i = 0; i < sources.size(); i++) { if (sources[i]->try_open_pack(p_path, p_replace_files, p_offset)) { return OK; @@ -46,17 +46,16 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_ return ERR_FILE_UNRECOGNIZED; } -void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) { - PathMD5 pmd5(path.md5_buffer()); - //printf("adding path %s, %lli, %lli\n", path.utf8().get_data(), pmd5.a, pmd5.b); +void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) { + PathMD5 pmd5(p_path.md5_buffer()); bool exists = files.has(pmd5); PackedFile pf; pf.encrypted = p_encrypted; - pf.pack = pkg_path; - pf.offset = ofs; - pf.size = size; + pf.pack = p_pkg_path; + pf.offset = p_ofs; + pf.size = p_size; for (int i = 0; i < 16; i++) { pf.md5[i] = p_md5[i]; } @@ -68,7 +67,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o if (!exists) { //search for dir - String p = path.replace_first("res://", ""); + String p = p_path.replace_first("res://", ""); PackedDir *cd = root; if (p.find("/") != -1) { //in a subdir @@ -87,7 +86,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o } } } - String filename = path.get_file(); + String filename = p_path.get_file(); // Don't add as a file if the path points to a directory if (!filename.is_empty()) { cd->files.insert(filename); @@ -126,7 +125,7 @@ PackedData::~PackedData() { ////////////////////////////////////////////////////////////////// -bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) { +bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { return false; @@ -261,7 +260,7 @@ bool FileAccessPack::is_open() const { return f->is_open(); } -void FileAccessPack::seek(size_t p_position) { +void FileAccessPack::seek(uint64_t p_position) { if (p_position > pf.size) { eof = true; } else { @@ -276,11 +275,11 @@ void FileAccessPack::seek_end(int64_t p_position) { seek(pf.size + p_position); } -size_t FileAccessPack::get_position() const { +uint64_t FileAccessPack::get_position() const { return pos; } -size_t FileAccessPack::get_len() const { +uint64_t FileAccessPack::get_length() const { return pf.size; } @@ -298,18 +297,17 @@ uint8_t FileAccessPack::get_8() const { return f->get_8(); } -int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessPack::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); if (eof) { return 0; } - uint64_t to_read = p_length; + int64_t to_read = p_length; if (to_read + pos > pf.size) { eof = true; - to_read = int64_t(pf.size) - int64_t(pos); + to_read = (int64_t)pf.size - (int64_t)pos; } pos += p_length; @@ -342,7 +340,7 @@ void FileAccessPack::store_8(uint8_t p_dest) { ERR_FAIL(); } -void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessPack::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL(); } @@ -549,7 +547,7 @@ Error DirAccessPack::remove(String p_name) { return ERR_UNAVAILABLE; } -size_t DirAccessPack::get_space_left() { +uint64_t DirAccessPack::get_space_left() { return 0; } diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 955108f455..9747e865c8 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -112,13 +112,13 @@ private: public: void add_pack_source(PackSource *p_source); - void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource + void add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource void set_disabled(bool p_disabled) { disabled = p_disabled; } _FORCE_INLINE_ bool is_disabled() const { return disabled; } static PackedData *get_singleton() { return singleton; } - Error add_pack(const String &p_path, bool p_replace_files, size_t p_offset); + Error add_pack(const String &p_path, bool p_replace_files, uint64_t p_offset); _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); @@ -132,21 +132,21 @@ public: class PackSource { public: - virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) = 0; + virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) = 0; virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0; virtual ~PackSource() {} }; class PackedSourcePCK : public PackSource { public: - virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset); + virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset); virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); }; class FileAccessPack : public FileAccess { PackedData::PackedFile pf; - mutable size_t pos; + mutable uint64_t pos; mutable bool eof; uint64_t off; @@ -160,16 +160,16 @@ public: virtual void close(); virtual bool is_open() const; - virtual void seek(size_t p_position); + virtual void seek(uint64_t p_position); virtual void seek_end(int64_t p_position = 0); - virtual size_t get_position() const; - virtual size_t get_len() const; + virtual uint64_t get_position() const; + virtual uint64_t get_length() const; virtual bool eof_reached() const; virtual uint8_t get_8() const; - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual void set_endian_swap(bool p_swap); @@ -178,7 +178,7 @@ public: virtual void flush(); virtual void store_8(uint8_t p_dest); - virtual void store_buffer(const uint8_t *p_src, int p_length); + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); virtual bool file_exists(const String &p_name); @@ -243,7 +243,11 @@ public: virtual Error rename(String p_from, String p_to); virtual Error remove(String p_name); - size_t get_space_left(); + uint64_t get_space_left(); + + virtual bool is_link(String p_file) { return false; } + virtual String read_link(String p_file) { return p_file; } + virtual Error create_link(String p_source, String p_target) { return FAILED; } virtual String get_filesystem_type() const; diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 397b577612..b8383fd865 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -43,14 +43,14 @@ static void *godot_open(void *data, const char *p_fname, int mode) { return nullptr; } - FileAccess *f = (FileAccess *)data; - f->open(p_fname, FileAccess::READ); + FileAccess *f = FileAccess::open(p_fname, FileAccess::READ); + ERR_FAIL_COND_V(!f, nullptr); - return f->is_open() ? data : nullptr; + return f; } static uLong godot_read(void *data, void *fdata, void *buf, uLong size) { - FileAccess *f = (FileAccess *)data; + FileAccess *f = (FileAccess *)fdata; f->get_buffer((uint8_t *)buf, size); return size; } @@ -60,20 +60,20 @@ static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong si } static long godot_tell(voidpf opaque, voidpf stream) { - FileAccess *f = (FileAccess *)opaque; + FileAccess *f = (FileAccess *)stream; return f->get_position(); } static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { - FileAccess *f = (FileAccess *)opaque; + FileAccess *f = (FileAccess *)stream; - int pos = offset; + uint64_t pos = offset; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: pos = f->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: - pos = f->get_len() + offset; + pos = f->get_length() + offset; break; default: break; @@ -84,13 +84,17 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { } static int godot_close(voidpf opaque, voidpf stream) { - FileAccess *f = (FileAccess *)opaque; - f->close(); + FileAccess *f = (FileAccess *)stream; + if (f) { + f->close(); + memdelete(f); + f = nullptr; + } return 0; } static int godot_testerror(voidpf opaque, voidpf stream) { - FileAccess *f = (FileAccess *)opaque; + FileAccess *f = (FileAccess *)stream; return f->get_error() != OK ? 1 : 0; } @@ -105,23 +109,18 @@ static void godot_free(voidpf opaque, voidpf address) { void ZipArchive::close_handle(unzFile p_file) const { ERR_FAIL_COND_MSG(!p_file, "Cannot close a file if none is open."); - FileAccess *f = (FileAccess *)unzGetOpaque(p_file); unzCloseCurrentFile(p_file); unzClose(p_file); - memdelete(f); } unzFile ZipArchive::get_file_handle(String p_file) const { ERR_FAIL_COND_V_MSG(!file_exists(p_file), nullptr, "File '" + p_file + " doesn't exist."); File file = files[p_file]; - FileAccess *f = FileAccess::open(packages[file.package].filename, FileAccess::READ); - ERR_FAIL_COND_V_MSG(!f, nullptr, "Cannot open file '" + packages[file.package].filename + "'."); - zlib_filefunc_def io; memset(&io, 0, sizeof(io)); - io.opaque = f; + io.opaque = nullptr; io.zopen_file = godot_open; io.zread_file = godot_read; io.zwrite_file = godot_write; @@ -135,7 +134,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { io.free_mem = godot_free; unzFile pkg = unzOpen2(packages[file.package].filename.utf8().get_data(), &io); - ERR_FAIL_COND_V(!pkg, nullptr); + ERR_FAIL_COND_V_MSG(!pkg, nullptr, "Cannot open file '" + packages[file.package].filename + "'."); int unz_err = unzGoToFilePos(pkg, &file.file_pos); if (unz_err != UNZ_OK || unzOpenCurrentFile(pkg) != UNZ_OK) { unzClose(pkg); @@ -145,8 +144,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { return pkg; } -bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset = 0) { - //printf("opening zip pack %s, %i, %i\n", p_name.utf8().get_data(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); +bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset = 0) { // load with offset feature only supported for PCK files ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with ZIP archives."); @@ -155,12 +153,9 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, size_ } zlib_filefunc_def io; + memset(&io, 0, sizeof(io)); - FileAccess *fa = FileAccess::open(p_path, FileAccess::READ); - if (!fa) { - return false; - } - io.opaque = fa; + io.opaque = nullptr; io.zopen_file = godot_open; io.zread_file = godot_read; io.zwrite_file = godot_write; @@ -231,9 +226,7 @@ ZipArchive::ZipArchive() { ZipArchive::~ZipArchive() { for (int i = 0; i < packages.size(); i++) { - FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile); unzClose(packages[i].zfile); - memdelete(f); } packages.clear(); @@ -269,22 +262,23 @@ bool FileAccessZip::is_open() const { return zfile != nullptr; } -void FileAccessZip::seek(size_t p_position) { +void FileAccessZip::seek(uint64_t p_position) { ERR_FAIL_COND(!zfile); + unzSeekCurrentFile(zfile, p_position); } void FileAccessZip::seek_end(int64_t p_position) { ERR_FAIL_COND(!zfile); - unzSeekCurrentFile(zfile, get_len() + p_position); + unzSeekCurrentFile(zfile, get_length() + p_position); } -size_t FileAccessZip::get_position() const { +uint64_t FileAccessZip::get_position() const { ERR_FAIL_COND_V(!zfile, 0); return unztell(zfile); } -size_t FileAccessZip::get_len() const { +uint64_t FileAccessZip::get_length() const { ERR_FAIL_COND_V(!zfile, 0); return file_info.uncompressed_size; } @@ -301,17 +295,17 @@ uint8_t FileAccessZip::get_8() const { return ret; } -int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessZip::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!zfile, -1); + at_eof = unzeof(zfile); if (at_eof) { return 0; } - int read = unzReadCurrentFile(zfile, p_dst, p_length); + int64_t read = unzReadCurrentFile(zfile, p_dst, p_length); ERR_FAIL_COND_V(read < 0, read); - if (read < p_length) { + if ((uint64_t)read < p_length) { at_eof = true; } return read; diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 8559f871ce..cca14ded62 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -67,7 +67,7 @@ public: bool file_exists(String p_name) const; - virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset); + virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset); FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); static ZipArchive *get_singleton(); @@ -87,20 +87,21 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte + virtual bool file_exists(const String &p_name); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 8414ee7c0c..fda4083804 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -843,7 +843,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p if (property_id == UINT16_MAX && p_from->get_script_instance()) { property_id = p_from->get_script_instance()->get_rset_property_id(p_name); } - ERR_FAIL_COND_MSG(property_id == UINT16_MAX, "Unable to take the `property_id` for the property:" + p_name + ". this can happen only if this property is not marked as `remote`."); + ERR_FAIL_COND_MSG(property_id == UINT16_MAX, "Unable to take the `property_id` for the property:" + p_name + ". This can only happen if this property is not marked as `remote`."); if (property_id <= UINT8_MAX) { // The ID fits in 1 byte diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index a0697ca18b..cadb02b5dd 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -120,7 +120,7 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encr pf.path = p_file; pf.src_path = p_src; pf.ofs = ofs; - pf.size = f->get_len(); + pf.size = f->get_length(); Vector<uint8_t> data = FileAccess::get_file_as_array(p_src); { @@ -236,7 +236,7 @@ Error PCKPacker::flush(bool p_verbose) { } while (to_write > 0) { - int read = src->get_buffer(buf, MIN(to_write, buf_max)); + uint64_t read = src->get_buffer(buf, MIN(to_write, buf_max)); ftmp->store_buffer(buf, read); to_write -= read; } diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index c4eb2a20bb..50c9b2371a 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1157,8 +1157,8 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons save_ustring(fw, get_ustring(f)); //type - size_t md_ofs = f->get_position(); - size_t importmd_ofs = f->get_64(); + uint64_t md_ofs = f->get_position(); + uint64_t importmd_ofs = f->get_64(); fw->store_64(0); //metadata offset for (int i = 0; i < 14; i++) { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 040e55b9db..b942c30086 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -867,7 +867,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem continue; } - String l = res_remaps[i].right(split + 1).strip_edges(); + String l = res_remaps[i].substr(split + 1).strip_edges(); if (l == locale) { // Exact match. new_path = res_remaps[i].left(split); break; diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index a1f8e79adc..938d93a01b 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -75,7 +75,7 @@ void XMLParser::_parse_closing_xml_element() { ++P; const char *pBeginClose = P; - while (*P != '>') { + while (*P && *P != '>') { ++P; } @@ -83,7 +83,10 @@ void XMLParser::_parse_closing_xml_element() { #ifdef DEBUG_XML print_line("XML CLOSE: " + node_name); #endif - ++P; + + if (*P) { + ++P; + } } void XMLParser::_ignore_definition() { @@ -91,11 +94,14 @@ void XMLParser::_ignore_definition() { char *F = P; // move until end marked with '>' reached - while (*P != '>') { + while (*P && *P != '>') { ++P; } node_name.parse_utf8(F, P - F); - ++P; + + if (*P) { + ++P; + } } bool XMLParser::_parse_cdata() { @@ -113,6 +119,7 @@ bool XMLParser::_parse_cdata() { } if (!*P) { + node_name = ""; return true; } @@ -131,10 +138,9 @@ bool XMLParser::_parse_cdata() { } if (cDataEnd) { - node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); - } else { - node_name = ""; + cDataEnd = P; } + node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); #ifdef DEBUG_XML print_line("XML CDATA: " + node_name); #endif @@ -146,24 +152,45 @@ void XMLParser::_parse_comment() { node_type = NODE_COMMENT; P += 1; - char *pCommentBegin = P; + char *pEndOfInput = data + length; + char *pCommentBegin; + char *pCommentEnd; - int count = 1; - - // move until end of comment reached - while (count) { - if (*P == '>') { - --count; - } else if (*P == '<') { - ++count; + if (P + 1 < pEndOfInput && P[0] == '-' && P[1] == '-') { + // Comment, use '-->' as end. + pCommentBegin = P + 2; + for (pCommentEnd = pCommentBegin; pCommentEnd + 2 < pEndOfInput; pCommentEnd++) { + if (pCommentEnd[0] == '-' && pCommentEnd[1] == '-' && pCommentEnd[2] == '>') { + break; + } + } + if (pCommentEnd + 2 < pEndOfInput) { + P = pCommentEnd + 3; + } else { + P = pCommentEnd = pEndOfInput; + } + } else { + // Like document type definition, match angle brackets. + pCommentBegin = P; + + int count = 1; + while (*P && count) { + if (*P == '>') { + --count; + } else if (*P == '<') { + ++count; + } + ++P; } - ++P; + if (count) { + pCommentEnd = P; + } else { + pCommentEnd = P - 1; + } } - P -= 3; - node_name = String::utf8(pCommentBegin + 2, (int)(P - pCommentBegin - 2)); - P += 3; + node_name = String::utf8(pCommentBegin, (int)(pCommentEnd - pCommentBegin)); #ifdef DEBUG_XML print_line("XML COMMENT: " + node_name); #endif @@ -178,14 +205,14 @@ void XMLParser::_parse_opening_xml_element() { const char *startName = P; // find end of element - while (*P != '>' && !_is_white_space(*P)) { + while (*P && *P != '>' && !_is_white_space(*P)) { ++P; } const char *endName = P; // find attributes - while (*P != '>') { + while (*P && *P != '>') { if (_is_white_space(*P)) { ++P; } else { @@ -195,10 +222,14 @@ void XMLParser::_parse_opening_xml_element() { // read the attribute names const char *attributeNameBegin = P; - while (!_is_white_space(*P) && *P != '=') { + while (*P && !_is_white_space(*P) && *P != '=') { ++P; } + if (!*P) { + break; + } + const char *attributeNameEnd = P; ++P; @@ -209,7 +240,7 @@ void XMLParser::_parse_opening_xml_element() { } if (!*P) { // malformatted xml file - return; + break; } const char attributeQuoteChar = *P; @@ -221,12 +252,10 @@ void XMLParser::_parse_opening_xml_element() { ++P; } - if (!*P) { // malformatted xml file - return; - } - const char *attributeValueEnd = P; - ++P; + if (*P) { + ++P; + } Attribute attr; attr.name = String::utf8(attributeNameBegin, @@ -258,7 +287,9 @@ void XMLParser::_parse_opening_xml_element() { print_line("XML OPEN: " + node_name); #endif - ++P; + if (*P) { + ++P; + } } void XMLParser::_parse_current_node() { @@ -270,10 +301,6 @@ void XMLParser::_parse_current_node() { ++P; } - if (!*P) { - return; - } - if (P - start > 0) { // we found some text, store it if (_set_text(start, P)) { @@ -281,6 +308,10 @@ void XMLParser::_parse_current_node() { } } + if (!*P) { + return; + } + ++P; // based on current token, parse and report next element @@ -445,7 +476,7 @@ Error XMLParser::open(const String &p_path) { ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); - length = file->get_len(); + length = file->get_length(); ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT); if (data) { diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index fe46868dd0..fb4c76aa7a 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -68,13 +68,13 @@ long zipio_tell(voidpf opaque, voidpf stream) { long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { FileAccess *f = *(FileAccess **)opaque; - int pos = offset; + uint64_t pos = offset; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: pos = f->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: - pos = f->get_len() + offset; + pos = f->get_length() + offset; break; default: break; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 50299902eb..037378b9d7 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -109,7 +109,7 @@ bool Basis::is_diagonal() const { } bool Basis::is_rotation() const { - return Math::is_equal_approx(determinant(), 1, UNIT_EPSILON) && is_orthogonal(); + return Math::is_equal_approx(determinant(), 1, (real_t)UNIT_EPSILON) && is_orthogonal(); } #ifdef MATH_CHECKS diff --git a/core/math/bvh.h b/core/math/bvh.h new file mode 100644 index 0000000000..cefbc9b0db --- /dev/null +++ b/core/math/bvh.h @@ -0,0 +1,695 @@ +/*************************************************************************/ +/* bvh.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef BVH_H +#define BVH_H + +// BVH +// This class provides a wrapper around BVH tree, which contains most of the functionality +// for a dynamic BVH with templated leaf size. +// However BVH also adds facilities for pairing, to maintain compatibility with Godot 3.2. +// Pairing is a collision pairing system, on top of the basic BVH. + +// Some notes on the use of BVH / Octree from Godot 3.2. +// This is not well explained elsewhere. +// The rendering tree mask and types that are sent to the BVH are NOT layer masks. +// They are INSTANCE_TYPES (defined in visual_server.h), e.g. MESH, MULTIMESH, PARTICLES etc. +// Thus the lights do no cull by layer mask in the BVH. + +// Layer masks are implemented in the renderers as a later step, and light_cull_mask appears to be +// implemented in GLES3 but not GLES2. Layer masks are not yet implemented for directional lights. + +#include "bvh_tree.h" + +#define BVHTREE_CLASS BVH_Tree<T, 2, MAX_ITEMS, USE_PAIRS, Bounds, Point> + +template <class T, bool USE_PAIRS = false, int MAX_ITEMS = 32, class Bounds = AABB, class Point = Vector3> +class BVH_Manager { +public: + // note we are using uint32_t instead of BVHHandle, losing type safety, but this + // is for compatibility with octree + typedef void *(*PairCallback)(void *, uint32_t, T *, int, uint32_t, T *, int); + typedef void (*UnpairCallback)(void *, uint32_t, T *, int, uint32_t, T *, int, void *); + + // these 2 are crucial for fine tuning, and can be applied manually + // see the variable declarations for more info. + void params_set_node_expansion(real_t p_value) { + if (p_value >= 0.0) { + tree._node_expansion = p_value; + tree._auto_node_expansion = false; + } else { + tree._auto_node_expansion = true; + } + } + + void params_set_pairing_expansion(real_t p_value) { + if (p_value >= 0.0) { + tree._pairing_expansion = p_value; + tree._auto_pairing_expansion = false; + } else { + tree._auto_pairing_expansion = true; + } + } + + void set_pair_callback(PairCallback p_callback, void *p_userdata) { + pair_callback = p_callback; + pair_callback_userdata = p_userdata; + } + void set_unpair_callback(UnpairCallback p_callback, void *p_userdata) { + unpair_callback = p_callback; + unpair_callback_userdata = p_userdata; + } + + BVHHandle create(T *p_userdata, bool p_active, const Bounds &p_aabb = Bounds(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t p_pairable_mask = 1) { + // not sure if absolutely necessary to flush collisions here. It will cost performance to, instead + // of waiting for update, so only uncomment this if there are bugs. + if (USE_PAIRS) { + //_check_for_collisions(); + } + +#ifdef TOOLS_ENABLED + if (!USE_PAIRS) { + if (p_pairable) { + WARN_PRINT_ONCE("creating pairable item in BVH with USE_PAIRS set to false"); + } + } +#endif + + BVHHandle h = tree.item_add(p_userdata, p_active, p_aabb, p_subindex, p_pairable, p_pairable_type, p_pairable_mask); + + if (USE_PAIRS) { + // for safety initialize the expanded AABB + Bounds &expanded_aabb = tree._pairs[h.id()].expanded_aabb; + expanded_aabb = p_aabb; + expanded_aabb.grow_by(tree._pairing_expansion); + + // force a collision check no matter the AABB + if (p_active) { + _add_changed_item(h, p_aabb, false); + _check_for_collisions(true); + } + } + + return h; + } + + //////////////////////////////////////////////////// + // wrapper versions that use uint32_t instead of handle + // for backward compatibility. Less type safe + void move(uint32_t p_handle, const Bounds &p_aabb) { + BVHHandle h; + h.set(p_handle); + move(h, p_aabb); + } + + void erase(uint32_t p_handle) { + BVHHandle h; + h.set(p_handle); + erase(h); + } + + void force_collision_check(uint32_t p_handle) { + BVHHandle h; + h.set(p_handle); + force_collision_check(h); + } + + bool activate(uint32_t p_handle, const Bounds &p_aabb, bool p_delay_collision_check = false) { + BVHHandle h; + h.set(p_handle); + return activate(h, p_aabb, p_delay_collision_check); + } + + bool deactivate(uint32_t p_handle) { + BVHHandle h; + h.set(p_handle); + return deactivate(h); + } + + void set_pairable(uint32_t p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask, bool p_force_collision_check = true) { + BVHHandle h; + h.set(p_handle); + set_pairable(h, p_pairable, p_pairable_type, p_pairable_mask, p_force_collision_check); + } + + bool is_pairable(uint32_t p_handle) const { + BVHHandle h; + h.set(p_handle); + return item_is_pairable(h); + } + int get_subindex(uint32_t p_handle) const { + BVHHandle h; + h.set(p_handle); + return item_get_subindex(h); + } + + T *get(uint32_t p_handle) const { + BVHHandle h; + h.set(p_handle); + return item_get_userdata(h); + } + + //////////////////////////////////////////////////// + + void move(BVHHandle p_handle, const Bounds &p_aabb) { + if (tree.item_move(p_handle, p_aabb)) { + if (USE_PAIRS) { + _add_changed_item(p_handle, p_aabb); + } + } + } + + void erase(BVHHandle p_handle) { + // call unpair and remove all references to the item + // before deleting from the tree + if (USE_PAIRS) { + _remove_changed_item(p_handle); + } + + tree.item_remove(p_handle); + + _check_for_collisions(true); + } + + // use in conjunction with activate if you have deferred the collision check, and + // set pairable has never been called. + // (deferred collision checks are a workaround for visual server for historical reasons) + void force_collision_check(BVHHandle p_handle) { + if (USE_PAIRS) { + // the aabb should already be up to date in the BVH + Bounds aabb; + item_get_AABB(p_handle, aabb); + + // add it as changed even if aabb not different + _add_changed_item(p_handle, aabb, false); + + // force an immediate full collision check, much like calls to set_pairable + _check_for_collisions(true); + } + } + + // these should be read as set_visible for render trees, + // but generically this makes items add or remove from the + // tree internally, to speed things up by ignoring inactive items + bool activate(BVHHandle p_handle, const Bounds &p_aabb, bool p_delay_collision_check = false) { + // sending the aabb here prevents the need for the BVH to maintain + // a redundant copy of the aabb. + // returns success + if (tree.item_activate(p_handle, p_aabb)) { + if (USE_PAIRS) { + // in the special case of the render tree, when setting visibility we are using the combination of + // activate then set_pairable. This would case 2 sets of collision checks. For efficiency here we allow + // deferring to have a single collision check at the set_pairable call. + // Watch for bugs! This may cause bugs if set_pairable is not called. + if (!p_delay_collision_check) { + _add_changed_item(p_handle, p_aabb, false); + + // force an immediate collision check, much like calls to set_pairable + _check_for_collisions(true); + } + } + return true; + } + + return false; + } + + bool deactivate(BVHHandle p_handle) { + // returns success + if (tree.item_deactivate(p_handle)) { + // call unpair and remove all references to the item + // before deleting from the tree + if (USE_PAIRS) { + _remove_changed_item(p_handle); + + // force check for collisions, much like an erase was called + _check_for_collisions(true); + } + return true; + } + + return false; + } + + bool get_active(BVHHandle p_handle) const { + return tree.item_get_active(p_handle); + } + + // call e.g. once per frame (this does a trickle optimize) + void update() { + tree.update(); + _check_for_collisions(); +#ifdef BVH_INTEGRITY_CHECKS + tree.integrity_check_all(); +#endif + } + + // this can be called more frequently than per frame if necessary + void update_collisions() { + _check_for_collisions(); + } + + // prefer calling this directly as type safe + void set_pairable(const BVHHandle &p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask, bool p_force_collision_check = true) { + // Returns true if the pairing state has changed. + bool state_changed = tree.item_set_pairable(p_handle, p_pairable, p_pairable_type, p_pairable_mask); + + if (USE_PAIRS) { + // not sure if absolutely necessary to flush collisions here. It will cost performance to, instead + // of waiting for update, so only uncomment this if there are bugs. + //_check_for_collisions(); + + if ((p_force_collision_check || state_changed) && get_active(p_handle)) { + // when the pairable state changes, we need to force a collision check because newly pairable + // items may be in collision, and unpairable items might move out of collision. + // We cannot depend on waiting for the next update, because that may come much later. + Bounds aabb; + item_get_AABB(p_handle, aabb); + + // passing false disables the optimization which prevents collision checks if + // the aabb hasn't changed + _add_changed_item(p_handle, aabb, false); + + // force an immediate collision check (probably just for this one item) + // but it must be a FULL collision check, also checking pairable state and masks. + // This is because AABB intersecting objects may have changed pairable state / mask + // such that they should no longer be paired. E.g. lights. + _check_for_collisions(true); + } // only if active + } + } + + // cull tests + int cull_aabb(const Bounds &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF) { + typename BVHTREE_CLASS::CullParams params; + + params.result_count_overall = 0; + params.result_max = p_result_max; + params.result_array = p_result_array; + params.subindex_array = p_subindex_array; + params.mask = p_mask; + params.pairable_type = 0; + params.test_pairable_only = false; + params.abb.from(p_aabb); + + tree.cull_aabb(params); + + return params.result_count_overall; + } + + int cull_segment(const Point &p_from, const Point &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF) { + typename BVHTREE_CLASS::CullParams params; + + params.result_count_overall = 0; + params.result_max = p_result_max; + params.result_array = p_result_array; + params.subindex_array = p_subindex_array; + params.mask = p_mask; + params.pairable_type = 0; + + params.segment.from = p_from; + params.segment.to = p_to; + + tree.cull_segment(params); + + return params.result_count_overall; + } + + int cull_point(const Point &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF) { + typename BVHTREE_CLASS::CullParams params; + + params.result_count_overall = 0; + params.result_max = p_result_max; + params.result_array = p_result_array; + params.subindex_array = p_subindex_array; + params.mask = p_mask; + params.pairable_type = 0; + + params.point = p_point; + + tree.cull_point(params); + return params.result_count_overall; + } + + int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF) { + if (!p_convex.size()) { + return 0; + } + + Vector<Vector3> convex_points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size()); + if (convex_points.size() == 0) { + return 0; + } + + typename BVHTREE_CLASS::CullParams params; + params.result_count_overall = 0; + params.result_max = p_result_max; + params.result_array = p_result_array; + params.subindex_array = nullptr; + params.mask = p_mask; + params.pairable_type = 0; + + params.hull.planes = &p_convex[0]; + params.hull.num_planes = p_convex.size(); + params.hull.points = &convex_points[0]; + params.hull.num_points = convex_points.size(); + + tree.cull_convex(params); + + return params.result_count_overall; + } + +private: + // do this after moving etc. + void _check_for_collisions(bool p_full_check = false) { + if (!changed_items.size()) { + // noop + return; + } + + Bounds bb; + + typename BVHTREE_CLASS::CullParams params; + + params.result_count_overall = 0; + params.result_max = INT_MAX; + params.result_array = nullptr; + params.subindex_array = nullptr; + params.mask = 0xFFFFFFFF; + params.pairable_type = 0; + + for (unsigned int n = 0; n < changed_items.size(); n++) { + const BVHHandle &h = changed_items[n]; + + // use the expanded aabb for pairing + const Bounds &expanded_aabb = tree._pairs[h.id()].expanded_aabb; + BVHABB_CLASS abb; + abb.from(expanded_aabb); + + // find all the existing paired aabbs that are no longer + // paired, and send callbacks + _find_leavers(h, abb, p_full_check); + + uint32_t changed_item_ref_id = h.id(); + + // set up the test from this item. + // this includes whether to test the non pairable tree, + // and the item mask. + tree.item_fill_cullparams(h, params); + + params.abb = abb; + + params.result_count_overall = 0; // might not be needed + tree.cull_aabb(params, false); + + for (unsigned int i = 0; i < tree._cull_hits.size(); i++) { + uint32_t ref_id = tree._cull_hits[i]; + + // don't collide against ourself + if (ref_id == changed_item_ref_id) { + continue; + } + +#ifdef BVH_CHECKS + // if neither are pairable, they should ignore each other + // THIS SHOULD NEVER HAPPEN .. now we only test the pairable tree + // if the changed item is not pairable + CRASH_COND(params.test_pairable_only && !tree._extra[ref_id].pairable); +#endif + + // checkmasks is already done in the cull routine. + BVHHandle h_collidee; + h_collidee.set_id(ref_id); + + // find NEW enterers, and send callbacks for them only + _collide(h, h_collidee); + } + } + _reset(); + } + +public: + void item_get_AABB(BVHHandle p_handle, Bounds &r_aabb) { + BVHABB_CLASS abb; + tree.item_get_ABB(p_handle, abb); + abb.to(r_aabb); + } + +private: + // supplemental funcs + bool item_is_pairable(BVHHandle p_handle) const { return _get_extra(p_handle).pairable; } + T *item_get_userdata(BVHHandle p_handle) const { return _get_extra(p_handle).userdata; } + int item_get_subindex(BVHHandle p_handle) const { return _get_extra(p_handle).subindex; } + + void _unpair(BVHHandle p_from, BVHHandle p_to) { + tree._handle_sort(p_from, p_to); + + typename BVHTREE_CLASS::ItemExtra &exa = tree._extra[p_from.id()]; + typename BVHTREE_CLASS::ItemExtra &exb = tree._extra[p_to.id()]; + + // if the userdata is the same, no collisions should occur + if ((exa.userdata == exb.userdata) && exa.userdata) { + return; + } + + typename BVHTREE_CLASS::ItemPairs &pairs_from = tree._pairs[p_from.id()]; + typename BVHTREE_CLASS::ItemPairs &pairs_to = tree._pairs[p_to.id()]; + + void *ud_from = pairs_from.remove_pair_to(p_to); + pairs_to.remove_pair_to(p_from); + + // callback + if (unpair_callback) { + unpair_callback(pair_callback_userdata, p_from, exa.userdata, exa.subindex, p_to, exb.userdata, exb.subindex, ud_from); + } + } + + // returns true if unpair + bool _find_leavers_process_pair(typename BVHTREE_CLASS::ItemPairs &p_pairs_from, const BVHABB_CLASS &p_abb_from, BVHHandle p_from, BVHHandle p_to, bool p_full_check) { + BVHABB_CLASS abb_to; + tree.item_get_ABB(p_to, abb_to); + + // do they overlap? + if (p_abb_from.intersects(abb_to)) { + // the full check for pairable / non pairable and mask changes is extra expense + // this need not be done in most cases (for speed) except in the case where set_pairable is called + // where the masks etc of the objects in question may have changed + if (!p_full_check) { + return false; + } + const typename BVHTREE_CLASS::ItemExtra &exa = _get_extra(p_from); + const typename BVHTREE_CLASS::ItemExtra &exb = _get_extra(p_to); + + // one of the two must be pairable to still pair + // if neither are pairable, we always unpair + if (exa.pairable || exb.pairable) { + // the masks must still be compatible to pair + // i.e. if there is a hit between the two, then they should stay paired + if (tree._cull_pairing_mask_test_hit(exa.pairable_mask, exa.pairable_type, exb.pairable_mask, exb.pairable_type)) { + return false; + } + } + } + + _unpair(p_from, p_to); + return true; + } + + // find all the existing paired aabbs that are no longer + // paired, and send callbacks + void _find_leavers(BVHHandle p_handle, const BVHABB_CLASS &expanded_abb_from, bool p_full_check) { + typename BVHTREE_CLASS::ItemPairs &p_from = tree._pairs[p_handle.id()]; + + BVHABB_CLASS abb_from = expanded_abb_from; + + // remove from pairing list for every partner + for (unsigned int n = 0; n < p_from.extended_pairs.size(); n++) { + BVHHandle h_to = p_from.extended_pairs[n].handle; + if (_find_leavers_process_pair(p_from, abb_from, p_handle, h_to, p_full_check)) { + // we need to keep the counter n up to date if we deleted a pair + // as the number of items in p_from.extended_pairs will have decreased by 1 + // and we don't want to miss an item + n--; + } + } + } + + // find NEW enterers, and send callbacks for them only + // handle a and b + void _collide(BVHHandle p_ha, BVHHandle p_hb) { + // only have to do this oneway, lower ID then higher ID + tree._handle_sort(p_ha, p_hb); + + const typename BVHTREE_CLASS::ItemExtra &exa = _get_extra(p_ha); + const typename BVHTREE_CLASS::ItemExtra &exb = _get_extra(p_hb); + + // if the userdata is the same, no collisions should occur + if ((exa.userdata == exb.userdata) && exa.userdata) { + return; + } + + typename BVHTREE_CLASS::ItemPairs &p_from = tree._pairs[p_ha.id()]; + typename BVHTREE_CLASS::ItemPairs &p_to = tree._pairs[p_hb.id()]; + + // does this pair exist already? + // or only check the one with lower number of pairs for greater speed + if (p_from.num_pairs <= p_to.num_pairs) { + if (p_from.contains_pair_to(p_hb)) { + return; + } + } else { + if (p_to.contains_pair_to(p_ha)) { + return; + } + } + + // callback + void *callback_userdata = nullptr; + + if (pair_callback) { + callback_userdata = pair_callback(pair_callback_userdata, p_ha, exa.userdata, exa.subindex, p_hb, exb.userdata, exb.subindex); + } + + // new pair! .. only really need to store the userdata on the lower handle, but both have storage so... + p_from.add_pair_to(p_hb, callback_userdata); + p_to.add_pair_to(p_ha, callback_userdata); + } + + // if we remove an item, we need to immediately remove the pairs, to prevent reading the pair after deletion + void _remove_pairs_containing(BVHHandle p_handle) { + typename BVHTREE_CLASS::ItemPairs &p_from = tree._pairs[p_handle.id()]; + + // remove from pairing list for every partner. + // can't easily use a for loop here, because removing changes the size of the list + while (p_from.extended_pairs.size()) { + BVHHandle h_to = p_from.extended_pairs[0].handle; + _unpair(p_handle, h_to); + } + } + +private: + const typename BVHTREE_CLASS::ItemExtra &_get_extra(BVHHandle p_handle) const { + return tree._extra[p_handle.id()]; + } + const typename BVHTREE_CLASS::ItemRef &_get_ref(BVHHandle p_handle) const { + return tree._refs[p_handle.id()]; + } + + void _reset() { + changed_items.clear(); + _tick++; + } + + void _add_changed_item(BVHHandle p_handle, const Bounds &aabb, bool p_check_aabb = true) { + // Note that non pairable items can pair with pairable, + // so all types must be added to the list + + // aabb check with expanded aabb. This greatly decreases processing + // at the cost of slightly less accurate pairing checks + // Note this pairing AABB is separate from the AABB in the actual tree + Bounds &expanded_aabb = tree._pairs[p_handle.id()].expanded_aabb; + + // passing p_check_aabb false disables the optimization which prevents collision checks if + // the aabb hasn't changed. This is needed where set_pairable has been called, but the position + // has not changed. + if (p_check_aabb && expanded_aabb.encloses(aabb)) { + return; + } + + // ALWAYS update the new expanded aabb, even if already changed once + // this tick, because it is vital that the AABB is kept up to date + expanded_aabb = aabb; + expanded_aabb.grow_by(tree._pairing_expansion); + + // this code is to ensure that changed items only appear once on the updated list + // collision checking them multiple times is not needed, and repeats the same thing + uint32_t &last_updated_tick = tree._extra[p_handle.id()].last_updated_tick; + + if (last_updated_tick == _tick) { + return; // already on changed list + } + + // mark as on list + last_updated_tick = _tick; + + // add to the list + changed_items.push_back(p_handle); + } + + void _remove_changed_item(BVHHandle p_handle) { + // Care has to be taken here for items that are deleted. The ref ID + // could be reused on the same tick for new items. This is probably + // rare but should be taken into consideration + + // callbacks + _remove_pairs_containing(p_handle); + + // remove from changed items (not very efficient yet) + for (int n = 0; n < (int)changed_items.size(); n++) { + if (changed_items[n] == p_handle) { + changed_items.remove_unordered(n); + + // because we are using an unordered remove, + // the last changed item will now be at spot 'n', + // and we need to redo it, so we prevent moving on to + // the next n at the next for iteration. + n--; + } + } + + // reset the last updated tick (may not be necessary but just in case) + tree._extra[p_handle.id()].last_updated_tick = 0; + } + + PairCallback pair_callback; + UnpairCallback unpair_callback; + void *pair_callback_userdata; + void *unpair_callback_userdata; + + BVHTREE_CLASS tree; + + // for collision pairing, + // maintain a list of all items moved etc on each frame / tick + LocalVector<BVHHandle, uint32_t, true> changed_items; + uint32_t _tick; + +public: + BVH_Manager() { + _tick = 1; // start from 1 so items with 0 indicate never updated + pair_callback = nullptr; + unpair_callback = nullptr; + pair_callback_userdata = nullptr; + unpair_callback_userdata = nullptr; + } +}; + +#undef BVHTREE_CLASS + +#endif // BVH_H diff --git a/core/math/bvh_abb.h b/core/math/bvh_abb.h new file mode 100644 index 0000000000..bd9a01a87e --- /dev/null +++ b/core/math/bvh_abb.h @@ -0,0 +1,276 @@ +/*************************************************************************/ +/* bvh_abb.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef BVH_ABB_H +#define BVH_ABB_H + +// special optimized version of axis aligned bounding box +template <class Bounds = AABB, class Point = Vector3> +struct BVH_ABB { + struct ConvexHull { + // convex hulls (optional) + const Plane *planes; + int num_planes; + const Vector3 *points; + int num_points; + }; + + struct Segment { + Point from; + Point to; + }; + + enum IntersectResult { + IR_MISS = 0, + IR_PARTIAL, + IR_FULL, + }; + + // we store mins with a negative value in order to test them with SIMD + Point min; + Point neg_max; + + bool operator==(const BVH_ABB &o) const { return (min == o.min) && (neg_max == o.neg_max); } + bool operator!=(const BVH_ABB &o) const { return (*this == o) == false; } + + void set(const Point &_min, const Point &_max) { + min = _min; + neg_max = -_max; + } + + // to and from standard AABB + void from(const Bounds &p_aabb) { + min = p_aabb.position; + neg_max = -(p_aabb.position + p_aabb.size); + } + + void to(Bounds &r_aabb) const { + r_aabb.position = min; + r_aabb.size = calculate_size(); + } + + void merge(const BVH_ABB &p_o) { + for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) { + neg_max[axis] = MIN(neg_max[axis], p_o.neg_max[axis]); + min[axis] = MIN(min[axis], p_o.min[axis]); + } + } + + Point calculate_size() const { + return -neg_max - min; + } + + Point calculate_centre() const { + return Point((calculate_size() * 0.5) + min); + } + + real_t get_proximity_to(const BVH_ABB &p_b) const { + const Point d = (min - neg_max) - (p_b.min - p_b.neg_max); + real_t proximity = 0.0; + for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) { + proximity += Math::abs(d[axis]); + } + return proximity; + } + + int select_by_proximity(const BVH_ABB &p_a, const BVH_ABB &p_b) const { + return (get_proximity_to(p_a) < get_proximity_to(p_b) ? 0 : 1); + } + + uint32_t find_cutting_planes(const BVH_ABB::ConvexHull &p_hull, uint32_t *p_plane_ids) const { + uint32_t count = 0; + + for (int n = 0; n < p_hull.num_planes; n++) { + const Plane &p = p_hull.planes[n]; + if (intersects_plane(p)) { + p_plane_ids[count++] = n; + } + } + + return count; + } + + bool intersects_plane(const Plane &p_p) const { + Vector3 size = calculate_size(); + Vector3 half_extents = size * 0.5; + Vector3 ofs = min + half_extents; + + // forward side of plane? + Vector3 point_offset( + (p_p.normal.x < 0) ? -half_extents.x : half_extents.x, + (p_p.normal.y < 0) ? -half_extents.y : half_extents.y, + (p_p.normal.z < 0) ? -half_extents.z : half_extents.z); + Vector3 point = point_offset + ofs; + + if (!p_p.is_point_over(point)) { + return false; + } + + point = -point_offset + ofs; + if (p_p.is_point_over(point)) { + return false; + } + + return true; + } + + bool intersects_convex_optimized(const ConvexHull &p_hull, const uint32_t *p_plane_ids, uint32_t p_num_planes) const { + Vector3 size = calculate_size(); + Vector3 half_extents = size * 0.5; + Vector3 ofs = min + half_extents; + + for (unsigned int i = 0; i < p_num_planes; i++) { + const Plane &p = p_hull.planes[p_plane_ids[i]]; + Vector3 point( + (p.normal.x > 0) ? -half_extents.x : half_extents.x, + (p.normal.y > 0) ? -half_extents.y : half_extents.y, + (p.normal.z > 0) ? -half_extents.z : half_extents.z); + point += ofs; + if (p.is_point_over(point)) { + return false; + } + } + + return true; + } + + bool intersects_convex_partial(const ConvexHull &p_hull) const { + Bounds bb; + to(bb); + return bb.intersects_convex_shape(p_hull.planes, p_hull.num_planes, p_hull.points, p_hull.num_points); + } + + IntersectResult intersects_convex(const ConvexHull &p_hull) const { + if (intersects_convex_partial(p_hull)) { + // fully within? very important for tree checks + if (is_within_convex(p_hull)) { + return IR_FULL; + } + + return IR_PARTIAL; + } + + return IR_MISS; + } + + bool is_within_convex(const ConvexHull &p_hull) const { + // use half extents routine + Bounds bb; + to(bb); + return bb.inside_convex_shape(p_hull.planes, p_hull.num_planes); + } + + bool is_point_within_hull(const ConvexHull &p_hull, const Vector3 &p_pt) const { + for (int n = 0; n < p_hull.num_planes; n++) { + if (p_hull.planes[n].distance_to(p_pt) > 0.0f) { + return false; + } + } + return true; + } + + bool intersects_segment(const Segment &p_s) const { + Bounds bb; + to(bb); + return bb.intersects_segment(p_s.from, p_s.to); + } + + bool intersects_point(const Point &p_pt) const { + if (_any_lessthan(-p_pt, neg_max)) { + return false; + } + if (_any_lessthan(p_pt, min)) { + return false; + } + return true; + } + + bool intersects(const BVH_ABB &p_o) const { + if (_any_morethan(p_o.min, -neg_max)) { + return false; + } + if (_any_morethan(min, -p_o.neg_max)) { + return false; + } + return true; + } + + bool is_other_within(const BVH_ABB &p_o) const { + if (_any_lessthan(p_o.neg_max, neg_max)) { + return false; + } + if (_any_lessthan(p_o.min, min)) { + return false; + } + return true; + } + + void grow(const Point &p_change) { + neg_max -= p_change; + min -= p_change; + } + + void expand(real_t p_change) { + Point change; + change.set_all(p_change); + grow(change); + } + + // Actually surface area metric. + float get_area() const { + Point d = calculate_size(); + return 2.0f * (d.x * d.y + d.y * d.z + d.z * d.x); + } + + void set_to_max_opposite_extents() { + neg_max.set_all(FLT_MAX); + min = neg_max; + } + + bool _any_morethan(const Point &p_a, const Point &p_b) const { + for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) { + if (p_a[axis] > p_b[axis]) { + return true; + } + } + return false; + } + + bool _any_lessthan(const Point &p_a, const Point &p_b) const { + for (int axis = 0; axis < Point::AXIS_COUNT; ++axis) { + if (p_a[axis] < p_b[axis]) { + return true; + } + } + return false; + } +}; + +#endif // BVH_ABB_H diff --git a/core/math/bvh_cull.inc b/core/math/bvh_cull.inc new file mode 100644 index 0000000000..cba8ea6cb3 --- /dev/null +++ b/core/math/bvh_cull.inc @@ -0,0 +1,534 @@ +public: +// cull parameters is a convenient way of passing a bunch +// of arguments through the culling functions without +// writing loads of code. Not all members are used for some cull checks +struct CullParams { + int result_count_overall; // both trees + int result_count; // this tree only + int result_max; + T **result_array; + int *subindex_array; + + // nobody truly understands how masks are intended to work. + uint32_t mask; + uint32_t pairable_type; + + // optional components for different tests + Vector3 point; + BVHABB_CLASS abb; + typename BVHABB_CLASS::ConvexHull hull; + typename BVHABB_CLASS::Segment segment; + + // when collision testing, non pairable moving items + // only need to be tested against the pairable tree. + // collisions with other non pairable items are irrelevant. + bool test_pairable_only; +}; + +private: +void _cull_translate_hits(CullParams &p) { + int num_hits = _cull_hits.size(); + int left = p.result_max - p.result_count_overall; + + if (num_hits > left) { + num_hits = left; + } + + int out_n = p.result_count_overall; + + for (int n = 0; n < num_hits; n++) { + uint32_t ref_id = _cull_hits[n]; + + const ItemExtra &ex = _extra[ref_id]; + p.result_array[out_n] = ex.userdata; + + if (p.subindex_array) { + p.subindex_array[out_n] = ex.subindex; + } + + out_n++; + } + + p.result_count = num_hits; + p.result_count_overall += num_hits; +} + +public: +int cull_convex(CullParams &r_params, bool p_translate_hits = true) { + _cull_hits.clear(); + r_params.result_count = 0; + + for (int n = 0; n < NUM_TREES; n++) { + if (_root_node_id[n] == BVHCommon::INVALID) { + continue; + } + + _cull_convex_iterative(_root_node_id[n], r_params); + } + + if (p_translate_hits) { + _cull_translate_hits(r_params); + } + + return r_params.result_count; +} + +int cull_segment(CullParams &r_params, bool p_translate_hits = true) { + _cull_hits.clear(); + r_params.result_count = 0; + + for (int n = 0; n < NUM_TREES; n++) { + if (_root_node_id[n] == BVHCommon::INVALID) { + continue; + } + + _cull_segment_iterative(_root_node_id[n], r_params); + } + + if (p_translate_hits) { + _cull_translate_hits(r_params); + } + + return r_params.result_count; +} + +int cull_point(CullParams &r_params, bool p_translate_hits = true) { + _cull_hits.clear(); + r_params.result_count = 0; + + for (int n = 0; n < NUM_TREES; n++) { + if (_root_node_id[n] == BVHCommon::INVALID) { + continue; + } + + _cull_point_iterative(_root_node_id[n], r_params); + } + + if (p_translate_hits) { + _cull_translate_hits(r_params); + } + + return r_params.result_count; +} + +int cull_aabb(CullParams &r_params, bool p_translate_hits = true) { + _cull_hits.clear(); + r_params.result_count = 0; + + for (int n = 0; n < NUM_TREES; n++) { + if (_root_node_id[n] == BVHCommon::INVALID) { + continue; + } + + if ((n == 0) && r_params.test_pairable_only) { + continue; + } + + _cull_aabb_iterative(_root_node_id[n], r_params); + } + + if (p_translate_hits) { + _cull_translate_hits(r_params); + } + + return r_params.result_count; +} + +bool _cull_hits_full(const CullParams &p) { + // instead of checking every hit, we can do a lazy check for this condition. + // it isn't a problem if we write too much _cull_hits because they only the + // result_max amount will be translated and outputted. But we might as + // well stop our cull checks after the maximum has been reached. + return (int)_cull_hits.size() >= p.result_max; +} + +// write this logic once for use in all routines +// double check this as a possible source of bugs in future. +bool _cull_pairing_mask_test_hit(uint32_t p_maskA, uint32_t p_typeA, uint32_t p_maskB, uint32_t p_typeB) const { + // double check this as a possible source of bugs in future. + bool A_match_B = p_maskA & p_typeB; + + if (!A_match_B) { + bool B_match_A = p_maskB & p_typeA; + if (!B_match_A) { + return false; + } + } + + return true; +} + +void _cull_hit(uint32_t p_ref_id, CullParams &p) { + // take into account masks etc + // this would be more efficient to do before plane checks, + // but done here for ease to get started + if (USE_PAIRS) { + const ItemExtra &ex = _extra[p_ref_id]; + + if (!_cull_pairing_mask_test_hit(p.mask, p.pairable_type, ex.pairable_mask, ex.pairable_type)) { + return; + } + } + + _cull_hits.push_back(p_ref_id); +} + +bool _cull_segment_iterative(uint32_t p_node_id, CullParams &r_params) { + // our function parameters to keep on a stack + struct CullSegParams { + uint32_t node_id; + }; + + // most of the iterative functionality is contained in this helper class + BVH_IterativeInfo<CullSegParams> ii; + + // alloca must allocate the stack from this function, it cannot be allocated in the + // helper class + ii.stack = (CullSegParams *)alloca(ii.get_alloca_stacksize()); + + // seed the stack + ii.get_first()->node_id = p_node_id; + + CullSegParams csp; + + // while there are still more nodes on the stack + while (ii.pop(csp)) { + TNode &tnode = _nodes[csp.node_id]; + + if (tnode.is_leaf()) { + // lazy check for hits full up condition + if (_cull_hits_full(r_params)) { + return false; + } + + TLeaf &leaf = _node_get_leaf(tnode); + + // test children individually + for (int n = 0; n < leaf.num_items; n++) { + const BVHABB_CLASS &aabb = leaf.get_aabb(n); + + if (aabb.intersects_segment(r_params.segment)) { + uint32_t child_id = leaf.get_item_ref_id(n); + + // register hit + _cull_hit(child_id, r_params); + } + } + } else { + // test children individually + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_id = tnode.children[n]; + const BVHABB_CLASS &child_abb = _nodes[child_id].aabb; + + if (child_abb.intersects_segment(r_params.segment)) { + // add to the stack + CullSegParams *child = ii.request(); + child->node_id = child_id; + } + } + } + + } // while more nodes to pop + + // true indicates results are not full + return true; +} + +bool _cull_point_iterative(uint32_t p_node_id, CullParams &r_params) { + // our function parameters to keep on a stack + struct CullPointParams { + uint32_t node_id; + }; + + // most of the iterative functionality is contained in this helper class + BVH_IterativeInfo<CullPointParams> ii; + + // alloca must allocate the stack from this function, it cannot be allocated in the + // helper class + ii.stack = (CullPointParams *)alloca(ii.get_alloca_stacksize()); + + // seed the stack + ii.get_first()->node_id = p_node_id; + + CullPointParams cpp; + + // while there are still more nodes on the stack + while (ii.pop(cpp)) { + TNode &tnode = _nodes[cpp.node_id]; + // no hit with this node? + if (!tnode.aabb.intersects_point(r_params.point)) { + continue; + } + + if (tnode.is_leaf()) { + // lazy check for hits full up condition + if (_cull_hits_full(r_params)) { + return false; + } + + TLeaf &leaf = _node_get_leaf(tnode); + + // test children individually + for (int n = 0; n < leaf.num_items; n++) { + if (leaf.get_aabb(n).intersects_point(r_params.point)) { + uint32_t child_id = leaf.get_item_ref_id(n); + + // register hit + _cull_hit(child_id, r_params); + } + } + } else { + // test children individually + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_id = tnode.children[n]; + + // add to the stack + CullPointParams *child = ii.request(); + child->node_id = child_id; + } + } + + } // while more nodes to pop + + // true indicates results are not full + return true; +} + +bool _cull_aabb_iterative(uint32_t p_node_id, CullParams &r_params, bool p_fully_within = false) { + // our function parameters to keep on a stack + struct CullAABBParams { + uint32_t node_id; + bool fully_within; + }; + + // most of the iterative functionality is contained in this helper class + BVH_IterativeInfo<CullAABBParams> ii; + + // alloca must allocate the stack from this function, it cannot be allocated in the + // helper class + ii.stack = (CullAABBParams *)alloca(ii.get_alloca_stacksize()); + + // seed the stack + ii.get_first()->node_id = p_node_id; + ii.get_first()->fully_within = p_fully_within; + + CullAABBParams cap; + + // while there are still more nodes on the stack + while (ii.pop(cap)) { + TNode &tnode = _nodes[cap.node_id]; + + if (tnode.is_leaf()) { + // lazy check for hits full up condition + if (_cull_hits_full(r_params)) { + return false; + } + + TLeaf &leaf = _node_get_leaf(tnode); + + // if fully within we can just add all items + // as long as they pass mask checks + if (cap.fully_within) { + for (int n = 0; n < leaf.num_items; n++) { + uint32_t child_id = leaf.get_item_ref_id(n); + + // register hit + _cull_hit(child_id, r_params); + } + } else { + for (int n = 0; n < leaf.num_items; n++) { + const BVHABB_CLASS &aabb = leaf.get_aabb(n); + + if (aabb.intersects(r_params.abb)) { + uint32_t child_id = leaf.get_item_ref_id(n); + + // register hit + _cull_hit(child_id, r_params); + } + } + } // not fully within + } else { + if (!cap.fully_within) { + // test children individually + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_id = tnode.children[n]; + const BVHABB_CLASS &child_abb = _nodes[child_id].aabb; + + if (child_abb.intersects(r_params.abb)) { + // is the node totally within the aabb? + bool fully_within = r_params.abb.is_other_within(child_abb); + + // add to the stack + CullAABBParams *child = ii.request(); + + // should always return valid child + child->node_id = child_id; + child->fully_within = fully_within; + } + } + } else { + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_id = tnode.children[n]; + + // add to the stack + CullAABBParams *child = ii.request(); + + // should always return valid child + child->node_id = child_id; + child->fully_within = true; + } + } + } + + } // while more nodes to pop + + // true indicates results are not full + return true; +} + +// returns full up with results +bool _cull_convex_iterative(uint32_t p_node_id, CullParams &r_params, bool p_fully_within = false) { + // our function parameters to keep on a stack + struct CullConvexParams { + uint32_t node_id; + bool fully_within; + }; + + // most of the iterative functionality is contained in this helper class + BVH_IterativeInfo<CullConvexParams> ii; + + // alloca must allocate the stack from this function, it cannot be allocated in the + // helper class + ii.stack = (CullConvexParams *)alloca(ii.get_alloca_stacksize()); + + // seed the stack + ii.get_first()->node_id = p_node_id; + ii.get_first()->fully_within = p_fully_within; + + // preallocate these as a once off to be reused + uint32_t max_planes = r_params.hull.num_planes; + uint32_t *plane_ids = (uint32_t *)alloca(sizeof(uint32_t) * max_planes); + + CullConvexParams ccp; + + // while there are still more nodes on the stack + while (ii.pop(ccp)) { + const TNode &tnode = _nodes[ccp.node_id]; + + if (!ccp.fully_within) { + typename BVHABB_CLASS::IntersectResult res = tnode.aabb.intersects_convex(r_params.hull); + + switch (res) { + default: { + continue; // miss, just move on to the next node in the stack + } break; + case BVHABB_CLASS::IR_PARTIAL: { + } break; + case BVHABB_CLASS::IR_FULL: { + ccp.fully_within = true; + } break; + } + + } // if not fully within already + + if (tnode.is_leaf()) { + // lazy check for hits full up condition + if (_cull_hits_full(r_params)) { + return false; + } + + const TLeaf &leaf = _node_get_leaf(tnode); + + // if fully within, simply add all items to the result + // (taking into account masks) + if (ccp.fully_within) { + for (int n = 0; n < leaf.num_items; n++) { + uint32_t child_id = leaf.get_item_ref_id(n); + + // register hit + _cull_hit(child_id, r_params); + } + + } else { + // we can either use a naive check of all the planes against the AABB, + // or an optimized check, which finds in advance which of the planes can possibly + // cut the AABB, and only tests those. This can be much faster. +#define BVH_CONVEX_CULL_OPTIMIZED +#ifdef BVH_CONVEX_CULL_OPTIMIZED + // first find which planes cut the aabb + uint32_t num_planes = tnode.aabb.find_cutting_planes(r_params.hull, plane_ids); + BVH_ASSERT(num_planes <= max_planes); + +//#define BVH_CONVEX_CULL_OPTIMIZED_RIGOR_CHECK +#ifdef BVH_CONVEX_CULL_OPTIMIZED_RIGOR_CHECK + // rigorous check + uint32_t results[MAX_ITEMS]; + uint32_t num_results = 0; +#endif + + // test children individually + for (int n = 0; n < leaf.num_items; n++) { + //const Item &item = leaf.get_item(n); + const BVHABB_CLASS &aabb = leaf.get_aabb(n); + + if (aabb.intersects_convex_optimized(r_params.hull, plane_ids, num_planes)) { + uint32_t child_id = leaf.get_item_ref_id(n); + +#ifdef BVH_CONVEX_CULL_OPTIMIZED_RIGOR_CHECK + results[num_results++] = child_id; +#endif + + // register hit + _cull_hit(child_id, r_params); + } + } + +#ifdef BVH_CONVEX_CULL_OPTIMIZED_RIGOR_CHECK + uint32_t test_count = 0; + + for (int n = 0; n < leaf.num_items; n++) { + const BVHABB_CLASS &aabb = leaf.get_aabb(n); + + if (aabb.intersects_convex_partial(r_params.hull)) { + uint32_t child_id = leaf.get_item_ref_id(n); + + CRASH_COND(child_id != results[test_count++]); + CRASH_COND(test_count > num_results); + } + } +#endif + +#else + // not BVH_CONVEX_CULL_OPTIMIZED + // test children individually + for (int n = 0; n < leaf.num_items; n++) { + const BVHABB_CLASS &aabb = leaf.get_aabb(n); + + if (aabb.intersects_convex_partial(r_params.hull)) { + uint32_t child_id = leaf.get_item_ref_id(n); + + // full up with results? exit early, no point in further testing + if (!_cull_hit(child_id, r_params)) + return false; + } + } +#endif // BVH_CONVEX_CULL_OPTIMIZED + } // if not fully within + } else { + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_id = tnode.children[n]; + + // add to the stack + CullConvexParams *child = ii.request(); + + // should always return valid child + child->node_id = child_id; + child->fully_within = ccp.fully_within; + } + } + + } // while more nodes to pop + + // true indicates results are not full + return true; +} diff --git a/core/math/bvh_debug.inc b/core/math/bvh_debug.inc new file mode 100644 index 0000000000..a97304334c --- /dev/null +++ b/core/math/bvh_debug.inc @@ -0,0 +1,68 @@ +public: +#ifdef BVH_VERBOSE +void _debug_recursive_print_tree(int p_tree_id) const { + if (_root_node_id[p_tree_id] != BVHCommon::INVALID) + _debug_recursive_print_tree_node(_root_node_id[p_tree_id]); +} + +String _debug_aabb_to_string(const BVHABB_CLASS &aabb) const { + String sz = "("; + sz += itos(aabb.min.x); + sz += " ~ "; + sz += itos(-aabb.neg_max.x); + sz += ") ("; + + sz += itos(aabb.min.y); + sz += " ~ "; + sz += itos(-aabb.neg_max.y); + sz += ") ("; + + sz += itos(aabb.min.z); + sz += " ~ "; + sz += itos(-aabb.neg_max.z); + sz += ") "; + + Vector3 size = aabb.calculate_size(); + float vol = size.x * size.y * size.z; + sz += "vol " + itos(vol); + + return sz; +} + +void _debug_recursive_print_tree_node(uint32_t p_node_id, int depth = 0) const { + const TNode &tnode = _nodes[p_node_id]; + + String sz = ""; + for (int n = 0; n < depth; n++) { + sz += "\t"; + } + sz += itos(p_node_id); + + if (tnode.is_leaf()) { + sz += " L"; + sz += itos(tnode.height) + " "; + const TLeaf &leaf = _node_get_leaf(tnode); + + sz += "["; + for (int n = 0; n < leaf.num_items; n++) { + if (n) + sz += ", "; + sz += "r"; + sz += itos(leaf.get_item_ref_id(n)); + } + sz += "] "; + } else { + sz += " N"; + sz += itos(tnode.height) + " "; + } + + sz += _debug_aabb_to_string(tnode.aabb); + print_line(sz); + + if (!tnode.is_leaf()) { + for (int n = 0; n < tnode.num_children; n++) { + _debug_recursive_print_tree_node(tnode.children[n], depth + 1); + } + } +} +#endif diff --git a/core/math/bvh_integrity.inc b/core/math/bvh_integrity.inc new file mode 100644 index 0000000000..02e9d30097 --- /dev/null +++ b/core/math/bvh_integrity.inc @@ -0,0 +1,42 @@ +void _integrity_check_all() { +#ifdef BVH_INTEGRITY_CHECKS + for (int n = 0; n < NUM_TREES; n++) { + uint32_t root = _root_node_id[n]; + if (root != BVHCommon::INVALID) { + _integrity_check_down(root); + } + } +#endif +} + +void _integrity_check_up(uint32_t p_node_id) { + TNode &node = _nodes[p_node_id]; + + BVHABB_CLASS abb = node.aabb; + node_update_aabb(node); + + BVHABB_CLASS abb2 = node.aabb; + abb2.expand(-_node_expansion); + + CRASH_COND(!abb.is_other_within(abb2)); +} + +void _integrity_check_down(uint32_t p_node_id) { + const TNode &node = _nodes[p_node_id]; + + if (node.is_leaf()) { + _integrity_check_up(p_node_id); + } else { + CRASH_COND(node.num_children != 2); + + for (int n = 0; n < node.num_children; n++) { + uint32_t child_id = node.children[n]; + + // check the children parent pointers are correct + TNode &child = _nodes[child_id]; + CRASH_COND(child.parent_id != p_node_id); + + _integrity_check_down(child_id); + } + } +} diff --git a/core/math/bvh_logic.inc b/core/math/bvh_logic.inc new file mode 100644 index 0000000000..afab08f151 --- /dev/null +++ b/core/math/bvh_logic.inc @@ -0,0 +1,230 @@ + +// for slow incremental optimization, we will periodically remove each +// item from the tree and reinsert, to give it a chance to find a better position +void _logic_item_remove_and_reinsert(uint32_t p_ref_id) { + // get the reference + ItemRef &ref = _refs[p_ref_id]; + + // no need to optimize inactive items + if (!ref.is_active()) { + return; + } + + // special case of debug draw + if (ref.item_id == BVHCommon::INVALID) { + return; + } + + BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID); + + // some overlay elaborate way to find out which tree the node is in! + BVHHandle temp_handle; + temp_handle.set_id(p_ref_id); + uint32_t tree_id = _handle_get_tree_id(temp_handle); + + // remove and reinsert + BVHABB_CLASS abb; + node_remove_item(p_ref_id, tree_id, &abb); + + // we must choose where to add to tree + ref.tnode_id = _logic_choose_item_add_node(_root_node_id[tree_id], abb); + _node_add_item(ref.tnode_id, p_ref_id, abb); + + refit_upward_and_balance(ref.tnode_id, tree_id); +} + +// from randy gaul balance function +BVHABB_CLASS _logic_abb_merge(const BVHABB_CLASS &a, const BVHABB_CLASS &b) { + BVHABB_CLASS c = a; + c.merge(b); + return c; +} + +//-------------------------------------------------------------------------------------------------- +/** +@file q3DynamicAABBTree.h +@author Randy Gaul +@date 10/10/2014 + Copyright (c) 2014 Randy Gaul http://www.randygaul.net + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +//-------------------------------------------------------------------------------------------------- + +// This function is based on the 'Balance' function from Randy Gaul's qu3e +// https://github.com/RandyGaul/qu3e +// It is MODIFIED from qu3e version. +// This is the only function used (and _logic_abb_merge helper function). +int32_t _logic_balance(int32_t iA, uint32_t p_tree_id) { + // return iA; // uncomment this to bypass balance + + TNode *A = &_nodes[iA]; + + if (A->is_leaf() || A->height == 1) { + return iA; + } + + /* A + / \ + B C + / \ / \ + D E F G + */ + + CRASH_COND(A->num_children != 2); + int32_t iB = A->children[0]; + int32_t iC = A->children[1]; + TNode *B = &_nodes[iB]; + TNode *C = &_nodes[iC]; + + int32_t balance = C->height - B->height; + + // C is higher, promote C + if (balance > 1) { + int32_t iF = C->children[0]; + int32_t iG = C->children[1]; + TNode *F = &_nodes[iF]; + TNode *G = &_nodes[iG]; + + // grandParent point to C + if (A->parent_id != BVHCommon::INVALID) { + if (_nodes[A->parent_id].children[0] == iA) { + _nodes[A->parent_id].children[0] = iC; + + } else { + _nodes[A->parent_id].children[1] = iC; + } + } else { + // check this .. seems dodgy + change_root_node(iC, p_tree_id); + } + + // Swap A and C + C->children[0] = iA; + C->parent_id = A->parent_id; + A->parent_id = iC; + + // Finish rotation + if (F->height > G->height) { + C->children[1] = iF; + A->children[1] = iG; + G->parent_id = iA; + A->aabb = _logic_abb_merge(B->aabb, G->aabb); + C->aabb = _logic_abb_merge(A->aabb, F->aabb); + + A->height = 1 + MAX(B->height, G->height); + C->height = 1 + MAX(A->height, F->height); + } + + else { + C->children[1] = iG; + A->children[1] = iF; + F->parent_id = iA; + A->aabb = _logic_abb_merge(B->aabb, F->aabb); + C->aabb = _logic_abb_merge(A->aabb, G->aabb); + + A->height = 1 + MAX(B->height, F->height); + C->height = 1 + MAX(A->height, G->height); + } + + return iC; + } + + // B is higher, promote B + else if (balance < -1) { + int32_t iD = B->children[0]; + int32_t iE = B->children[1]; + TNode *D = &_nodes[iD]; + TNode *E = &_nodes[iE]; + + // grandParent point to B + if (A->parent_id != BVHCommon::INVALID) { + if (_nodes[A->parent_id].children[0] == iA) { + _nodes[A->parent_id].children[0] = iB; + } else { + _nodes[A->parent_id].children[1] = iB; + } + } + + else { + // check this .. seems dodgy + change_root_node(iB, p_tree_id); + } + + // Swap A and B + B->children[1] = iA; + B->parent_id = A->parent_id; + A->parent_id = iB; + + // Finish rotation + if (D->height > E->height) { + B->children[0] = iD; + A->children[0] = iE; + E->parent_id = iA; + A->aabb = _logic_abb_merge(C->aabb, E->aabb); + B->aabb = _logic_abb_merge(A->aabb, D->aabb); + + A->height = 1 + MAX(C->height, E->height); + B->height = 1 + MAX(A->height, D->height); + } + + else { + B->children[0] = iE; + A->children[0] = iD; + D->parent_id = iA; + A->aabb = _logic_abb_merge(C->aabb, D->aabb); + B->aabb = _logic_abb_merge(A->aabb, E->aabb); + + A->height = 1 + MAX(C->height, D->height); + B->height = 1 + MAX(A->height, E->height); + } + + return iB; + } + + return iA; +} + +// either choose an existing node to add item to, or create a new node and return this +uint32_t _logic_choose_item_add_node(uint32_t p_node_id, const BVHABB_CLASS &p_aabb) { + while (true) { + BVH_ASSERT(p_node_id != BVHCommon::INVALID); + TNode &tnode = _nodes[p_node_id]; + + if (tnode.is_leaf()) { + // if a leaf, and non full, use this to add to + if (!node_is_leaf_full(tnode)) { + return p_node_id; + } + + // else split the leaf, and use one of the children to add to + return split_leaf(p_node_id, p_aabb); + } + + // this should not happen??? + // is still happening, need to debug and find circumstances. Is not that serious + // but would be nice to prevent. I think it only happens with the root node. + if (tnode.num_children == 1) { + WARN_PRINT_ONCE("BVH::recursive_choose_item_add_node, node with 1 child, recovering"); + p_node_id = tnode.children[0]; + } else { + BVH_ASSERT(tnode.num_children == 2); + TNode &childA = _nodes[tnode.children[0]]; + TNode &childB = _nodes[tnode.children[1]]; + int which = p_aabb.select_by_proximity(childA.aabb, childB.aabb); + + p_node_id = tnode.children[which]; + } + } +} diff --git a/core/math/bvh_misc.inc b/core/math/bvh_misc.inc new file mode 100644 index 0000000000..71aa0e4fe0 --- /dev/null +++ b/core/math/bvh_misc.inc @@ -0,0 +1,55 @@ + +int _handle_get_tree_id(BVHHandle p_handle) const { + if (USE_PAIRS) { + int tree = 0; + if (_extra[p_handle.id()].pairable) { + tree = 1; + } + return tree; + } + return 0; +} + +public: +void _handle_sort(BVHHandle &p_ha, BVHHandle &p_hb) const { + if (p_ha.id() > p_hb.id()) { + BVHHandle temp = p_hb; + p_hb = p_ha; + p_ha = temp; + } +} + +private: +void create_root_node(int p_tree) { + // if there is no root node, create one + if (_root_node_id[p_tree] == BVHCommon::INVALID) { + uint32_t root_node_id; + TNode *node = _nodes.request(root_node_id); + node->clear(); + _root_node_id[p_tree] = root_node_id; + + // make the root node a leaf + uint32_t leaf_id; + TLeaf *leaf = _leaves.request(leaf_id); + leaf->clear(); + node->neg_leaf_id = -(int)leaf_id; + } +} + +bool node_is_leaf_full(TNode &tnode) const { + const TLeaf &leaf = _node_get_leaf(tnode); + return leaf.is_full(); +} + +public: +TLeaf &_node_get_leaf(TNode &tnode) { + BVH_ASSERT(tnode.is_leaf()); + return _leaves[tnode.get_leaf_id()]; +} + +const TLeaf &_node_get_leaf(const TNode &tnode) const { + BVH_ASSERT(tnode.is_leaf()); + return _leaves[tnode.get_leaf_id()]; +} + +private: diff --git a/core/math/bvh_pair.inc b/core/math/bvh_pair.inc new file mode 100644 index 0000000000..839db59a3a --- /dev/null +++ b/core/math/bvh_pair.inc @@ -0,0 +1,62 @@ +public: +// note .. maybe this can be attached to another node structure? +// depends which works best for cache. +struct ItemPairs { + struct Link { + void set(BVHHandle h, void *ud) { + handle = h; + userdata = ud; + } + BVHHandle handle; + void *userdata; + }; + + void clear() { + num_pairs = 0; + extended_pairs.reset(); + expanded_aabb = Bounds(); + } + + Bounds expanded_aabb; + + // maybe we can just use the number in the vector TODO + int32_t num_pairs; + LocalVector<Link> extended_pairs; + + void add_pair_to(BVHHandle h, void *p_userdata) { + Link temp; + temp.set(h, p_userdata); + + extended_pairs.push_back(temp); + num_pairs++; + } + + uint32_t find_pair_to(BVHHandle h) const { + for (int n = 0; n < num_pairs; n++) { + if (extended_pairs[n].handle == h) { + return n; + } + } + return -1; + } + + bool contains_pair_to(BVHHandle h) const { + return find_pair_to(h) != BVHCommon::INVALID; + } + + // return success + void *remove_pair_to(BVHHandle h) { + void *userdata = nullptr; + + for (int n = 0; n < num_pairs; n++) { + if (extended_pairs[n].handle == h) { + userdata = extended_pairs[n].userdata; + extended_pairs.remove_unordered(n); + num_pairs--; + break; + } + } + + return userdata; + } +}; diff --git a/core/math/bvh_public.inc b/core/math/bvh_public.inc new file mode 100644 index 0000000000..2c1e406712 --- /dev/null +++ b/core/math/bvh_public.inc @@ -0,0 +1,423 @@ +public: +BVHHandle item_add(T *p_userdata, bool p_active, const Bounds &p_aabb, int32_t p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask, bool p_invisible = false) { +#ifdef BVH_VERBOSE_TREE + VERBOSE_PRINT("\nitem_add BEFORE"); + _debug_recursive_print_tree(0); + VERBOSE_PRINT("\n"); +#endif + + BVHABB_CLASS abb; + abb.from(p_aabb); + + // handle to be filled with the new item ref + BVHHandle handle; + + // ref id easier to pass around than handle + uint32_t ref_id; + + // this should never fail + ItemRef *ref = _refs.request(ref_id); + + // the extra data should be parallel list to the references + uint32_t extra_id; + ItemExtra *extra = _extra.request(extra_id); + BVH_ASSERT(extra_id == ref_id); + + // pairs info + if (USE_PAIRS) { + uint32_t pairs_id; + ItemPairs *pairs = _pairs.request(pairs_id); + pairs->clear(); + BVH_ASSERT(pairs_id == ref_id); + } + + extra->subindex = p_subindex; + extra->userdata = p_userdata; + extra->last_updated_tick = 0; + + // add an active reference to the list for slow incremental optimize + // this list must be kept in sync with the references as they are added or removed. + extra->active_ref_id = _active_refs.size(); + _active_refs.push_back(ref_id); + + if (USE_PAIRS) { + extra->pairable_mask = p_pairable_mask; + extra->pairable_type = p_pairable_type; + extra->pairable = p_pairable; + } else { + // just for safety, in case this gets queried etc + extra->pairable = 0; + p_pairable = false; + } + + // assign to handle to return + handle.set_id(ref_id); + + uint32_t tree_id = 0; + if (p_pairable) { + tree_id = 1; + } + + create_root_node(tree_id); + + // we must choose where to add to tree + if (p_active) { + ref->tnode_id = _logic_choose_item_add_node(_root_node_id[tree_id], abb); + + bool refit = _node_add_item(ref->tnode_id, ref_id, abb); + + if (refit) { + // only need to refit from the parent + const TNode &add_node = _nodes[ref->tnode_id]; + if (add_node.parent_id != BVHCommon::INVALID) { + refit_upward_and_balance(add_node.parent_id, tree_id); + } + } + } else { + ref->set_inactive(); + } + +#ifdef BVH_VERBOSE + // memory use + int mem = _refs.estimate_memory_use(); + mem += _nodes.estimate_memory_use(); + + String sz = _debug_aabb_to_string(abb); + VERBOSE_PRINT("\titem_add [" + itos(ref_id) + "] " + itos(_refs.size()) + " refs,\t" + itos(_nodes.size()) + " nodes " + sz); + VERBOSE_PRINT("mem use : " + itos(mem) + ", num nodes : " + itos(_nodes.size())); + +#endif + + return handle; +} + +void _debug_print_refs() { +#ifdef BVH_VERBOSE_TREE + print_line("refs....."); + for (int n = 0; n < _refs.size(); n++) { + const ItemRef &ref = _refs[n]; + print_line("tnode_id " + itos(ref.tnode_id) + ", item_id " + itos(ref.item_id)); + } + +#endif +} + +// returns false if noop +bool item_move(BVHHandle p_handle, const Bounds &p_aabb) { + uint32_t ref_id = p_handle.id(); + + // get the reference + ItemRef &ref = _refs[ref_id]; + if (!ref.is_active()) { + return false; + } + + BVHABB_CLASS abb; + abb.from(p_aabb); + + BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID); + TNode &tnode = _nodes[ref.tnode_id]; + + // does it fit within the current aabb? + if (tnode.aabb.is_other_within(abb)) { + // do nothing .. fast path .. not moved enough to need refit + + // however we WILL update the exact aabb in the leaf, as this will be needed + // for accurate collision detection + TLeaf &leaf = _node_get_leaf(tnode); + + BVHABB_CLASS &leaf_abb = leaf.get_aabb(ref.item_id); + + // no change? + if (leaf_abb == abb) { + return false; + } + + leaf_abb = abb; + _integrity_check_all(); + + return true; + } + + uint32_t tree_id = _handle_get_tree_id(p_handle); + + // remove and reinsert + node_remove_item(ref_id, tree_id); + + // we must choose where to add to tree + ref.tnode_id = _logic_choose_item_add_node(_root_node_id[tree_id], abb); + + // add to the tree + bool needs_refit = _node_add_item(ref.tnode_id, ref_id, abb); + + // only need to refit from the PARENT + if (needs_refit) { + // only need to refit from the parent + const TNode &add_node = _nodes[ref.tnode_id]; + if (add_node.parent_id != BVHCommon::INVALID) { + // not sure we need to rebalance all the time, this can be done less often + refit_upward(add_node.parent_id); + } + //refit_upward_and_balance(add_node.parent_id); + } + + return true; +} + +void item_remove(BVHHandle p_handle) { + uint32_t ref_id = p_handle.id(); + + uint32_t tree_id = _handle_get_tree_id(p_handle); + + VERBOSE_PRINT("item_remove [" + itos(ref_id) + "] "); + + //////////////////////////////////////// + // remove the active reference from the list for slow incremental optimize + // this list must be kept in sync with the references as they are added or removed. + uint32_t active_ref_id = _extra[ref_id].active_ref_id; + uint32_t ref_id_moved_back = _active_refs[_active_refs.size() - 1]; + + // swap back and decrement for fast unordered remove + _active_refs[active_ref_id] = ref_id_moved_back; + _active_refs.resize(_active_refs.size() - 1); + + // keep the moved active reference up to date + _extra[ref_id_moved_back].active_ref_id = active_ref_id; + //////////////////////////////////////// + + // remove the item from the node (only if active) + if (_refs[ref_id].is_active()) { + node_remove_item(ref_id, tree_id); + } + + // remove the item reference + _refs.free(ref_id); + _extra.free(ref_id); + if (USE_PAIRS) { + _pairs.free(ref_id); + } + + // don't think refit_all is necessary? + //refit_all(_tree_id); + +#ifdef BVH_VERBOSE_TREE + _debug_recursive_print_tree(tree_id); +#endif +} + +// returns success +bool item_activate(BVHHandle p_handle, const Bounds &p_aabb) { + uint32_t ref_id = p_handle.id(); + ItemRef &ref = _refs[ref_id]; + if (ref.is_active()) { + // noop + return false; + } + + // add to tree + BVHABB_CLASS abb; + abb.from(p_aabb); + + uint32_t tree_id = _handle_get_tree_id(p_handle); + + // we must choose where to add to tree + ref.tnode_id = _logic_choose_item_add_node(_root_node_id[tree_id], abb); + _node_add_item(ref.tnode_id, ref_id, abb); + + refit_upward_and_balance(ref.tnode_id, tree_id); + + return true; +} + +// returns success +bool item_deactivate(BVHHandle p_handle) { + uint32_t ref_id = p_handle.id(); + ItemRef &ref = _refs[ref_id]; + if (!ref.is_active()) { + // noop + return false; + } + + uint32_t tree_id = _handle_get_tree_id(p_handle); + + // remove from tree + BVHABB_CLASS abb; + node_remove_item(ref_id, tree_id, &abb); + + // mark as inactive + ref.set_inactive(); + return true; +} + +bool item_get_active(BVHHandle p_handle) const { + uint32_t ref_id = p_handle.id(); + const ItemRef &ref = _refs[ref_id]; + return ref.is_active(); +} + +// during collision testing, we want to set the mask and whether pairable for the item testing from +void item_fill_cullparams(BVHHandle p_handle, CullParams &r_params) const { + uint32_t ref_id = p_handle.id(); + const ItemExtra &extra = _extra[ref_id]; + + // testing from a non pairable item, we only want to test pairable items + r_params.test_pairable_only = extra.pairable == 0; + + // we take into account the mask of the item testing from + r_params.mask = extra.pairable_mask; + r_params.pairable_type = extra.pairable_type; +} + +bool item_is_pairable(const BVHHandle &p_handle) { + uint32_t ref_id = p_handle.id(); + const ItemExtra &extra = _extra[ref_id]; + return extra.pairable != 0; +} + +void item_get_ABB(const BVHHandle &p_handle, BVHABB_CLASS &r_abb) { + // change tree? + uint32_t ref_id = p_handle.id(); + const ItemRef &ref = _refs[ref_id]; + + TNode &tnode = _nodes[ref.tnode_id]; + TLeaf &leaf = _node_get_leaf(tnode); + + r_abb = leaf.get_aabb(ref.item_id); +} + +bool item_set_pairable(const BVHHandle &p_handle, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) { + // change tree? + uint32_t ref_id = p_handle.id(); + + ItemExtra &ex = _extra[ref_id]; + ItemRef &ref = _refs[ref_id]; + + bool active = ref.is_active(); + bool pairable_changed = (ex.pairable != 0) != p_pairable; + bool state_changed = pairable_changed || (ex.pairable_type != p_pairable_type) || (ex.pairable_mask != p_pairable_mask); + + ex.pairable_type = p_pairable_type; + ex.pairable_mask = p_pairable_mask; + + if (active && pairable_changed) { + // record abb + TNode &tnode = _nodes[ref.tnode_id]; + TLeaf &leaf = _node_get_leaf(tnode); + BVHABB_CLASS abb = leaf.get_aabb(ref.item_id); + + // make sure current tree is correct prior to changing + uint32_t tree_id = _handle_get_tree_id(p_handle); + + // remove from old tree + node_remove_item(ref_id, tree_id); + + // we must set the pairable AFTER getting the current tree + // because the pairable status determines which tree + ex.pairable = p_pairable; + + // add to new tree + tree_id = _handle_get_tree_id(p_handle); + create_root_node(tree_id); + + // we must choose where to add to tree + ref.tnode_id = _logic_choose_item_add_node(_root_node_id[tree_id], abb); + bool needs_refit = _node_add_item(ref.tnode_id, ref_id, abb); + + // only need to refit from the PARENT + if (needs_refit) { + // only need to refit from the parent + const TNode &add_node = _nodes[ref.tnode_id]; + if (add_node.parent_id != BVHCommon::INVALID) { + refit_upward_and_balance(add_node.parent_id, tree_id); + } + } + } else { + // always keep this up to date + ex.pairable = p_pairable; + } + + return state_changed; +} + +void incremental_optimize() { + // first update all aabbs as one off step.. + // this is cheaper than doing it on each move as each leaf may get touched multiple times + // in a frame. + for (int n = 0; n < NUM_TREES; n++) { + if (_root_node_id[n] != BVHCommon::INVALID) { + refit_branch(_root_node_id[n]); + } + } + + // now do small section reinserting to get things moving + // gradually, and keep items in the right leaf + if (_current_active_ref >= _active_refs.size()) { + _current_active_ref = 0; + } + + // special case + if (!_active_refs.size()) { + return; + } + + uint32_t ref_id = _active_refs[_current_active_ref++]; + + _logic_item_remove_and_reinsert(ref_id); + +#ifdef BVH_VERBOSE + /* + // memory use + int mem_refs = _refs.estimate_memory_use(); + int mem_nodes = _nodes.estimate_memory_use(); + int mem_leaves = _leaves.estimate_memory_use(); + + String sz; + sz += "mem_refs : " + itos(mem_refs) + " "; + sz += "mem_nodes : " + itos(mem_nodes) + " "; + sz += "mem_leaves : " + itos(mem_leaves) + " "; + sz += ", num nodes : " + itos(_nodes.size()); + print_line(sz); + */ +#endif +} + +void update() { + incremental_optimize(); + + // keep the expansion values up to date with the world bound +//#define BVH_ALLOW_AUTO_EXPANSION +#ifdef BVH_ALLOW_AUTO_EXPANSION + if (_auto_node_expansion || _auto_pairing_expansion) { + BVHABB_CLASS world_bound; + world_bound.set_to_max_opposite_extents(); + + bool bound_valid = false; + + for (int n = 0; n < NUM_TREES; n++) { + uint32_t node_id = _root_node_id[n]; + if (node_id != BVHCommon::INVALID) { + world_bound.merge(_nodes[node_id].aabb); + bound_valid = true; + } + } + + // if there are no nodes, do nothing, but if there are... + if (bound_valid) { + Bounds bb; + world_bound.to(bb); + real_t size = bb.get_longest_axis_size(); + + // automatic AI decision for best parameters. + // These can be overridden in project settings. + + // these magic numbers are determined by experiment + if (_auto_node_expansion) { + _node_expansion = size * 0.025; + } + if (_auto_pairing_expansion) { + _pairing_expansion = size * 0.009; + } + } + } +#endif +} diff --git a/core/math/bvh_refit.inc b/core/math/bvh_refit.inc new file mode 100644 index 0000000000..717a3438c7 --- /dev/null +++ b/core/math/bvh_refit.inc @@ -0,0 +1,141 @@ +void _debug_node_verify_bound(uint32_t p_node_id) { + TNode &node = _nodes[p_node_id]; + BVHABB_CLASS abb_before = node.aabb; + + node_update_aabb(node); + + BVHABB_CLASS abb_after = node.aabb; + CRASH_COND(abb_before != abb_after); +} + +void node_update_aabb(TNode &tnode) { + tnode.aabb.set_to_max_opposite_extents(); + tnode.height = 0; + + if (!tnode.is_leaf()) { + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_node_id = tnode.children[n]; + + // merge with child aabb + const TNode &tchild = _nodes[child_node_id]; + tnode.aabb.merge(tchild.aabb); + + // do heights at the same time + if (tchild.height > tnode.height) { + tnode.height = tchild.height; + } + } + + // the height of a non leaf is always 1 bigger than the biggest child + tnode.height++; + +#ifdef BVH_CHECKS + if (!tnode.num_children) { + // the 'blank' aabb will screw up parent aabbs + WARN_PRINT("BVH_Tree::TNode no children, AABB is undefined"); + } +#endif + } else { + // leaf + const TLeaf &leaf = _node_get_leaf(tnode); + + for (int n = 0; n < leaf.num_items; n++) { + tnode.aabb.merge(leaf.get_aabb(n)); + } + + // now the leaf items are unexpanded, we expand only in the node AABB + tnode.aabb.expand(_node_expansion); +#ifdef BVH_CHECKS + if (!leaf.num_items) { + // the 'blank' aabb will screw up parent aabbs + WARN_PRINT("BVH_Tree::TLeaf no items, AABB is undefined"); + } +#endif + } +} + +void refit_all(int p_tree_id) { + refit_downward(_root_node_id[p_tree_id]); +} + +void refit_upward(uint32_t p_node_id) { + while (p_node_id != BVHCommon::INVALID) { + TNode &tnode = _nodes[p_node_id]; + node_update_aabb(tnode); + p_node_id = tnode.parent_id; + } +} + +void refit_upward_and_balance(uint32_t p_node_id, uint32_t p_tree_id) { + while (p_node_id != BVHCommon::INVALID) { + uint32_t before = p_node_id; + p_node_id = _logic_balance(p_node_id, p_tree_id); + + if (before != p_node_id) { + VERBOSE_PRINT("REBALANCED!"); + } + + TNode &tnode = _nodes[p_node_id]; + + // update overall aabb from the children + node_update_aabb(tnode); + + p_node_id = tnode.parent_id; + } +} + +void refit_downward(uint32_t p_node_id) { + TNode &tnode = _nodes[p_node_id]; + + // do children first + if (!tnode.is_leaf()) { + for (int n = 0; n < tnode.num_children; n++) { + refit_downward(tnode.children[n]); + } + } + + node_update_aabb(tnode); +} + +// go down to the leaves, then refit upward +void refit_branch(uint32_t p_node_id) { + // our function parameters to keep on a stack + struct RefitParams { + uint32_t node_id; + }; + + // most of the iterative functionality is contained in this helper class + BVH_IterativeInfo<RefitParams> ii; + + // alloca must allocate the stack from this function, it cannot be allocated in the + // helper class + ii.stack = (RefitParams *)alloca(ii.get_alloca_stacksize()); + + // seed the stack + ii.get_first()->node_id = p_node_id; + + RefitParams rp; + + // while there are still more nodes on the stack + while (ii.pop(rp)) { + TNode &tnode = _nodes[rp.node_id]; + + // do children first + if (!tnode.is_leaf()) { + for (int n = 0; n < tnode.num_children; n++) { + uint32_t child_id = tnode.children[n]; + + // add to the stack + RefitParams *child = ii.request(); + child->node_id = child_id; + } + } else { + // leaf .. only refit upward if dirty + TLeaf &leaf = _node_get_leaf(tnode); + if (leaf.is_dirty()) { + leaf.set_dirty(false); + refit_upward(p_node_id); + } + } + } // while more nodes to pop +} diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc new file mode 100644 index 0000000000..3fcc4c7b10 --- /dev/null +++ b/core/math/bvh_split.inc @@ -0,0 +1,294 @@ +void _split_inform_references(uint32_t p_node_id) { + TNode &node = _nodes[p_node_id]; + TLeaf &leaf = _node_get_leaf(node); + + for (int n = 0; n < leaf.num_items; n++) { + uint32_t ref_id = leaf.get_item_ref_id(n); + + ItemRef &ref = _refs[ref_id]; + ref.tnode_id = p_node_id; + ref.item_id = n; + } +} + +void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, uint16_t *group_b, const BVHABB_CLASS *temp_bounds, const BVHABB_CLASS full_bound) { + // special case for low leaf sizes .. should static compile out + if (MAX_ITEMS < 4) { + uint32_t ind = group_a[0]; + + // add to b + group_b[num_b++] = ind; + + // remove from a + group_a[0] = group_a[num_a - 1]; + num_a--; + return; + } + + Point centre = full_bound.calculate_centre(); + Point size = full_bound.calculate_size(); + + int order[3]; + + order[0] = size.min_axis(); + order[2] = size.max_axis(); + order[1] = 3 - (order[0] + order[2]); + + // simplest case, split on the longest axis + int split_axis = order[0]; + for (int a = 0; a < num_a; a++) { + uint32_t ind = group_a[a]; + + if (temp_bounds[ind].min.coord[split_axis] > centre.coord[split_axis]) { + // add to b + group_b[num_b++] = ind; + + // remove from a + group_a[a] = group_a[num_a - 1]; + num_a--; + + // do this one again, as it has been replaced + a--; + } + } + + // detect when split on longest axis failed + int min_threshold = MAX_ITEMS / 4; + int min_group_size[3]; + min_group_size[0] = MIN(num_a, num_b); + if (min_group_size[0] < min_threshold) { + // slow but sure .. first move everything back into a + for (int b = 0; b < num_b; b++) { + group_a[num_a++] = group_b[b]; + } + num_b = 0; + + // now calculate the best split + for (int axis = 1; axis < 3; axis++) { + split_axis = order[axis]; + int count = 0; + + for (int a = 0; a < num_a; a++) { + uint32_t ind = group_a[a]; + + if (temp_bounds[ind].min.coord[split_axis] > centre.coord[split_axis]) { + count++; + } + } + + min_group_size[axis] = MIN(count, num_a - count); + } // for axis + + // best axis + int best_axis = 0; + int best_min = min_group_size[0]; + for (int axis = 1; axis < 3; axis++) { + if (min_group_size[axis] > best_min) { + best_min = min_group_size[axis]; + best_axis = axis; + } + } + + // now finally do the split + if (best_min > 0) { + split_axis = order[best_axis]; + + for (int a = 0; a < num_a; a++) { + uint32_t ind = group_a[a]; + + if (temp_bounds[ind].min.coord[split_axis] > centre.coord[split_axis]) { + // add to b + group_b[num_b++] = ind; + + // remove from a + group_a[a] = group_a[num_a - 1]; + num_a--; + + // do this one again, as it has been replaced + a--; + } + } + } // if there was a split! + } // if the longest axis wasn't a good split + + // special case, none crossed threshold + if (!num_b) { + uint32_t ind = group_a[0]; + + // add to b + group_b[num_b++] = ind; + + // remove from a + group_a[0] = group_a[num_a - 1]; + num_a--; + } + // opposite problem! :) + if (!num_a) { + uint32_t ind = group_b[0]; + + // add to a + group_a[num_a++] = ind; + + // remove from b + group_b[0] = group_b[num_b - 1]; + num_b--; + } +} + +void _split_leaf_sort_groups(int &num_a, int &num_b, uint16_t *group_a, uint16_t *group_b, const BVHABB_CLASS *temp_bounds) { + BVHABB_CLASS groupb_aabb; + groupb_aabb.set_to_max_opposite_extents(); + for (int n = 0; n < num_b; n++) { + int which = group_b[n]; + groupb_aabb.merge(temp_bounds[which]); + } + BVHABB_CLASS groupb_aabb_new; + + BVHABB_CLASS rest_aabb; + + float best_size = FLT_MAX; + int best_candidate = -1; + + // find most likely from a to move into b + for (int check = 0; check < num_a; check++) { + rest_aabb.set_to_max_opposite_extents(); + groupb_aabb_new = groupb_aabb; + + // find aabb of all the rest + for (int rest = 0; rest < num_a; rest++) { + if (rest == check) { + continue; + } + + int which = group_a[rest]; + rest_aabb.merge(temp_bounds[which]); + } + + groupb_aabb_new.merge(temp_bounds[group_a[check]]); + + // now compare the sizes + float size = groupb_aabb_new.get_area() + rest_aabb.get_area(); + if (size < best_size) { + best_size = size; + best_candidate = check; + } + } + + // we should now have the best, move it from group a to group b + group_b[num_b++] = group_a[best_candidate]; + + // remove best candidate from group a + num_a--; + group_a[best_candidate] = group_a[num_a]; +} + +uint32_t split_leaf(uint32_t p_node_id, const BVHABB_CLASS &p_added_item_aabb) { + return split_leaf_complex(p_node_id, p_added_item_aabb); +} + +// aabb is the new inserted node +uint32_t split_leaf_complex(uint32_t p_node_id, const BVHABB_CLASS &p_added_item_aabb) { + VERBOSE_PRINT("split_leaf"); + + // note the tnode before and AFTER splitting may be a different address + // in memory because the vector could get relocated. So we need to reget + // the tnode after the split + BVH_ASSERT(_nodes[p_node_id].is_leaf()); + + // first create child leaf nodes + uint32_t *child_ids = (uint32_t *)alloca(sizeof(uint32_t) * MAX_CHILDREN); + + for (int n = 0; n < MAX_CHILDREN; n++) { + // create node children + TNode *child_node = _nodes.request(child_ids[n]); + + child_node->clear(); + + // back link to parent + child_node->parent_id = p_node_id; + + // make each child a leaf node + node_make_leaf(child_ids[n]); + } + + // don't get any leaves or nodes till AFTER the split + TNode &tnode = _nodes[p_node_id]; + uint32_t orig_leaf_id = tnode.get_leaf_id(); + const TLeaf &orig_leaf = _node_get_leaf(tnode); + + // store the final child ids + for (int n = 0; n < MAX_CHILDREN; n++) { + tnode.children[n] = child_ids[n]; + } + + // mark as no longer a leaf node + tnode.num_children = MAX_CHILDREN; + + // 2 groups, A and B, and assign children to each to split equally + int max_children = orig_leaf.num_items + 1; // plus 1 for the wildcard .. the item being added + //CRASH_COND(max_children > MAX_CHILDREN); + + uint16_t *group_a = (uint16_t *)alloca(sizeof(uint16_t) * max_children); + uint16_t *group_b = (uint16_t *)alloca(sizeof(uint16_t) * max_children); + + // we are copying the ABBs. This is ugly, but we need one extra for the inserted item... + BVHABB_CLASS *temp_bounds = (BVHABB_CLASS *)alloca(sizeof(BVHABB_CLASS) * max_children); + + int num_a = max_children; + int num_b = 0; + + // setup - start with all in group a + for (int n = 0; n < orig_leaf.num_items; n++) { + group_a[n] = n; + temp_bounds[n] = orig_leaf.get_aabb(n); + } + // wildcard + int wildcard = orig_leaf.num_items; + + group_a[wildcard] = wildcard; + temp_bounds[wildcard] = p_added_item_aabb; + + // we can choose here either an equal split, or just 1 in the new leaf + _split_leaf_sort_groups_simple(num_a, num_b, group_a, group_b, temp_bounds, tnode.aabb); + + uint32_t wildcard_node = BVHCommon::INVALID; + + // now there should be equal numbers in both groups + for (int n = 0; n < num_a; n++) { + int which = group_a[n]; + + if (which != wildcard) { + const BVHABB_CLASS &source_item_aabb = orig_leaf.get_aabb(which); + uint32_t source_item_ref_id = orig_leaf.get_item_ref_id(which); + //const Item &source_item = orig_leaf.get_item(which); + _node_add_item(tnode.children[0], source_item_ref_id, source_item_aabb); + } else { + wildcard_node = tnode.children[0]; + } + } + for (int n = 0; n < num_b; n++) { + int which = group_b[n]; + + if (which != wildcard) { + const BVHABB_CLASS &source_item_aabb = orig_leaf.get_aabb(which); + uint32_t source_item_ref_id = orig_leaf.get_item_ref_id(which); + //const Item &source_item = orig_leaf.get_item(which); + _node_add_item(tnode.children[1], source_item_ref_id, source_item_aabb); + } else { + wildcard_node = tnode.children[1]; + } + } + + // now remove all items from the parent and replace with the child nodes + _leaves.free(orig_leaf_id); + + // we should keep the references up to date! + for (int n = 0; n < MAX_CHILDREN; n++) { + _split_inform_references(tnode.children[n]); + } + + refit_upward(p_node_id); + + BVH_ASSERT(wildcard_node != BVHCommon::INVALID); + return wildcard_node; +} diff --git a/core/math/bvh_structs.inc b/core/math/bvh_structs.inc new file mode 100644 index 0000000000..1d1e0e6468 --- /dev/null +++ b/core/math/bvh_structs.inc @@ -0,0 +1,180 @@ + +public: +struct ItemRef { + uint32_t tnode_id; // -1 is invalid + uint32_t item_id; // in the leaf + + bool is_active() const { return tnode_id != BVHCommon::INACTIVE; } + void set_inactive() { + tnode_id = BVHCommon::INACTIVE; + item_id = BVHCommon::INACTIVE; + } +}; + +// extra info kept in separate parallel list to the references, +// as this is less used as keeps cache better +struct ItemExtra { + uint32_t last_updated_tick; + uint32_t pairable; + uint32_t pairable_mask; + uint32_t pairable_type; + + int32_t subindex; + + // the active reference is a separate list of which references + // are active so that we can slowly iterate through it over many frames for + // slow optimize. + uint32_t active_ref_id; + + T *userdata; +}; + +// this is an item OR a child node depending on whether a leaf node +struct Item { + BVHABB_CLASS aabb; + uint32_t item_ref_id; +}; + +// tree leaf +struct TLeaf { + uint16_t num_items; + +private: + uint16_t dirty; + // separate data orientated lists for faster SIMD traversal + uint32_t item_ref_ids[MAX_ITEMS]; + BVHABB_CLASS aabbs[MAX_ITEMS]; + +public: + // accessors + BVHABB_CLASS &get_aabb(uint32_t p_id) { return aabbs[p_id]; } + const BVHABB_CLASS &get_aabb(uint32_t p_id) const { return aabbs[p_id]; } + + uint32_t &get_item_ref_id(uint32_t p_id) { return item_ref_ids[p_id]; } + const uint32_t &get_item_ref_id(uint32_t p_id) const { return item_ref_ids[p_id]; } + + bool is_dirty() const { return dirty; } + void set_dirty(bool p) { dirty = p; } + + void clear() { + num_items = 0; + set_dirty(true); + } + bool is_full() const { return num_items >= MAX_ITEMS; } + + void remove_item_unordered(uint32_t p_id) { + BVH_ASSERT(p_id < num_items); + num_items--; + aabbs[p_id] = aabbs[num_items]; + item_ref_ids[p_id] = item_ref_ids[num_items]; + } + + uint32_t request_item() { + if (num_items < MAX_ITEMS) { + uint32_t id = num_items; + num_items++; + return id; + } + return -1; + } +}; + +// tree node +struct TNode { + BVHABB_CLASS aabb; + // either number of children if positive + // or leaf id if negative (leaf id 0 is disallowed) + union { + int32_t num_children; + int32_t neg_leaf_id; + }; + uint32_t parent_id; // or -1 + uint16_t children[MAX_CHILDREN]; + + // height in the tree, where leaves are 0, and all above are 1+ + // (or the highest where there is a tie off) + int32_t height; + + bool is_leaf() const { return num_children < 0; } + void set_leaf_id(int id) { neg_leaf_id = -id; } + int get_leaf_id() const { return -neg_leaf_id; } + + void clear() { + num_children = 0; + parent_id = BVHCommon::INVALID; + height = 0; // or -1 for testing + + // for safety set to improbable value + aabb.set_to_max_opposite_extents(); + + // other members are not blanked for speed .. they may be uninitialized + } + + bool is_full_of_children() const { return num_children >= MAX_CHILDREN; } + + void remove_child_internal(uint32_t child_num) { + children[child_num] = children[num_children - 1]; + num_children--; + } + + int find_child(uint32_t p_child_node_id) { + BVH_ASSERT(!is_leaf()); + + for (int n = 0; n < num_children; n++) { + if (children[n] == p_child_node_id) { + return n; + } + } + + // not found + return -1; + } +}; + +// instead of using linked list we maintain +// item references (for quick lookup) +PooledList<ItemRef, true> _refs; +PooledList<ItemExtra, true> _extra; +PooledList<ItemPairs> _pairs; + +// these 2 are not in sync .. nodes != leaves! +PooledList<TNode, true> _nodes; +PooledList<TLeaf, true> _leaves; + +// we can maintain an un-ordered list of which references are active, +// in order to do a slow incremental optimize of the tree over each frame. +// This will work best if dynamic objects and static objects are in a different tree. +LocalVector<uint32_t, uint32_t, true> _active_refs; +uint32_t _current_active_ref = 0; + +// instead of translating directly to the userdata output, +// we keep an intermediate list of hits as reference IDs, which can be used +// for pairing collision detection +LocalVector<uint32_t, uint32_t, true> _cull_hits; + +// we now have multiple root nodes, allowing us to store +// more than 1 tree. This can be more efficient, while sharing the same +// common lists +enum { NUM_TREES = 2, +}; + +// Tree 0 - Non pairable +// Tree 1 - Pairable +// This is more efficient because in physics we only need check non pairable against the pairable tree. +uint32_t _root_node_id[NUM_TREES]; + +// these values may need tweaking according to the project +// the bound of the world, and the average velocities of the objects + +// node expansion is important in the rendering tree +// larger values give less re-insertion as items move... +// but on the other hand over estimates the bounding box of nodes. +// we can either use auto mode, where the expansion is based on the root node size, or specify manually +real_t _node_expansion = 0.5; +bool _auto_node_expansion = true; + +// pairing expansion important for physics pairing +// larger values gives more 'sticky' pairing, and is less likely to exhibit tunneling +// we can either use auto mode, where the expansion is based on the root node size, or specify manually +real_t _pairing_expansion = 0.1; +bool _auto_pairing_expansion = true; diff --git a/core/math/bvh_tree.h b/core/math/bvh_tree.h new file mode 100644 index 0000000000..3169d31ec7 --- /dev/null +++ b/core/math/bvh_tree.h @@ -0,0 +1,421 @@ +/*************************************************************************/ +/* bvh_tree.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef BVH_TREE_H +#define BVH_TREE_H + +// BVH Tree +// This is an implementation of a dynamic BVH with templated leaf size. +// This differs from most dynamic BVH in that it can handle more than 1 object +// in leaf nodes. This can make it far more efficient in certain circumstances. +// It also means that the splitting logic etc have to be completely different +// to a simpler tree. +// Note that MAX_CHILDREN should be fixed at 2 for now. + +#include "core/math/aabb.h" +#include "core/math/bvh_abb.h" +#include "core/math/geometry_3d.h" +#include "core/math/vector3.h" +#include "core/string/print_string.h" +#include "core/templates/local_vector.h" +#include "core/templates/pooled_list.h" +#include <limits.h> + +#define BVHABB_CLASS BVH_ABB<Bounds, Point> + +// never do these checks in release +#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) +//#define BVH_VERBOSE +//#define BVH_VERBOSE_TREE + +//#define BVH_VERBOSE_FRAME +//#define BVH_CHECKS +//#define BVH_INTEGRITY_CHECKS +#endif + +// debug only assert +#ifdef BVH_CHECKS +#define BVH_ASSERT(a) CRASH_COND((a) == false) +#else +#define BVH_ASSERT(a) +#endif + +#ifdef BVH_VERBOSE +#define VERBOSE_PRINT print_line +#else +#define VERBOSE_PRINT(a) +#endif + +// really just a namespace +struct BVHCommon { + // these could possibly also be the same constant, + // although this may be useful for debugging. + // or use zero for invalid and +1 based indices. + static const uint32_t INVALID = (0xffffffff); + static const uint32_t INACTIVE = (0xfffffffe); +}; + +// really a handle, can be anything +// note that zero is a valid reference for the BVH .. this may involve using +// a plus one based ID for clients that expect 0 to be invalid. +struct BVHHandle { + // conversion operator + operator uint32_t() const { return _data; } + void set(uint32_t p_value) { _data = p_value; } + + uint32_t _data; + + void set_invalid() { _data = BVHCommon::INVALID; } + bool is_invalid() const { return _data == BVHCommon::INVALID; } + uint32_t id() const { return _data; } + void set_id(uint32_t p_id) { _data = p_id; } + + bool operator==(const BVHHandle &p_h) const { return _data == p_h._data; } + bool operator!=(const BVHHandle &p_h) const { return (*this == p_h) == false; } +}; + +// helper class to make iterative versions of recursive functions +template <class T> +class BVH_IterativeInfo { +public: + enum { + ALLOCA_STACK_SIZE = 128 + }; + + int32_t depth = 1; + int32_t threshold = ALLOCA_STACK_SIZE - 2; + T *stack; + //only used in rare occasions when you run out of alloca memory + // because tree is too unbalanced. + LocalVector<T> aux_stack; + int32_t get_alloca_stacksize() const { return ALLOCA_STACK_SIZE * sizeof(T); } + + T *get_first() const { + return &stack[0]; + } + + // pop the last member of the stack, or return false + bool pop(T &r_value) { + if (!depth) { + return false; + } + + depth--; + r_value = stack[depth]; + return true; + } + + // request new addition to stack + T *request() { + if (depth > threshold) { + if (aux_stack.is_empty()) { + aux_stack.resize(ALLOCA_STACK_SIZE * 2); + memcpy(aux_stack.ptr(), stack, get_alloca_stacksize()); + } else { + aux_stack.resize(aux_stack.size() * 2); + } + stack = aux_stack.ptr(); + threshold = aux_stack.size() - 2; + } + return &stack[depth++]; + } +}; + +template <class T, int MAX_CHILDREN, int MAX_ITEMS, bool USE_PAIRS = false, class Bounds = AABB, class Point = Vector3> +class BVH_Tree { + friend class BVH; + +#include "bvh_pair.inc" +#include "bvh_structs.inc" + +public: + BVH_Tree() { + for (int n = 0; n < NUM_TREES; n++) { + _root_node_id[n] = BVHCommon::INVALID; + } + + // disallow zero leaf ids + // (as these ids are stored as negative numbers in the node) + uint32_t dummy_leaf_id; + _leaves.request(dummy_leaf_id); + } + +private: + bool node_add_child(uint32_t p_node_id, uint32_t p_child_node_id) { + TNode &tnode = _nodes[p_node_id]; + if (tnode.is_full_of_children()) { + return false; + } + + tnode.children[tnode.num_children] = p_child_node_id; + tnode.num_children += 1; + + // back link in the child to the parent + TNode &tnode_child = _nodes[p_child_node_id]; + tnode_child.parent_id = p_node_id; + + return true; + } + + void node_replace_child(uint32_t p_parent_id, uint32_t p_old_child_id, uint32_t p_new_child_id) { + TNode &parent = _nodes[p_parent_id]; + BVH_ASSERT(!parent.is_leaf()); + + int child_num = parent.find_child(p_old_child_id); + BVH_ASSERT(child_num != BVHCommon::INVALID); + parent.children[child_num] = p_new_child_id; + + TNode &new_child = _nodes[p_new_child_id]; + new_child.parent_id = p_parent_id; + } + + void node_remove_child(uint32_t p_parent_id, uint32_t p_child_id, uint32_t p_tree_id, bool p_prevent_sibling = false) { + TNode &parent = _nodes[p_parent_id]; + BVH_ASSERT(!parent.is_leaf()); + + int child_num = parent.find_child(p_child_id); + BVH_ASSERT(child_num != BVHCommon::INVALID); + + parent.remove_child_internal(child_num); + + // no need to keep back references for children at the moment + + uint32_t sibling_id; // always a node id, as tnode is never a leaf + bool sibling_present = false; + + // if there are more children, or this is the root node, don't try and delete + if (parent.num_children > 1) { + return; + } + + // if there is 1 sibling, it can be moved to be a child of the + if (parent.num_children == 1) { + // else there is now a redundant node with one child, which can be removed + sibling_id = parent.children[0]; + sibling_present = true; + } + + // now there may be no children in this node .. in which case it can be deleted + // remove node if empty + // remove link from parent + uint32_t grandparent_id = parent.parent_id; + + // special case for root node + if (grandparent_id == BVHCommon::INVALID) { + if (sibling_present) { + // change the root node + change_root_node(sibling_id, p_tree_id); + + // delete the old root node as no longer needed + _nodes.free(p_parent_id); + } + + return; + } + + if (sibling_present) { + node_replace_child(grandparent_id, p_parent_id, sibling_id); + } else { + node_remove_child(grandparent_id, p_parent_id, p_tree_id, true); + } + + // put the node on the free list to recycle + _nodes.free(p_parent_id); + } + + void change_root_node(uint32_t p_new_root_id, uint32_t p_tree_id) { + _root_node_id[p_tree_id] = p_new_root_id; + TNode &root = _nodes[p_new_root_id]; + + // mark no parent + root.parent_id = BVHCommon::INVALID; + } + + void node_make_leaf(uint32_t p_node_id) { + uint32_t child_leaf_id; + TLeaf *child_leaf = _leaves.request(child_leaf_id); + child_leaf->clear(); + + // zero is reserved at startup, to prevent this id being used + // (as they are stored as negative values in the node, and zero is already taken) + BVH_ASSERT(child_leaf_id != 0); + + TNode &node = _nodes[p_node_id]; + node.neg_leaf_id = -(int)child_leaf_id; + } + + void node_remove_item(uint32_t p_ref_id, uint32_t p_tree_id, BVHABB_CLASS *r_old_aabb = nullptr) { + // get the reference + ItemRef &ref = _refs[p_ref_id]; + uint32_t owner_node_id = ref.tnode_id; + + // debug draw special + // This may not be needed + if (owner_node_id == BVHCommon::INVALID) { + return; + } + + TNode &tnode = _nodes[owner_node_id]; + CRASH_COND(!tnode.is_leaf()); + + TLeaf &leaf = _node_get_leaf(tnode); + + // if the aabb is not determining the corner size, then there is no need to refit! + // (optimization, as merging AABBs takes a lot of time) + const BVHABB_CLASS &old_aabb = leaf.get_aabb(ref.item_id); + + // shrink a little to prevent using corner aabbs + // in order to miss the corners first we shrink by node_expansion + // (which is added to the overall bound of the leaf), then we also + // shrink by an epsilon, in order to miss out the very corner aabbs + // which are important in determining the bound. Any other aabb + // within this can be removed and not affect the overall bound. + BVHABB_CLASS node_bound = tnode.aabb; + node_bound.expand(-_node_expansion - 0.001f); + bool refit = true; + + if (node_bound.is_other_within(old_aabb)) { + refit = false; + } + + // record the old aabb if required (for incremental remove_and_reinsert) + if (r_old_aabb) { + *r_old_aabb = old_aabb; + } + + leaf.remove_item_unordered(ref.item_id); + + if (leaf.num_items) { + // the swapped item has to have its reference changed to, to point to the new item id + uint32_t swapped_ref_id = leaf.get_item_ref_id(ref.item_id); + + ItemRef &swapped_ref = _refs[swapped_ref_id]; + + swapped_ref.item_id = ref.item_id; + + // only have to refit if it is an edge item + // This is a VERY EXPENSIVE STEP + // we defer the refit updates until the update function is called once per frame + if (refit) { + leaf.set_dirty(true); + } + } else { + // remove node if empty + // remove link from parent + if (tnode.parent_id != BVHCommon::INVALID) { + // DANGER .. this can potentially end up with root node with 1 child ... + // we don't want this and must check for it + + uint32_t parent_id = tnode.parent_id; + + node_remove_child(parent_id, owner_node_id, p_tree_id); + refit_upward(parent_id); + + // put the node on the free list to recycle + _nodes.free(owner_node_id); + } + + // else if no parent, it is the root node. Do not delete + } + + ref.tnode_id = BVHCommon::INVALID; + ref.item_id = BVHCommon::INVALID; // unset + } + + // returns true if needs refit of PARENT tree only, the node itself AABB is calculated + // within this routine + bool _node_add_item(uint32_t p_node_id, uint32_t p_ref_id, const BVHABB_CLASS &p_aabb) { + ItemRef &ref = _refs[p_ref_id]; + ref.tnode_id = p_node_id; + + TNode &node = _nodes[p_node_id]; + BVH_ASSERT(node.is_leaf()); + TLeaf &leaf = _node_get_leaf(node); + + // optimization - we only need to do a refit + // if the added item is changing the AABB of the node. + // in most cases it won't. + bool needs_refit = true; + + // expand bound now + BVHABB_CLASS expanded = p_aabb; + expanded.expand(_node_expansion); + + // the bound will only be valid if there is an item in there already + if (leaf.num_items) { + if (node.aabb.is_other_within(expanded)) { + // no change to node AABBs + needs_refit = false; + } else { + node.aabb.merge(expanded); + } + } else { + // bound of the node = the new aabb + node.aabb = expanded; + } + + ref.item_id = leaf.request_item(); + BVH_ASSERT(ref.item_id != BVHCommon::INVALID); + + // set the aabb of the new item + leaf.get_aabb(ref.item_id) = p_aabb; + + // back reference on the item back to the item reference + leaf.get_item_ref_id(ref.item_id) = p_ref_id; + + return needs_refit; + } + + uint32_t _node_create_another_child(uint32_t p_node_id, const BVHABB_CLASS &p_aabb) { + uint32_t child_node_id; + TNode *child_node = _nodes.request(child_node_id); + child_node->clear(); + + // may not be necessary + child_node->aabb = p_aabb; + + node_add_child(p_node_id, child_node_id); + + return child_node_id; + } + +#include "bvh_cull.inc" +#include "bvh_debug.inc" +#include "bvh_integrity.inc" +#include "bvh_logic.inc" +#include "bvh_misc.inc" +#include "bvh_public.inc" +#include "bvh_refit.inc" +#include "bvh_split.inc" +}; + +#undef VERBOSE_PRINT + +#endif // BVH_TREE_H diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp new file mode 100644 index 0000000000..682a7ea39e --- /dev/null +++ b/core/math/convex_hull.cpp @@ -0,0 +1,2290 @@ +/*************************************************************************/ +/* convex_hull.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +/* + * Based on Godot's patched VHACD-version of Bullet's btConvexHullComputer. + * See /thirdparty/vhacd/btConvexHullComputer.cpp at 64403ddcab9f1dca2408f0a412a22d899708bbb1 + * In turn, based on /src/LinearMath/btConvexHullComputer.cpp in <https://github.com/bulletphysics/bullet3> + * at 73b217fb07e7e3ce126caeb28ab3c9ddd0718467 + * + * Changes: + * - int32_t is consistently used instead of int in some cases + * - integrated patch db0d6c92927f5a1358b887f2645c11f3014f0e8a from Bullet (CWE-190 integer overflow in btConvexHullComputer) + * - adapted to Godot's code style + * - replaced Bullet's types (e.g. vectors) with Godot's + * - replaced custom Pool implementation with PagedAllocator + */ + +/* +Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "convex_hull.h" + +#include "core/error/error_macros.h" +#include "core/math/aabb.h" +#include "core/math/math_defs.h" +#include "core/os/memory.h" +#include "core/templates/paged_allocator.h" + +#include <string.h> + +//#define DEBUG_CONVEX_HULL +//#define SHOW_ITERATIONS + +// -- GODOT start -- +// Assembly optimizations are not used at the moment. +//#define USE_X86_64_ASM +// -- GODOT end -- + +#ifdef DEBUG_ENABLED +#define CHULL_ASSERT(m_cond) \ + do { \ + if (unlikely(!(m_cond))) { \ + ERR_PRINT("Assertion \"" _STR(m_cond) "\" failed."); \ + } \ + } while (0) +#else +#define CHULL_ASSERT(m_cond) \ + do { \ + } while (0) +#endif + +#if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS) +#include <stdio.h> +#endif + +// Convex hull implementation based on Preparata and Hong +// Ole Kniemeyer, MAXON Computer GmbH +class ConvexHullInternal { +public: + class Point64 { + public: + int64_t x; + int64_t y; + int64_t z; + + Point64(int64_t p_x, int64_t p_y, int64_t p_z) { + x = p_x; + y = p_y; + z = p_z; + } + + bool is_zero() { + return (x == 0) && (y == 0) && (z == 0); + } + + int64_t dot(const Point64 &b) const { + return x * b.x + y * b.y + z * b.z; + } + }; + + class Point32 { + public: + int32_t x = 0; + int32_t y = 0; + int32_t z = 0; + int32_t index = -1; + + Point32() { + } + + Point32(int32_t p_x, int32_t p_y, int32_t p_z) { + x = p_x; + y = p_y; + z = p_z; + } + + bool operator==(const Point32 &b) const { + return (x == b.x) && (y == b.y) && (z == b.z); + } + + bool operator!=(const Point32 &b) const { + return (x != b.x) || (y != b.y) || (z != b.z); + } + + bool is_zero() { + return (x == 0) && (y == 0) && (z == 0); + } + + Point64 cross(const Point32 &b) const { + return Point64((int64_t)y * b.z - (int64_t)z * b.y, (int64_t)z * b.x - (int64_t)x * b.z, (int64_t)x * b.y - (int64_t)y * b.x); + } + + Point64 cross(const Point64 &b) const { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + int64_t dot(const Point32 &b) const { + return (int64_t)x * b.x + (int64_t)y * b.y + (int64_t)z * b.z; + } + + int64_t dot(const Point64 &b) const { + return x * b.x + y * b.y + z * b.z; + } + + Point32 operator+(const Point32 &b) const { + return Point32(x + b.x, y + b.y, z + b.z); + } + + Point32 operator-(const Point32 &b) const { + return Point32(x - b.x, y - b.y, z - b.z); + } + }; + + class Int128 { + public: + uint64_t low = 0; + uint64_t high = 0; + + Int128() { + } + + Int128(uint64_t p_low, uint64_t p_high) { + low = p_low; + high = p_high; + } + + Int128(uint64_t p_low) { + low = p_low; + high = 0; + } + + Int128(int64_t p_value) { + low = p_value; + if (p_value >= 0) { + high = 0; + } else { + high = (uint64_t)-1LL; + } + } + + static Int128 mul(int64_t a, int64_t b); + + static Int128 mul(uint64_t a, uint64_t b); + + Int128 operator-() const { + return Int128((uint64_t) - (int64_t)low, ~high + (low == 0)); + } + + Int128 operator+(const Int128 &b) const { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__("addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; +#else + uint64_t lo = low + b.low; + return Int128(lo, high + b.high + (lo < low)); +#endif + } + + Int128 operator-(const Int128 &b) const { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__("subq %[bl], %[rl]\n\t" + "sbbq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; +#else + return *this + -b; +#endif + } + + Int128 &operator+=(const Int128 &b) { +#ifdef USE_X86_64_ASM + __asm__("addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(low), [rh] "=r"(high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); +#else + uint64_t lo = low + b.low; + if (lo < low) { + ++high; + } + low = lo; + high += b.high; +#endif + return *this; + } + + Int128 &operator++() { + if (++low == 0) { + ++high; + } + return *this; + } + + Int128 operator*(int64_t b) const; + + real_t to_scalar() const { + return ((int64_t)high >= 0) ? real_t(high) * (real_t(0x100000000LL) * real_t(0x100000000LL)) + real_t(low) : -(-*this).to_scalar(); + } + + int32_t get_sign() const { + return ((int64_t)high < 0) ? -1 : (high || low) ? 1 : + 0; + } + + bool operator<(const Int128 &b) const { + return (high < b.high) || ((high == b.high) && (low < b.low)); + } + + int32_t ucmp(const Int128 &b) const { + if (high < b.high) { + return -1; + } + if (high > b.high) { + return 1; + } + if (low < b.low) { + return -1; + } + if (low > b.low) { + return 1; + } + return 0; + } + }; + + class Rational64 { + private: + uint64_t numerator; + uint64_t denominator; + int32_t sign; + + public: + Rational64(int64_t p_numerator, int64_t p_denominator) { + if (p_numerator > 0) { + sign = 1; + numerator = (uint64_t)p_numerator; + } else if (p_numerator < 0) { + sign = -1; + numerator = (uint64_t)-p_numerator; + } else { + sign = 0; + numerator = 0; + } + if (p_denominator > 0) { + denominator = (uint64_t)p_denominator; + } else if (p_denominator < 0) { + sign = -sign; + denominator = (uint64_t)-p_denominator; + } else { + denominator = 0; + } + } + + bool is_negative_infinity() const { + return (sign < 0) && (denominator == 0); + } + + bool is_nan() const { + return (sign == 0) && (denominator == 0); + } + + int32_t compare(const Rational64 &b) const; + + real_t to_scalar() const { + return sign * ((denominator == 0) ? FLT_MAX : (real_t)numerator / denominator); + } + }; + + class Rational128 { + private: + Int128 numerator; + Int128 denominator; + int32_t sign; + bool is_int_64; + + public: + Rational128(int64_t p_value) { + if (p_value > 0) { + sign = 1; + this->numerator = p_value; + } else if (p_value < 0) { + sign = -1; + this->numerator = -p_value; + } else { + sign = 0; + this->numerator = (uint64_t)0; + } + this->denominator = (uint64_t)1; + is_int_64 = true; + } + + Rational128(const Int128 &p_numerator, const Int128 &p_denominator) { + sign = p_numerator.get_sign(); + if (sign >= 0) { + this->numerator = p_numerator; + } else { + this->numerator = -p_numerator; + } + int32_t dsign = p_denominator.get_sign(); + if (dsign >= 0) { + this->denominator = p_denominator; + } else { + sign = -sign; + this->denominator = -p_denominator; + } + is_int_64 = false; + } + + int32_t compare(const Rational128 &b) const; + + int32_t compare(int64_t b) const; + + real_t to_scalar() const { + return sign * ((denominator.get_sign() == 0) ? FLT_MAX : numerator.to_scalar() / denominator.to_scalar()); + } + }; + + class PointR128 { + public: + Int128 x; + Int128 y; + Int128 z; + Int128 denominator; + + PointR128() { + } + + PointR128(Int128 p_x, Int128 p_y, Int128 p_z, Int128 p_denominator) { + x = p_x; + y = p_y; + z = p_z; + denominator = p_denominator; + } + + real_t xvalue() const { + return x.to_scalar() / denominator.to_scalar(); + } + + real_t yvalue() const { + return y.to_scalar() / denominator.to_scalar(); + } + + real_t zvalue() const { + return z.to_scalar() / denominator.to_scalar(); + } + }; + + class Edge; + class Face; + + class Vertex { + public: + Vertex *next = nullptr; + Vertex *prev = nullptr; + Edge *edges = nullptr; + Face *first_nearby_face = nullptr; + Face *last_nearby_face = nullptr; + PointR128 point128; + Point32 point; + int32_t copy = -1; + + Vertex() { + } + +#ifdef DEBUG_CONVEX_HULL + void print() { + printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); + } + + void print_graph(); +#endif + + Point32 operator-(const Vertex &b) const { + return point - b.point; + } + + Rational128 dot(const Point64 &b) const { + return (point.index >= 0) ? Rational128(point.dot(b)) : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); + } + + real_t xvalue() const { + return (point.index >= 0) ? real_t(point.x) : point128.xvalue(); + } + + real_t yvalue() const { + return (point.index >= 0) ? real_t(point.y) : point128.yvalue(); + } + + real_t zvalue() const { + return (point.index >= 0) ? real_t(point.z) : point128.zvalue(); + } + + void receive_nearby_faces(Vertex *p_src) { + if (last_nearby_face) { + last_nearby_face->next_with_same_nearby_vertex = p_src->first_nearby_face; + } else { + first_nearby_face = p_src->first_nearby_face; + } + if (p_src->last_nearby_face) { + last_nearby_face = p_src->last_nearby_face; + } + for (Face *f = p_src->first_nearby_face; f; f = f->next_with_same_nearby_vertex) { + CHULL_ASSERT(f->nearby_vertex == p_src); + f->nearby_vertex = this; + } + p_src->first_nearby_face = nullptr; + p_src->last_nearby_face = nullptr; + } + }; + + class Edge { + public: + Edge *next = nullptr; + Edge *prev = nullptr; + Edge *reverse = nullptr; + Vertex *target = nullptr; + Face *face = nullptr; + int32_t copy = -1; + + void link(Edge *n) { + CHULL_ASSERT(reverse->target == n->reverse->target); + next = n; + n->prev = this; + } + +#ifdef DEBUG_CONVEX_HULL + void print() { + printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, + reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); + } +#endif + }; + + class Face { + public: + Face *next = nullptr; + Vertex *nearby_vertex = nullptr; + Face *next_with_same_nearby_vertex = nullptr; + Point32 origin; + Point32 dir0; + Point32 dir1; + + Face() { + } + + void init(Vertex *p_a, Vertex *p_b, Vertex *p_c) { + nearby_vertex = p_a; + origin = p_a->point; + dir0 = *p_b - *p_a; + dir1 = *p_c - *p_a; + if (p_a->last_nearby_face) { + p_a->last_nearby_face->next_with_same_nearby_vertex = this; + } else { + p_a->first_nearby_face = this; + } + p_a->last_nearby_face = this; + } + + Point64 get_normal() { + return dir0.cross(dir1); + } + }; + + template <typename UWord, typename UHWord> + class DMul { + private: + static uint32_t high(uint64_t p_value) { + return (uint32_t)(p_value >> 32); + } + + static uint32_t low(uint64_t p_value) { + return (uint32_t)p_value; + } + + static uint64_t mul(uint32_t a, uint32_t b) { + return (uint64_t)a * (uint64_t)b; + } + + static void shl_half(uint64_t &p_value) { + p_value <<= 32; + } + + static uint64_t high(Int128 p_value) { + return p_value.high; + } + + static uint64_t low(Int128 p_value) { + return p_value.low; + } + + static Int128 mul(uint64_t a, uint64_t b) { + return Int128::mul(a, b); + } + + static void shl_half(Int128 &p_value) { + p_value.high = p_value.low; + p_value.low = 0; + } + + public: + static void mul(UWord p_a, UWord p_b, UWord &r_low, UWord &r_high) { + UWord p00 = mul(low(p_a), low(p_b)); + UWord p01 = mul(low(p_a), high(p_b)); + UWord p10 = mul(high(p_a), low(p_b)); + UWord p11 = mul(high(p_a), high(p_b)); + UWord p0110 = UWord(low(p01)) + UWord(low(p10)); + p11 += high(p01); + p11 += high(p10); + p11 += high(p0110); + shl_half(p0110); + p00 += p0110; + if (p00 < p0110) { + ++p11; + } + r_low = p00; + r_high = p11; + } + }; + +private: + class IntermediateHull { + public: + Vertex *min_xy = nullptr; + Vertex *max_xy = nullptr; + Vertex *min_yx = nullptr; + Vertex *max_yx = nullptr; + + IntermediateHull() { + } + + void print(); + }; + + enum Orientation { NONE, + CLOCKWISE, + COUNTER_CLOCKWISE }; + + Vector3 scaling; + Vector3 center; + PagedAllocator<Vertex> vertex_pool; + PagedAllocator<Edge> edge_pool; + PagedAllocator<Face> face_pool; + LocalVector<Vertex *> original_vertices; + int32_t merge_stamp = 0; + int32_t min_axis = 0; + int32_t med_axis = 0; + int32_t max_axis = 0; + int32_t used_edge_pairs = 0; + int32_t max_used_edge_pairs = 0; + + static Orientation get_orientation(const Edge *p_prev, const Edge *p_next, const Point32 &p_s, const Point32 &p_t); + Edge *find_max_angle(bool p_ccw, const Vertex *p_start, const Point32 &p_s, const Point64 &p_rxs, const Point64 &p_ssxrxs, Rational64 &p_min_cot); + void find_edge_for_coplanar_faces(Vertex *p_c0, Vertex *p_c1, Edge *&p_e0, Edge *&p_e1, Vertex *p_stop0, Vertex *p_stop1); + + Edge *new_edge_pair(Vertex *p_from, Vertex *p_to); + + void remove_edge_pair(Edge *p_edge) { + Edge *n = p_edge->next; + Edge *r = p_edge->reverse; + + CHULL_ASSERT(p_edge->target && r->target); + + if (n != p_edge) { + n->prev = p_edge->prev; + p_edge->prev->next = n; + r->target->edges = n; + } else { + r->target->edges = nullptr; + } + + n = r->next; + + if (n != r) { + n->prev = r->prev; + r->prev->next = n; + p_edge->target->edges = n; + } else { + p_edge->target->edges = nullptr; + } + + edge_pool.free(p_edge); + edge_pool.free(r); + used_edge_pairs--; + } + + void compute_internal(int32_t p_start, int32_t p_end, IntermediateHull &r_result); + + bool merge_projection(IntermediateHull &p_h0, IntermediateHull &p_h1, Vertex *&r_c0, Vertex *&r_c1); + + void merge(IntermediateHull &p_h0, IntermediateHull &p_h1); + + Vector3 to_gd_vector(const Point32 &p_v); + + Vector3 get_gd_normal(Face *p_face); + + bool shift_face(Face *p_face, real_t p_amount, LocalVector<Vertex *> p_stack); + +public: + ~ConvexHullInternal() { + vertex_pool.reset(true); + edge_pool.reset(true); + face_pool.reset(true); + } + + Vertex *vertex_list; + + void compute(const Vector3 *p_coords, int32_t p_count); + + Vector3 get_coordinates(const Vertex *p_v); + + real_t shrink(real_t amount, real_t p_clamp_amount); +}; + +ConvexHullInternal::Int128 ConvexHullInternal::Int128::operator*(int64_t b) const { + bool negative = (int64_t)high < 0; + Int128 a = negative ? -*this : *this; + if (b < 0) { + negative = !negative; + b = -b; + } + Int128 result = mul(a.low, (uint64_t)b); + result.high += a.high * (uint64_t)b; + return negative ? -result : result; +} + +ConvexHullInternal::Int128 ConvexHullInternal::Int128::mul(int64_t a, int64_t b) { + Int128 result; + +#ifdef USE_X86_64_ASM + __asm__("imulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); + return result; + +#else + bool negative = a < 0; + if (negative) { + a = -a; + } + if (b < 0) { + negative = !negative; + b = -b; + } + DMul<uint64_t, uint32_t>::mul((uint64_t)a, (uint64_t)b, result.low, result.high); + return negative ? -result : result; +#endif +} + +ConvexHullInternal::Int128 ConvexHullInternal::Int128::mul(uint64_t a, uint64_t b) { + Int128 result; + +#ifdef USE_X86_64_ASM + __asm__("mulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); + +#else + DMul<uint64_t, uint32_t>::mul(a, b, result.low, result.high); +#endif + + return result; +} + +int32_t ConvexHullInternal::Rational64::compare(const Rational64 &b) const { + if (sign != b.sign) { + return sign - b.sign; + } else if (sign == 0) { + return 0; + } + + // return (numerator * b.denominator > b.numerator * denominator) ? sign : (numerator * b.denominator < b.numerator * denominator) ? -sign : 0; + +#ifdef USE_X86_64_ASM + + int32_t result; + int64_t tmp; + int64_t dummy; + __asm__("mulq %[bn]\n\t" + "movq %%rax, %[tmp]\n\t" + "movq %%rdx, %%rbx\n\t" + "movq %[tn], %%rax\n\t" + "mulq %[bd]\n\t" + "subq %[tmp], %%rax\n\t" + "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" + "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise + "orq %%rdx, %%rax\n\t" + "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero + "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) + "shll $16, %%ebx\n\t" // ebx has same sign as difference + : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) + : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) + : "%rdx", "cc"); + return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) + // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) + : + 0; + +#else + + return sign * Int128::mul(numerator, b.denominator).ucmp(Int128::mul(denominator, b.numerator)); + +#endif +} + +int32_t ConvexHullInternal::Rational128::compare(const Rational128 &b) const { + if (sign != b.sign) { + return sign - b.sign; + } else if (sign == 0) { + return 0; + } + if (is_int_64) { + return -b.compare(sign * (int64_t)numerator.low); + } + + Int128 nbd_low, nbd_high, dbn_low, dbn_high; + DMul<Int128, uint64_t>::mul(numerator, b.denominator, nbd_low, nbd_high); + DMul<Int128, uint64_t>::mul(denominator, b.numerator, dbn_low, dbn_high); + + int32_t cmp = nbd_high.ucmp(dbn_high); + if (cmp) { + return cmp * sign; + } + return nbd_low.ucmp(dbn_low) * sign; +} + +int32_t ConvexHullInternal::Rational128::compare(int64_t b) const { + if (is_int_64) { + int64_t a = sign * (int64_t)numerator.low; + return (a > b) ? 1 : (a < b) ? -1 : + 0; + } + if (b > 0) { + if (sign <= 0) { + return -1; + } + } else if (b < 0) { + if (sign >= 0) { + return 1; + } + b = -b; + } else { + return sign; + } + + return numerator.ucmp(denominator * b) * sign; +} + +ConvexHullInternal::Edge *ConvexHullInternal::new_edge_pair(Vertex *p_from, Vertex *p_to) { + CHULL_ASSERT(p_from && p_to); + Edge *e = edge_pool.alloc(); + Edge *r = edge_pool.alloc(); + e->reverse = r; + r->reverse = e; + e->copy = merge_stamp; + r->copy = merge_stamp; + e->target = p_to; + r->target = p_from; + e->face = nullptr; + r->face = nullptr; + used_edge_pairs++; + if (used_edge_pairs > max_used_edge_pairs) { + max_used_edge_pairs = used_edge_pairs; + } + return e; +} + +bool ConvexHullInternal::merge_projection(IntermediateHull &r_h0, IntermediateHull &r_h1, Vertex *&r_c0, Vertex *&r_c1) { + Vertex *v0 = r_h0.max_yx; + Vertex *v1 = r_h1.min_yx; + if ((v0->point.x == v1->point.x) && (v0->point.y == v1->point.y)) { + CHULL_ASSERT(v0->point.z < v1->point.z); + Vertex *v1p = v1->prev; + if (v1p == v1) { + r_c0 = v0; + if (v1->edges) { + CHULL_ASSERT(v1->edges->next == v1->edges); + v1 = v1->edges->target; + CHULL_ASSERT(v1->edges->next == v1->edges); + } + r_c1 = v1; + return false; + } + Vertex *v1n = v1->next; + v1p->next = v1n; + v1n->prev = v1p; + if (v1 == r_h1.min_xy) { + if ((v1n->point.x < v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y < v1p->point.y))) { + r_h1.min_xy = v1n; + } else { + r_h1.min_xy = v1p; + } + } + if (v1 == r_h1.max_xy) { + if ((v1n->point.x > v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y > v1p->point.y))) { + r_h1.max_xy = v1n; + } else { + r_h1.max_xy = v1p; + } + } + } + + v0 = r_h0.max_xy; + v1 = r_h1.max_xy; + Vertex *v00 = nullptr; + Vertex *v10 = nullptr; + int32_t sign = 1; + + for (int32_t side = 0; side <= 1; side++) { + int32_t dx = (v1->point.x - v0->point.x) * sign; + if (dx > 0) { + while (true) { + int32_t dy = v1->point.y - v0->point.y; + + Vertex *w0 = side ? v0->next : v0->prev; + if (w0 != v0) { + int32_t dx0 = (w0->point.x - v0->point.x) * sign; + int32_t dy0 = w0->point.y - v0->point.y; + if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0)))) { + v0 = w0; + dx = (v1->point.x - v0->point.x) * sign; + continue; + } + } + + Vertex *w1 = side ? v1->next : v1->prev; + if (w1 != v1) { + int32_t dx1 = (w1->point.x - v1->point.x) * sign; + int32_t dy1 = w1->point.y - v1->point.y; + int32_t dxn = (w1->point.x - v0->point.x) * sign; + if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1)))) { + v1 = w1; + dx = dxn; + continue; + } + } + + break; + } + } else if (dx < 0) { + while (true) { + int32_t dy = v1->point.y - v0->point.y; + + Vertex *w1 = side ? v1->prev : v1->next; + if (w1 != v1) { + int32_t dx1 = (w1->point.x - v1->point.x) * sign; + int32_t dy1 = w1->point.y - v1->point.y; + if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1)))) { + v1 = w1; + dx = (v1->point.x - v0->point.x) * sign; + continue; + } + } + + Vertex *w0 = side ? v0->prev : v0->next; + if (w0 != v0) { + int32_t dx0 = (w0->point.x - v0->point.x) * sign; + int32_t dy0 = w0->point.y - v0->point.y; + int32_t dxn = (v1->point.x - w0->point.x) * sign; + if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0)))) { + v0 = w0; + dx = dxn; + continue; + } + } + + break; + } + } else { + int32_t x = v0->point.x; + int32_t y0 = v0->point.y; + Vertex *w0 = v0; + Vertex *t; + while (((t = side ? w0->next : w0->prev) != v0) && (t->point.x == x) && (t->point.y <= y0)) { + w0 = t; + y0 = t->point.y; + } + v0 = w0; + + int32_t y1 = v1->point.y; + Vertex *w1 = v1; + while (((t = side ? w1->prev : w1->next) != v1) && (t->point.x == x) && (t->point.y >= y1)) { + w1 = t; + y1 = t->point.y; + } + v1 = w1; + } + + if (side == 0) { + v00 = v0; + v10 = v1; + + v0 = r_h0.min_xy; + v1 = r_h1.min_xy; + sign = -1; + } + } + + v0->prev = v1; + v1->next = v0; + + v00->next = v10; + v10->prev = v00; + + if (r_h1.min_xy->point.x < r_h0.min_xy->point.x) { + r_h0.min_xy = r_h1.min_xy; + } + if (r_h1.max_xy->point.x >= r_h0.max_xy->point.x) { + r_h0.max_xy = r_h1.max_xy; + } + + r_h0.max_yx = r_h1.max_yx; + + r_c0 = v00; + r_c1 = v10; + + return true; +} + +void ConvexHullInternal::compute_internal(int32_t p_start, int32_t p_end, IntermediateHull &r_result) { + int32_t n = p_end - p_start; + switch (n) { + case 0: + r_result.min_xy = nullptr; + r_result.max_xy = nullptr; + r_result.min_yx = nullptr; + r_result.max_yx = nullptr; + return; + case 2: { + Vertex *v = original_vertices[p_start]; + Vertex *w = original_vertices[p_start + 1]; + if (v->point != w->point) { + int32_t dx = v->point.x - w->point.x; + int32_t dy = v->point.y - w->point.y; + + if ((dx == 0) && (dy == 0)) { + if (v->point.z > w->point.z) { + Vertex *t = w; + w = v; + v = t; + } + CHULL_ASSERT(v->point.z < w->point.z); + v->next = v; + v->prev = v; + r_result.min_xy = v; + r_result.max_xy = v; + r_result.min_yx = v; + r_result.max_yx = v; + } else { + v->next = w; + v->prev = w; + w->next = v; + w->prev = v; + + if ((dx < 0) || ((dx == 0) && (dy < 0))) { + r_result.min_xy = v; + r_result.max_xy = w; + } else { + r_result.min_xy = w; + r_result.max_xy = v; + } + + if ((dy < 0) || ((dy == 0) && (dx < 0))) { + r_result.min_yx = v; + r_result.max_yx = w; + } else { + r_result.min_yx = w; + r_result.max_yx = v; + } + } + + Edge *e = new_edge_pair(v, w); + e->link(e); + v->edges = e; + + e = e->reverse; + e->link(e); + w->edges = e; + + return; + } + [[fallthrough]]; + } + case 1: { + Vertex *v = original_vertices[p_start]; + v->edges = nullptr; + v->next = v; + v->prev = v; + + r_result.min_xy = v; + r_result.max_xy = v; + r_result.min_yx = v; + r_result.max_yx = v; + + return; + } + } + + int32_t split0 = p_start + n / 2; + Point32 p = original_vertices[split0 - 1]->point; + int32_t split1 = split0; + while ((split1 < p_end) && (original_vertices[split1]->point == p)) { + split1++; + } + compute_internal(p_start, split0, r_result); + IntermediateHull hull1; + compute_internal(split1, p_end, hull1); +#ifdef DEBUG_CONVEX_HULL + printf("\n\nMerge\n"); + r_result.print(); + hull1.print(); +#endif + merge(r_result, hull1); +#ifdef DEBUG_CONVEX_HULL + printf("\n Result\n"); + r_result.print(); +#endif +} + +#ifdef DEBUG_CONVEX_HULL +void ConvexHullInternal::IntermediateHull::print() { + printf(" Hull\n"); + for (Vertex *v = min_xy; v;) { + printf(" "); + v->print(); + if (v == max_xy) { + printf(" max_xy"); + } + if (v == min_yx) { + printf(" min_yx"); + } + if (v == max_yx) { + printf(" max_yx"); + } + if (v->next->prev != v) { + printf(" Inconsistency"); + } + printf("\n"); + v = v->next; + if (v == min_xy) { + break; + } + } + if (min_xy) { + min_xy->copy = (min_xy->copy == -1) ? -2 : -1; + min_xy->print_graph(); + } +} + +void ConvexHullInternal::Vertex::print_graph() { + print(); + printf("\nEdges\n"); + Edge *e = edges; + if (e) { + do { + e->print(); + printf("\n"); + e = e->next; + } while (e != edges); + do { + Vertex *v = e->target; + if (v->copy != copy) { + v->copy = copy; + v->print_graph(); + } + e = e->next; + } while (e != edges); + } +} +#endif + +ConvexHullInternal::Orientation ConvexHullInternal::get_orientation(const Edge *p_prev, const Edge *p_next, const Point32 &p_s, const Point32 &p_t) { + CHULL_ASSERT(p_prev->reverse->target == p_next->reverse->target); + if (p_prev->next == p_next) { + if (p_prev->prev == p_next) { + Point64 n = p_t.cross(p_s); + Point64 m = (*p_prev->target - *p_next->reverse->target).cross(*p_next->target - *p_next->reverse->target); + CHULL_ASSERT(!m.is_zero()); + int64_t dot = n.dot(m); + CHULL_ASSERT(dot != 0); + return (dot > 0) ? COUNTER_CLOCKWISE : CLOCKWISE; + } + return COUNTER_CLOCKWISE; + } else if (p_prev->prev == p_next) { + return CLOCKWISE; + } else { + return NONE; + } +} + +ConvexHullInternal::Edge *ConvexHullInternal::find_max_angle(bool p_ccw, const Vertex *p_start, const Point32 &p_s, const Point64 &p_rxs, const Point64 &p_sxrxs, Rational64 &p_min_cot) { + Edge *min_edge = nullptr; + +#ifdef DEBUG_CONVEX_HULL + printf("find max edge for %d\n", p_start->point.index); +#endif + Edge *e = p_start->edges; + if (e) { + do { + if (e->copy > merge_stamp) { + Point32 t = *e->target - *p_start; + Rational64 cot(t.dot(p_sxrxs), t.dot(p_rxs)); +#ifdef DEBUG_CONVEX_HULL + printf(" Angle is %f (%d) for ", Math::atan(cot.to_scalar()), (int32_t)cot.is_nan()); + e->print(); +#endif + if (cot.is_nan()) { + CHULL_ASSERT(p_ccw ? (t.dot(p_s) < 0) : (t.dot(p_s) > 0)); + } else { + int32_t cmp; + if (min_edge == nullptr) { + p_min_cot = cot; + min_edge = e; + } else if ((cmp = cot.compare(p_min_cot)) < 0) { + p_min_cot = cot; + min_edge = e; + } else if ((cmp == 0) && (p_ccw == (get_orientation(min_edge, e, p_s, t) == COUNTER_CLOCKWISE))) { + min_edge = e; + } + } +#ifdef DEBUG_CONVEX_HULL + printf("\n"); +#endif + } + e = e->next; + } while (e != p_start->edges); + } + return min_edge; +} + +void ConvexHullInternal::find_edge_for_coplanar_faces(Vertex *p_c0, Vertex *p_c1, Edge *&p_e0, Edge *&p_e1, Vertex *p_stop0, Vertex *p_stop1) { + Edge *start0 = p_e0; + Edge *start1 = p_e1; + Point32 et0 = start0 ? start0->target->point : p_c0->point; + Point32 et1 = start1 ? start1->target->point : p_c1->point; + Point32 s = p_c1->point - p_c0->point; + Point64 normal = ((start0 ? start0 : start1)->target->point - p_c0->point).cross(s); + int64_t dist = p_c0->point.dot(normal); + CHULL_ASSERT(!start1 || (start1->target->point.dot(normal) == dist)); + Point64 perp = s.cross(normal); + CHULL_ASSERT(!perp.is_zero()); + +#ifdef DEBUG_CONVEX_HULL + printf(" Advancing %d %d (%p %p, %d %d)\n", p_c0->point.index, p_c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1); +#endif + + int64_t max_dot0 = et0.dot(perp); + if (p_e0) { + while (p_e0->target != p_stop0) { + Edge *e = p_e0->reverse->prev; + if (e->target->point.dot(normal) < dist) { + break; + } + CHULL_ASSERT(e->target->point.dot(normal) == dist); + if (e->copy == merge_stamp) { + break; + } + int64_t dot = e->target->point.dot(perp); + if (dot <= max_dot0) { + break; + } + max_dot0 = dot; + p_e0 = e; + et0 = e->target->point; + } + } + + int64_t max_dot1 = et1.dot(perp); + if (p_e1) { + while (p_e1->target != p_stop1) { + Edge *e = p_e1->reverse->next; + if (e->target->point.dot(normal) < dist) { + break; + } + CHULL_ASSERT(e->target->point.dot(normal) == dist); + if (e->copy == merge_stamp) { + break; + } + int64_t dot = e->target->point.dot(perp); + if (dot <= max_dot1) { + break; + } + max_dot1 = dot; + p_e1 = e; + et1 = e->target->point; + } + } + +#ifdef DEBUG_CONVEX_HULL + printf(" Starting at %d %d\n", et0.index, et1.index); +#endif + + int64_t dx = max_dot1 - max_dot0; + if (dx > 0) { + while (true) { + int64_t dy = (et1 - et0).dot(s); + + if (p_e0 && (p_e0->target != p_stop0)) { + Edge *f0 = p_e0->next->reverse; + if (f0->copy > merge_stamp) { + int64_t dx0 = (f0->target->point - et0).dot(perp); + int64_t dy0 = (f0->target->point - et0).dot(s); + if ((dx0 == 0) ? (dy0 < 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) >= 0))) { + et0 = f0->target->point; + dx = (et1 - et0).dot(perp); + p_e0 = (p_e0 == start0) ? nullptr : f0; + continue; + } + } + } + + if (p_e1 && (p_e1->target != p_stop1)) { + Edge *f1 = p_e1->reverse->next; + if (f1->copy > merge_stamp) { + Point32 d1 = f1->target->point - et1; + if (d1.dot(normal) == 0) { + int64_t dx1 = d1.dot(perp); + int64_t dy1 = d1.dot(s); + int64_t dxn = (f1->target->point - et0).dot(perp); + if ((dxn > 0) && ((dx1 == 0) ? (dy1 < 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) > 0)))) { + p_e1 = f1; + et1 = p_e1->target->point; + dx = dxn; + continue; + } + } else { + CHULL_ASSERT((p_e1 == start1) && (d1.dot(normal) < 0)); + } + } + } + + break; + } + } else if (dx < 0) { + while (true) { + int64_t dy = (et1 - et0).dot(s); + + if (p_e1 && (p_e1->target != p_stop1)) { + Edge *f1 = p_e1->prev->reverse; + if (f1->copy > merge_stamp) { + int64_t dx1 = (f1->target->point - et1).dot(perp); + int64_t dy1 = (f1->target->point - et1).dot(s); + if ((dx1 == 0) ? (dy1 > 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) <= 0))) { + et1 = f1->target->point; + dx = (et1 - et0).dot(perp); + p_e1 = (p_e1 == start1) ? nullptr : f1; + continue; + } + } + } + + if (p_e0 && (p_e0->target != p_stop0)) { + Edge *f0 = p_e0->reverse->prev; + if (f0->copy > merge_stamp) { + Point32 d0 = f0->target->point - et0; + if (d0.dot(normal) == 0) { + int64_t dx0 = d0.dot(perp); + int64_t dy0 = d0.dot(s); + int64_t dxn = (et1 - f0->target->point).dot(perp); + if ((dxn < 0) && ((dx0 == 0) ? (dy0 > 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) < 0)))) { + p_e0 = f0; + et0 = p_e0->target->point; + dx = dxn; + continue; + } + } else { + CHULL_ASSERT((p_e0 == start0) && (d0.dot(normal) < 0)); + } + } + } + + break; + } + } +#ifdef DEBUG_CONVEX_HULL + printf(" Advanced edges to %d %d\n", et0.index, et1.index); +#endif +} + +void ConvexHullInternal::merge(IntermediateHull &p_h0, IntermediateHull &p_h1) { + if (!p_h1.max_xy) { + return; + } + if (!p_h0.max_xy) { + p_h0 = p_h1; + return; + } + + merge_stamp--; + + Vertex *c0 = nullptr; + Edge *to_prev0 = nullptr; + Edge *first_new0 = nullptr; + Edge *pending_head0 = nullptr; + Edge *pending_tail0 = nullptr; + Vertex *c1 = nullptr; + Edge *to_prev1 = nullptr; + Edge *first_new1 = nullptr; + Edge *pending_head1 = nullptr; + Edge *pending_tail1 = nullptr; + Point32 prev_point; + + if (merge_projection(p_h0, p_h1, c0, c1)) { + Point32 s = *c1 - *c0; + Point64 normal = Point32(0, 0, -1).cross(s); + Point64 t = s.cross(normal); + CHULL_ASSERT(!t.is_zero()); + + Edge *e = c0->edges; + Edge *start0 = nullptr; + if (e) { + do { + int64_t dot = (*e->target - *c0).dot(normal); + CHULL_ASSERT(dot <= 0); + if ((dot == 0) && ((*e->target - *c0).dot(t) > 0)) { + if (!start0 || (get_orientation(start0, e, s, Point32(0, 0, -1)) == CLOCKWISE)) { + start0 = e; + } + } + e = e->next; + } while (e != c0->edges); + } + + e = c1->edges; + Edge *start1 = nullptr; + if (e) { + do { + int64_t dot = (*e->target - *c1).dot(normal); + CHULL_ASSERT(dot <= 0); + if ((dot == 0) && ((*e->target - *c1).dot(t) > 0)) { + if (!start1 || (get_orientation(start1, e, s, Point32(0, 0, -1)) == COUNTER_CLOCKWISE)) { + start1 = e; + } + } + e = e->next; + } while (e != c1->edges); + } + + if (start0 || start1) { + find_edge_for_coplanar_faces(c0, c1, start0, start1, nullptr, nullptr); + if (start0) { + c0 = start0->target; + } + if (start1) { + c1 = start1->target; + } + } + + prev_point = c1->point; + prev_point.z++; + } else { + prev_point = c1->point; + prev_point.x++; + } + + Vertex *first0 = c0; + Vertex *first1 = c1; + bool first_run = true; + + while (true) { + Point32 s = *c1 - *c0; + Point32 r = prev_point - c0->point; + Point64 rxs = r.cross(s); + Point64 sxrxs = s.cross(rxs); + +#ifdef DEBUG_CONVEX_HULL + printf("\n Checking %d %d\n", c0->point.index, c1->point.index); +#endif + Rational64 min_cot0(0, 0); + Edge *min0 = find_max_angle(false, c0, s, rxs, sxrxs, min_cot0); + Rational64 min_cot1(0, 0); + Edge *min1 = find_max_angle(true, c1, s, rxs, sxrxs, min_cot1); + if (!min0 && !min1) { + Edge *e = new_edge_pair(c0, c1); + e->link(e); + c0->edges = e; + + e = e->reverse; + e->link(e); + c1->edges = e; + return; + } else { + int32_t cmp = !min0 ? 1 : !min1 ? -1 : + min_cot0.compare(min_cot1); +#ifdef DEBUG_CONVEX_HULL + printf(" -> Result %d\n", cmp); +#endif + if (first_run || ((cmp >= 0) ? !min_cot1.is_negative_infinity() : !min_cot0.is_negative_infinity())) { + Edge *e = new_edge_pair(c0, c1); + if (pending_tail0) { + pending_tail0->prev = e; + } else { + pending_head0 = e; + } + e->next = pending_tail0; + pending_tail0 = e; + + e = e->reverse; + if (pending_tail1) { + pending_tail1->next = e; + } else { + pending_head1 = e; + } + e->prev = pending_tail1; + pending_tail1 = e; + } + + Edge *e0 = min0; + Edge *e1 = min1; + +#ifdef DEBUG_CONVEX_HULL + printf(" Found min edges to %d %d\n", e0 ? e0->target->point.index : -1, e1 ? e1->target->point.index : -1); +#endif + + if (cmp == 0) { + find_edge_for_coplanar_faces(c0, c1, e0, e1, nullptr, nullptr); + } + + if ((cmp >= 0) && e1) { + if (to_prev1) { + for (Edge *e = to_prev1->next, *n = nullptr; e != min1; e = n) { + n = e->next; + remove_edge_pair(e); + } + } + + if (pending_tail1) { + if (to_prev1) { + to_prev1->link(pending_head1); + } else { + min1->prev->link(pending_head1); + first_new1 = pending_head1; + } + pending_tail1->link(min1); + pending_head1 = nullptr; + pending_tail1 = nullptr; + } else if (!to_prev1) { + first_new1 = min1; + } + + prev_point = c1->point; + c1 = e1->target; + to_prev1 = e1->reverse; + } + + if ((cmp <= 0) && e0) { + if (to_prev0) { + for (Edge *e = to_prev0->prev, *n = nullptr; e != min0; e = n) { + n = e->prev; + remove_edge_pair(e); + } + } + + if (pending_tail0) { + if (to_prev0) { + pending_head0->link(to_prev0); + } else { + pending_head0->link(min0->next); + first_new0 = pending_head0; + } + min0->link(pending_tail0); + pending_head0 = nullptr; + pending_tail0 = nullptr; + } else if (!to_prev0) { + first_new0 = min0; + } + + prev_point = c0->point; + c0 = e0->target; + to_prev0 = e0->reverse; + } + } + + if ((c0 == first0) && (c1 == first1)) { + if (to_prev0 == nullptr) { + pending_head0->link(pending_tail0); + c0->edges = pending_tail0; + } else { + for (Edge *e = to_prev0->prev, *n = nullptr; e != first_new0; e = n) { + n = e->prev; + remove_edge_pair(e); + } + if (pending_tail0) { + pending_head0->link(to_prev0); + first_new0->link(pending_tail0); + } + } + + if (to_prev1 == nullptr) { + pending_tail1->link(pending_head1); + c1->edges = pending_tail1; + } else { + for (Edge *e = to_prev1->next, *n = nullptr; e != first_new1; e = n) { + n = e->next; + remove_edge_pair(e); + } + if (pending_tail1) { + to_prev1->link(pending_head1); + pending_tail1->link(first_new1); + } + } + + return; + } + + first_run = false; + } +} + +struct PointComparator { + _FORCE_INLINE_ bool operator()(const ConvexHullInternal::Point32 &p, const ConvexHullInternal::Point32 &q) const { + return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); + } +}; + +void ConvexHullInternal::compute(const Vector3 *p_coords, int32_t p_count) { + AABB aabb; + for (int32_t i = 0; i < p_count; i++) { + Vector3 p = p_coords[i]; + if (i == 0) { + aabb.position = p; + } else { + aabb.expand_to(p); + } + } + + Vector3 s = aabb.size; + max_axis = s.max_axis(); + min_axis = s.min_axis(); + if (min_axis == max_axis) { + min_axis = (max_axis + 1) % 3; + } + med_axis = 3 - max_axis - min_axis; + + s /= real_t(10216); + if (((med_axis + 1) % 3) != max_axis) { + s *= -1; + } + scaling = s; + + if (s[0] != 0) { + s[0] = real_t(1) / s[0]; + } + if (s[1] != 0) { + s[1] = real_t(1) / s[1]; + } + if (s[2] != 0) { + s[2] = real_t(1) / s[2]; + } + + center = aabb.position; + + LocalVector<Point32> points; + points.resize(p_count); + for (int32_t i = 0; i < p_count; i++) { + Vector3 p = p_coords[i]; + p = (p - center) * s; + points[i].x = (int32_t)p[med_axis]; + points[i].y = (int32_t)p[max_axis]; + points[i].z = (int32_t)p[min_axis]; + points[i].index = i; + } + + points.sort_custom<PointComparator>(); + + vertex_pool.reset(true); + original_vertices.resize(p_count); + for (int32_t i = 0; i < p_count; i++) { + Vertex *v = vertex_pool.alloc(); + v->edges = nullptr; + v->point = points[i]; + v->copy = -1; + original_vertices[i] = v; + } + + points.clear(); + + edge_pool.reset(true); + + used_edge_pairs = 0; + max_used_edge_pairs = 0; + + merge_stamp = -3; + + IntermediateHull hull; + compute_internal(0, p_count, hull); + vertex_list = hull.min_xy; +#ifdef DEBUG_CONVEX_HULL + printf("max. edges %d (3v = %d)", max_used_edge_pairs, 3 * p_count); +#endif +} + +Vector3 ConvexHullInternal::to_gd_vector(const Point32 &p_v) { + Vector3 p; + p[med_axis] = real_t(p_v.x); + p[max_axis] = real_t(p_v.y); + p[min_axis] = real_t(p_v.z); + return p * scaling; +} + +Vector3 ConvexHullInternal::get_gd_normal(Face *p_face) { + return to_gd_vector(p_face->dir0).cross(to_gd_vector(p_face->dir1)).normalized(); +} + +Vector3 ConvexHullInternal::get_coordinates(const Vertex *p_v) { + Vector3 p; + p[med_axis] = p_v->xvalue(); + p[max_axis] = p_v->yvalue(); + p[min_axis] = p_v->zvalue(); + return p * scaling + center; +} + +real_t ConvexHullInternal::shrink(real_t p_amount, real_t p_clamp_amount) { + if (!vertex_list) { + return 0; + } + int32_t stamp = --merge_stamp; + LocalVector<Vertex *> stack; + vertex_list->copy = stamp; + stack.push_back(vertex_list); + LocalVector<Face *> faces; + + Point32 ref = vertex_list->point; + Int128 hull_center_x(0, 0); + Int128 hull_center_y(0, 0); + Int128 hull_center_z(0, 0); + Int128 volume(0, 0); + + while (stack.size() > 0) { + Vertex *v = stack[stack.size() - 1]; + stack.remove(stack.size() - 1); + Edge *e = v->edges; + if (e) { + do { + if (e->target->copy != stamp) { + e->target->copy = stamp; + stack.push_back(e->target); + } + if (e->copy != stamp) { + Face *face = face_pool.alloc(); + face->init(e->target, e->reverse->prev->target, v); + faces.push_back(face); + Edge *f = e; + + Vertex *a = nullptr; + Vertex *b = nullptr; + do { + if (a && b) { + int64_t vol = (v->point - ref).dot((a->point - ref).cross(b->point - ref)); + CHULL_ASSERT(vol >= 0); + Point32 c = v->point + a->point + b->point + ref; + hull_center_x += vol * c.x; + hull_center_y += vol * c.y; + hull_center_z += vol * c.z; + volume += vol; + } + + CHULL_ASSERT(f->copy != stamp); + f->copy = stamp; + f->face = face; + + a = b; + b = f->target; + + f = f->reverse->prev; + } while (f != e); + } + e = e->next; + } while (e != v->edges); + } + } + + if (volume.get_sign() <= 0) { + return 0; + } + + Vector3 hull_center; + hull_center[med_axis] = hull_center_x.to_scalar(); + hull_center[max_axis] = hull_center_y.to_scalar(); + hull_center[min_axis] = hull_center_z.to_scalar(); + hull_center /= 4 * volume.to_scalar(); + hull_center *= scaling; + + int32_t face_count = faces.size(); + + if (p_clamp_amount > 0) { + real_t min_dist = FLT_MAX; + for (int32_t i = 0; i < face_count; i++) { + Vector3 normal = get_gd_normal(faces[i]); + real_t dist = normal.dot(to_gd_vector(faces[i]->origin) - hull_center); + if (dist < min_dist) { + min_dist = dist; + } + } + + if (min_dist <= 0) { + return 0; + } + + p_amount = MIN(p_amount, min_dist * p_clamp_amount); + } + + uint32_t seed = 243703; + for (int32_t i = 0; i < face_count; i++, seed = 1664525 * seed + 1013904223) { + SWAP(faces[i], faces[seed % face_count]); + } + + for (int32_t i = 0; i < face_count; i++) { + if (!shift_face(faces[i], p_amount, stack)) { + return -p_amount; + } + } + + return p_amount; +} + +bool ConvexHullInternal::shift_face(Face *p_face, real_t p_amount, LocalVector<Vertex *> p_stack) { + Vector3 orig_shift = get_gd_normal(p_face) * -p_amount; + if (scaling[0] != 0) { + orig_shift[0] /= scaling[0]; + } + if (scaling[1] != 0) { + orig_shift[1] /= scaling[1]; + } + if (scaling[2] != 0) { + orig_shift[2] /= scaling[2]; + } + Point32 shift((int32_t)orig_shift[med_axis], (int32_t)orig_shift[max_axis], (int32_t)orig_shift[min_axis]); + if (shift.is_zero()) { + return true; + } + Point64 normal = p_face->get_normal(); +#ifdef DEBUG_CONVEX_HULL + printf("\nShrinking p_face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n", + p_face->origin.x, p_face->origin.y, p_face->origin.z, p_face->dir0.x, p_face->dir0.y, p_face->dir0.z, p_face->dir1.x, p_face->dir1.y, p_face->dir1.z, shift.x, shift.y, shift.z); +#endif + int64_t orig_dot = p_face->origin.dot(normal); + Point32 shifted_origin = p_face->origin + shift; + int64_t shifted_dot = shifted_origin.dot(normal); + CHULL_ASSERT(shifted_dot <= orig_dot); + if (shifted_dot >= orig_dot) { + return false; + } + + Edge *intersection = nullptr; + + Edge *start_edge = p_face->nearby_vertex->edges; +#ifdef DEBUG_CONVEX_HULL + printf("Start edge is "); + start_edge->print(); + printf(", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.x, normal.y, normal.z, shifted_dot); +#endif + Rational128 opt_dot = p_face->nearby_vertex->dot(normal); + int32_t cmp = opt_dot.compare(shifted_dot); +#ifdef SHOW_ITERATIONS + int32_t n = 0; +#endif + if (cmp >= 0) { + Edge *e = start_edge; + do { +#ifdef SHOW_ITERATIONS + n++; +#endif + Rational128 dot = e->target->dot(normal); + CHULL_ASSERT(dot.compare(orig_dot) <= 0); +#ifdef DEBUG_CONVEX_HULL + printf("Moving downwards, edge is "); + e->print(); + printf(", dot is %f (%f %lld)\n", (float)dot.to_scalar(), (float)opt_dot.to_scalar(), shifted_dot); +#endif + if (dot.compare(opt_dot) < 0) { + int32_t c = dot.compare(shifted_dot); + opt_dot = dot; + e = e->reverse; + start_edge = e; + if (c < 0) { + intersection = e; + break; + } + cmp = c; + } + e = e->prev; + } while (e != start_edge); + + if (!intersection) { + return false; + } + } else { + Edge *e = start_edge; + do { +#ifdef SHOW_ITERATIONS + n++; +#endif + Rational128 dot = e->target->dot(normal); + CHULL_ASSERT(dot.compare(orig_dot) <= 0); +#ifdef DEBUG_CONVEX_HULL + printf("Moving upwards, edge is "); + e->print(); + printf(", dot is %f (%f %lld)\n", (float)dot.to_scalar(), (float)opt_dot.to_scalar(), shifted_dot); +#endif + if (dot.compare(opt_dot) > 0) { + cmp = dot.compare(shifted_dot); + if (cmp >= 0) { + intersection = e; + break; + } + opt_dot = dot; + e = e->reverse; + start_edge = e; + } + e = e->prev; + } while (e != start_edge); + + if (!intersection) { + return true; + } + } + +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to find initial intersection\n", n); +#endif + + if (cmp == 0) { + Edge *e = intersection->reverse->next; +#ifdef SHOW_ITERATIONS + n = 0; +#endif + while (e->target->dot(normal).compare(shifted_dot) <= 0) { +#ifdef SHOW_ITERATIONS + n++; +#endif + e = e->next; + if (e == intersection->reverse) { + return true; + } +#ifdef DEBUG_CONVEX_HULL + printf("Checking for outwards edge, current edge is "); + e->print(); + printf("\n"); +#endif + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to check for complete containment\n", n); +#endif + } + + Edge *first_intersection = nullptr; + Edge *face_edge = nullptr; + Edge *first_face_edge = nullptr; + +#ifdef SHOW_ITERATIONS + int32_t m = 0; +#endif + while (true) { +#ifdef SHOW_ITERATIONS + m++; +#endif +#ifdef DEBUG_CONVEX_HULL + printf("Intersecting edge is "); + intersection->print(); + printf("\n"); +#endif + if (cmp == 0) { + Edge *e = intersection->reverse->next; + start_edge = e; +#ifdef SHOW_ITERATIONS + n = 0; +#endif + while (true) { +#ifdef SHOW_ITERATIONS + n++; +#endif + if (e->target->dot(normal).compare(shifted_dot) >= 0) { + break; + } + intersection = e->reverse; + e = e->next; + if (e == start_edge) { + return true; + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to advance intersection\n", n); +#endif + } + +#ifdef DEBUG_CONVEX_HULL + printf("Advanced intersecting edge to "); + intersection->print(); + printf(", cmp = %d\n", cmp); +#endif + + if (!first_intersection) { + first_intersection = intersection; + } else if (intersection == first_intersection) { + break; + } + + int32_t prev_cmp = cmp; + Edge *prev_intersection = intersection; + Edge *prev_face_edge = face_edge; + + Edge *e = intersection->reverse; +#ifdef SHOW_ITERATIONS + n = 0; +#endif + while (true) { +#ifdef SHOW_ITERATIONS + n++; +#endif + e = e->reverse->prev; + CHULL_ASSERT(e != intersection->reverse); + cmp = e->target->dot(normal).compare(shifted_dot); +#ifdef DEBUG_CONVEX_HULL + printf("Testing edge "); + e->print(); + printf(" -> cmp = %d\n", cmp); +#endif + if (cmp >= 0) { + intersection = e; + break; + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to find other intersection of p_face\n", n); +#endif + + if (cmp > 0) { + Vertex *removed = intersection->target; + e = intersection->reverse; + if (e->prev == e) { + removed->edges = nullptr; + } else { + removed->edges = e->prev; + e->prev->link(e->next); + e->link(e); + } +#ifdef DEBUG_CONVEX_HULL + printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); +#endif + + Point64 n0 = intersection->face->get_normal(); + Point64 n1 = intersection->reverse->face->get_normal(); + int64_t m00 = p_face->dir0.dot(n0); + int64_t m01 = p_face->dir1.dot(n0); + int64_t m10 = p_face->dir0.dot(n1); + int64_t m11 = p_face->dir1.dot(n1); + int64_t r0 = (intersection->face->origin - shifted_origin).dot(n0); + int64_t r1 = (intersection->reverse->face->origin - shifted_origin).dot(n1); + Int128 det = Int128::mul(m00, m11) - Int128::mul(m01, m10); + CHULL_ASSERT(det.get_sign() != 0); + Vertex *v = vertex_pool.alloc(); + v->point.index = -1; + v->copy = -1; + v->point128 = PointR128(Int128::mul(p_face->dir0.x * r0, m11) - Int128::mul(p_face->dir0.x * r1, m01) + Int128::mul(p_face->dir1.x * r1, m00) - Int128::mul(p_face->dir1.x * r0, m10) + det * shifted_origin.x, + Int128::mul(p_face->dir0.y * r0, m11) - Int128::mul(p_face->dir0.y * r1, m01) + Int128::mul(p_face->dir1.y * r1, m00) - Int128::mul(p_face->dir1.y * r0, m10) + det * shifted_origin.y, + Int128::mul(p_face->dir0.z * r0, m11) - Int128::mul(p_face->dir0.z * r1, m01) + Int128::mul(p_face->dir1.z * r1, m00) - Int128::mul(p_face->dir1.z * r0, m10) + det * shifted_origin.z, + det); + v->point.x = (int32_t)v->point128.xvalue(); + v->point.y = (int32_t)v->point128.yvalue(); + v->point.z = (int32_t)v->point128.zvalue(); + intersection->target = v; + v->edges = e; + + p_stack.push_back(v); + p_stack.push_back(removed); + p_stack.push_back(nullptr); + } + + if (cmp || prev_cmp || (prev_intersection->reverse->next->target != intersection->target)) { + face_edge = new_edge_pair(prev_intersection->target, intersection->target); + if (prev_cmp == 0) { + face_edge->link(prev_intersection->reverse->next); + } + if ((prev_cmp == 0) || prev_face_edge) { + prev_intersection->reverse->link(face_edge); + } + if (cmp == 0) { + intersection->reverse->prev->link(face_edge->reverse); + } + face_edge->reverse->link(intersection->reverse); + } else { + face_edge = prev_intersection->reverse->next; + } + + if (prev_face_edge) { + if (prev_cmp > 0) { + face_edge->link(prev_face_edge->reverse); + } else if (face_edge != prev_face_edge->reverse) { + p_stack.push_back(prev_face_edge->target); + while (face_edge->next != prev_face_edge->reverse) { + Vertex *removed = face_edge->next->target; + remove_edge_pair(face_edge->next); + p_stack.push_back(removed); +#ifdef DEBUG_CONVEX_HULL + printf("2: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); +#endif + } + p_stack.push_back(nullptr); + } + } + face_edge->face = p_face; + face_edge->reverse->face = intersection->face; + + if (!first_face_edge) { + first_face_edge = face_edge; + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to process all intersections\n", m); +#endif + + if (cmp > 0) { + first_face_edge->reverse->target = face_edge->target; + first_intersection->reverse->link(first_face_edge); + first_face_edge->link(face_edge->reverse); + } else if (first_face_edge != face_edge->reverse) { + p_stack.push_back(face_edge->target); + while (first_face_edge->next != face_edge->reverse) { + Vertex *removed = first_face_edge->next->target; + remove_edge_pair(first_face_edge->next); + p_stack.push_back(removed); +#ifdef DEBUG_CONVEX_HULL + printf("3: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); +#endif + } + p_stack.push_back(nullptr); + } + + CHULL_ASSERT(p_stack.size() > 0); + vertex_list = p_stack[0]; + +#ifdef DEBUG_CONVEX_HULL + printf("Removing part\n"); +#endif +#ifdef SHOW_ITERATIONS + n = 0; +#endif + uint32_t pos = 0; + while (pos < p_stack.size()) { + uint32_t end = p_stack.size(); + while (pos < end) { + Vertex *kept = p_stack[pos++]; +#ifdef DEBUG_CONVEX_HULL + kept->print(); +#endif + bool deeper = false; + Vertex *removed; + while ((removed = p_stack[pos++]) != nullptr) { +#ifdef SHOW_ITERATIONS + n++; +#endif + kept->receive_nearby_faces(removed); + while (removed->edges) { + if (!deeper) { + deeper = true; + p_stack.push_back(kept); + } + p_stack.push_back(removed->edges->target); + remove_edge_pair(removed->edges); + } + } + if (deeper) { + p_stack.push_back(nullptr); + } + } + } +#ifdef SHOW_ITERATIONS + printf("Needed %d iterations to remove part\n", n); +#endif + + p_stack.resize(0); + p_face->origin = shifted_origin; + + return true; +} + +static int32_t get_vertex_copy(ConvexHullInternal::Vertex *p_vertex, LocalVector<ConvexHullInternal::Vertex *> &p_vertices) { + int32_t index = p_vertex->copy; + if (index < 0) { + index = p_vertices.size(); + p_vertex->copy = index; + p_vertices.push_back(p_vertex); +#ifdef DEBUG_CONVEX_HULL + printf("Vertex %d gets index *%d\n", p_vertex->point.index, index); +#endif + } + return index; +} + +real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, real_t p_shrink, real_t p_shrink_clamp) { + if (p_count <= 0) { + vertices.clear(); + edges.clear(); + faces.clear(); + return 0; + } + + ConvexHullInternal hull; + hull.compute(p_coords, p_count); + + real_t shift = 0; + if ((p_shrink > 0) && ((shift = hull.shrink(p_shrink, p_shrink_clamp)) < 0)) { + vertices.clear(); + edges.clear(); + faces.clear(); + return shift; + } + + vertices.resize(0); + edges.resize(0); + faces.resize(0); + + LocalVector<ConvexHullInternal::Vertex *> old_vertices; + get_vertex_copy(hull.vertex_list, old_vertices); + int32_t copied = 0; + while (copied < (int32_t)old_vertices.size()) { + ConvexHullInternal::Vertex *v = old_vertices[copied]; + vertices.push_back(hull.get_coordinates(v)); + ConvexHullInternal::Edge *first_edge = v->edges; + if (first_edge) { + int32_t first_copy = -1; + int32_t prev_copy = -1; + ConvexHullInternal::Edge *e = first_edge; + do { + if (e->copy < 0) { + int32_t s = edges.size(); + edges.push_back(Edge()); + edges.push_back(Edge()); + Edge *c = &edges[s]; + Edge *r = &edges[s + 1]; + e->copy = s; + e->reverse->copy = s + 1; + c->reverse = 1; + r->reverse = -1; + c->target_vertex = get_vertex_copy(e->target, old_vertices); + r->target_vertex = copied; +#ifdef DEBUG_CONVEX_HULL + printf(" CREATE: Vertex *%d has edge to *%d\n", copied, c->get_target_vertex()); +#endif + } + if (prev_copy >= 0) { + edges[e->copy].next = prev_copy - e->copy; + } else { + first_copy = e->copy; + } + prev_copy = e->copy; + e = e->next; + } while (e != first_edge); + edges[first_copy].next = prev_copy - first_copy; + } + copied++; + } + + for (int32_t i = 0; i < copied; i++) { + ConvexHullInternal::Vertex *v = old_vertices[i]; + ConvexHullInternal::Edge *first_edge = v->edges; + if (first_edge) { + ConvexHullInternal::Edge *e = first_edge; + do { + if (e->copy >= 0) { +#ifdef DEBUG_CONVEX_HULL + printf("Vertex *%d has edge to *%d\n", i, edges[e->copy].get_target_vertex()); +#endif + faces.push_back(e->copy); + ConvexHullInternal::Edge *f = e; + do { +#ifdef DEBUG_CONVEX_HULL + printf(" Face *%d\n", edges[f->copy].get_target_vertex()); +#endif + f->copy = -1; + f = f->reverse->prev; + } while (f != e); + } + e = e->next; + } while (e != first_edge); + } + } + + return shift; +} + +Error ConvexHullComputer::convex_hull(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh) { + r_mesh = Geometry3D::MeshData(); // clear + + if (p_points.size() == 0) { + return FAILED; // matches QuickHull + } + + ConvexHullComputer ch; + ch.compute(p_points.ptr(), p_points.size(), -1.0, -1.0); + + r_mesh.vertices = ch.vertices; + + r_mesh.edges.resize(ch.edges.size()); + for (uint32_t i = 0; i < ch.edges.size(); i++) { + r_mesh.edges.write[i].a = (&ch.edges[i])->get_source_vertex(); + r_mesh.edges.write[i].b = (&ch.edges[i])->get_target_vertex(); + } + + r_mesh.faces.resize(ch.faces.size()); + for (uint32_t i = 0; i < ch.faces.size(); i++) { + const Edge *e_start = &ch.edges[ch.faces[i]]; + const Edge *e = e_start; + Geometry3D::MeshData::Face &face = r_mesh.faces.write[i]; + + do { + face.indices.push_back(e->get_target_vertex()); + + e = e->get_next_edge_of_face(); + } while (e != e_start); + + // compute normal + if (face.indices.size() >= 3) { + face.plane = Plane(r_mesh.vertices[face.indices[0]], r_mesh.vertices[face.indices[2]], r_mesh.vertices[face.indices[1]]); + } else { + WARN_PRINT("Too few vertices per face."); + } + } + + return OK; +} diff --git a/core/math/convex_hull.h b/core/math/convex_hull.h new file mode 100644 index 0000000000..ba7be9c5e8 --- /dev/null +++ b/core/math/convex_hull.h @@ -0,0 +1,112 @@ +/*************************************************************************/ +/* convex_hull.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +/* +Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef CONVEX_HULL_H +#define CONVEX_HULL_H + +#include "core/math/geometry_3d.h" +#include "core/math/vector3.h" +#include "core/templates/local_vector.h" +#include "core/templates/vector.h" + +/// Convex hull implementation based on Preparata and Hong +/// See http://code.google.com/p/bullet/issues/detail?id=275 +/// Ole Kniemeyer, MAXON Computer GmbH +class ConvexHullComputer { +public: + class Edge { + private: + int32_t next = 0; + int32_t reverse = 0; + int32_t target_vertex = 0; + + friend class ConvexHullComputer; + + public: + int32_t get_source_vertex() const { + return (this + reverse)->target_vertex; + } + + int32_t get_target_vertex() const { + return target_vertex; + } + + const Edge *get_next_edge_of_vertex() const // clockwise list of all edges of a vertex + { + return this + next; + } + + const Edge *get_next_edge_of_face() const // counter-clockwise list of all edges of a face + { + return (this + reverse)->get_next_edge_of_vertex(); + } + + const Edge *get_reverse_edge() const { + return this + reverse; + } + }; + + // Vertices of the output hull + Vector<Vector3> vertices; + + // Edges of the output hull + LocalVector<Edge> edges; + + // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons + LocalVector<int32_t> faces; + + /* + Compute convex hull of "count" vertices stored in "coords". + If "shrink" is positive, the convex hull is shrunken by that amount (each face is moved by "shrink" length units + towards the center along its normal). + If "shrinkClamp" is positive, "shrink" is clamped to not exceed "shrinkClamp * innerRadius", where "innerRadius" + is the minimum distance of a face to the center of the convex hull. + The returned value is the amount by which the hull has been shrunken. If it is negative, the amount was so large + that the resulting convex hull is empty. + The output convex hull can be found in the member variables "vertices", "edges", "faces". + */ + real_t compute(const Vector3 *p_coords, int32_t p_count, real_t p_shrink, real_t p_shrink_clamp); + + static Error convex_hull(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_mesh); +}; + +#endif // CONVEX_HULL_H diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp index 200095d8cb..8e596f0f9d 100644 --- a/core/math/dynamic_bvh.cpp +++ b/core/math/dynamic_bvh.cpp @@ -312,8 +312,11 @@ void DynamicBVH::optimize_incremental(int passes) { if (passes < 0) { passes = total_leaves; } - if (bvh_root && (passes > 0)) { + if (passes > 0) { do { + if (!bvh_root) { + break; + } Node *node = bvh_root; unsigned bit = 0; while (node->is_internal()) { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index c0d7649b65..3389407e72 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -275,8 +275,8 @@ public: static _ALWAYS_INLINE_ double db2linear(double p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); } static _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); } - static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } - static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } + static _ALWAYS_INLINE_ double round(double p_val) { return ::round(p_val); } + static _ALWAYS_INLINE_ float round(float p_val) { return ::roundf(p_val); } static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) { int64_t range = max - min; @@ -311,20 +311,20 @@ public: static float random(float from, float to); static int random(int from, int to); - static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) { + static _ALWAYS_INLINE_ bool is_equal_approx(float a, float b) { // Check for exact equality first, required to handle "infinity" values. if (a == b) { return true; } // Then check for approximate equality. - real_t tolerance = CMP_EPSILON * abs(a); + float tolerance = CMP_EPSILON * abs(a); if (tolerance < CMP_EPSILON) { tolerance = CMP_EPSILON; } return abs(a - b) < tolerance; } - static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b, real_t tolerance) { + static _ALWAYS_INLINE_ bool is_equal_approx(float a, float b, float tolerance) { // Check for exact equality first, required to handle "infinity" values. if (a == b) { return true; @@ -333,7 +333,33 @@ public: return abs(a - b) < tolerance; } - static _ALWAYS_INLINE_ bool is_zero_approx(real_t s) { + static _ALWAYS_INLINE_ bool is_zero_approx(float s) { + return abs(s) < CMP_EPSILON; + } + + static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b) { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) { + return true; + } + // Then check for approximate equality. + double tolerance = CMP_EPSILON * abs(a); + if (tolerance < CMP_EPSILON) { + tolerance = CMP_EPSILON; + } + return abs(a - b) < tolerance; + } + + static _ALWAYS_INLINE_ bool is_equal_approx(double a, double b, double tolerance) { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) { + return true; + } + // Then check for approximate equality. + return abs(a - b) < tolerance; + } + + static _ALWAYS_INLINE_ bool is_zero_approx(double s) { return abs(s) < CMP_EPSILON; } @@ -358,28 +384,10 @@ public: return u.d; } - //this function should be as fast as possible and rounding mode should not matter + // This function should be as fast as possible and rounding mode should not matter. static _ALWAYS_INLINE_ int fast_ftoi(float a) { - static int b; - -#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0603) || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // windows 8 phone? - b = (int)((a > 0.0) ? (a + 0.5) : (a - 0.5)); - -#elif defined(_MSC_VER) && _MSC_VER < 1800 - __asm fld a __asm fistp b - /*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) - // use AT&T inline assembly style, document that - // we use memory as output (=m) and input (m) - __asm__ __volatile__ ( - "flds %1 \n\t" - "fistpl %0 \n\t" - : "=m" (b) - : "m" (a));*/ - -#else - b = lrintf(a); //assuming everything but msvc 2012 or earlier has lrint -#endif - return b; + // Assuming every supported compiler has `lrint()`. + return lrintf(a); } static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) { diff --git a/core/math/quat.cpp b/core/math/quat.cpp index 6f13e04027..3982a0b993 100644 --- a/core/math/quat.cpp +++ b/core/math/quat.cpp @@ -87,7 +87,7 @@ Quat Quat::normalized() const { } bool Quat::is_normalized() const { - return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON); //use less epsilon + return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); //use less epsilon } Quat Quat::inverse() const { diff --git a/core/math/quat.h b/core/math/quat.h index 9db914fe52..d9b130c050 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -28,14 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Circular dependency between Vector3 and Basis :/ -#include "core/math/vector3.h" - #ifndef QUAT_H #define QUAT_H #include "core/math/math_defs.h" #include "core/math/math_funcs.h" +#include "core/math/vector3.h" #include "core/string/ustring.h" class Quat { diff --git a/core/math/rect2.h b/core/math/rect2.h index 512499bdb2..1dc027cf72 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -182,13 +182,17 @@ struct Rect2 { inline Rect2 grow(real_t p_amount) const { Rect2 g = *this; - g.position.x -= p_amount; - g.position.y -= p_amount; - g.size.width += p_amount * 2; - g.size.height += p_amount * 2; + g.grow_by(p_amount); return g; } + inline void grow_by(real_t p_amount) { + position.x -= p_amount; + position.y -= p_amount; + size.width += p_amount * 2; + size.height += p_amount * 2; + } + inline Rect2 grow_side(Side p_side, real_t p_amount) const { Rect2 g = *this; g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0, diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 5129ed336e..46a08b53ab 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -59,7 +59,7 @@ Vector2 Vector2::normalized() const { bool Vector2::is_normalized() const { // use length_squared() instead of length() to avoid sqrt(), makes it more stringent. - return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON); + return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); } real_t Vector2::distance_to(const Vector2 &p_vector2) const { diff --git a/core/math/vector2.h b/core/math/vector2.h index edc6e3a3ef..6abe0f5ea9 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -37,18 +37,26 @@ struct Vector2i; struct Vector2 { + static const int AXIS_COUNT = 2; + enum Axis { AXIS_X, AXIS_Y, }; union { - real_t x = 0; - real_t width; - }; - union { - real_t y = 0; - real_t height; + struct { + union { + real_t x; + real_t width; + }; + union { + real_t y; + real_t height; + }; + }; + + real_t coord[2] = { 0 }; }; _FORCE_INLINE_ real_t &operator[](int p_idx) { @@ -58,6 +66,18 @@ struct Vector2 { return p_idx ? y : x; } + _FORCE_INLINE_ void set_all(real_t p_value) { + x = y = p_value; + } + + _FORCE_INLINE_ int min_axis() const { + return x < y ? 0 : 1; + } + + _FORCE_INLINE_ int max_axis() const { + return x < y ? 1 : 0; + } + void normalize(); Vector2 normalized() const; bool is_normalized() const; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index f0629d3db8..d4317d506c 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -52,14 +52,6 @@ real_t Vector3::get_axis(int p_axis) const { return operator[](p_axis); } -int Vector3::min_axis() const { - return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); -} - -int Vector3::max_axis() const { - return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); -} - void Vector3::snap(Vector3 p_step) { x = Math::snapped(x, p_step.x); y = Math::snapped(y, p_step.y); diff --git a/core/math/vector3.h b/core/math/vector3.h index 377581bb45..adfc52566f 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -38,6 +38,8 @@ class Basis; struct Vector3 { + static const int AXIS_COUNT = 3; + enum Axis { AXIS_X, AXIS_Y, @@ -65,8 +67,17 @@ struct Vector3 { void set_axis(int p_axis, real_t p_value); real_t get_axis(int p_axis) const; - int min_axis() const; - int max_axis() const; + _FORCE_INLINE_ void set_all(real_t p_value) { + x = y = z = p_value; + } + + _FORCE_INLINE_ int min_axis() const { + return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); + } + + _FORCE_INLINE_ int max_axis() const { + return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); + } _FORCE_INLINE_ real_t length() const; _FORCE_INLINE_ real_t length_squared() const; @@ -412,7 +423,7 @@ Vector3 Vector3::normalized() const { bool Vector3::is_normalized() const { // use length_squared() instead of length() to avoid sqrt(), makes it more stringent. - return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON); + return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); } Vector3 Vector3::inverse() const { diff --git a/core/object/object.cpp b/core/object/object.cpp index 413f917518..a8b2c4a939 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1345,7 +1345,7 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, if (!s) { bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal) || (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)); - ERR_FAIL_COND_MSG(signal_is_valid, "Attempt to disconnect a nonexistent connection from '" + to_string() + "'. signal: '" + p_signal + "', callable: '" + p_callable + "'."); + ERR_FAIL_COND_MSG(signal_is_valid, "Attempt to disconnect a nonexistent connection from '" + to_string() + "'. Signal: '" + p_signal + "', callable: '" + p_callable + "'."); } ERR_FAIL_COND_MSG(!s, vformat("Disconnecting nonexistent signal '%s' in %s.", p_signal, to_string())); diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index b7c3a17ba9..39ae475c12 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -331,7 +331,7 @@ public: } }; -Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags) { +Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags, bool p_copy_links) { List<String> dirs; String curdir = get_current_dir(); @@ -339,7 +339,9 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag String n = get_next(); while (n != String()) { if (n != "." && n != "..") { - if (current_is_dir()) { + if (p_copy_links && is_link(get_current_dir().plus_file(n))) { + create_link(read_link(get_current_dir().plus_file(n)), p_to + n); + } else if (current_is_dir()) { dirs.push_back(n); } else { const String &rel_path = n; @@ -371,7 +373,7 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag Error err = change_dir(E->get()); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot change current directory to '" + E->get() + "'."); - err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags); + err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags, p_copy_links); if (err) { change_dir(".."); ERR_FAIL_V_MSG(err, "Failed to copy recursively."); @@ -383,7 +385,7 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag return OK; } -Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) { +Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags, bool p_copy_links) { ERR_FAIL_COND_V_MSG(!dir_exists(p_from), ERR_FILE_NOT_FOUND, "Source directory doesn't exist."); DirAccess *target_da = DirAccess::create_for_path(p_to); @@ -402,7 +404,7 @@ Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) { } DirChanger dir_changer(this, p_from); - Error err = _copy_dir(target_da, p_to, p_chmod_flags); + Error err = _copy_dir(target_da, p_to, p_chmod_flags, p_copy_links); memdelete(target_da); return err; diff --git a/core/os/dir_access.h b/core/os/dir_access.h index 7f0bcd372d..16154a4850 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -50,7 +50,7 @@ private: AccessType _access_type = ACCESS_FILESYSTEM; static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object - Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags); + Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags, bool p_copy_links); protected: String _get_root_path() const; @@ -87,13 +87,17 @@ public: virtual bool is_readable(String p_dir) { return true; }; virtual bool is_writable(String p_dir) { return true; }; static bool exists(String p_dir); - virtual size_t get_space_left() = 0; + virtual uint64_t get_space_left() = 0; - Error copy_dir(String p_from, String p_to, int p_chmod_flags = -1); + Error copy_dir(String p_from, String p_to, int p_chmod_flags = -1, bool p_copy_links = false); virtual Error copy(String p_from, String p_to, int p_chmod_flags = -1); virtual Error rename(String p_from, String p_to) = 0; virtual Error remove(String p_name) = 0; + virtual bool is_link(String p_file) = 0; + virtual String read_link(String p_file) = 0; + virtual Error create_link(String p_source, String p_target) = 0; + // Meant for editor code when we want to quickly remove a file without custom // handling (e.g. removing a cache file). static void remove_file_or_error(String p_path) { diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index ad234c2d49..d1b940190a 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -367,10 +367,10 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const { return strings; } -int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); - int i = 0; + + uint64_t i = 0; for (i = 0; i < p_length && !eof_reached(); i++) { p_dst[i] = get_8(); } @@ -380,11 +380,11 @@ int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const { String FileAccess::get_as_utf8_string() const { Vector<uint8_t> sourcef; - int len = get_len(); + uint64_t len = get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); - int r = get_buffer(w, len); + uint64_t r = get_buffer(w, len); ERR_FAIL_COND_V(r != len, String()); w[len] = 0; @@ -550,8 +550,8 @@ void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_ store_line(line); } -void FileAccess::store_buffer(const uint8_t *p_src, int p_length) { - for (int i = 0; i < p_length; i++) { +void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) { + for (uint64_t i = 0; i < p_length; i++) { store_8(p_src[i]); } } @@ -565,7 +565,7 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_err ERR_FAIL_V_MSG(Vector<uint8_t>(), "Can't open file from path '" + String(p_path) + "'."); } Vector<uint8_t> data; - data.resize(f->get_len()); + data.resize(f->get_length()); f->get_buffer(data.ptrw(), data.size()); memdelete(f); return data; @@ -601,7 +601,7 @@ String FileAccess::get_md5(const String &p_file) { unsigned char step[32768]; while (true) { - int br = f->get_buffer(step, 32768); + uint64_t br = f->get_buffer(step, 32768); if (br > 0) { ctx.update(step, br); } @@ -629,7 +629,7 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { unsigned char step[32768]; while (true) { - int br = f->get_buffer(step, 32768); + uint64_t br = f->get_buffer(step, 32768); if (br > 0) { ctx.update(step, br); } @@ -658,7 +658,7 @@ String FileAccess::get_sha256(const String &p_file) { unsigned char step[32768]; while (true) { - int br = f->get_buffer(step, 32768); + uint64_t br = f->get_buffer(step, 32768); if (br > 0) { ctx.update(step, br); } diff --git a/core/os/file_access.h b/core/os/file_access.h index 1c78204c1d..1b9fb2f422 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -93,10 +93,10 @@ public: virtual String get_path() const { return ""; } /// returns the path for the current open file virtual String get_path_absolute() const { return ""; } /// returns the absolute path for the current open file - virtual void seek(size_t p_position) = 0; ///< seek to a given position - virtual void seek_end(int64_t p_position = 0) = 0; ///< seek from the end of file - virtual size_t get_position() const = 0; ///< get position in the file - virtual size_t get_len() const = 0; ///< get size of the file + virtual void seek(uint64_t p_position) = 0; ///< seek to a given position + virtual void seek_end(int64_t p_position = 0) = 0; ///< seek from the end of file with negative offset + virtual uint64_t get_position() const = 0; ///< get position in the file + virtual uint64_t get_length() const = 0; ///< get size of the file virtual bool eof_reached() const = 0; ///< reading passed EOF @@ -109,7 +109,7 @@ public: virtual double get_double() const; virtual real_t get_real() const; - virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; ///< get an array of bytes virtual String get_line() const; virtual String get_token() const; virtual Vector<String> get_csv_line(const String &p_delim = ",") const; @@ -142,7 +142,7 @@ public: virtual void store_pascal_string(const String &p_string); virtual String get_pascal_string(); - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_name) = 0; ///< return true if a file exists diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index 4b2cafd8fe..4c5f0b5220 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -60,7 +60,7 @@ static const _KeyCodeText _keycodes[] = { {KEY_PAGEUP ,"PageUp"}, {KEY_PAGEDOWN ,"PageDown"}, {KEY_SHIFT ,"Shift"}, - {KEY_CONTROL ,"Control"}, + {KEY_CTRL ,"Ctrl"}, #ifdef OSX_ENABLED {KEY_META ,"Command"}, #else @@ -314,7 +314,7 @@ bool keycode_has_unicode(uint32_t p_keycode) { case KEY_PAGEUP: case KEY_PAGEDOWN: case KEY_SHIFT: - case KEY_CONTROL: + case KEY_CTRL: case KEY_META: case KEY_ALT: case KEY_CAPSLOCK: @@ -401,7 +401,7 @@ String keycode_get_string(uint32_t p_code) { codestr += "+"; } if (p_code & KEY_MASK_CTRL) { - codestr += find_keycode_name(KEY_CONTROL); + codestr += find_keycode_name(KEY_CTRL); codestr += "+"; } if (p_code & KEY_MASK_META) { diff --git a/core/os/keyboard.h b/core/os/keyboard.h index f6fe5fc070..33f9213c4e 100644 --- a/core/os/keyboard.h +++ b/core/os/keyboard.h @@ -68,7 +68,7 @@ enum Key { KEY_PAGEUP = SPKEY | 0x13, KEY_PAGEDOWN = SPKEY | 0x14, KEY_SHIFT = SPKEY | 0x15, - KEY_CONTROL = SPKEY | 0x16, + KEY_CTRL = SPKEY | 0x16, KEY_META = SPKEY | 0x17, KEY_ALT = SPKEY | 0x18, KEY_CAPSLOCK = SPKEY | 0x19, diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index bdb66526a4..49cf171f2b 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -939,7 +939,7 @@ const char32_t *String::get_data() const { } void String::erase(int p_pos, int p_chars) { - *this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars))); + *this = left(MAX(p_pos, 0)) + substr(p_pos + p_chars, length() - ((p_pos + p_chars))); } String String::capitalize() const { @@ -3382,14 +3382,14 @@ String String::format(const Variant &values, String placeholder) const { if (value_arr.size() == 2) { Variant v_key = value_arr[0]; String key = v_key; - if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") { + if (key.left(1) == "\"" && key.right(1) == "\"") { key = key.substr(1, key.length() - 2); } Variant v_val = value_arr[1]; String val = v_val; - if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") { + if (val.left(1) == "\"" && val.right(1) == "\"") { val = val.substr(1, val.length() - 2); } @@ -3401,7 +3401,7 @@ String String::format(const Variant &values, String placeholder) const { Variant v_val = values_arr[i]; String val = v_val; - if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") { + if (val.left(1) == "\"" && val.right(1) == "\"") { val = val.substr(1, val.length() - 2); } @@ -3421,11 +3421,11 @@ String String::format(const Variant &values, String placeholder) const { String key = E->get(); String val = d[E->get()]; - if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") { + if (key.left(1) == "\"" && key.right(1) == "\"") { key = key.substr(1, key.length() - 2); } - if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") { + if (val.left(1) == "\"" && val.right(1) == "\"") { val = val.substr(1, val.length() - 2); } @@ -3529,6 +3529,10 @@ String String::repeat(int p_count) const { } String String::left(int p_pos) const { + if (p_pos < 0) { + p_pos = length() + p_pos; + } + if (p_pos <= 0) { return ""; } @@ -3541,15 +3545,19 @@ String String::left(int p_pos) const { } String String::right(int p_pos) const { - if (p_pos >= length()) { - return ""; + if (p_pos < 0) { + p_pos = length() + p_pos; } if (p_pos <= 0) { + return ""; + } + + if (p_pos >= length()) { return *this; } - return substr(p_pos, (length() - p_pos)); + return substr(length() - p_pos); } char32_t String::unicode_at(int p_idx) const { diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h index 7002034710..481289309f 100644 --- a/core/templates/paged_allocator.h +++ b/core/templates/paged_allocator.h @@ -35,6 +35,8 @@ #include "core/os/spin_lock.h" #include "core/typedefs.h" +#include <type_traits> + template <class T, bool thread_safe = false> class PagedAllocator { T **page_pool = nullptr; @@ -89,8 +91,10 @@ public: allocs_available++; } - void reset() { - ERR_FAIL_COND(allocs_available < pages_allocated * page_size); + void reset(bool p_allow_unfreed = false) { + if (!p_allow_unfreed || !std::is_trivially_destructible<T>::value) { + ERR_FAIL_COND(allocs_available < pages_allocated * page_size); + } if (pages_allocated) { for (uint32_t i = 0; i < pages_allocated; i++) { memfree(page_pool[i]); diff --git a/servers/physics_3d/broad_phase_3d_basic.h b/core/templates/pooled_list.h index 54d34e005f..b4a6d2d1dd 100644 --- a/servers/physics_3d/broad_phase_3d_basic.h +++ b/core/templates/pooled_list.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_3d_basic.h */ +/* pooled_list.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,78 +28,68 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_BASIC_H -#define BROAD_PHASE_BASIC_H +#pragma once -#include "broad_phase_3d_sw.h" -#include "core/templates/map.h" +// Simple template to provide a pool with O(1) allocate and free. +// The freelist could alternatively be a linked list placed within the unused elements +// to use less memory, however a separate freelist is probably more cache friendly. -class BroadPhase3DBasic : public BroadPhase3DSW { - struct Element { - CollisionObject3DSW *owner; - bool _static; - AABB aabb; - int subindex; - }; +// NOTE : Take great care when using this with non POD types. The construction and destruction +// is done in the LocalVector, NOT as part of the pool. So requesting a new item does not guarantee +// a constructor is run, and free does not guarantee a destructor. +// You should generally handle clearing +// an item explicitly after a request, as it may contain 'leftovers'. +// This is by design for fastest use in the BVH. If you want a more general pool +// that does call constructors / destructors on request / free, this should probably be +// a separate template. - Map<ID, Element> element_map; +#include "core/templates/local_vector.h" - ID current; +template <class T, bool force_trivial = false> +class PooledList { + LocalVector<T, uint32_t, force_trivial> list; + LocalVector<uint32_t, uint32_t, true> freelist; - struct PairKey { - union { - struct { - ID a; - ID b; - }; - uint64_t key; - }; - - _FORCE_INLINE_ bool operator<(const PairKey &p_key) const { - return key < p_key.key; - } - - PairKey() { key = 0; } - PairKey(ID p_a, ID p_b) { - if (p_a > p_b) { - a = p_b; - b = p_a; - } else { - a = p_a; - b = p_b; - } - } - }; - - Map<PairKey, void *> pair_map; - - PairCallback pair_callback; - void *pair_userdata; - UnpairCallback unpair_callback; - void *unpair_userdata; + // not all list members are necessarily used + int _used_size; public: - // 0 is an invalid ID - virtual ID create(CollisionObject3DSW *p_object, int p_subindex = 0); - virtual void move(ID p_id, const AABB &p_aabb); - virtual void set_static(ID p_id, bool p_static); - virtual void remove(ID p_id); - - virtual CollisionObject3DSW *get_object(ID p_id) const; - virtual bool is_static(ID p_id) const; - virtual int get_subindex(ID p_id) const; - - virtual int cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - virtual int cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - - virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); - virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); - - virtual void update(); + PooledList() { + _used_size = 0; + } + + int estimate_memory_use() const { + return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t)); + } + + const T &operator[](uint32_t p_index) const { + return list[p_index]; + } + T &operator[](uint32_t p_index) { + return list[p_index]; + } + + int size() const { return _used_size; } + + T *request(uint32_t &r_id) { + _used_size++; + + if (freelist.size()) { + // pop from freelist + int new_size = freelist.size() - 1; + r_id = freelist[new_size]; + freelist.resize(new_size); + return &list[r_id]; + } - static BroadPhase3DSW *_create(); - BroadPhase3DBasic(); + r_id = list.size(); + list.resize(r_id + 1); + return &list[r_id]; + } + void free(const uint32_t &p_id) { + // should not be on free list already + CRASH_COND(p_id >= list.size()); + freelist.push_back(p_id); + _used_size--; + } }; - -#endif // BROAD_PHASE_BASIC_H diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 3c7e2a0719..09cf785390 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -366,8 +366,8 @@ Array Array::filter(const Callable &p_callable) const { new_arr.resize(size()); int accepted_count = 0; + const Variant *argptrs[1]; for (int i = 0; i < size(); i++) { - const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *)); argptrs[0] = &get(i); Variant result; @@ -392,8 +392,8 @@ Array Array::map(const Callable &p_callable) const { Array new_arr; new_arr.resize(size()); + const Variant *argptrs[1]; for (int i = 0; i < size(); i++) { - const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *)); argptrs[0] = &get(i); Variant result; @@ -417,8 +417,8 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const start = 1; } + const Variant *argptrs[2]; for (int i = start; i < size(); i++) { - const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *) * 2); argptrs[0] = &ret; argptrs[1] = &get(i); diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index e06b3e07ef..5c87042f6b 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -50,6 +50,15 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu custom->call(p_arguments, p_argcount, r_return_value, r_call_error); } else { Object *obj = ObjectDB::get_instance(ObjectID(object)); +#ifdef DEBUG_ENABLED + if (!obj) { + r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_call_error.argument = 0; + r_call_error.expected = 0; + r_return_value = Variant(); + return; + } +#endif r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error); } } diff --git a/core/variant/callable.h b/core/variant/callable.h index d91bebfa5f..20d0804292 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -44,9 +44,9 @@ class CallableCustom; // is required. It is designed for the standard case (object and method) // but can be optimized or customized. +// Enforce 16 bytes with `alignas` to avoid arch-specific alignment issues on x86 vs armv7. class Callable { - //needs to be max 16 bytes in 64 bits - StringName method; + alignas(8) StringName method; union { uint64_t object = 0; CallableCustom *custom; @@ -138,8 +138,9 @@ public: // be put inside a Variant, but it is not // used by the engine itself. +// Enforce 16 bytes with `alignas` to avoid arch-specific alignment issues on x86 vs armv7. class Signal { - StringName name; + alignas(8) StringName name; ObjectID object; public: diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index efaaa8cd19..063611d415 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -611,6 +611,9 @@ struct _VariantCall { if (buffer_size <= 0) { ERR_FAIL_V_MSG(decompressed, "Decompression buffer size must be greater than zero."); } + if (p_instance->size() == 0) { + ERR_FAIL_V_MSG(decompressed, "Compressed buffer size must be greater than zero."); + } decompressed.resize(buffer_size); int result = Compression::decompress(decompressed.ptrw(), buffer_size, p_instance->ptr(), p_instance->size(), mode); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 7d33d85cd6..fb791f8c0c 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -43,18 +43,21 @@ public: v->type = p_type; switch (p_type) { - case Variant::AABB: - init_aabb(v); + case Variant::STRING: + init_string(v); break; case Variant::TRANSFORM2D: init_transform2d(v); break; + case Variant::AABB: + init_aabb(v); + break; + case Variant::BASIS: + init_basis(v); + break; case Variant::TRANSFORM: init_transform(v); break; - case Variant::STRING: - init_string(v); - break; case Variant::STRING_NAME: init_string_name(v); break; @@ -192,6 +195,10 @@ public: v->type = GetTypeInfo<T>::VARIANT_TYPE; } + // Should be in the same order as Variant::Type for consistency. + // Those primitive and vector types don't need an `init_` method: + // Nil, bool, float, Vector2/i, Rect2/i, Vector3/i, Plane, Quat, Color, RID. + // Object is a special case, handled via `object_assign_null`. _FORCE_INLINE_ static void init_string(Variant *v) { memnew_placement(v->_data._mem, String); v->type = Variant::STRING; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index af66a11fe5..e210fa8808 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1393,7 +1393,7 @@ <constant name="KEY_SHIFT" value="16777237" enum="Key"> Shift key. </constant> - <constant name="KEY_CONTROL" value="16777238" enum="Key"> + <constant name="KEY_CTRL" value="16777238" enum="Key"> Control key. </constant> <constant name="KEY_META" value="16777239" enum="Key"> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index a1e522d146..f7a116b934 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -60,8 +60,8 @@ <member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus" default="false"> If [code]true[/code], the area's audio bus overrides the default audio bus. </member> - <member name="gravity" type="float" setter="set_gravity" getter="get_gravity" default="98.0"> - The area's gravity intensity (ranges from -1024 to 1024). This value multiplies the gravity vector. This is useful to alter the force of gravity without altering its direction. + <member name="gravity" type="float" setter="set_gravity" getter="get_gravity" default="980.0"> + The area's gravity intensity (in pixels per second squared). This value multiplies the gravity vector. This is useful to alter the force of gravity without altering its direction. </member> <member name="gravity_distance_scale" type="float" setter="set_gravity_distance_scale" getter="get_gravity_distance_scale" default="0.0"> The falloff factor for point gravity. The greater the value, the faster gravity decreases with distance. @@ -107,7 +107,7 @@ </description> </signal> <signal name="area_shape_entered"> - <argument index="0" name="area_id" type="int"> + <argument index="0" name="area_rid" type="RID"> </argument> <argument index="1" name="area" type="Area2D"> </argument> @@ -124,7 +124,7 @@ </description> </signal> <signal name="area_shape_exited"> - <argument index="0" name="area_id" type="int"> + <argument index="0" name="area_rid" type="RID"> </argument> <argument index="1" name="area" type="Area2D"> </argument> @@ -157,7 +157,7 @@ </description> </signal> <signal name="body_shape_entered"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node2D"> </argument> @@ -174,7 +174,7 @@ </description> </signal> <signal name="body_shape_exited"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node2D"> </argument> diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml index e69a89a836..108387823b 100644 --- a/doc/classes/Area3D.xml +++ b/doc/classes/Area3D.xml @@ -59,7 +59,7 @@ If [code]true[/code], the area's audio bus overrides the default audio bus. </member> <member name="gravity" type="float" setter="set_gravity" getter="get_gravity" default="9.8"> - The area's gravity intensity (ranges from -1024 to 1024). This value multiplies the gravity vector. This is useful to alter the force of gravity without altering its direction. + The area's gravity intensity (in meters per second squared). This value multiplies the gravity vector. This is useful to alter the force of gravity without altering its direction. </member> <member name="gravity_distance_scale" type="float" setter="set_gravity_distance_scale" getter="get_gravity_distance_scale" default="0.0"> The falloff factor for point gravity. The greater the value, the faster gravity decreases with distance. @@ -117,7 +117,7 @@ </description> </signal> <signal name="area_shape_entered"> - <argument index="0" name="area_id" type="int"> + <argument index="0" name="area_rid" type="RID"> </argument> <argument index="1" name="area" type="Area3D"> </argument> @@ -134,7 +134,7 @@ </description> </signal> <signal name="area_shape_exited"> - <argument index="0" name="area_id" type="int"> + <argument index="0" name="area_rid" type="RID"> </argument> <argument index="1" name="area" type="Area3D"> </argument> @@ -167,7 +167,7 @@ </description> </signal> <signal name="body_shape_entered"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node3D"> </argument> @@ -184,7 +184,7 @@ </description> </signal> <signal name="body_shape_exited"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node3D"> </argument> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 624b51e463..879b61a880 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -333,14 +333,14 @@ [gdscript] # Will evaluate to `true`. if 2 in [2, 4, 6, 8]: - print("Containes!") + print("Contains!") [/gdscript] [csharp] // As there is no "in" keyword in C#, you have to use Contains var array = new Godot.Collections.Array{2, 4, 6, 8}; if (array.Contains(2)) { - GD.Print("Containes!"); + GD.Print("Contains!"); } [/csharp] [/codeblocks] diff --git a/doc/classes/AudioEffectPitchShift.xml b/doc/classes/AudioEffectPitchShift.xml index afe364de63..917556fded 100644 --- a/doc/classes/AudioEffectPitchShift.xml +++ b/doc/classes/AudioEffectPitchShift.xml @@ -12,7 +12,7 @@ <methods> </methods> <members> - <member name="fft_size" type="int" setter="set_fft_size" getter="get_fft_size" enum="AudioEffectPitchShift.FFT_Size" default="3"> + <member name="fft_size" type="int" setter="set_fft_size" getter="get_fft_size" enum="AudioEffectPitchShift.FFTSize" default="3"> </member> <member name="oversampling" type="int" setter="set_oversampling" getter="get_oversampling" default="4"> </member> @@ -21,18 +21,18 @@ </member> </members> <constants> - <constant name="FFT_SIZE_256" value="0" enum="FFT_Size"> + <constant name="FFT_SIZE_256" value="0" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_512" value="1" enum="FFT_Size"> + <constant name="FFT_SIZE_512" value="1" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_1024" value="2" enum="FFT_Size"> + <constant name="FFT_SIZE_1024" value="2" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_2048" value="3" enum="FFT_Size"> + <constant name="FFT_SIZE_2048" value="3" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_4096" value="4" enum="FFT_Size"> + <constant name="FFT_SIZE_4096" value="4" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_MAX" value="5" enum="FFT_Size"> - Represents the size of the [enum FFT_Size] enum. + <constant name="FFT_SIZE_MAX" value="5" enum="FFTSize"> + Represents the size of the [enum FFTSize] enum. </constant> </constants> </class> diff --git a/doc/classes/AudioEffectSpectrumAnalyzer.xml b/doc/classes/AudioEffectSpectrumAnalyzer.xml index 4c08b18f1d..79a8932e25 100644 --- a/doc/classes/AudioEffectSpectrumAnalyzer.xml +++ b/doc/classes/AudioEffectSpectrumAnalyzer.xml @@ -11,24 +11,24 @@ <members> <member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="2.0"> </member> - <member name="fft_size" type="int" setter="set_fft_size" getter="get_fft_size" enum="AudioEffectSpectrumAnalyzer.FFT_Size" default="2"> + <member name="fft_size" type="int" setter="set_fft_size" getter="get_fft_size" enum="AudioEffectSpectrumAnalyzer.FFTSize" default="2"> </member> <member name="tap_back_pos" type="float" setter="set_tap_back_pos" getter="get_tap_back_pos" default="0.01"> </member> </members> <constants> - <constant name="FFT_SIZE_256" value="0" enum="FFT_Size"> + <constant name="FFT_SIZE_256" value="0" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_512" value="1" enum="FFT_Size"> + <constant name="FFT_SIZE_512" value="1" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_1024" value="2" enum="FFT_Size"> + <constant name="FFT_SIZE_1024" value="2" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_2048" value="3" enum="FFT_Size"> + <constant name="FFT_SIZE_2048" value="3" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_4096" value="4" enum="FFT_Size"> + <constant name="FFT_SIZE_4096" value="4" enum="FFTSize"> </constant> - <constant name="FFT_SIZE_MAX" value="5" enum="FFT_Size"> - Represents the size of the [enum FFT_Size] enum. + <constant name="FFT_SIZE_MAX" value="5" enum="FFTSize"> + Represents the size of the [enum FFTSize] enum. </constant> </constants> </class> diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index aa9f99a31e..9e70978db8 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -199,7 +199,7 @@ <member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" default="true"> If [code]true[/code], results in fractional delta calculation which has a smoother particles display effect. </member> - <member name="gravity" type="Vector2" setter="set_gravity" getter="get_gravity" default="Vector2( 0, 98 )"> + <member name="gravity" type="Vector2" setter="set_gravity" getter="get_gravity" default="Vector2( 0, 980 )"> Gravity applied to every particle. </member> <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0"> diff --git a/doc/classes/CharFXTransform.xml b/doc/classes/CharFXTransform.xml index 850098f741..7b57dc05f8 100644 --- a/doc/classes/CharFXTransform.xml +++ b/doc/classes/CharFXTransform.xml @@ -37,7 +37,7 @@ The position offset the character will be drawn with (in pixels). </member> <member name="outline" type="bool" setter="set_outline" getter="is_outline" default="false"> - If [code]ture[/code], FX transform is called for outline drawing. Setting this property won't affect drawing. + If [code]true[/code], FX transform is called for outline drawing. Setting this property won't affect drawing. </member> <member name="range" type="Vector2i" setter="set_range" getter="get_range" default="Vector2i( 0, 0 )"> Absolute character range in the string, corresponding to the glyph. Setting this property won't affect drawing. diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml index 81795abcdd..42a6df866f 100644 --- a/doc/classes/CodeEdit.xml +++ b/doc/classes/CodeEdit.xml @@ -193,8 +193,6 @@ </theme_item> <theme_item name="line_spacing" type="int" default="4"> </theme_item> - <theme_item name="mark_color" type="Color" default="Color( 1, 0.4, 0.4, 0.4 )"> - </theme_item> <theme_item name="normal" type="StyleBox"> </theme_item> <theme_item name="outline_size" type="int" default="0"> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index c0f918a01f..a9a230b78f 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -462,10 +462,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a color from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code]. + Returns a color from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. [codeblocks] [gdscript] func _ready(): @@ -485,10 +485,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a constant from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code]. + Returns a constant from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. </description> </method> <method name="get_theme_font" qualifiers="const"> @@ -496,10 +496,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a font from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code]. + Returns a font from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. </description> </method> <method name="get_theme_font_size" qualifiers="const"> @@ -507,10 +507,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a font size from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code]. + Returns a font size from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. </description> </method> <method name="get_theme_icon" qualifiers="const"> @@ -518,10 +518,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns an icon from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code]. + Returns an icon from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. </description> </method> <method name="get_theme_stylebox" qualifiers="const"> @@ -529,10 +529,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns a [StyleBox] from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code]. + Returns a [StyleBox] from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code]. </description> </method> <method name="get_tooltip" qualifiers="const"> @@ -593,10 +593,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if [Color] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if [Color] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. </description> </method> <method name="has_theme_color_override" qualifiers="const"> @@ -613,10 +613,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if constant with given [code]name[/code] and associated with [Control] of given [code]node_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if constant with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. </description> </method> <method name="has_theme_constant_override" qualifiers="const"> @@ -633,10 +633,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if font with given [code]name[/code] and associated with [Control] of given [code]node_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if font with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. </description> </method> <method name="has_theme_font_override" qualifiers="const"> @@ -653,10 +653,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if font size with given [code]name[/code] and associated with [Control] of given [code]type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if font size with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. </description> </method> <method name="has_theme_font_size_override" qualifiers="const"> @@ -673,10 +673,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if icon with given [code]name[/code] and associated with [Control] of given [code]node_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if icon with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. </description> </method> <method name="has_theme_icon_override" qualifiers="const"> @@ -693,10 +693,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if [StyleBox] with given [code]name[/code] and associated with [Control] of given [code]node_type[/code] exists in assigned [Theme]. + Returns [code]true[/code] if [StyleBox] with given [code]name[/code] and associated with [Control] of given [code]theme_type[/code] exists in assigned [Theme]. </description> </method> <method name="has_theme_stylebox_override" qualifiers="const"> @@ -1173,7 +1173,12 @@ Tells the parent [Container] nodes how they should resize and place the node on the Y axis. Use one of the [enum SizeFlags] constants to change the flags. See the constants to learn what each does. </member> <member name="theme" type="Theme" setter="set_theme" getter="get_theme"> - Changing this property replaces the current [Theme] resource this node and all its [Control] children use. + The [Theme] resource this node and all its [Control] children use. If a child node has its own [Theme] resource set, theme items are merged with child's definitions having higher priority. + </member> + <member name="theme_custom_type" type="StringName" setter="set_theme_custom_type" getter="get_theme_custom_type" default="@"""> + The type name used by this [Control] to look up its own theme items. By default, the class name of the node is used (e.g. [code]Button[/code] for the [Button] control), as well as the class names of all parent classes (in order of inheritance). Setting this property gives the highest priority to the type of the specified name, then falls back on the class names. + [b]Note:[/b] To look up [Control]'s own items use various [code]get_theme_*[/code] methods without specifying [code]theme_type[/code]. + [b]Note:[/b] Theme items are looked for in the tree order, from branch to root, where each [Control] node is checked for its [member theme] property. The earliest match against any type/class name is returned. The project-level Theme and the default Theme are checked last. </member> </members> <signals> diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index a9d7960501..2c61d723cd 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -154,14 +154,14 @@ <method name="list_dir_begin"> <return type="int" enum="Error"> </return> - <argument index="0" name="skip_navigational" type="bool" default="false"> + <argument index="0" name="show_navigational" type="bool" default="false"> </argument> - <argument index="1" name="skip_hidden" type="bool" default="false"> + <argument index="1" name="show_hidden" type="bool" default="false"> </argument> <description> Initializes the stream used to list all files and directories using the [method get_next] function, closing the current opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end]. - If [code]skip_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are filtered out. - If [code]skip_hidden[/code] is [code]true[/code], hidden files are filtered out. + If [code]show_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are included too. + If [code]show_hidden[/code] is [code]true[/code], hidden files are included too. </description> </method> <method name="list_dir_end"> diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index a5328ce382..3f324bf1a0 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -57,6 +57,12 @@ [b]Note:[/b] This returns the main editor control containing the whole editor, not the 2D or 3D viewports specifically. </description> </method> + <method name="get_editor_paths"> + <return type="EditorPaths"> + </return> + <description> + </description> + </method> <method name="get_editor_scale" qualifiers="const"> <return type="float"> </return> diff --git a/doc/classes/EditorPaths.xml b/doc/classes/EditorPaths.xml new file mode 100644 index 0000000000..b92927fd53 --- /dev/null +++ b/doc/classes/EditorPaths.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorPaths" inherits="Object" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_cache_dir" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_config_dir" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_data_dir" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_self_contained_file" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_settings_dir" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="is_self_contained" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorResourcePicker.xml b/doc/classes/EditorResourcePicker.xml new file mode 100644 index 0000000000..30c73daa77 --- /dev/null +++ b/doc/classes/EditorResourcePicker.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorResourcePicker" inherits="HBoxContainer" version="4.0"> + <brief_description> + Godot editor's control for selecting [Resource] type properties. + </brief_description> + <description> + This [Control] node is used in the editor's Inspector dock to allow editing of [Resource] type properties. It provides options for creating, loading, saving and converting resources. Can be used with [EditorInspectorPlugin] to recreate the same behavior. + [b]Note:[/b] This [Control] does not include any editor for the resource, as editing is controlled by the Inspector dock itself or sub-Inspectors. + </description> + <tutorials> + </tutorials> + <methods> + <method name="can_drop_data_fw" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="position" type="Vector2"> + </argument> + <argument index="1" name="data" type="Variant"> + </argument> + <argument index="2" name="from" type="Control"> + </argument> + <description> + </description> + </method> + <method name="drop_data_fw"> + <return type="void"> + </return> + <argument index="0" name="position" type="Vector2"> + </argument> + <argument index="1" name="data" type="Variant"> + </argument> + <argument index="2" name="from" type="Control"> + </argument> + <description> + </description> + </method> + <method name="get_allowed_types" qualifiers="const"> + <return type="PackedStringArray"> + </return> + <description> + Returns a list of all allowed types and subtypes corresponding to the [member base_type]. If the [member base_type] is empty, an empty list is returned. + </description> + </method> + <method name="get_drag_data_fw"> + <return type="Variant"> + </return> + <argument index="0" name="position" type="Vector2"> + </argument> + <argument index="1" name="from" type="Control"> + </argument> + <description> + </description> + </method> + <method name="handle_menu_selected" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + This virtual method can be implemented to handle context menu items not handled by default. See [method set_create_options]. + </description> + </method> + <method name="set_create_options" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="menu_node" type="Object"> + </argument> + <description> + This virtual method is called when updating the context menu of [EditorResourcePicker]. Implement this method to override the "New ..." items with your own options. [code]menu_node[/code] is a reference to the [PopupMenu] node. + [b]Note:[/b] Implement [method handle_menu_selected] to handle these custom items. + </description> + </method> + <method name="set_toggle_pressed"> + <return type="void"> + </return> + <argument index="0" name="pressed" type="bool"> + </argument> + <description> + Sets the toggle mode state for the main button. Works only if [member toggle_mode] is set to [code]true[/code]. + </description> + </method> + </methods> + <members> + <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default=""""> + The base type of allowed resource types. Can be a comma-separated list of several options. + </member> + <member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true"> + If [code]true[/code], the value can be selected and edited. + </member> + <member name="edited_resource" type="Resource" setter="set_edited_resource" getter="get_edited_resource"> + The edited resource value. + </member> + <member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" default="false"> + If [code]true[/code], the main button with the resource preview works in the toggle mode. Use [method set_toggle_pressed] to manually set the state. + </member> + </members> + <signals> + <signal name="resource_changed"> + <argument index="0" name="resource" type="Resource"> + </argument> + <description> + Emitted when the value of the edited resource was changed. + </description> + </signal> + <signal name="resource_selected"> + <argument index="0" name="resource" type="Resource"> + </argument> + <description> + Emitted when the resource value was set and user clicked to edit it. + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml index 0c1d969518..3239a75ada 100644 --- a/doc/classes/EditorResourcePreview.xml +++ b/doc/classes/EditorResourcePreview.xml @@ -40,7 +40,8 @@ <argument index="3" name="userdata" type="Variant"> </argument> <description> - Queue a resource being edited for preview (using an instance). Once the preview is ready, your receiver.receiver_func will be called either containing the preview texture or an empty texture (if no preview was possible). Callback must have the format: (path,texture,userdata). Userdata can be anything. + Queue the [code]resource[/code] being edited for preview. Once the preview is ready, the [code]receiver[/code]'s [code]receiver_func[/code] will be called. The [code]receiver_func[/code] must take the following four arguments: [String] path, [Texture2D] preview, [Texture2D] thumbnail_preview, [Variant] userdata. [code]userdata[/code] can be anything, and will be returned when [code]receiver_func[/code] is called. + [b]Note[/b]: If it was not possible to create the preview the [code]receiver_func[/code] will still be called, but the preview will be null. </description> </method> <method name="queue_resource_preview"> @@ -55,7 +56,8 @@ <argument index="3" name="userdata" type="Variant"> </argument> <description> - Queue a resource file for preview (using a path). Once the preview is ready, your receiver.receiver_func will be called either containing the preview texture or an empty texture (if no preview was possible). Callback must have the format: (path,texture,userdata). Userdata can be anything. + Queue a resource file located at [code]path[/code] for preview. Once the preview is ready, the [code]receiver[/code]'s [code]receiver_func[/code] will be called. The [code]receiver_func[/code] must take the following four arguments: [String] path, [Texture2D] preview, [Texture2D] thumbnail_preview, [Variant] userdata. [code]userdata[/code] can be anything, and will be returned when [code]receiver_func[/code] is called. + [b]Note[/b]: If it was not possible to create the preview the [code]receiver_func[/code] will still be called, but the preview will be null. </description> </method> <method name="remove_preview_generator"> diff --git a/doc/classes/EditorScriptPicker.xml b/doc/classes/EditorScriptPicker.xml new file mode 100644 index 0000000000..8334676d92 --- /dev/null +++ b/doc/classes/EditorScriptPicker.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorScriptPicker" inherits="EditorResourcePicker" version="4.0"> + <brief_description> + Godot editor's control for selecting the [code]script[/code] property of a [Node]. + </brief_description> + <description> + Similar to [EditorResourcePicker] this [Control] node is used in the editor's Inspector dock, but only to edit the [code]script[/code] property of a [Node]. Default options for creating new resources of all possible subtypes are replaced with dedicated buttons that open the "Attach Node Script" dialog. Can be used with [EditorInspectorPlugin] to recreate the same behavior. + [b]Note:[/b] You must set the [member script_owner] for the custom context menu items to work. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="script_owner" type="Node" setter="set_script_owner" getter="get_script_owner"> + The owner [Node] of the script property that holds the edited resource. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 016d0128eb..e732223516 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -124,15 +124,6 @@ Returns the value of the setting specified by [code]name[/code]. This is equivalent to using [method Object.get] on the EditorSettings instance. </description> </method> - <method name="get_settings_dir" qualifiers="const"> - <return type="String"> - </return> - <description> - Gets the global settings path for the engine. Inside this path, you can find some standard paths such as: - [code]settings/tmp[/code] - Used for temporary storage of files - [code]settings/templates[/code] - Where export templates are located - </description> - </method> <method name="has_setting" qualifiers="const"> <return type="bool"> </return> diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml index 381f4fae04..935335943f 100644 --- a/doc/classes/EditorSpinSlider.xml +++ b/doc/classes/EditorSpinSlider.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorSpinSlider" inherits="Range" version="4.0"> <brief_description> + Godot editor's control for editing numeric values. </brief_description> <description> + This [Control] node is used in the editor's Inspector dock to allow editing of numeric values. Can be used with [EditorInspectorPlugin] to recreate the same behavior. </description> <tutorials> </tutorials> diff --git a/doc/classes/File.xml b/doc/classes/File.xml index f0b9156b89..2206730523 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -61,7 +61,7 @@ </return> <description> Returns [code]true[/code] if the file cursor has read past the end of the file. - [b]Note:[/b] This function will still return [code]false[/code] while at the end of the file and only activates when reading past it. This can be confusing but it conforms to how low-level file access works in all operating systems. There is always [method get_len] and [method get_position] to implement a custom logic. + [b]Note:[/b] This function will still return [code]false[/code] while at the end of the file and only activates when reading past it. This can be confusing but it conforms to how low-level file access works in all operating systems. There is always [method get_length] and [method get_position] to implement a custom logic. </description> </method> <method name="file_exists" qualifiers="const"> @@ -121,10 +121,10 @@ <method name="get_buffer" qualifiers="const"> <return type="PackedByteArray"> </return> - <argument index="0" name="len" type="int"> + <argument index="0" name="length" type="int"> </argument> <description> - Returns next [code]len[/code] bytes of the file as a [PackedByteArray]. + Returns next [code]length[/code] bytes of the file as a [PackedByteArray]. </description> </method> <method name="get_csv_line" qualifiers="const"> @@ -158,7 +158,7 @@ Returns the next 32 bits from the file as a floating-point number. </description> </method> - <method name="get_len" qualifiers="const"> + <method name="get_length" qualifiers="const"> <return type="int"> </return> <description> diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index ebe4e3b00d..ebd6d2b92c 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -31,7 +31,9 @@ <member name="amount" type="int" setter="set_amount" getter="get_amount" default="8"> Number of particles emitted in one emission cycle. </member> - <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="GPUParticles2D.DrawOrder" default="0"> + <member name="collision_base_size" type="float" setter="set_collision_base_size" getter="get_collision_base_size" default="1.0"> + </member> + <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="GPUParticles2D.DrawOrder" default="1"> Particle draw order. Uses [enum DrawOrder] values. </member> <member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" default="true"> @@ -40,7 +42,7 @@ <member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio" default="0.0"> How rapidly particles in an emission cycle are emitted. If greater than [code]0[/code], there will be a gap in emissions before the next cycle begins. </member> - <member name="fixed_fps" type="int" setter="set_fixed_fps" getter="get_fixed_fps" default="0"> + <member name="fixed_fps" type="int" setter="set_fixed_fps" getter="get_fixed_fps" default="30"> The particle system's frame rate is fixed to a value. For instance, changing the value to 2 will make the particles render at 2 frames per second. Note this does not slow down the simulation of the particle system itself. </member> <member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" default="true"> @@ -70,6 +72,14 @@ <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> Particle texture. If [code]null[/code], particles will be squares. </member> + <member name="trail_enabled" type="bool" setter="set_trail_enabled" getter="is_trail_enabled" default="false"> + </member> + <member name="trail_length_secs" type="float" setter="set_trail_length" getter="get_trail_length" default="0.3"> + </member> + <member name="trail_section_subdivisions" type="int" setter="set_trail_section_subdivisions" getter="get_trail_section_subdivisions" default="4"> + </member> + <member name="trail_sections" type="int" setter="set_trail_sections" getter="get_trail_sections" default="8"> + </member> <member name="visibility_rect" type="Rect2" setter="set_visibility_rect" getter="get_visibility_rect" default="Rect2( -100, -100, 200, 200 )"> The [Rect2] that determines the node's region which needs to be visible on screen for the particle system to be active. Grow the rect if particles suddenly appear/disappear when the node enters/exits the screen. The [Rect2] can be grown via code or with the [b]Particles → Generate Visibility Rect[/b] editor tool. @@ -82,5 +92,7 @@ <constant name="DRAW_ORDER_LIFETIME" value="1" enum="DrawOrder"> Particles are drawn in order of remaining lifetime. </constant> + <constant name="DRAW_ORDER_REVERSE_LIFETIME" value="2" enum="DrawOrder"> + </constant> </constants> </class> diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index e5d6581ddc..76f0fdb406 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -126,7 +126,7 @@ </member> <member name="sub_emitter" type="NodePath" setter="set_sub_emitter" getter="get_sub_emitter" default="NodePath("")"> </member> - <member name="trail_enabled" type="bool" setter="set_enable_trail" getter="is_trail_enabled" default="false"> + <member name="trail_enabled" type="bool" setter="set_trail_enabled" getter="is_trail_enabled" default="false"> </member> <member name="trail_length_secs" type="float" setter="set_trail_length" getter="get_trail_length" default="0.3"> </member> @@ -144,7 +144,9 @@ <constant name="DRAW_ORDER_LIFETIME" value="1" enum="DrawOrder"> Particles are drawn in order of remaining lifetime. </constant> - <constant name="DRAW_ORDER_VIEW_DEPTH" value="2" enum="DrawOrder"> + <constant name="DRAW_ORDER_REVERSE_LIFETIME" value="2" enum="DrawOrder"> + </constant> + <constant name="DRAW_ORDER_VIEW_DEPTH" value="3" enum="DrawOrder"> Particles are drawn in order of depth. </constant> <constant name="EMIT_FLAG_POSITION" value="1" enum="EmitFlags"> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index aae3126c0f..82ba45f11a 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -40,7 +40,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns the color of the input connection [code]idx[/code]. + Returns the [Color] of the input connection [code]idx[/code]. </description> </method> <method name="get_connection_input_count"> @@ -74,7 +74,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns the color of the output connection [code]idx[/code]. + Returns the [Color] of the output connection [code]idx[/code]. </description> </method> <method name="get_connection_output_count"> @@ -117,7 +117,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns the color set to [code]idx[/code] left (input) slot. + Returns the left (input) [Color] of the slot [code]idx[/code]. </description> </method> <method name="get_slot_color_right" qualifiers="const"> @@ -126,7 +126,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns the color set to [code]idx[/code] right (output) slot. + Returns the right (output) [Color] of the slot [code]idx[/code]. </description> </method> <method name="get_slot_type_left" qualifiers="const"> @@ -135,7 +135,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns the (integer) type of left (input) [code]idx[/code] slot. + Returns the left (input) type of the slot [code]idx[/code]. </description> </method> <method name="get_slot_type_right" qualifiers="const"> @@ -144,7 +144,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns the (integer) type of right (output) [code]idx[/code] slot. + Returns the right (output) type of the slot [code]idx[/code]. </description> </method> <method name="is_slot_enabled_left" qualifiers="const"> @@ -153,7 +153,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns [code]true[/code] if left (input) slot [code]idx[/code] is enabled, [code]false[/code] otherwise. + Returns [code]true[/code] if left (input) side of the slot [code]idx[/code] is enabled. </description> </method> <method name="is_slot_enabled_right" qualifiers="const"> @@ -162,7 +162,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Returns [code]true[/code] if right (output) slot [code]idx[/code] is enabled, [code]false[/code] otherwise. + Returns [code]true[/code] if right (output) side of the slot [code]idx[/code] is enabled. </description> </method> <method name="set_opentype_feature"> @@ -204,6 +204,73 @@ [code]color_left[/code]/[code]right[/code] is the tint of the port's icon on this side. [code]custom_left[/code]/[code]right[/code] is a custom texture for this side's port. [b]Note:[/b] This method only sets properties of the slot. To create the slot, add a [Control]-derived child to the GraphNode. + Individual properties can be set using one of the [code]set_slot_*[/code] methods. You must enable at least one side of the slot to do so. + </description> + </method> + <method name="set_slot_color_left"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="color_left" type="Color"> + </argument> + <description> + Sets the [Color] of the left (input) side of the slot [code]idx[/code] to [code]color_left[/code]. + </description> + </method> + <method name="set_slot_color_right"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="color_right" type="Color"> + </argument> + <description> + Sets the [Color] of the right (output) side of the slot [code]idx[/code] to [code]color_right[/code]. + </description> + </method> + <method name="set_slot_enabled_left"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="enable_left" type="bool"> + </argument> + <description> + Toggles the left (input) side of the slot [code]idx[/code]. If [code]enable_left[/code] is [code]true[/code], a port will appear on the left side and the slot will be able to be connected from this side. + </description> + </method> + <method name="set_slot_enabled_right"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="enable_right" type="bool"> + </argument> + <description> + Toggles the right (output) side of the slot [code]idx[/code]. If [code]enable_right[/code] is [code]true[/code], a port will appear on the right side and the slot will be able to be connected from this side. + </description> + </method> + <method name="set_slot_type_left"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="type_left" type="int"> + </argument> + <description> + Sets the left (input) type of the slot [code]idx[/code] to [code]type_left[/code]. + </description> + </method> + <method name="set_slot_type_right"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="type_right" type="int"> + </argument> + <description> + Sets the right (output) type of the slot [code]idx[/code] to [code]type_right[/code]. </description> </method> </methods> diff --git a/doc/classes/InputEventWithModifiers.xml b/doc/classes/InputEventWithModifiers.xml index dd782209e5..3beea7f9a0 100644 --- a/doc/classes/InputEventWithModifiers.xml +++ b/doc/classes/InputEventWithModifiers.xml @@ -12,23 +12,23 @@ <methods> </methods> <members> - <member name="alt" type="bool" setter="set_alt" getter="get_alt" default="false"> + <member name="alt_pressed" type="bool" setter="set_alt_pressed" getter="is_alt_pressed" default="false"> State of the [kbd]Alt[/kbd] modifier. </member> - <member name="command" type="bool" setter="set_command" getter="get_command" default="false"> + <member name="command_pressed" type="bool" setter="set_command_pressed" getter="is_command_pressed" default="false"> State of the [kbd]Cmd[/kbd] modifier. </member> - <member name="control" type="bool" setter="set_control" getter="get_control" default="false"> + <member name="ctrl_pressed" type="bool" setter="set_ctrl_pressed" getter="is_ctrl_pressed" default="false"> State of the [kbd]Ctrl[/kbd] modifier. </member> - <member name="meta" type="bool" setter="set_metakey" getter="get_metakey" default="false"> + <member name="meta_pressed" type="bool" setter="set_meta_pressed" getter="is_meta_pressed" default="false"> State of the [kbd]Meta[/kbd] modifier. </member> - <member name="shift" type="bool" setter="set_shift" getter="get_shift" default="false"> + <member name="shift_pressed" type="bool" setter="set_shift_pressed" getter="is_shift_pressed" default="false"> State of the [kbd]Shift[/kbd] modifier. </member> <member name="store_command" type="bool" setter="set_store_command" getter="is_storing_command" default="true"> - If [code]true[/code], pressing [kbd]Cmd[/kbd] on macOS or [kbd]Ctrl[/kbd] on all other platforms will both be serialized as [member command]. If [code]false[/code], those same keys will be serialized as [member meta] on macOS and [member control] on all other platforms. + If [code]true[/code], pressing [kbd]Cmd[/kbd] on macOS or [kbd]Ctrl[/kbd] on all other platforms will both be serialized as [member command_pressed]. If [code]false[/code], those same keys will be serialized as [member meta_pressed] on macOS and [member ctrl_pressed] on all other platforms. This aids with cross-platform compatibility when developing e.g. on Windows for macOS, or vice-versa. </member> </members> diff --git a/doc/classes/JavaScript.xml b/doc/classes/JavaScript.xml index c707a72ee8..c87e637ff5 100644 --- a/doc/classes/JavaScript.xml +++ b/doc/classes/JavaScript.xml @@ -11,6 +11,40 @@ <link title="Exporting for the Web: Calling JavaScript from script">https://docs.godotengine.org/en/latest/getting_started/workflow/export/exporting_for_web.html#calling-javascript-from-script</link> </tutorials> <methods> + <method name="create_callback"> + <return type="JavaScriptObject"> + </return> + <argument index="0" name="callable" type="Callable"> + </argument> + <description> + Creates a reference to a [Callable] that can be used as a callback by JavaScript. The reference must be kept until the callback happens, or it won't be called at all. See [JavaScriptObject] for usage. + </description> + </method> + <method name="create_object" qualifiers="vararg"> + <return type="Variant"> + </return> + <argument index="0" name="object" type="String"> + </argument> + <description> + Creates a new JavaScript object using the [code]new[/code] constructor. The [code]object[/code] must a valid property of the JavaScript [code]window[/code]. See [JavaScriptObject] for usage. + </description> + </method> + <method name="download_buffer"> + <return type="void"> + </return> + <argument index="0" name="buffer" type="PackedByteArray"> + </argument> + <argument index="1" name="name" type="String"> + </argument> + <argument index="2" name="mime" type="String" default=""application/octet-stream""> + </argument> + <description> + Prompts the user to download a file containing the specified [code]buffer[/code]. The file will have the given [code]name[/code] and [code]mime[/code] type. + [b]Note:[/b] The browser may override the [url=https://en.wikipedia.org/wiki/Media_type]MIME type[/url] provided based on the file [code]name[/code]'s extension. + [b]Note:[/b] Browsers might block the download if [method download_buffer] is not being called from a user interaction (e.g. button click). + [b]Note:[/b] Browsers might ask the user for permission or block the download if multiple download requests are made in a quick succession. + </description> + </method> <method name="eval"> <return type="Variant"> </return> @@ -23,6 +57,15 @@ If [code]use_global_execution_context[/code] is [code]true[/code], the code will be evaluated in the global execution context. Otherwise, it is evaluated in the execution context of a function within the engine's runtime environment. </description> </method> + <method name="get_interface"> + <return type="JavaScriptObject"> + </return> + <argument index="0" name="interface" type="String"> + </argument> + <description> + Returns an interface to a JavaScript object that can be used by scripts. The [code]interface[/code] must be a valid property of the JavaScript [code]window[/code]. The callback must accept a single [Array] argument, which will contain the JavaScript [code]arguments[/code]. See [JavaScriptObject] for usage. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/JavaScriptObject.xml b/doc/classes/JavaScriptObject.xml new file mode 100644 index 0000000000..a9e9c77e89 --- /dev/null +++ b/doc/classes/JavaScriptObject.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="JavaScriptObject" inherits="Reference" version="4.0"> + <brief_description> + A wrapper class for native JavaScript objects. + </brief_description> + <description> + JavaScriptObject is used to interact with JavaScript objects retrieved or created via [method JavaScript.get_interface], [method JavaScript.create_object], or [method JavaScript.create_callback]. + Example: + [codeblock] + extends Node + + var _my_js_callback = JavaScript.create_callback(self, "myCallback") # This reference must be kept + var console = JavaScript.get_interface("console") + + func _init(): + var buf = JavaScript.create_object("ArrayBuffer", 10) # new ArrayBuffer(10) + print(buf) # prints [JavaScriptObject:OBJECT_ID] + var uint8arr = JavaScript.create_object("Uint8Array", buf) # new Uint8Array(buf) + uint8arr[1] = 255 + prints(uint8arr[1], uint8arr.byteLength) # prints 255 10 + console.log(uint8arr) # prints in browser console "Uint8Array(10) [ 0, 255, 0, 0, 0, 0, 0, 0, 0, 0 ]" + + # Equivalent of JavaScript: Array.from(uint8arr).forEach(myCallback) + JavaScript.get_interface("Array").from(uint8arr).forEach(_my_js_callback) + + func myCallback(args): + # Will be called with the parameters passed to the "forEach" callback + # [0, 0, [JavaScriptObject:1173]] + # [255, 1, [JavaScriptObject:1173]] + # ... + # [0, 9, [JavaScriptObject:1180]] + print(args) + [/codeblock] + Note: Only available in the "HTML5" platform. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml index db7a3187f0..3c679047a0 100644 --- a/doc/classes/MeshDataTool.xml +++ b/doc/classes/MeshDataTool.xml @@ -15,7 +15,7 @@ mdt.create_from_surface(mesh, 0) for i in range(mdt.get_vertex_count()): var vertex = mdt.get_vertex(i) - # In this example we extend the mesh by one unit, which results in seperated faces as it is flat shaded. + # In this example we extend the mesh by one unit, which results in separated faces as it is flat shaded. vertex += mdt.get_vertex_normal(i) # Save your change. mdt.set_vertex(i, vertex) @@ -33,7 +33,7 @@ for (var i = 0; i < mdt.GetVertexCount(); i++) { Vector3 vertex = mdt.GetVertex(i); - // In this example we extend the mesh by one unit, which results in seperated faces as it is flat shaded. + // In this example we extend the mesh by one unit, which results in separated faces as it is flat shaded. vertex += mdt.GetVertexNormal(i); // Save your change. mdt.SetVertex(i, vertex); diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml index eed0ec8d7e..988fb72267 100644 --- a/doc/classes/Node2D.xml +++ b/doc/classes/Node2D.xml @@ -154,7 +154,7 @@ If [code]true[/code], the node's Z index is relative to its parent's Z index. If this node's Z index is 2 and its parent's effective Z index is 3, then this node's effective Z index will be 2 + 3 = 5. </member> <member name="z_index" type="int" setter="set_z_index" getter="get_z_index" default="0"> - Z index. Controls the order in which the nodes render. A node with a higher Z index will display in front of others. + Z index. Controls the order in which the nodes render. A node with a higher Z index will display in front of others. Must be between [constant RenderingServer.CANVAS_ITEM_Z_MIN] and [constant RenderingServer.CANVAS_ITEM_Z_MAX] (inclusive). </member> </members> <constants> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index cb95deb9a0..b8b437f78f 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -357,7 +357,7 @@ </return> <description> Returns the current UNIX epoch timestamp in seconds. - [b]Important:[/b] This is the system clock that the user can manully set. [b]Never use[/b] this method for precise time calculation since its results are also subject to automatic adjustments by the operating system. [b]Always use[/b] [method get_ticks_usec] or [method get_ticks_msec] for precise time calculation instead, since they are guaranteed to be monotonic (i.e. never decrease). + [b]Important:[/b] This is the system clock that the user can manually set. [b]Never use[/b] this method for precise time calculation since its results are also subject to automatic adjustments by the operating system. [b]Always use[/b] [method get_ticks_usec] or [method get_ticks_msec] for precise time calculation instead, since they are guaranteed to be monotonic (i.e. never decrease). </description> </method> <method name="get_unix_time_from_datetime" qualifiers="const"> @@ -368,7 +368,7 @@ <description> Gets an epoch time value from a dictionary of time values. [code]datetime[/code] must be populated with the following keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]hour[/code], [code]minute[/code], [code]second[/code]. - If the dictionary is empty [code]0[/code] is returned. + If the dictionary is empty [code]0[/code] is returned. If some keys are omitted, they default to the equivalent values for the UNIX epoch timestamp 0 (1970-01-01 at 00:00:00 UTC). You can pass the output from [method get_datetime_from_unix_time] directly into this function. Daylight Savings Time ([code]dst[/code]), if present, is ignored. </description> </method> diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml index 6d7f99a55b..3c364b621a 100644 --- a/doc/classes/ParticlesMaterial.xml +++ b/doc/classes/ParticlesMaterial.xml @@ -135,7 +135,7 @@ </member> <member name="collision_bounce" type="float" setter="set_collision_bounce" getter="get_collision_bounce" default="0.0"> </member> - <member name="collision_enabled" type="bool" setter="set_collision_enabled" getter="is_collision_enabled" default="true"> + <member name="collision_enabled" type="bool" setter="set_collision_enabled" getter="is_collision_enabled" default="false"> </member> <member name="collision_friction" type="float" setter="set_collision_friction" getter="get_collision_friction" default="0.0"> </member> diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 229facd08b..cfa4215fd4 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -1018,6 +1018,15 @@ Activates or deactivates the 2D physics engine. </description> </method> + <method name="set_collision_iterations"> + <return type="void"> + </return> + <argument index="0" name="iterations" type="int"> + </argument> + <description> + Sets the amount of iterations for calculating velocities of colliding bodies. The greater the amount, the more accurate the collisions, but with a performance loss. + </description> + </method> <method name="shape_get_data" qualifiers="const"> <return type="Variant"> </return> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3200f789b8..73899daaea 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -6,7 +6,7 @@ <description> Contains global variables accessible from everywhere. Use [method get_setting], [method set_setting] or [method has_setting] to access them. Variables stored in [code]project.godot[/code] are also loaded into ProjectSettings, making this object very useful for reading custom game configuration options. When naming a Project Settings property, use the full path to the setting including the category. For example, [code]"application/config/name"[/code] for the project name. Category and property names can be viewed in the Project Settings dialog. - [b]Feature tags:[/b] Project settings can be overriden for specific platforms and configurations (debug, release, ...) using [url=https://docs.godotengine.org/en/latest/tutorials/export/feature_tags.html]feature tags[/url]. + [b]Feature tags:[/b] Project settings can be overridden for specific platforms and configurations (debug, release, ...) using [url=https://docs.godotengine.org/en/latest/tutorials/export/feature_tags.html]feature tags[/url]. [b]Overriding:[/b] Any project setting can be overridden by creating a file named [code]override.cfg[/code] in the project's root directory. This can also be used in exported projects by placing this file in the same directory as the project binary. Overriding will still take the base project settings' [url=https://docs.godotengine.org/en/latest/tutorials/export/feature_tags.html]feature tags[/url] in account. Therefore, make sure to [i]also[/i] override the setting with the desired feature tags if you want them to override base project settings on all platforms and configurations. </description> <tutorials> @@ -494,8 +494,9 @@ <member name="display/window/energy_saving/keep_screen_on" type="bool" setter="" getter="" default="true"> If [code]true[/code], keeps the screen on (even in case of inactivity), so the screensaver does not take over. Works on desktop and mobile platforms. </member> - <member name="display/window/handheld/orientation" type="String" setter="" getter="" default=""landscape""> - Default orientation on mobile devices. + <member name="display/window/handheld/orientation" type="int" setter="" getter="" default="0"> + The default screen orientation to use on mobile devices. See [enum DisplayServer.ScreenOrientation] for possible values. + [b]Note:[/b] When set to a portrait orientation, this project setting does not flip the project resolution's width and height automatically. Instead, you have to set [member display/window/size/width] and [member display/window/size/height] accordingly. </member> <member name="display/window/ios/hide_home_indicator" type="bool" setter="" getter="" default="true"> If [code]true[/code], the home indicator is hidden automatically. This only affects iOS devices without a physical home button. @@ -732,6 +733,10 @@ </member> <member name="input/ui_text_select_all" type="Dictionary" setter="" getter=""> </member> + <member name="input/ui_text_select_word_under_caret" type="Dictionary" setter="" getter=""> + If no selection is currently active, selects the word currently under the caret in text fields. If a selection is currently active, deselects the current selection. + [b]Note:[/b] Currently, this is only implemented in [TextEdit], not [LineEdit]. + </member> <member name="input/ui_text_toggle_insert_mode" type="Dictionary" setter="" getter=""> </member> <member name="input/ui_undo" type="Dictionary" setter="" getter=""> @@ -1197,27 +1202,21 @@ The CA certificates bundle to use for SSL connections. If this is set to a non-empty value, this will [i]override[/i] Godot's default [url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-certificates.crt]Mozilla certificate bundle[/url]. If left empty, the default certificate bundle will be used. If in doubt, leave this setting empty. </member> - <member name="physics/2d/bp_hash_table_size" type="int" setter="" getter="" default="4096"> - Size of the hash table used for the broad-phase 2D hash grid algorithm. - </member> - <member name="physics/2d/cell_size" type="int" setter="" getter="" default="128"> - Cell size used for the broad-phase 2D hash grid algorithm (in pixels). - </member> <member name="physics/2d/default_angular_damp" type="float" setter="" getter="" default="1.0"> The default angular damp in 2D. [b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration. </member> - <member name="physics/2d/default_gravity" type="int" setter="" getter="" default="98"> - The default gravity strength in 2D. + <member name="physics/2d/default_gravity" type="float" setter="" getter="" default="980.0"> + The default gravity strength in 2D (in pixels per second squared). [b]Note:[/b] This property is only read when the project starts. To change the default gravity at runtime, use the following code sample: [codeblocks] [gdscript] - # Set the default gravity strength to 98. - PhysicsServer2D.area_set_param(get_viewport().find_world_2d().space, PhysicsServer2D.AREA_PARAM_GRAVITY, 98) + # Set the default gravity strength to 980. + PhysicsServer2D.area_set_param(get_viewport().find_world_2d().space, PhysicsServer2D.AREA_PARAM_GRAVITY, 980) [/gdscript] [csharp] - // Set the default gravity strength to 98. - PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2d().Space, PhysicsServer2D.AreaParameter.Gravity, 98); + // Set the default gravity strength to 980. + PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2d().Space, PhysicsServer2D.AreaParameter.Gravity, 980); [/csharp] [/codeblocks] </member> @@ -1239,9 +1238,6 @@ The default linear damp in 2D. [b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration. </member> - <member name="physics/2d/large_object_surface_threshold_in_cells" type="int" setter="" getter="" default="512"> - Threshold defining the surface size that constitutes a large object with regard to cells in the broad-phase 2D hash grid algorithm. - </member> <member name="physics/2d/physics_engine" type="String" setter="" getter="" default=""DEFAULT""> Sets which physics engine to use for 2D physics. "DEFAULT" and "GodotPhysics2D" are the same, as there is currently no alternative 2D physics server implemented. @@ -1263,7 +1259,7 @@ [b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration. </member> <member name="physics/3d/default_gravity" type="float" setter="" getter="" default="9.8"> - The default gravity strength in 3D. + The default gravity strength in 3D (in meters per second squared). [b]Note:[/b] This property is only read when the project starts. To change the default gravity at runtime, use the following code sample: [codeblocks] [gdscript] @@ -1506,6 +1502,16 @@ <member name="rendering/reflections/sky_reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> Lower-end override for [member rendering/reflections/sky_reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. </member> + <member name="rendering/shader_compiler/shader_cache/compress" type="bool" setter="" getter="" default="true"> + </member> + <member name="rendering/shader_compiler/shader_cache/enabled" type="bool" setter="" getter="" default="true"> + </member> + <member name="rendering/shader_compiler/shader_cache/strip_debug" type="bool" setter="" getter="" default="false"> + </member> + <member name="rendering/shader_compiler/shader_cache/strip_debug.release" type="bool" setter="" getter="" default="true"> + </member> + <member name="rendering/shader_compiler/shader_cache/use_zstd_compression" type="bool" setter="" getter="" default="true"> + </member> <member name="rendering/shading/overrides/force_blinn_over_ggx" type="bool" setter="" getter="" default="false"> If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model. </member> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 638b0bb297..7a345f726d 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -3388,7 +3388,7 @@ <constant name="PARTICLES_DRAW_ORDER_LIFETIME" value="1" enum="ParticlesDrawOrder"> Sort particles based on their lifetime. </constant> - <constant name="PARTICLES_DRAW_ORDER_VIEW_DEPTH" value="2" enum="ParticlesDrawOrder"> + <constant name="PARTICLES_DRAW_ORDER_VIEW_DEPTH" value="3" enum="ParticlesDrawOrder"> Sort particles based on their distance to the camera. </constant> <constant name="VIEWPORT_UPDATE_DISABLED" value="0" enum="ViewportUpdateMode"> diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 2548f8d911..75736798fd 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -27,6 +27,7 @@ <description> Duplicates the resource, returning a new resource. By default, sub-resources are shared between resource copies for efficiency. This can be changed by passing [code]true[/code] to the [code]subresources[/code] argument which will copy the subresources. [b]Note:[/b] If [code]subresources[/code] is [code]true[/code], this method will only perform a shallow copy. Nested resources within subresources will not be duplicated and will still be shared. + [b]Note:[/b] When duplicating a resource, only [code]export[/code]ed properties are copied. Other properties will be set to their default value in the new resource. </description> </method> <method name="emit_changed"> diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index ed375a8b1e..a37ebb2dd5 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -193,7 +193,7 @@ </description> </signal> <signal name="body_shape_entered"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node"> </argument> @@ -210,7 +210,7 @@ </description> </signal> <signal name="body_shape_exited"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node"> </argument> diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml index 1c6c8852a9..2ee8e2697c 100644 --- a/doc/classes/RigidBody3D.xml +++ b/doc/classes/RigidBody3D.xml @@ -103,7 +103,7 @@ [b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead. </description> </method> - <method name="get_inverse_inertia_tensor"> + <method name="get_inverse_inertia_tensor" qualifiers="const"> <return type="Basis"> </return> <description> @@ -217,7 +217,7 @@ </description> </signal> <signal name="body_shape_entered"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node"> </argument> @@ -235,7 +235,7 @@ </description> </signal> <signal name="body_shape_exited"> - <argument index="0" name="body_id" type="int"> + <argument index="0" name="body_rid" type="RID"> </argument> <argument index="1" name="body" type="Node"> </argument> diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml index ee498de302..e5c4c32450 100644 --- a/doc/classes/ScriptEditorBase.xml +++ b/doc/classes/ScriptEditorBase.xml @@ -18,6 +18,13 @@ Adds a [EditorSyntaxHighlighter] to the open script. </description> </method> + <method name="get_base_editor" qualifiers="const"> + <return type="Control"> + </return> + <description> + Returns the underlying [Control] used for editing scripts. This can be either [CodeEdit] (for text scripts) or [GraphEdit] (for visual scripts). + </description> + </method> </methods> <signals> <signal name="edited_script_changed"> diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index 0b278d7d25..44ad460459 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -22,17 +22,6 @@ Adds a bone, with name [code]name[/code]. [method get_bone_count] will become the bone index. </description> </method> - <method name="bind_child_node_to_bone"> - <return type="void"> - </return> - <argument index="0" name="bone_idx" type="int"> - </argument> - <argument index="1" name="node" type="Node"> - </argument> - <description> - [i]Deprecated soon.[/i] - </description> - </method> <method name="bone_transform_to_world_transform"> <return type="Transform"> </return> @@ -143,15 +132,6 @@ Returns the rest transform for a bone [code]bone_idx[/code]. </description> </method> - <method name="get_bound_child_nodes_to_bone" qualifiers="const"> - <return type="Array"> - </return> - <argument index="0" name="bone_idx" type="int"> - </argument> - <description> - [i]Deprecated soon.[/i] - </description> - </method> <method name="is_bone_rest_disabled" qualifiers="const"> <return type="bool"> </return> @@ -299,17 +279,6 @@ Sets the rest transform for bone [code]bone_idx[/code]. </description> </method> - <method name="unbind_child_node_from_bone"> - <return type="void"> - </return> - <argument index="0" name="bone_idx" type="int"> - </argument> - <argument index="1" name="node" type="Node"> - </argument> - <description> - [i]Deprecated soon.[/i] - </description> - </method> <method name="unparent_bone_and_rest"> <return type="void"> </return> diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml index 617ad3a371..c320adb1be 100644 --- a/doc/classes/Sprite2D.xml +++ b/doc/classes/Sprite2D.xml @@ -64,7 +64,7 @@ <member name="frame" type="int" setter="set_frame" getter="get_frame" default="0"> Current frame to display from sprite sheet. [member hframes] or [member vframes] must be greater than 1. </member> - <member name="frame_coords" type="Vector2" setter="set_frame_coords" getter="get_frame_coords" default="Vector2( 0, 0 )"> + <member name="frame_coords" type="Vector2i" setter="set_frame_coords" getter="get_frame_coords" default="Vector2i( 0, 0 )"> Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member hframes] or [member vframes] must be greater than 1. </member> <member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1"> diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml index 658fd1a4f2..a7d61a6bab 100644 --- a/doc/classes/Sprite3D.xml +++ b/doc/classes/Sprite3D.xml @@ -14,7 +14,7 @@ <member name="frame" type="int" setter="set_frame" getter="get_frame" default="0"> Current frame to display from sprite sheet. [member hframes] or [member vframes] must be greater than 1. </member> - <member name="frame_coords" type="Vector2" setter="set_frame_coords" getter="get_frame_coords" default="Vector2( 0, 0 )"> + <member name="frame_coords" type="Vector2i" setter="set_frame_coords" getter="get_frame_coords" default="Vector2i( 0, 0 )"> Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member hframes] or [member vframes] must be greater than 1. </member> <member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1"> diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml index a1b858acf6..f120103916 100644 --- a/doc/classes/StreamPeer.xml +++ b/doc/classes/StreamPeer.xml @@ -4,7 +4,7 @@ Abstraction and base class for stream-based protocols. </brief_description> <description> - StreamPeer is an abstraction and base class for stream-based protocols (such as TCP or UNIX sockets). It provides an API for sending and receiving data through streams as raw data or strings. + StreamPeer is an abstraction and base class for stream-based protocols (such as TCP). It provides an API for sending and receiving data through streams as raw data or strings. </description> <tutorials> </tutorials> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 416438e648..a81defa16c 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -397,7 +397,12 @@ <argument index="0" name="position" type="int"> </argument> <description> - Returns a number of characters from the left of the string. + Returns a number of characters from the left of the string. If negative [code]position[/code] is used, the characters are counted downwards from [String]'s length. + Examples: + [codeblock] + print("sample text".left(3)) #prints "sam" + print("sample text".left(-3)) #prints "sample t" + [/codeblock] </description> </method> <method name="length" qualifiers="const"> @@ -669,7 +674,12 @@ <argument index="0" name="position" type="int"> </argument> <description> - Returns the right side of the string from a given position. + Returns a number of characters from the right of the string. If negative [code]position[/code] is used, the characters are counted downwards from [String]'s length. + Examples: + [codeblock] + print("sample text".right(3)) #prints "ext" + print("sample text".right(-3)) #prints "ple text" + [/codeblock] </description> </method> <method name="rpad" qualifiers="const"> diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml index b6e9eda1d1..f54f22d6fa 100644 --- a/doc/classes/SubViewport.xml +++ b/doc/classes/SubViewport.xml @@ -25,7 +25,7 @@ <member name="render_target_update_mode" type="int" setter="set_update_mode" getter="get_update_mode" enum="SubViewport.UpdateMode" default="2"> The update mode when the sub-viewport is used as a render target. </member> - <member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i( 0, 0 )"> + <member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i( 512, 512 )"> The width and height of the sub-viewport. </member> <member name="size_2d_override" type="Vector2i" setter="set_size_2d_override" getter="get_size_2d_override" default="Vector2i( 0, 0 )"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 088bcd1c3c..29067b5534 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -5,6 +5,7 @@ </brief_description> <description> TextEdit is meant for editing large, multiline text. It also has facilities for editing code, such as syntax highlighting support and multiple levels of undo/redo. + [b]Note:[/b] When holding down [kbd]Alt[/kbd], the vertical scroll wheel will scroll 5 times as fast as it would normally do. This also works in the Godot script editor. </description> <tutorials> </tutorials> @@ -166,6 +167,15 @@ Returns the text of a specific line. </description> </method> + <method name="get_line_background_color"> + <return type="Color"> + </return> + <argument index="0" name="line" type="int"> + </argument> + <description> + Returns the current background color of the line. [code]Color(0, 0, 0, 0)[/code] is returned if no color is set. + </description> + </method> <method name="get_line_count" qualifiers="const"> <return type="int"> </return> @@ -282,6 +292,13 @@ Returns the selection end line. </description> </method> + <method name="get_visible_line_count" qualifiers="const"> + <return type="int"> + </return> + <description> + Returns the number of visible lines, including wrapped text. + </description> + </method> <method name="get_word_under_cursor" qualifiers="const"> <return type="String"> </return> @@ -540,6 +557,17 @@ If [code]true[/code], hides the line of the specified index. </description> </method> + <method name="set_line_background_color"> + <return type="void"> + </return> + <argument index="0" name="line" type="int"> + </argument> + <argument index="1" name="color" type="Color"> + </argument> + <description> + Sets the current background color of the line. Set to [code]Color(0, 0, 0, 0)[/code] for no color. + </description> + </method> <method name="set_line_gutter_clickable"> <return type="void"> </return> @@ -714,10 +742,10 @@ If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added. </member> <member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0"> - If there is a horizontal scrollbar this determines the current horizontal scroll value in pixels. + If there is a horizontal scrollbar, this determines the current horizontal scroll value in pixels. </member> <member name="scroll_vertical" type="float" setter="set_v_scroll" getter="get_v_scroll" default="0.0"> - If there is a vertical scrollbar this determines the current vertical scroll value in line numbers, starting at 0 for the top line. + If there is a vertical scrollbar, this determines the current vertical scroll value in line numbers, starting at 0 for the top line. </member> <member name="selecting_enabled" type="bool" setter="set_selecting_enabled" getter="is_selecting_enabled" default="true"> If [code]true[/code], text can be selected. @@ -979,9 +1007,6 @@ <theme_item name="line_spacing" type="int" default="4"> Sets the spacing between the lines. </theme_item> - <theme_item name="mark_color" type="Color" default="Color( 1, 0.4, 0.4, 0.4 )"> - Sets the [Color] of marked text. - </theme_item> <theme_item name="normal" type="StyleBox"> Sets the [StyleBox] of this [TextEdit]. </theme_item> diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml index 3173dddb42..7448697df3 100644 --- a/doc/classes/Theme.xml +++ b/doc/classes/Theme.xml @@ -23,10 +23,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Clears the [Color] at [code]name[/code] if the theme has [code]node_type[/code]. + Clears the [Color] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="clear_constant"> @@ -34,10 +34,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Clears the constant at [code]name[/code] if the theme has [code]node_type[/code]. + Clears the constant at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="clear_font"> @@ -45,10 +45,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Clears the [Font] at [code]name[/code] if the theme has [code]node_type[/code]. + Clears the [Font] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="clear_font_size"> @@ -56,10 +56,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Clears the font size [code]name[/code] if the theme has [code]node_type[/code]. + Clears the font size [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="clear_icon"> @@ -67,10 +67,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Clears the icon at [code]name[/code] if the theme has [code]node_type[/code]. + Clears the icon at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="clear_stylebox"> @@ -78,10 +78,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Clears [StyleBox] at [code]name[/code] if the theme has [code]node_type[/code]. + Clears [StyleBox] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="clear_theme_item"> @@ -91,10 +91,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Clears the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]node_type[/code]. + Clears the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="copy_default_theme"> @@ -118,19 +118,19 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns the [Color] at [code]name[/code] if the theme has [code]node_type[/code]. + Returns the [Color] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_color_list" qualifiers="const"> <return type="PackedStringArray"> </return> - <argument index="0" name="node_type" type="String"> + <argument index="0" name="theme_type" type="String"> </argument> <description> - Returns all the [Color]s as a [PackedStringArray] filled with each [Color]'s name, for use in [method get_color], if the theme has [code]node_type[/code]. + Returns all the [Color]s as a [PackedStringArray] filled with each [Color]'s name, for use in [method get_color], if the theme has [code]theme_type[/code]. </description> </method> <method name="get_color_type_list" qualifiers="const"> @@ -145,19 +145,19 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns the constant at [code]name[/code] if the theme has [code]node_type[/code]. + Returns the constant at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_constant_list" qualifiers="const"> <return type="PackedStringArray"> </return> - <argument index="0" name="node_type" type="String"> + <argument index="0" name="theme_type" type="String"> </argument> <description> - Returns all the constants as a [PackedStringArray] filled with each constant's name, for use in [method get_constant], if the theme has [code]node_type[/code]. + Returns all the constants as a [PackedStringArray] filled with each constant's name, for use in [method get_constant], if the theme has [code]theme_type[/code]. </description> </method> <method name="get_constant_type_list" qualifiers="const"> @@ -172,19 +172,19 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns the [Font] at [code]name[/code] if the theme has [code]node_type[/code]. + Returns the [Font] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_font_list" qualifiers="const"> <return type="PackedStringArray"> </return> - <argument index="0" name="node_type" type="String"> + <argument index="0" name="theme_type" type="String"> </argument> <description> - Returns all the [Font]s as a [PackedStringArray] filled with each [Font]'s name, for use in [method get_font], if the theme has [code]node_type[/code]. + Returns all the [Font]s as a [PackedStringArray] filled with each [Font]'s name, for use in [method get_font], if the theme has [code]theme_type[/code]. </description> </method> <method name="get_font_size" qualifiers="const"> @@ -192,19 +192,19 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns the font size at [code]name[/code] if the theme has [code]node_type[/code]. + Returns the font size at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_font_size_list" qualifiers="const"> <return type="PackedStringArray"> </return> - <argument index="0" name="node_type" type="String"> + <argument index="0" name="theme_type" type="String"> </argument> <description> - Returns all the font sizes as a [PackedStringArray] filled with each font size name, for use in [method get_font_size], if the theme has [code]node_type[/code]. + Returns all the font sizes as a [PackedStringArray] filled with each font size name, for use in [method get_font_size], if the theme has [code]theme_type[/code]. </description> </method> <method name="get_font_size_type_list" qualifiers="const"> @@ -226,19 +226,19 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns the icon [Texture2D] at [code]name[/code] if the theme has [code]node_type[/code]. + Returns the icon [Texture2D] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_icon_list" qualifiers="const"> <return type="PackedStringArray"> </return> - <argument index="0" name="node_type" type="String"> + <argument index="0" name="theme_type" type="String"> </argument> <description> - Returns all the icons as a [PackedStringArray] filled with each [Texture2D]'s name, for use in [method get_icon], if the theme has [code]node_type[/code]. + Returns all the icons as a [PackedStringArray] filled with each [Texture2D]'s name, for use in [method get_icon], if the theme has [code]theme_type[/code]. </description> </method> <method name="get_icon_type_list" qualifiers="const"> @@ -253,21 +253,21 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns the [StyleBox] at [code]name[/code] if the theme has [code]node_type[/code]. - Valid [code]name[/code]s may be found using [method get_stylebox_list]. Valid [code]node_type[/code]s may be found using [method get_stylebox_type_list]. + Returns the [StyleBox] at [code]name[/code] if the theme has [code]theme_type[/code]. + Valid [code]name[/code]s may be found using [method get_stylebox_list]. Valid [code]theme_type[/code]s may be found using [method get_stylebox_type_list]. </description> </method> <method name="get_stylebox_list" qualifiers="const"> <return type="PackedStringArray"> </return> - <argument index="0" name="node_type" type="String"> + <argument index="0" name="theme_type" type="String"> </argument> <description> - Returns all the [StyleBox]s as a [PackedStringArray] filled with each [StyleBox]'s name, for use in [method get_stylebox], if the theme has [code]node_type[/code]. - Valid [code]node_type[/code]s may be found using [method get_stylebox_type_list]. + Returns all the [StyleBox]s as a [PackedStringArray] filled with each [StyleBox]'s name, for use in [method get_stylebox], if the theme has [code]theme_type[/code]. + Valid [code]theme_type[/code]s may be found using [method get_stylebox_type_list]. </description> </method> <method name="get_stylebox_type_list" qualifiers="const"> @@ -284,11 +284,11 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Returns the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]node_type[/code]. - Valid [code]name[/code]s may be found using [method get_theme_item_list] or a data type specific method. Valid [code]node_type[/code]s may be found using [method get_theme_item_type_list] or a data type specific method. + Returns the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]theme_type[/code]. + Valid [code]name[/code]s may be found using [method get_theme_item_list] or a data type specific method. Valid [code]theme_type[/code]s may be found using [method get_theme_item_type_list] or a data type specific method. </description> </method> <method name="get_theme_item_list" qualifiers="const"> @@ -296,11 +296,11 @@ </return> <argument index="0" name="data_type" type="int" enum="Theme.DataType"> </argument> - <argument index="1" name="node_type" type="String"> + <argument index="1" name="theme_type" type="String"> </argument> <description> - Returns all the theme items of [code]data_type[/code] as a [PackedStringArray] filled with each theme items's name, for use in [method get_theme_item] or a data type specific method, if the theme has [code]node_type[/code]. - Valid [code]node_type[/code]s may be found using [method get_theme_item_type_list] or a data type specific method. + Returns all the theme items of [code]data_type[/code] as a [PackedStringArray] filled with each theme items's name, for use in [method get_theme_item] or a data type specific method, if the theme has [code]theme_type[/code]. + Valid [code]theme_type[/code]s may be found using [method get_theme_item_type_list] or a data type specific method. </description> </method> <method name="get_theme_item_type_list" qualifiers="const"> @@ -324,11 +324,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if [Color] with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if [Color] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_constant" qualifiers="const"> @@ -336,11 +336,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if constant with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if constant with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_font" qualifiers="const"> @@ -348,11 +348,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if [Font] with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if [Font] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_font_size" qualifiers="const"> @@ -360,11 +360,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if font size with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if font size with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_icon" qualifiers="const"> @@ -372,11 +372,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if icon [Texture2D] with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if icon [Texture2D] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_stylebox" qualifiers="const"> @@ -384,11 +384,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if [StyleBox] with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if [StyleBox] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_theme_item" qualifiers="const"> @@ -398,11 +398,11 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Returns [code]true[/code] if a theme item of [code]data_type[/code] with [code]name[/code] is in [code]node_type[/code]. - Returns [code]false[/code] if the theme does not have [code]node_type[/code]. + Returns [code]true[/code] if a theme item of [code]data_type[/code] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="rename_color"> @@ -412,10 +412,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Renames the [Color] at [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames the [Color] at [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="rename_constant"> @@ -425,10 +425,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Renames the constant at [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames the constant at [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="rename_font"> @@ -438,10 +438,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Renames the [Font] at [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames the [Font] at [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="rename_font_size"> @@ -451,10 +451,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Renames the font size [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames the font size [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="rename_icon"> @@ -464,10 +464,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Renames the icon at [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames the icon at [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="rename_stylebox"> @@ -477,10 +477,10 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <description> - Renames [StyleBox] at [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames [StyleBox] at [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="rename_theme_item"> @@ -492,10 +492,10 @@ </argument> <argument index="2" name="name" type="StringName"> </argument> - <argument index="3" name="node_type" type="StringName"> + <argument index="3" name="theme_type" type="StringName"> </argument> <description> - Renames the theme item of [code]data_type[/code] at [code]old_name[/code] to [code]name[/code] if the theme has [code]node_type[/code]. If [code]name[/code] is already taken, this method fails. + Renames the theme item of [code]data_type[/code] at [code]old_name[/code] to [code]name[/code] if the theme has [code]theme_type[/code]. If [code]name[/code] is already taken, this method fails. </description> </method> <method name="set_color"> @@ -503,13 +503,13 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <argument index="2" name="color" type="Color"> </argument> <description> - Sets the theme's [Color] to [code]color[/code] at [code]name[/code] in [code]node_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Sets the theme's [Color] to [code]color[/code] at [code]name[/code] in [code]theme_type[/code]. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> <method name="set_constant"> @@ -517,13 +517,13 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <argument index="2" name="constant" type="int"> </argument> <description> - Sets the theme's constant to [code]constant[/code] at [code]name[/code] in [code]node_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Sets the theme's constant to [code]constant[/code] at [code]name[/code] in [code]theme_type[/code]. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> <method name="set_font"> @@ -531,13 +531,13 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <argument index="2" name="font" type="Font"> </argument> <description> - Sets the theme's [Font] to [code]font[/code] at [code]name[/code] in [code]node_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Sets the theme's [Font] to [code]font[/code] at [code]name[/code] in [code]theme_type[/code]. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> <method name="set_font_size"> @@ -545,13 +545,13 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <argument index="2" name="font_size" type="int"> </argument> <description> - Sets the theme's font size to [code]font_size[/code] at [code]name[/code] in [code]node_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Sets the theme's font size to [code]font_size[/code] at [code]name[/code] in [code]theme_type[/code]. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> <method name="set_icon"> @@ -559,13 +559,13 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <argument index="2" name="texture" type="Texture2D"> </argument> <description> - Sets the theme's icon [Texture2D] to [code]texture[/code] at [code]name[/code] in [code]node_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Sets the theme's icon [Texture2D] to [code]texture[/code] at [code]name[/code] in [code]theme_type[/code]. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> <method name="set_stylebox"> @@ -573,13 +573,13 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="node_type" type="StringName"> + <argument index="1" name="theme_type" type="StringName"> </argument> <argument index="2" name="texture" type="StyleBox"> </argument> <description> - Sets theme's [StyleBox] to [code]stylebox[/code] at [code]name[/code] in [code]node_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Sets theme's [StyleBox] to [code]stylebox[/code] at [code]name[/code] in [code]theme_type[/code]. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> <method name="set_theme_item"> @@ -589,14 +589,14 @@ </argument> <argument index="1" name="name" type="StringName"> </argument> - <argument index="2" name="node_type" type="StringName"> + <argument index="2" name="theme_type" type="StringName"> </argument> <argument index="3" name="value" type="Variant"> </argument> <description> - Sets the theme item of [code]data_type[/code] to [code]value[/code] at [code]name[/code] in [code]node_type[/code]. + Sets the theme item of [code]data_type[/code] to [code]value[/code] at [code]name[/code] in [code]theme_type[/code]. Does nothing if the [code]value[/code] type does not match [code]data_type[/code]. - Creates [code]node_type[/code] if the theme does not have it. + Creates [code]theme_type[/code] if the theme does not have it. </description> </method> </methods> diff --git a/doc/classes/TileData.xml b/doc/classes/TileData.xml index e3bc910ab6..efcbdf2e95 100644 --- a/doc/classes/TileData.xml +++ b/doc/classes/TileData.xml @@ -229,7 +229,7 @@ </member> <member name="transpose" type="bool" setter="set_transpose" getter="get_transpose" default="false"> </member> - <member name="y_sort_origin" type="Vector2i" setter="set_y_sort_origin" getter="get_y_sort_origin" default="Vector2i( 0, 0 )"> + <member name="y_sort_origin" type="int" setter="set_y_sort_origin" getter="get_y_sort_origin" default="0"> </member> <member name="z_index" type="int" setter="set_z_index" getter="get_z_index" default="0"> </member> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 76d8f1840f..fd52a28486 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -90,9 +90,10 @@ <method name="map_to_world" qualifiers="const"> <return type="Vector2"> </return> - <argument index="0" name="map_position" type="Vector2"> + <argument index="0" name="map_position" type="Vector2i"> </argument> <description> + Returns the local position corresponding to the given tilemap (grid-based) coordinates. </description> </method> <method name="set_cell"> @@ -107,6 +108,7 @@ <argument index="3" name="alternative_tile" type="int" default="-1"> </argument> <description> + Sets the tile index for the cell given by a Vector2i. </description> </method> <method name="update_dirty_quadrants"> @@ -137,6 +139,7 @@ <signals> <signal name="changed"> <description> + Emitted when the [TileSet] of this TileMap changes. </description> </signal> </signals> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 13c6b9070a..2015b1f1cd 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -20,7 +20,7 @@ <method name="add_source"> <return type="int"> </return> - <argument index="0" name="atlas_source_id_override" type="TileSetAtlasSource"> + <argument index="0" name="atlas_source_id_override" type="TileSetSource"> </argument> <argument index="1" name="arg1" type="int" default="-1"> </argument> @@ -298,12 +298,15 @@ </members> <constants> <constant name="TILE_SHAPE_SQUARE" value="0" enum="TileShape"> + Orthogonal orientation mode. </constant> <constant name="TILE_SHAPE_ISOMETRIC" value="1" enum="TileShape"> + Isometric orientation mode. </constant> <constant name="TILE_SHAPE_HALF_OFFSET_SQUARE" value="2" enum="TileShape"> </constant> <constant name="TILE_SHAPE_HEXAGON" value="3" enum="TileShape"> + Hexagon orientation mode. </constant> <constant name="TILE_LAYOUT_STACKED" value="0" enum="TileLayout"> </constant> diff --git a/doc/classes/TileSetScenesCollectionSource.xml b/doc/classes/TileSetScenesCollectionSource.xml new file mode 100644 index 0000000000..1a00eb51c0 --- /dev/null +++ b/doc/classes/TileSetScenesCollectionSource.xml @@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="TileSetScenesCollectionSource" inherits="TileSetSource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="create_scene_tile"> + <return type="int"> + </return> + <argument index="0" name="packed_scene" type="PackedScene"> + </argument> + <argument index="1" name="id_override" type="int" default="-1"> + </argument> + <description> + </description> + </method> + <method name="get_alternative_tile_id" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="atlas_coords" type="Vector2i"> + </argument> + <argument index="1" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_alternative_tiles_count" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="atlas_coords" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="get_next_scene_tile_id" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_scene_tile_display_placeholder" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_scene_tile_id"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_scene_tile_scene" qualifiers="const"> + <return type="PackedScene"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_scene_tiles_count"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_tile_id" qualifiers="const"> + <return type="Vector2i"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_tiles_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="has_alternative_tile" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="atlas_coords" type="Vector2i"> + </argument> + <argument index="1" name="alternative_tile" type="int"> + </argument> + <description> + </description> + </method> + <method name="has_scene_tile_id"> + <return type="bool"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="has_tile" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="atlas_coords" type="Vector2i"> + </argument> + <description> + </description> + </method> + <method name="remove_scene_tile"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_scene_tile_display_placeholder"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="display_placeholder" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_scene_tile_id"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="new_id" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_scene_tile_scene"> + <return type="void"> + </return> + <argument index="0" name="id" type="int"> + </argument> + <argument index="1" name="packed_scene" type="PackedScene"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index a09f1bf470..c31467c67e 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -30,7 +30,7 @@ } [/csharp] [/codeblocks] - To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root]. You can use [method Object.free] on a [TreeItem] to remove it from the [Tree]. + To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_first_child] after getting the root through [method get_root]. You can use [method Object.free] on a [TreeItem] to remove it from the [Tree]. </description> <tutorials> </tutorials> @@ -533,6 +533,12 @@ <theme_item name="checked" type="Texture2D"> The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is checked. </theme_item> + <theme_item name="children_hl_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> + The [Color] of the relationship lines between the selected [TreeItem] and its children. + </theme_item> + <theme_item name="children_hl_line_width" type="int" default="1"> + The width of the relationship lines between the selected [TreeItem] and its children. + </theme_item> <theme_item name="cursor" type="StyleBox"> [StyleBox] used for the cursor, when the [Tree] is being focused. </theme_item> @@ -587,8 +593,20 @@ <theme_item name="outline_size" type="int" default="0"> The size of the text outline. </theme_item> + <theme_item name="parent_hl_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> + The [Color] of the relationship lines between the selected [TreeItem] and its parents. + </theme_item> + <theme_item name="parent_hl_line_margin" type="int" default="0"> + The space between the parent relationship lines for the selected [TreeItem] and the relationship lines to its siblings that are not selected. + </theme_item> + <theme_item name="parent_hl_line_width" type="int" default="1"> + The width of the relationship lines between the selected [TreeItem] and its parents. + </theme_item> <theme_item name="relationship_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> - [Color] of the relationship lines. + The default [Color] of the relationship lines. + </theme_item> + <theme_item name="relationship_line_width" type="int" default="1"> + The default width of the relationship lines. </theme_item> <theme_item name="scroll_border" type="int" default="4"> The maximum distance between the mouse cursor and the control's border to trigger border scrolling when dragging. diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index add23c2ce6..7d37580504 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -63,6 +63,16 @@ Removes all OpenType features. </description> </method> + <method name="create_child"> + <return type="TreeItem"> + </return> + <argument index="0" name="idx" type="int" default="-1"> + </argument> + <description> + Creates an item and adds it as a child. + The new item will be inserted as position [code]idx[/code] (the default value [code]-1[/code] means the last position), or it will be the last child if [code]idx[/code] is higher than the child count. + </description> + </method> <method name="deselect"> <return type="void"> </return> @@ -123,11 +133,28 @@ Returns the column's cell mode. </description> </method> - <method name="get_children"> + <method name="get_child"> <return type="TreeItem"> </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Returns a child item by its index (see [method get_child_count]). This method is often used for iterating all children of an item. + Negative indices access the children from the last one. + </description> + </method> + <method name="get_child_count"> + <return type="int"> + </return> <description> - Returns the TreeItem's first child item or a null object if there is none. + Returns the number of child items. + </description> + </method> + <method name="get_children"> + <return type="Array"> + </return> + <description> + Returns an array of references to the item's children. </description> </method> <method name="get_custom_bg_color" qualifiers="const"> @@ -157,6 +184,13 @@ Returns [code]true[/code] if [code]expand_right[/code] is set. </description> </method> + <method name="get_first_child"> + <return type="TreeItem"> + </return> + <description> + Returns the TreeItem's first child. + </description> + </method> <method name="get_icon" qualifiers="const"> <return type="Texture2D"> </return> @@ -193,6 +227,13 @@ Returns the icon [Texture2D] region as [Rect2]. </description> </method> + <method name="get_index"> + <return type="int"> + </return> + <description> + Returns the node's order in the tree. For example, if called on the first child item the position is [code]0[/code]. + </description> + </method> <method name="get_language" qualifiers="const"> <return type="String"> </return> @@ -342,6 +383,13 @@ Returns the given column's tooltip. </description> </method> + <method name="get_tree"> + <return type="Tree"> + </return> + <description> + Returns the [Tree] that owns this TreeItem. + </description> + </method> <method name="is_button_disabled" qualifiers="const"> <return type="bool"> </return> @@ -397,18 +445,24 @@ Returns [code]true[/code] if column [code]column[/code] is selected. </description> </method> - <method name="move_to_bottom"> + <method name="move_after"> <return type="void"> </return> + <argument index="0" name="item" type="Object"> + </argument> <description> - Moves this TreeItem to the bottom in the [Tree] hierarchy. + Moves this TreeItem right after the given [code]item[/code]. + [b]Note:[/b] You can't move to the root or move the root. </description> </method> - <method name="move_to_top"> + <method name="move_before"> <return type="void"> </return> + <argument index="0" name="item" type="Object"> + </argument> <description> - Moves this TreeItem to the top in the [Tree] hierarchy. + Moves this TreeItem right before the given [code]item[/code]. + [b]Note:[/b] You can't move to the root or move the root. </description> </method> <method name="remove_child"> diff --git a/doc/classes/VisualShaderNodeBillboard.xml b/doc/classes/VisualShaderNodeBillboard.xml new file mode 100644 index 0000000000..53bcfa7b5c --- /dev/null +++ b/doc/classes/VisualShaderNodeBillboard.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeBillboard" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A node that controls how the object faces the camera to be used within the visual shader graph. + </brief_description> + <description> + The output port of this node needs to be connected to [code]Model View Matrix[/code] port of [VisualShaderNodeOutput]. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="billboard_type" type="int" setter="set_billboard_type" getter="get_billboard_type" enum="VisualShaderNodeBillboard.BillboardType" default="1"> + Controls how the object faces the camera. See [enum BillboardType]. + </member> + <member name="keep_scale" type="bool" setter="set_keep_scale_enabled" getter="is_keep_scale_enabled" default="false"> + If [code]true[/code], the shader will keep the scale set for the mesh. Otherwise, the scale is lost when billboarding. + </member> + </members> + <constants> + <constant name="BILLBOARD_TYPE_DISABLED" value="0" enum="BillboardType"> + Billboarding is disabled and the node does nothing. + </constant> + <constant name="BILLBOARD_TYPE_ENABLED" value="1" enum="BillboardType"> + A standard billboarding algorithm is enabled. + </constant> + <constant name="BILLBOARD_TYPE_FIXED_Y" value="2" enum="BillboardType"> + A billboarding algorithm to rotate around Y-axis is enabled. + </constant> + <constant name="BILLBOARD_TYPE_PARTICLES" value="3" enum="BillboardType"> + A billboarding algorithm designed to use on particles is enabled. + </constant> + <constant name="BILLBOARD_TYPE_MAX" value="4" enum="BillboardType"> + Represents the size of the [enum BillboardType] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index b99a251a11..37709753bc 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -45,7 +45,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -55,7 +55,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -65,10 +65,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns the [Font] at [code]name[/code] if the theme has [code]type[/code]. + Returns the [Font] at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_theme_font_size" qualifiers="const"> @@ -76,10 +76,10 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns the font size at [code]name[/code] if the theme has [code]type[/code]. + Returns the font size at [code]name[/code] if the theme has [code]theme_type[/code]. </description> </method> <method name="get_theme_icon" qualifiers="const"> @@ -87,7 +87,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -97,7 +97,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -119,7 +119,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -129,7 +129,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -139,11 +139,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if [Font] with [code]name[/code] is in [code]type[/code]. - Returns [code]false[/code] if the theme does not have [code]type[/code]. + Returns [code]true[/code] if [Font] with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_theme_font_size" qualifiers="const"> @@ -151,11 +151,11 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> - Returns [code]true[/code] if font size with [code]name[/code] is in [code]type[/code]. - Returns [code]false[/code] if the theme does not have [code]type[/code]. + Returns [code]true[/code] if font size with [code]name[/code] is in [code]theme_type[/code]. + Returns [code]false[/code] if the theme does not have [code]theme_type[/code]. </description> </method> <method name="has_theme_icon" qualifiers="const"> @@ -163,7 +163,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -173,7 +173,7 @@ </return> <argument index="0" name="name" type="StringName"> </argument> - <argument index="1" name="type" type="StringName" default=""""> + <argument index="1" name="theme_type" type="StringName" default=""""> </argument> <description> </description> @@ -340,6 +340,8 @@ </member> <member name="theme" type="Theme" setter="set_theme" getter="get_theme"> </member> + <member name="theme_custom_type" type="StringName" setter="set_theme_custom_type" getter="get_theme_custom_type" default="@"""> + </member> <member name="title" type="String" setter="set_title" getter="get_title" default=""""> </member> <member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false"> diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 1a27c54757..8f20a3472c 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -554,6 +554,7 @@ public: RID particles_allocate() override { return RID(); } void particles_initialize(RID p_rid) override {} + void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override {} void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {} void particles_set_emitting(RID p_particles, bool p_emitting) override {} void particles_set_amount(RID p_particles, int p_amount) override {} diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp index ded6bbc53e..8b2e786146 100644 --- a/drivers/png/image_loader_png.cpp +++ b/drivers/png/image_loader_png.cpp @@ -37,7 +37,7 @@ #include <string.h> Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { - const size_t buffer_size = f->get_len(); + const uint64_t buffer_size = f->get_length(); Vector<uint8_t> file_buffer; Error err = file_buffer.resize(buffer_size); if (err) { diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 5e87bc019b..0f8f2260f2 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -40,13 +40,19 @@ void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) { switch (pa_context_get_state(c)) { case PA_CONTEXT_TERMINATED: + print_verbose("PulseAudio: context terminated"); + ad->pa_ready = -1; + break; case PA_CONTEXT_FAILED: + print_verbose("PulseAudio: context failed"); ad->pa_ready = -1; break; case PA_CONTEXT_READY: + print_verbose("PulseAudio: context ready"); ad->pa_ready = 1; break; default: + print_verbose("PulseAudio: context other"); // TODO: Check if we want to handle some of the other // PA context states like PA_CONTEXT_UNCONNECTED. break; @@ -61,6 +67,13 @@ void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l return; } + // If eol is set to a negative number there's an error. + if (eol < 0) { + ERR_PRINT("PulseAudio: sink info error: " + String(pa_strerror(pa_context_errno(c)))); + ad->pa_status--; + return; + } + ad->pa_map = l->channel_map; ad->pa_status++; } @@ -73,6 +86,13 @@ void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_inf return; } + // If eol is set to a negative number there's an error. + if (eol < 0) { + ERR_PRINT("PulseAudio: sink info error: " + String(pa_strerror(pa_context_errno(c)))); + ad->pa_status--; + return; + } + ad->pa_rec_map = l->channel_map; ad->pa_status++; } @@ -86,7 +106,7 @@ void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_inf ad->pa_status++; } -void AudioDriverPulseAudio::detect_channels(bool capture) { +Error AudioDriverPulseAudio::detect_channels(bool capture) { pa_channel_map_init_stereo(capture ? &pa_rec_map : &pa_map); String device = capture ? capture_device_name : device_name; @@ -104,7 +124,8 @@ void AudioDriverPulseAudio::detect_channels(bool capture) { pa_operation_unref(pa_op); } else { - ERR_PRINT("pa_context_get_server_info error"); + ERR_PRINT("pa_context_get_server_info error: " + String(pa_strerror(pa_context_errno(pa_ctx)))); + return FAILED; } } @@ -114,6 +135,7 @@ void AudioDriverPulseAudio::detect_channels(bool capture) { } else { strcpy(dev, device.utf8().get_data()); } + print_verbose("PulseAudio: Detecting channels for device: " + String(dev)); // Now using the device name get the amount of channels pa_status = 0; @@ -133,6 +155,10 @@ void AudioDriverPulseAudio::detect_channels(bool capture) { } pa_operation_unref(pa_op); + + if (pa_status == -1) { + return FAILED; + } } else { if (capture) { ERR_PRINT("pa_context_get_source_info_by_name error"); @@ -140,6 +166,8 @@ void AudioDriverPulseAudio::detect_channels(bool capture) { ERR_PRINT("pa_context_get_sink_info_by_name error"); } } + + return OK; } Error AudioDriverPulseAudio::init_device() { @@ -156,7 +184,13 @@ Error AudioDriverPulseAudio::init_device() { // Note: If using an even amount of channels (2, 4, etc) channels and pa_map.channels will be equal, // if not then pa_map.channels will have the real amount of channels PulseAudio is using and channels // will have the amount of channels Godot is using (in this case it's pa_map.channels + 1) - detect_channels(); + Error err = detect_channels(); + if (err != OK) { + // This most likely means there are no sinks. + ERR_PRINT("PulseAudio: init device failed to detect number of channels"); + return err; + } + switch (pa_map.channels) { case 1: // Mono case 3: // Surround 2.1 @@ -294,10 +328,8 @@ Error AudioDriverPulseAudio::init() { return ERR_CANT_OPEN; } - Error err = init_device(); - if (err == OK) { - thread.start(AudioDriverPulseAudio::thread_func, this); - } + init_device(); + thread.start(AudioDriverPulseAudio::thread_func, this); return OK; } @@ -441,7 +473,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { pa_operation_unref(pa_op); } else { - ERR_PRINT("pa_context_get_server_info error"); + ERR_PRINT("pa_context_get_server_info error: " + String(pa_strerror(pa_context_errno(ad->pa_ctx)))); } if (old_default_device != ad->default_device) { diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index fa9b573d94..1358561c02 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -89,7 +89,7 @@ class AudioDriverPulseAudio : public AudioDriver { Error capture_init_device(); void capture_finish_device(); - void detect_channels(bool capture = false); + Error detect_channels(bool capture = false); static void thread_func(void *p_udata); diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 22151b60c1..a2c9bae852 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -406,14 +406,61 @@ Error DirAccessUnix::remove(String p_path) { } } -size_t DirAccessUnix::get_space_left() { +bool DirAccessUnix::is_link(String p_file) { + if (p_file.is_rel_path()) { + p_file = get_current_dir().plus_file(p_file); + } + + p_file = fix_path(p_file); + + struct stat flags; + if ((lstat(p_file.utf8().get_data(), &flags) != 0)) { + return FAILED; + } + + return S_ISLNK(flags.st_mode); +} + +String DirAccessUnix::read_link(String p_file) { + if (p_file.is_rel_path()) { + p_file = get_current_dir().plus_file(p_file); + } + + p_file = fix_path(p_file); + + char buf[256]; + memset(buf, 0, 256); + ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf)); + String link; + if (len > 0) { + link.parse_utf8(buf, len); + } + return link; +} + +Error DirAccessUnix::create_link(String p_source, String p_target) { + if (p_target.is_rel_path()) { + p_target = get_current_dir().plus_file(p_target); + } + + p_source = fix_path(p_source); + p_target = fix_path(p_target); + + if (symlink(p_source.utf8().get_data(), p_target.utf8().get_data()) == 0) { + return OK; + } else { + return FAILED; + } +} + +uint64_t DirAccessUnix::get_space_left() { #ifndef NO_STATVFS struct statvfs vfs; if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) { return 0; }; - return vfs.f_bfree * vfs.f_bsize; + return (uint64_t)vfs.f_bavail * (uint64_t)vfs.f_frsize; #else // FIXME: Implement this. return 0; diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index 54f4a5c312..28a7053d25 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -79,7 +79,11 @@ public: virtual Error rename(String p_path, String p_new_path); virtual Error remove(String p_path); - virtual size_t get_space_left(); + virtual bool is_link(String p_file); + virtual String read_link(String p_file); + virtual Error create_link(String p_source, String p_target); + + virtual uint64_t get_space_left(); virtual String get_filesystem_type() const; diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 4c08380dd0..ec23df62d0 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -184,11 +184,11 @@ String FileAccessUnix::get_path_absolute() const { return path; } -void FileAccessUnix::seek(size_t p_position) { +void FileAccessUnix::seek(uint64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); last_error = OK; - if (fseek(f, p_position, SEEK_SET)) { + if (fseeko(f, p_position, SEEK_SET)) { check_errors(); } } @@ -196,15 +196,15 @@ void FileAccessUnix::seek(size_t p_position) { void FileAccessUnix::seek_end(int64_t p_position) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); - if (fseek(f, p_position, SEEK_END)) { + if (fseeko(f, p_position, SEEK_END)) { check_errors(); } } -size_t FileAccessUnix::get_position() const { +uint64_t FileAccessUnix::get_position() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); - long pos = ftell(f); + int64_t pos = ftello(f); if (pos < 0) { check_errors(); ERR_FAIL_V(0); @@ -212,15 +212,15 @@ size_t FileAccessUnix::get_position() const { return pos; } -size_t FileAccessUnix::get_len() const { +uint64_t FileAccessUnix::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); - long pos = ftell(f); + int64_t pos = ftello(f); ERR_FAIL_COND_V(pos < 0, 0); - ERR_FAIL_COND_V(fseek(f, 0, SEEK_END), 0); - long size = ftell(f); + ERR_FAIL_COND_V(fseeko(f, 0, SEEK_END), 0); + int64_t size = ftello(f); ERR_FAIL_COND_V(size < 0, 0); - ERR_FAIL_COND_V(fseek(f, pos, SEEK_SET), 0); + ERR_FAIL_COND_V(fseeko(f, pos, SEEK_SET), 0); return size; } @@ -239,11 +239,11 @@ uint8_t FileAccessUnix::get_8() const { return b; } -int FileAccessUnix::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessUnix::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use."); - int read = fread(p_dst, 1, p_length, f); + + uint64_t read = fread(p_dst, 1, p_length, f); check_errors(); return read; }; @@ -262,10 +262,10 @@ void FileAccessUnix::store_8(uint8_t p_dest) { ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1); } -void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessUnix::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); ERR_FAIL_COND(!p_src); - ERR_FAIL_COND((int)fwrite(p_src, 1, p_length, f) != p_length); + ERR_FAIL_COND(fwrite(p_src, 1, p_length, f) != p_length); } bool FileAccessUnix::file_exists(const String &p_path) { diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 998fad7909..5b1599c67f 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -61,21 +61,21 @@ public: virtual String get_path() const; /// returns the path for the current open file virtual String get_path_absolute() const; /// returns the absolute path for the current open file - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_path); ///< return true if a file exists diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 4649cee17f..38455bdbed 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -529,7 +529,7 @@ Error VulkanContext::_check_capabilities() { device_features_func(gpu, &device_features); multiview_capabilities.is_supported = multiview_features.multiview; - // For now we ignore if multiview is available in geometry and tesselation as we do not currently support those + // For now we ignore if multiview is available in geometry and tessellation as we do not currently support those } // check extended properties diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 2c9f28717d..55f9e6de17 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -198,7 +198,7 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) { if (_get_root_string() == "") { int p = current_dir.find(":"); if (p != -1) { - return current_dir.right(p + 1); + return current_dir.substr(p + 1); } } return current_dir; @@ -325,14 +325,15 @@ FileType DirAccessWindows::get_file_type(const String& p_file) const { } */ -size_t DirAccessWindows::get_space_left() { + +uint64_t DirAccessWindows::get_space_left() { uint64_t bytes = 0; if (!GetDiskFreeSpaceEx(nullptr, (PULARGE_INTEGER)&bytes, nullptr, nullptr)) { return 0; } //this is either 0 or a value in bytes. - return (size_t)bytes; + return bytes; } String DirAccessWindows::get_filesystem_type() const { diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h index 7f10023470..b151b631e9 100644 --- a/drivers/windows/dir_access_windows.h +++ b/drivers/windows/dir_access_windows.h @@ -78,8 +78,11 @@ public: virtual Error rename(String p_path, String p_new_path); virtual Error remove(String p_path); - //virtual FileType get_file_type() const; - size_t get_space_left(); + virtual bool is_link(String p_file) { return false; }; + virtual String read_link(String p_file) { return p_file; }; + virtual Error create_link(String p_source, String p_target) { return FAILED; }; + + uint64_t get_space_left(); virtual String get_filesystem_type() const; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index b1b3fc9092..1f46b44f5e 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -193,10 +193,11 @@ bool FileAccessWindows::is_open() const { return (f != nullptr); } -void FileAccessWindows::seek(size_t p_position) { +void FileAccessWindows::seek(uint64_t p_position) { ERR_FAIL_COND(!f); + last_error = OK; - if (fseek(f, p_position, SEEK_SET)) { + if (_fseeki64(f, p_position, SEEK_SET)) { check_errors(); } prev_op = 0; @@ -204,28 +205,27 @@ void FileAccessWindows::seek(size_t p_position) { void FileAccessWindows::seek_end(int64_t p_position) { ERR_FAIL_COND(!f); - if (fseek(f, p_position, SEEK_END)) { + if (_fseeki64(f, p_position, SEEK_END)) { check_errors(); } prev_op = 0; } -size_t FileAccessWindows::get_position() const { - size_t aux_position = 0; - aux_position = ftell(f); - if (!aux_position) { +uint64_t FileAccessWindows::get_position() const { + int64_t aux_position = _ftelli64(f); + if (aux_position < 0) { check_errors(); } return aux_position; } -size_t FileAccessWindows::get_len() const { +uint64_t FileAccessWindows::get_length() const { ERR_FAIL_COND_V(!f, 0); - size_t pos = get_position(); - fseek(f, 0, SEEK_END); - int size = get_position(); - fseek(f, pos, SEEK_SET); + uint64_t pos = get_position(); + _fseeki64(f, 0, SEEK_END); + uint64_t size = get_position(); + _fseeki64(f, pos, SEEK_SET); return size; } @@ -252,17 +252,17 @@ uint8_t FileAccessWindows::get_8() const { return b; } -int FileAccessWindows::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessWindows::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!f, -1); + if (flags == READ_WRITE || flags == WRITE_READ) { if (prev_op == WRITE) { fflush(f); } prev_op = READ; } - int read = fread(p_dst, 1, p_length, f); + uint64_t read = fread(p_dst, 1, p_length, f); check_errors(); return read; }; @@ -292,7 +292,7 @@ void FileAccessWindows::store_8(uint8_t p_dest) { fwrite(&p_dest, 1, 1, f); } -void FileAccessWindows::store_buffer(const uint8_t *p_src, int p_length) { +void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND(!f); if (flags == READ_WRITE || flags == WRITE_READ) { if (prev_op == READ) { diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 507e0b2c20..95f3a75548 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -56,21 +56,21 @@ public: virtual String get_path() const; /// returns the path for the current open file virtual String get_path_absolute() const; /// returns the absolute path for the current open file - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte - virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes + virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index c0d5716c4e..d195561a85 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -63,7 +63,7 @@ static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = { String InputEventConfigurationDialog::get_event_text(const Ref<InputEvent> &p_event) { ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEvent"); - // Joypad motion events will display slighlty differently than what the event->as_text() provides. See #43660. + // Joypad motion events will display slightly differently than what the event->as_text() provides. See #43660. Ref<InputEventJoypadMotion> jpmotion = p_event; if (jpmotion.is_valid()) { String desc = TTR("Unknown Joypad Axis"); @@ -97,11 +97,11 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) { if (mod.is_valid()) { show_mods = true; - mod_checkboxes[MOD_ALT]->set_pressed(mod->get_alt()); - mod_checkboxes[MOD_SHIFT]->set_pressed(mod->get_shift()); - mod_checkboxes[MOD_COMMAND]->set_pressed(mod->get_command()); - mod_checkboxes[MOD_CONTROL]->set_pressed(mod->get_control()); - mod_checkboxes[MOD_META]->set_pressed(mod->get_metakey()); + mod_checkboxes[MOD_ALT]->set_pressed(mod->is_alt_pressed()); + mod_checkboxes[MOD_SHIFT]->set_pressed(mod->is_shift_pressed()); + mod_checkboxes[MOD_COMMAND]->set_pressed(mod->is_command_pressed()); + mod_checkboxes[MOD_CTRL]->set_pressed(mod->is_ctrl_pressed()); + mod_checkboxes[MOD_META]->set_pressed(mod->is_meta_pressed()); store_command_checkbox->set_pressed(mod->is_storing_command()); } @@ -122,9 +122,9 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) { // Update selected item in input list for keys, joybuttons and joyaxis only (since the mouse cannot be "listened" for). if (k.is_valid() || joyb.is_valid() || joym.is_valid()) { - TreeItem *category = input_list_tree->get_root()->get_children(); + TreeItem *category = input_list_tree->get_root()->get_first_child(); while (category) { - TreeItem *input_item = category->get_children(); + TreeItem *input_item = category->get_first_child(); // has_type this should be always true, unless the tree structure has been misconfigured. bool has_type = input_item->get_parent()->has_meta("__type"); @@ -384,15 +384,15 @@ void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) { } if (p_index == 0) { - ie->set_alt(p_checked); + ie->set_alt_pressed(p_checked); } else if (p_index == 1) { - ie->set_shift(p_checked); + ie->set_shift_pressed(p_checked); } else if (p_index == 2) { - ie->set_command(p_checked); + ie->set_command_pressed(p_checked); } else if (p_index == 3) { - ie->set_control(p_checked); + ie->set_ctrl_pressed(p_checked); } else if (p_index == 4) { - ie->set_metakey(p_checked); + ie->set_meta_pressed(p_checked); } _set_event(ie); @@ -413,7 +413,7 @@ void InputEventConfigurationDialog::_store_command_toggled(bool p_checked) { mod_checkboxes[MOD_COMMAND]->show(); mod_checkboxes[MOD_COMMAND]->set_text("Meta (Command)"); #else - mod_checkboxes[MOD_CONTROL]->hide(); + mod_checkboxes[MOD_CTRL]->hide(); mod_checkboxes[MOD_COMMAND]->show(); mod_checkboxes[MOD_COMMAND]->set_text("Control (Command)"); @@ -421,7 +421,7 @@ void InputEventConfigurationDialog::_store_command_toggled(bool p_checked) { } else { // If not, hide Command, show Control and Meta. mod_checkboxes[MOD_COMMAND]->hide(); - mod_checkboxes[MOD_CONTROL]->show(); + mod_checkboxes[MOD_CTRL]->show(); mod_checkboxes[MOD_META]->show(); } } @@ -469,11 +469,11 @@ void InputEventConfigurationDialog::_input_list_item_selected() { } // Maintain modifier state from checkboxes - k->set_alt(mod_checkboxes[MOD_ALT]->is_pressed()); - k->set_shift(mod_checkboxes[MOD_SHIFT]->is_pressed()); - k->set_command(mod_checkboxes[MOD_COMMAND]->is_pressed()); - k->set_control(mod_checkboxes[MOD_CONTROL]->is_pressed()); - k->set_metakey(mod_checkboxes[MOD_META]->is_pressed()); + k->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); + k->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); + k->set_command_pressed(mod_checkboxes[MOD_COMMAND]->is_pressed()); + k->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed()); + k->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); k->set_store_command(store_command_checkbox->is_pressed()); _set_event(k); @@ -484,11 +484,11 @@ void InputEventConfigurationDialog::_input_list_item_selected() { mb.instance(); mb->set_button_index(idx); // Maintain modifier state from checkboxes - mb->set_alt(mod_checkboxes[MOD_ALT]->is_pressed()); - mb->set_shift(mod_checkboxes[MOD_SHIFT]->is_pressed()); - mb->set_command(mod_checkboxes[MOD_COMMAND]->is_pressed()); - mb->set_control(mod_checkboxes[MOD_CONTROL]->is_pressed()); - mb->set_metakey(mod_checkboxes[MOD_META]->is_pressed()); + mb->set_alt_pressed(mod_checkboxes[MOD_ALT]->is_pressed()); + mb->set_shift_pressed(mod_checkboxes[MOD_SHIFT]->is_pressed()); + mb->set_command_pressed(mod_checkboxes[MOD_COMMAND]->is_pressed()); + mb->set_ctrl_pressed(mod_checkboxes[MOD_CTRL]->is_pressed()); + mb->set_meta_pressed(mod_checkboxes[MOD_META]->is_pressed()); mb->set_store_command(store_command_checkbox->is_pressed()); _set_event(mb); @@ -731,7 +731,7 @@ void ActionMapEditor::_add_action_pressed() { void ActionMapEditor::_add_action(const String &p_name) { if (p_name == "" || !_is_action_name_valid(p_name)) { - show_message(TTR("Invalid action name. it cannot be.is_empty()() nor contain '/', ':', '=', '\\' or '\"'")); + show_message(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'")); return; } @@ -756,7 +756,7 @@ void ActionMapEditor::_action_edited() { if (new_name == "" || !_is_action_name_valid(new_name)) { ti->set_text(0, old_name); - show_message(TTR("Invalid action name. it cannot be.is_empty()() nor contain '/', ':', '=', '\\' or '\"'")); + show_message(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'")); return; } diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h index fb097ddfdd..aff3e6e957 100644 --- a/editor/action_map_editor.h +++ b/editor/action_map_editor.h @@ -78,11 +78,11 @@ private: MOD_ALT, MOD_SHIFT, MOD_COMMAND, - MOD_CONTROL, + MOD_CTRL, MOD_META, MOD_MAX }; - String mods[MOD_MAX] = { "Alt", "Shift", "Command", "Control", "Meta" }; + String mods[MOD_MAX] = { "Alt", "Shift", "Command", "Ctrl", "Metakey" }; CheckBox *mod_checkboxes[MOD_MAX]; CheckBox *store_command_checkbox; diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 67b52bf0ca..63ffab6727 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -619,7 +619,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { float v_zoom_orig = v_zoom; - if (mb->get_command()) { + if (mb->is_command_pressed()) { timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); } else { if (v_zoom < 100000) { @@ -632,7 +632,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { float v_zoom_orig = v_zoom; - if (mb->get_command()) { + if (mb->is_command_pressed()) { timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); } else { if (v_zoom > 0.000001) { @@ -691,9 +691,9 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { //first check point //command makes it ignore the main point, so control point editors can be force-edited //path 2D editing in the 3D and 2D editors works the same way - if (!mb->get_command()) { + if (!mb->is_command_pressed()) { if (edit_points[i].point_rect.has_point(mb->get_position())) { - if (mb->get_shift()) { + if (mb->is_shift_pressed()) { //add to selection if (selection.has(i)) { selection.erase(i); @@ -743,7 +743,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { } //insert new point - if (mb->get_command() && mb->get_position().x >= timeline->get_name_limit() && mb->get_position().x < get_size().width - timeline->get_buttons_width()) { + if (mb->is_command_pressed() && mb->get_position().x >= timeline->get_name_limit() && mb->get_position().x < get_size().width - timeline->get_buttons_width()) { Array new_point; new_point.resize(5); @@ -961,7 +961,7 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { if (box_selecting_attempt && mm.is_valid()) { if (!box_selecting) { box_selecting = true; - box_selecting_add = mm->get_shift(); + box_selecting_add = mm->is_shift_pressed(); } box_selection_to = mm->get_position(); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 89f77f3c77..3620fda4f8 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1659,7 +1659,7 @@ void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) { int x = mb->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); - emit_signal("timeline_changed", ofs, false); + emit_signal("timeline_changed", ofs, false, Input::get_singleton()->is_key_pressed(KEY_ALT)); dragging_timeline = true; } if (!dragging_timeline && mb->get_button_index() == MOUSE_BUTTON_MIDDLE) { @@ -1698,7 +1698,7 @@ void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) { if (dragging_timeline) { int x = mm->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); - emit_signal("timeline_changed", ofs, false); + emit_signal("timeline_changed", ofs, false, Input::get_singleton()->is_key_pressed(KEY_ALT)); } if (panning_timeline) { int x = mm->get_position().x - get_name_limit(); @@ -2662,7 +2662,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { } if (key_idx != -1) { - if (mb->get_command() || mb->get_shift()) { + if (mb->is_command_pressed() || mb->is_shift_pressed()) { if (editor->is_key_selected(track, key_idx)) { emit_signal("deselect_key", key_idx); } else { @@ -3254,8 +3254,8 @@ void AnimationTrackEditor::_name_limit_changed() { } } -void AnimationTrackEditor::_timeline_changed(float p_new_pos, bool p_drag) { - emit_signal("timeline_changed", p_new_pos, p_drag); +void AnimationTrackEditor::_timeline_changed(float p_new_pos, bool p_drag, bool p_timeline_only) { + emit_signal("timeline_changed", p_new_pos, p_drag, p_timeline_only); } void AnimationTrackEditor::_track_remove_request(int p_track) { @@ -4028,7 +4028,7 @@ bool AnimationTrackEditor::is_selection_active() const { } bool AnimationTrackEditor::is_snap_enabled() const { - return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CTRL); } void AnimationTrackEditor::_update_tracks() { @@ -4959,12 +4959,12 @@ void AnimationTrackEditor::_box_selection_draw() { void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->get_command() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { + if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); scroll->accept_event(); } - if (mb.is_valid() && mb->is_pressed() && mb->get_command() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { + if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); scroll->accept_event(); } @@ -4980,7 +4980,7 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { for (int i = 0; i < track_edits.size(); i++) { Rect2 local_rect = box_select_rect; local_rect.position -= track_edits[i]->get_global_position(); - track_edits[i]->append_to_selection(local_rect, mb->get_command()); + track_edits[i]->append_to_selection(local_rect, mb->is_command_pressed()); } if (_get_track_selected() == -1 && track_edits.size() > 0) { //minimal hack to make shortcuts work @@ -5010,7 +5010,7 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) { } if (!box_selection->is_visible_in_tree()) { - if (!mm->get_command() && !mm->get_shift()) { + if (!mm->is_command_pressed() && !mm->is_shift_pressed()) { _clear_selection(); } box_selection->show(); @@ -5216,7 +5216,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { track_clipboard.clear(); TreeItem *root = track_copy_select->get_root(); if (root) { - TreeItem *it = root->get_children(); + TreeItem *it = root->get_first_child(); while (it) { Dictionary md = it->get_metadata(0); int idx = md["track_idx"]; @@ -5602,7 +5602,7 @@ void AnimationTrackEditor::_show_imported_anim_warning() { } void AnimationTrackEditor::_select_all_tracks_for_copy() { - TreeItem *track = track_copy_select->get_root()->get_children(); + TreeItem *track = track_copy_select->get_root()->get_first_child(); if (!track) { return; } @@ -5616,7 +5616,7 @@ void AnimationTrackEditor::_select_all_tracks_for_copy() { track = track->get_next(); } - track = track_copy_select->get_root()->get_children(); + track = track_copy_select->get_root()->get_first_child(); while (track) { track->set_checked(0, !all_selected); track = track->get_next(); @@ -5681,7 +5681,7 @@ void AnimationTrackEditor::_pick_track_select_recursive(TreeItem *p_item, const p_select_candidates.push_back(node); } - TreeItem *c = p_item->get_children(); + TreeItem *c = p_item->get_first_child(); while (c) { _pick_track_select_recursive(c, p_filter, p_select_candidates); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index c25865effb..8befc830fa 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -328,7 +328,7 @@ class AnimationTrackEditor : public VBoxContainer { void _update_tracks(); void _name_limit_changed(); - void _timeline_changed(float p_new_pos, bool p_drag); + void _timeline_changed(float p_new_pos, bool p_drag, bool p_timeline_only = false); void _track_remove_request(int p_track); void _track_grab_focus(int p_track); diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index ae79299331..54c1e89d1e 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -1091,7 +1091,7 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) { if (len_resizing && mm.is_valid()) { len_resizing_rel += mm->get_relative().x; - len_resizing_start = mm->get_shift(); + len_resizing_start = mm->is_shift_pressed(); update(); accept_event(); return; @@ -1100,7 +1100,7 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && get_default_cursor_shape() == CURSOR_HSIZE) { len_resizing = true; - len_resizing_start = mb->get_shift(); + len_resizing_start = mb->is_shift_pressed(); len_resizing_from_px = mb->get_position().x; len_resizing_rel = 0; update(); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 1c62c3d3e1..97ba5d7a5f 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -302,7 +302,7 @@ void FindReplaceBar::_replace_all() { matches_label->add_theme_color_override("font_color", rc > 0 ? get_theme_color("font_color", "Label") : get_theme_color("error_color", "Editor")); matches_label->set_text(vformat(TTR("%d replaced."), rc)); - text_editor->call_deferred("connect", "text_changed", Callable(this, "_editor_text_changed")); + text_editor->call_deferred("connect", "text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed)); results_count = -1; } @@ -726,7 +726,7 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_command()) { + if (mb->is_pressed() && mb->is_command_pressed()) { if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { _zoom_in(); } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { @@ -1012,7 +1012,7 @@ void CodeTextEditor::convert_indent_to_spaces() { if (cursor_line == i && cursor_column > j) { cursor_column += indent_size - 1; } - line = line.left(j) + indent + line.right(j + 1); + line = line.left(j) + indent + line.substr(j + 1); } j++; } @@ -1056,7 +1056,7 @@ void CodeTextEditor::convert_indent_to_tabs() { if (cursor_line == i && cursor_column > j) { cursor_column -= indent_size; } - line = line.left(j - indent_size) + "\t" + line.right(j + 1); + line = line.left(j - indent_size) + "\t" + line.substr(j + 1); j = 0; space_count = -1; } @@ -1114,7 +1114,7 @@ void CodeTextEditor::convert_case(CaseStyle p_case) { new_line = text_editor->get_line(i).left(begin_col) + new_line; } if (i == end) { - new_line = new_line + text_editor->get_line(i).right(end_col); + new_line = new_line + text_editor->get_line(i).substr(end_col); } text_editor->set_line(i, new_line); } @@ -1474,6 +1474,34 @@ void CodeTextEditor::goto_error() { } } +void CodeTextEditor::_update_text_editor_theme() { + text_editor->add_theme_color_override("background_color", EDITOR_GET("text_editor/highlighting/background_color")); + text_editor->add_theme_color_override("completion_background_color", EDITOR_GET("text_editor/highlighting/completion_background_color")); + text_editor->add_theme_color_override("completion_selected_color", EDITOR_GET("text_editor/highlighting/completion_selected_color")); + text_editor->add_theme_color_override("completion_existing_color", EDITOR_GET("text_editor/highlighting/completion_existing_color")); + text_editor->add_theme_color_override("completion_scroll_color", EDITOR_GET("text_editor/highlighting/completion_scroll_color")); + text_editor->add_theme_color_override("completion_font_color", EDITOR_GET("text_editor/highlighting/completion_font_color")); + text_editor->add_theme_color_override("font_color", EDITOR_GET("text_editor/highlighting/text_color")); + text_editor->add_theme_color_override("line_number_color", EDITOR_GET("text_editor/highlighting/line_number_color")); + text_editor->add_theme_color_override("caret_color", EDITOR_GET("text_editor/highlighting/caret_color")); + text_editor->add_theme_color_override("caret_background_color", EDITOR_GET("text_editor/highlighting/caret_background_color")); + text_editor->add_theme_color_override("font_selected_color", EDITOR_GET("text_editor/highlighting/text_selected_color")); + text_editor->add_theme_color_override("selection_color", EDITOR_GET("text_editor/highlighting/selection_color")); + text_editor->add_theme_color_override("brace_mismatch_color", EDITOR_GET("text_editor/highlighting/brace_mismatch_color")); + text_editor->add_theme_color_override("current_line_color", EDITOR_GET("text_editor/highlighting/current_line_color")); + text_editor->add_theme_color_override("line_length_guideline_color", EDITOR_GET("text_editor/highlighting/line_length_guideline_color")); + text_editor->add_theme_color_override("word_highlighted_color", EDITOR_GET("text_editor/highlighting/word_highlighted_color")); + text_editor->add_theme_color_override("bookmark_color", EDITOR_GET("text_editor/highlighting/bookmark_color")); + text_editor->add_theme_color_override("breakpoint_color", EDITOR_GET("text_editor/highlighting/breakpoint_color")); + text_editor->add_theme_color_override("executing_line_color", EDITOR_GET("text_editor/highlighting/executing_line_color")); + text_editor->add_theme_color_override("code_folding_color", EDITOR_GET("text_editor/highlighting/code_folding_color")); + text_editor->add_theme_color_override("search_result_color", EDITOR_GET("text_editor/highlighting/search_result_color")); + text_editor->add_theme_color_override("search_result_border_color", EDITOR_GET("text_editor/highlighting/search_result_border_color")); + text_editor->add_theme_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6)); + emit_signal("load_theme_settings"); + _load_theme_settings(); +} + void CodeTextEditor::_update_font() { text_editor->add_theme_font_override("font", get_theme_font("source", "EditorFonts")); text_editor->add_theme_font_size_override("font_size", get_theme_font_size("source_size", "EditorFonts")); @@ -1497,6 +1525,7 @@ void CodeTextEditor::_update_font() { } void CodeTextEditor::_on_settings_change() { + _update_text_editor_theme(); _update_font(); font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size"); @@ -1583,14 +1612,11 @@ void CodeTextEditor::_error_pressed(const Ref<InputEvent> &p_event) { void CodeTextEditor::_notification(int p_what) { switch (p_what) { - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - _load_theme_settings(); - emit_signal("load_theme_settings"); - } break; case NOTIFICATION_THEME_CHANGED: { if (toggle_scripts_button->is_visible()) { update_toggle_scripts_button(); } + _update_text_editor_theme(); _update_font(); } break; case NOTIFICATION_ENTER_TREE: { diff --git a/editor/code_editor.h b/editor/code_editor.h index e201da446e..e6dadbd6fa 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -161,6 +161,7 @@ class CodeTextEditor : public VBoxContainer { void _on_settings_change(); + void _update_text_editor_theme(); void _update_font(); void _complete_request(); Ref<Texture2D> _get_completion_icon(const ScriptCodeCompletionOption &p_option); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 0c1fb6fe4d..de2be710c5 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -66,8 +66,8 @@ public: bool _set(const StringName &p_name, const Variant &p_value) { String name = p_name; - if (name.begins_with("bind/")) { - int which = name.get_slice("/", 1).to_int() - 1; + if (name.begins_with("bind/argument_")) { + int which = name.get_slice("_", 1).to_int() - 1; ERR_FAIL_INDEX_V(which, params.size(), false); params.write[which] = p_value; } else { @@ -80,8 +80,8 @@ public: bool _get(const StringName &p_name, Variant &r_ret) const { String name = p_name; - if (name.begins_with("bind/")) { - int which = name.get_slice("/", 1).to_int() - 1; + if (name.begins_with("bind/argument_")) { + int which = name.get_slice("_", 1).to_int() - 1; ERR_FAIL_INDEX_V(which, params.size(), false); r_ret = params[which]; } else { @@ -93,7 +93,7 @@ public: void _get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < params.size(); i++) { - p_list->push_back(PropertyInfo(params[i].get_type(), "bind/" + itos(i + 1))); + p_list->push_back(PropertyInfo(params[i].get_type(), "bind/argument_" + itos(i + 1))); } } @@ -655,7 +655,7 @@ void ConnectionsDock::_disconnect_all() { return; } - TreeItem *child = item->get_children(); + TreeItem *child = item->get_first_child(); String signalName = item->get_metadata(0).operator Dictionary()["name"]; undo_redo->create_action(vformat(TTR("Disconnect all from signal: '%s'"), signalName)); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 6befee090b..d60e2783ec 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -508,23 +508,35 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const { return res; } - // signatures - Vector<String> signatures; - const Vector<EditorProfiler::Metric::Category> &categories = frame_metrics[0].categories; - - for (int j = 0; j < categories.size(); j++) { - const EditorProfiler::Metric::Category &c = categories[j]; - signatures.push_back(c.signature); - - for (int k = 0; k < c.items.size(); k++) { - signatures.push_back(c.items[k].signature); + // Different metrics may contain different number of categories. + Set<StringName> possible_signatures; + for (int i = 0; i < frame_metrics.size(); i++) { + const Metric &m = frame_metrics[i]; + if (!m.valid) { + continue; + } + for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) { + possible_signatures.insert(E->key()); + } + for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) { + possible_signatures.insert(E->key()); } } + + // Generate CSV header and cache indices. + Map<StringName, int> sig_map; + Vector<String> signatures; + signatures.resize(possible_signatures.size()); + int sig_index = 0; + for (const Set<StringName>::Element *E = possible_signatures.front(); E; E = E->next()) { + signatures.write[sig_index] = E->get(); + sig_map[E->get()] = sig_index; + sig_index++; + } res.push_back(signatures); // values Vector<String> values; - values.resize(signatures.size()); int index = last_metric; @@ -535,20 +547,23 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const { index = 0; } - if (!frame_metrics[index].valid) { + const Metric &m = frame_metrics[index]; + + if (!m.valid) { continue; } - int it = 0; - const Vector<EditorProfiler::Metric::Category> &frame_cat = frame_metrics[index].categories; - for (int j = 0; j < frame_cat.size(); j++) { - const EditorProfiler::Metric::Category &c = frame_cat[j]; - values.write[it++] = String::num_real(c.total_time); + // Don't keep old values since there may be empty cells. + values.clear(); + values.resize(possible_signatures.size()); - for (int k = 0; k < c.items.size(); k++) { - values.write[it++] = String::num_real(c.items[k].total); - } + for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) { + values.write[sig_map[E->key()]] = String::num_real(E->value()->total_time); + } + for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) { + values.write[sig_map[E->key()]] = String::num_real(E->value()->total); } + res.push_back(values); } diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 1d95161e6c..7493cc2a8d 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -220,7 +220,7 @@ void ScriptEditorDebugger::_file_selected(const String &p_file) { file->store_csv_line(headers); if (vmem_tree->get_root()) { - TreeItem *ti = vmem_tree->get_root()->get_children(); + TreeItem *ti = vmem_tree->get_root()->get_first_child(); while (ti) { Vector<String> values; values.resize(vmem_tree->get_columns()); @@ -1319,7 +1319,7 @@ bool ScriptEditorDebugger::is_skip_breakpoints() { void ScriptEditorDebugger::_error_activated() { TreeItem *selected = error_tree->get_selected(); - TreeItem *ci = selected->get_children(); + TreeItem *ci = selected->get_first_child(); if (ci) { selected->set_collapsed(!selected->is_collapsed()); } @@ -1341,7 +1341,7 @@ void ScriptEditorDebugger::_expand_errors_list() { return; } - TreeItem *item = root->get_children(); + TreeItem *item = root->get_first_child(); while (item) { item->set_collapsed(false); item = item->get_next(); @@ -1354,7 +1354,7 @@ void ScriptEditorDebugger::_collapse_errors_list() { return; } - TreeItem *item = root->get_children(); + TreeItem *item = root->get_first_child(); while (item) { item->set_collapsed(true); item = item->get_next(); @@ -1403,7 +1403,7 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { int rpad_len = text.length(); text = type + text + ti->get_text(1) + "\n"; - TreeItem *ci = ti->get_children(); + TreeItem *ci = ti->get_first_child(); while (ci) { text += " " + ci->get_text(0).rpad(rpad_len) + ci->get_text(1) + "\n"; ci = ci->get_next(); @@ -1419,7 +1419,7 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { } // We only need the first child here (C++ source stack trace). - TreeItem *ci = ti->get_children(); + TreeItem *ci = ti->get_first_child(); // Parse back the `file:line @ method()` string. const Vector<String> file_line_number = ci->get_text(1).split("@")[0].strip_edges().split(":"); ERR_FAIL_COND_MSG(file_line_number.size() < 2, "Incorrect C++ source stack trace file:line format (please report)."); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 57d44ca56c..c085205f63 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -725,8 +725,8 @@ void OrphanResourcesDialog::_find_to_delete(TreeItem *p_item, List<String> &path paths.push_back(p_item->get_metadata(0)); } - if (p_item->get_children()) { - _find_to_delete(p_item->get_children(), paths); + if (p_item->get_first_child()) { + _find_to_delete(p_item->get_first_child(), paths); } p_item = p_item->get_next(); diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 2d29076476..9dcd550f5c 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -45,8 +45,8 @@ void EditorAssetInstaller::_update_subitems(TreeItem *p_item, bool p_check, bool p_item->set_checked(0, false); } - if (p_item->get_children()) { - _update_subitems(p_item->get_children(), p_check); + if (p_item->get_first_child()) { + _update_subitems(p_item->get_first_child(), p_check); } if (!p_first && p_item->get_next()) { @@ -60,7 +60,7 @@ void EditorAssetInstaller::_uncheck_parent(TreeItem *p_item) { } bool any_checked = false; - TreeItem *item = p_item->get_children(); + TreeItem *item = p_item->get_first_child(); while (item) { if (item->is_checked(0)) { any_checked = true; diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index e7934bed0a..4317760379 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -173,6 +173,9 @@ void EditorAudioBus::_notification(int p_what) { bypass->set_icon(get_theme_icon("AudioBusBypass", "EditorIcons")); bus_options->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons")); + + audio_value_preview_box->add_theme_color_override("font_color", get_theme_color("font_color", "TooltipLabel")); + audio_value_preview_box->add_theme_style_override("panel", get_theme_stylebox("panel", "TooltipPanel")); } break; case NOTIFICATION_MOUSE_EXIT: case NOTIFICATION_DRAG_END: { @@ -312,7 +315,7 @@ void EditorAudioBus::_volume_changed(float p_normalized) { const float p_db = this->_normalized_volume_to_scaled_db(p_normalized); - if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CTRL)) { // Snap the value when holding Ctrl for easier editing. // To do so, it needs to be converted back to normalized volume (as the slider uses that unit). slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db))); @@ -372,22 +375,31 @@ float EditorAudioBus::_scaled_db_to_normalized_volume(float db) { void EditorAudioBus::_show_value(float slider_value) { float db; - if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CTRL)) { // Display the correct (snapped) value when holding Ctrl db = Math::round(_normalized_volume_to_scaled_db(slider_value)); } else { db = _normalized_volume_to_scaled_db(slider_value); } - String text = vformat("%10.1f dB", db); + String text; + if (Math::is_zero_approx(Math::snapped(db, 0.1))) { + // Prevent displaying `-0.0 dB` and show ` 0.0 dB` instead. + // The leading space makes the text visually line up with its positive/negative counterparts. + text = " 0.0 dB"; + } else { + // Show an explicit `+` sign if positive. + text = vformat("%+.1f dB", db); + } + // Also set the preview text as a standard Control tooltip. + // This way, it can be seen when the slider is merely hovered (instead of dragged). slider->set_tooltip(text); audio_value_preview_label->set_text(text); - Vector2 slider_size = slider->get_size(); - Vector2 slider_position = slider->get_global_position(); - float left_padding = 5.0f; - float vert_padding = 10.0f; - Vector2 box_position = Vector2(slider_size.x + left_padding, (slider_size.y - vert_padding) * (1.0f - slider->get_value()) - vert_padding); + const Vector2 slider_size = slider->get_size(); + const Vector2 slider_position = slider->get_global_position(); + const float vert_padding = 10.0f; + const Vector2 box_position = Vector2(slider_size.x, (slider_size.y - vert_padding) * (1.0f - slider->get_value()) - vert_padding); audio_value_preview_box->set_position(slider_position + box_position); audio_value_preview_box->set_size(audio_value_preview_label->get_size()); if (slider->has_focus() && !audio_value_preview_box->is_visible()) { @@ -830,14 +842,13 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { audio_value_preview_label->set_v_size_flags(SIZE_EXPAND_FILL); audio_value_preview_label->set_h_size_flags(SIZE_EXPAND_FILL); audio_value_preview_label->set_mouse_filter(MOUSE_FILTER_PASS); + audio_value_preview_box->add_theme_color_override("font_color", get_theme_color("font_color", "TooltipLabel")); audioprev_hbc->add_child(audio_value_preview_label); slider->add_child(audio_value_preview_box); audio_value_preview_box->set_as_top_level(true); - Ref<StyleBoxFlat> panel_style = memnew(StyleBoxFlat); - panel_style->set_bg_color(Color(0.0f, 0.0f, 0.0f, 0.8f)); - audio_value_preview_box->add_theme_style_override("panel", panel_style); + audio_value_preview_box->add_theme_style_override("panel", get_theme_stylebox("panel", "TooltipPanel")); audio_value_preview_box->set_mouse_filter(MOUSE_FILTER_PASS); audio_value_preview_box->hide(); @@ -925,7 +936,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { bus_options->set_shortcut_context(this); bus_options->set_h_size_flags(SIZE_SHRINK_END); bus_options->set_anchor(SIDE_RIGHT, 0.0); - bus_options->set_tooltip(TTR("Bus options")); + bus_options->set_tooltip(TTR("Bus Options")); hbc->add_child(bus_options); bus_popup = bus_options->get_popup(); @@ -1400,7 +1411,7 @@ void EditorAudioMeterNotches::_bind_methods() { void EditorAudioMeterNotches::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - notch_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(0, 0, 0); + notch_color = get_theme_color("font_color", "Editor"); } break; case NOTIFICATION_DRAW: { _draw_audio_notches(); @@ -1416,13 +1427,13 @@ void EditorAudioMeterNotches::_draw_audio_notches() { for (int i = 0; i < notches.size(); i++) { AudioNotch n = notches[i]; draw_line(Vector2(0, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding), - Vector2(line_length, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding), + Vector2(line_length * EDSCALE, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding), notch_color, - 1); + Math::round(EDSCALE)); if (n.render_db_value) { draw_string(font, - Vector2(line_length + label_space, + Vector2((line_length + label_space) * EDSCALE, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + (font_height / 4) + top_padding), String::num(Math::abs(n.db_value)) + "dB", HALIGN_LEFT, -1, font_size, @@ -1432,5 +1443,5 @@ void EditorAudioMeterNotches::_draw_audio_notches() { } EditorAudioMeterNotches::EditorAudioMeterNotches() { - notch_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(0, 0, 0); + notch_color = get_theme_color("font_color", "Editor"); } diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index 8dfc2137ef..0fbda8ece9 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -243,10 +243,10 @@ private: List<AudioNotch> notches; public: - float line_length = 5.0f; - float label_space = 2.0f; - float btm_padding = 9.0f; - float top_padding = 5.0f; + const float line_length = 5.0f; + const float label_space = 2.0f; + const float btm_padding = 9.0f; + const float top_padding = 5.0f; Color notch_color; void add_notch(float p_normalized_offset, float p_db_value, bool p_render_value = false); diff --git a/editor/editor_builders.py b/editor/editor_builders.py index 86c5c87a68..ff0daa86ff 100644 --- a/editor/editor_builders.py +++ b/editor/editor_builders.py @@ -53,7 +53,7 @@ def make_fonts_header(target, source, env): g.write("#ifndef _EDITOR_FONTS_H\n") g.write("#define _EDITOR_FONTS_H\n") - # saving uncompressed, since freetype will reference from memory pointer + # Saving uncompressed, since FreeType will reference from memory pointer. for i in range(len(source)): with open(source[i], "rb") as f: buf = f.read() diff --git a/editor/editor_data.h b/editor/editor_data.h index 2ece94d6a3..df6ba9d0c9 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -167,7 +167,7 @@ public: EditorPlugin *get_editor_plugin(int p_idx); UndoRedo &get_undo_redo(); - void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks shoud have 4 args: (Object* undo_redo, Object *modified_object, String property, Varian new_value) + void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks should have 4 args: (Object* undo_redo, Object *modified_object, String property, Variant new_value) void remove_undo_redo_inspector_hook_callback(Callable p_callable); const Vector<Callable> get_undo_redo_inspector_hook_callback(); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index a368a9618e..40313fbeff 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1065,7 +1065,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } } else { // Use default text server data. - String icu_data_file = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_icu_data"); + String icu_data_file = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_icu_data"); TS->save_support_data(icu_data_file); Vector<uint8_t> array = FileAccess::get_file_as_array(icu_data_file); err = p_func(p_udata, ts_data, array, idx, total, enc_in_filters, enc_ex_filters, key); @@ -1078,7 +1078,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } String config_file = "project.binary"; - String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file); + String engine_cfb = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp" + config_file); ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list); Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); DirAccess::remove_file_or_error(engine_cfb); @@ -1100,9 +1100,9 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c // Create the temporary export directory if it doesn't exist. DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->make_dir_recursive(EditorSettings::get_singleton()->get_cache_dir()); + da->make_dir_recursive(EditorPaths::get_singleton()->get_cache_dir()); - String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp"); + String tmppath = EditorPaths::get_singleton()->get_cache_dir().plus_file("packtmp"); FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE); ERR_FAIL_COND_V_MSG(!ftmp, ERR_CANT_CREATE, "Cannot create file '" + tmppath + "'."); @@ -1222,12 +1222,12 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c } for (int i = 0; i < pd.file_ofs.size(); i++) { - int string_len = pd.file_ofs[i].path_utf8.length(); - int pad = _get_pad(4, string_len); + uint32_t string_len = pd.file_ofs[i].path_utf8.length(); + uint32_t pad = _get_pad(4, string_len); fhead->store_32(string_len + pad); fhead->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len); - for (int j = 0; j < pad; j++) { + for (uint32_t j = 0; j < pad; j++) { fhead->store_8(0); } @@ -1269,8 +1269,8 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c uint8_t buf[bufsize]; while (true) { - int got = ftmp->get_buffer(buf, bufsize); - if (got <= 0) { + uint64_t got = ftmp->get_buffer(buf, bufsize); + if (got == 0) { break; } f->store_buffer(buf, got); @@ -1280,13 +1280,13 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c if (p_embed) { // Ensure embedded data ends at a 64-bit multiple - int64_t embed_end = f->get_position() - embed_pos + 12; - int pad = embed_end % 8; - for (int i = 0; i < pad; i++) { + uint64_t embed_end = f->get_position() - embed_pos + 12; + uint64_t pad = embed_end % 8; + for (uint64_t i = 0; i < pad; i++) { f->store_8(0); } - int64_t pck_size = f->get_position() - pck_start_pos; + uint64_t pck_size = f->get_position() - pck_start_pos; f->store_64(pck_size); f->store_32(PACK_HEADER_MAGIC); @@ -1984,7 +1984,7 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con if (!convert) { return; } - String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); + String tmp_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); if (err != OK) { DirAccess::remove_file_or_error(tmp_path); diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index bd00d86ec8..d232153206 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -46,6 +46,16 @@ const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = { TTRC("Import Dock"), }; +const char *EditorFeatureProfile::feature_descriptions[FEATURE_MAX] = { + TTRC("Allows to view and edit 3D scenes."), + TTRC("Allows to edit scripts using the integrated script editor."), + TTRC("Provides built-in access to the Asset Library."), + TTRC("Allows editing the node hierarchy in the Scene dock."), + TTRC("Allows to work with signals and groups of the node selected in the Scene dock."), + TTRC("Allows to browse the local file system via a dedicated dock."), + TTRC("Allows to configure import settings for individual assets. Requires the FileSystem dock to function."), +}; + const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { "3d", "script", @@ -118,6 +128,18 @@ bool EditorFeatureProfile::has_class_properties_disabled(const StringName &p_cla return disabled_properties.has(p_class); } +void EditorFeatureProfile::set_item_collapsed(const StringName &p_class, bool p_collapsed) { + if (p_collapsed) { + collapsed_classes.insert(p_class); + } else { + collapsed_classes.erase(p_class); + } +} + +bool EditorFeatureProfile::is_item_collapsed(const StringName &p_class) const { + return collapsed_classes.has(p_class); +} + void EditorFeatureProfile::set_disable_feature(Feature p_feature, bool p_disable) { ERR_FAIL_INDEX(p_feature, FEATURE_MAX); features_disabled[p_feature] = p_disable; @@ -133,6 +155,11 @@ String EditorFeatureProfile::get_feature_name(Feature p_feature) { return feature_names[p_feature]; } +String EditorFeatureProfile::get_feature_description(Feature p_feature) { + ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, String()); + return feature_descriptions[p_feature]; +} + Error EditorFeatureProfile::save_to_file(const String &p_path) { Dictionary json; json["type"] = "feature_profile"; @@ -406,7 +433,7 @@ void EditorFeatureProfileManager::_profile_action(int p_action) { export_profile->set_current_file(_get_selected_profile() + ".profile"); } break; case PROFILE_NEW: { - new_profile_dialog->popup_centered(); + new_profile_dialog->popup_centered(Size2(240, 60) * EDSCALE); new_profile_name->clear(); new_profile_name->grab_focus(); } break; @@ -414,8 +441,8 @@ void EditorFeatureProfileManager::_profile_action(int p_action) { String selected = _get_selected_profile(); ERR_FAIL_COND(selected == String()); - erase_profile_dialog->set_text(vformat(TTR("Erase profile '%s'? (no undo)"), selected)); - erase_profile_dialog->popup_centered(); + erase_profile_dialog->set_text(vformat(TTR("Remove currently selected profile, '%s'? Cannot be undone."), selected)); + erase_profile_dialog->popup_centered(Size2(240, 60) * EDSCALE); } break; } } @@ -484,6 +511,9 @@ void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const S class_item->set_selectable(0, true); class_item->set_metadata(0, p_class); + bool collapsed = edited->is_item_collapsed(p_class); + class_item->set_collapsed(collapsed); + if (p_class == p_selected) { class_item->select(0); } @@ -520,12 +550,28 @@ void EditorFeatureProfileManager::_class_list_item_selected() { } Variant md = item->get_metadata(0); - if (md.get_type() != Variant::STRING && md.get_type() != Variant::STRING_NAME) { + if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) { + String class_name = md; + String class_description; + + DocTools *dd = EditorHelp::get_doc_data(); + Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(class_name); + if (E) { + class_description = DTR(E->get().brief_description); + } + + description_bit->set_text(class_description); + } else if (md.get_type() == Variant::INT) { + int feature_id = md; + String feature_description = EditorFeatureProfile::get_feature_description(EditorFeatureProfile::Feature(feature_id)); + + description_bit->set_text(feature_description); + return; + } else { return; } String class_name = md; - if (edited->is_class_disabled(class_name)) { return; } @@ -545,27 +591,28 @@ void EditorFeatureProfileManager::_class_list_item_selected() { option->set_metadata(0, CLASS_OPTION_DISABLE_EDITOR); } - TreeItem *properties = property_list->create_item(root); - properties->set_text(0, TTR("Enabled Properties:")); - List<PropertyInfo> props; - ClassDB::get_property_list(class_name, &props, true); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String name = E->get().name; - if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) { - continue; + if (props.size() > 0) { + TreeItem *properties = property_list->create_item(root); + properties->set_text(0, TTR("Class Properties:")); + + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + String name = E->get().name; + if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) { + continue; + } + TreeItem *property = property_list->create_item(properties); + property->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + property->set_editable(0, true); + property->set_selectable(0, true); + property->set_checked(0, !edited->is_class_property_disabled(class_name, name)); + property->set_text(0, name.capitalize()); + property->set_metadata(0, name); + String icon_type = Variant::get_type_name(E->get().type); + property->set_icon(0, EditorNode::get_singleton()->get_class_icon(icon_type)); } - TreeItem *property = property_list->create_item(properties); - property->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - property->set_editable(0, true); - property->set_selectable(0, true); - property->set_checked(0, !edited->is_class_property_disabled(class_name, name)); - property->set_text(0, name.capitalize()); - property->set_metadata(0, name); - String icon_type = Variant::get_type_name(E->get().type); - property->set_icon(0, EditorNode::get_singleton()->get_class_icon(icon_type)); } updating_features = false; @@ -596,6 +643,26 @@ void EditorFeatureProfileManager::_class_list_item_edited() { } } +void EditorFeatureProfileManager::_class_list_item_collapsed(Object *p_item) { + if (updating_features) { + return; + } + + TreeItem *item = Object::cast_to<TreeItem>(p_item); + if (!item) { + return; + } + + Variant md = item->get_metadata(0); + if (md.get_type() != Variant::STRING && md.get_type() != Variant::STRING_NAME) { + return; + } + + String class_name = md; + bool collapsed = item->is_collapsed(); + edited->set_item_collapsed(class_name, collapsed); +} + void EditorFeatureProfileManager::_property_item_edited() { if (updating_features) { return; @@ -675,7 +742,7 @@ void EditorFeatureProfileManager::_update_selected_profile() { TreeItem *features = class_list->create_item(root); TreeItem *last_feature; - features->set_text(0, TTR("Enabled Features:")); + features->set_text(0, TTR("Main Features") + ":"); for (int i = 0; i < EditorFeatureProfile::FEATURE_MAX; i++) { TreeItem *feature; if (i == EditorFeatureProfile::FEATURE_IMPORT_DOCK) { @@ -699,7 +766,7 @@ void EditorFeatureProfileManager::_update_selected_profile() { } TreeItem *classes = class_list->create_item(root); - classes->set_text(0, TTR("Enabled Classes:")); + classes->set_text(0, TTR("Nodes and Classes") + ":"); _fill_classes_from(classes, "Node", class_selected); _fill_classes_from(classes, "Resource", class_selected); @@ -797,47 +864,51 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { current_profile_name->set_text(TTR("(none)")); current_profile_name->set_editable(false); current_profile_name->set_h_size_flags(Control::SIZE_EXPAND_FILL); - profile_actions[PROFILE_CLEAR] = memnew(Button(TTR("Unset"))); + profile_actions[PROFILE_CLEAR] = memnew(Button(TTR("Reset to Default"))); name_hbc->add_child(profile_actions[PROFILE_CLEAR]); profile_actions[PROFILE_CLEAR]->set_disabled(true); profile_actions[PROFILE_CLEAR]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_CLEAR)); main_vbc->add_margin_child(TTR("Current Profile:"), name_hbc); + main_vbc->add_child(memnew(HSeparator)); + HBoxContainer *profiles_hbc = memnew(HBoxContainer); profile_list = memnew(OptionButton); profile_list->set_h_size_flags(Control::SIZE_EXPAND_FILL); profiles_hbc->add_child(profile_list); profile_list->connect("item_selected", callable_mp(this, &EditorFeatureProfileManager::_profile_selected)); - profile_actions[PROFILE_SET] = memnew(Button(TTR("Make Current"))); - profiles_hbc->add_child(profile_actions[PROFILE_SET]); - profile_actions[PROFILE_SET]->set_disabled(true); - profile_actions[PROFILE_SET]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_SET)); + profile_actions[PROFILE_NEW] = memnew(Button(TTR("Create Profile"))); + profiles_hbc->add_child(profile_actions[PROFILE_NEW]); + profile_actions[PROFILE_NEW]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_NEW)); - profile_actions[PROFILE_ERASE] = memnew(Button(TTR("Remove"))); + profile_actions[PROFILE_ERASE] = memnew(Button(TTR("Remove Profile"))); profiles_hbc->add_child(profile_actions[PROFILE_ERASE]); profile_actions[PROFILE_ERASE]->set_disabled(true); profile_actions[PROFILE_ERASE]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_ERASE)); - profiles_hbc->add_child(memnew(VSeparator)); + main_vbc->add_margin_child(TTR("Available Profiles:"), profiles_hbc); - profile_actions[PROFILE_NEW] = memnew(Button(TTR("New"))); - profiles_hbc->add_child(profile_actions[PROFILE_NEW]); - profile_actions[PROFILE_NEW]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_NEW)); + HBoxContainer *current_profile_hbc = memnew(HBoxContainer); - profiles_hbc->add_child(memnew(VSeparator)); + profile_actions[PROFILE_SET] = memnew(Button(TTR("Make Current"))); + current_profile_hbc->add_child(profile_actions[PROFILE_SET]); + profile_actions[PROFILE_SET]->set_disabled(true); + profile_actions[PROFILE_SET]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_SET)); + + current_profile_hbc->add_child(memnew(VSeparator)); profile_actions[PROFILE_IMPORT] = memnew(Button(TTR("Import"))); - profiles_hbc->add_child(profile_actions[PROFILE_IMPORT]); + current_profile_hbc->add_child(profile_actions[PROFILE_IMPORT]); profile_actions[PROFILE_IMPORT]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_IMPORT)); profile_actions[PROFILE_EXPORT] = memnew(Button(TTR("Export"))); - profiles_hbc->add_child(profile_actions[PROFILE_EXPORT]); + current_profile_hbc->add_child(profile_actions[PROFILE_EXPORT]); profile_actions[PROFILE_EXPORT]->set_disabled(true); profile_actions[PROFILE_EXPORT]->connect("pressed", callable_mp(this, &EditorFeatureProfileManager::_profile_action), varray(PROFILE_EXPORT)); - main_vbc->add_margin_child(TTR("Available Profiles:"), profiles_hbc); + main_vbc->add_child(current_profile_hbc); h_split = memnew(HSplitContainer); h_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); @@ -848,11 +919,12 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { class_list_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); class_list = memnew(Tree); - class_list_vbc->add_margin_child(TTR("Enabled Classes:"), class_list, true); + class_list_vbc->add_margin_child(TTR("Configure Selected Profile") + ":", class_list, true); class_list->set_hide_root(true); class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); class_list->connect("cell_selected", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_selected)); class_list->connect("item_edited", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_edited), varray(), CONNECT_DEFERRED); + class_list->connect("item_collapsed", callable_mp(this, &EditorFeatureProfileManager::_class_list_item_collapsed)); // It will be displayed once the user creates or chooses a profile. class_list_vbc->hide(); @@ -860,8 +932,12 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { h_split->add_child(property_list_vbc); property_list_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + description_bit = memnew(EditorHelpBit); + property_list_vbc->add_margin_child(TTR("Description") + ":", description_bit, false); + description_bit->set_custom_minimum_size(Size2(0, 80) * EDSCALE); + property_list = memnew(Tree); - property_list_vbc->add_margin_child(TTR("Class Options:"), property_list, true); + property_list_vbc->add_margin_child(TTR("Extra Options") + ":", property_list, true); property_list->set_hide_root(true); property_list->set_hide_folding(true); property_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); @@ -879,9 +955,14 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { h_split->add_child(no_profile_selected_help); new_profile_dialog = memnew(ConfirmationDialog); - new_profile_dialog->set_title(TTR("New profile name:")); + new_profile_dialog->set_title(TTR("Create Profile")); + VBoxContainer *new_profile_vb = memnew(VBoxContainer); + new_profile_dialog->add_child(new_profile_vb); + Label *new_profile_label = memnew(Label); + new_profile_label->set_text(TTR("New profile name") + ":"); + new_profile_vb->add_child(new_profile_label); new_profile_name = memnew(LineEdit); - new_profile_dialog->add_child(new_profile_name); + new_profile_vb->add_child(new_profile_name); new_profile_name->set_custom_minimum_size(Size2(300 * EDSCALE, 1)); add_child(new_profile_dialog); new_profile_dialog->connect("confirmed", callable_mp(this, &EditorFeatureProfileManager::_create_new_profile)); @@ -890,7 +971,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() { erase_profile_dialog = memnew(ConfirmationDialog); add_child(erase_profile_dialog); - erase_profile_dialog->set_title(TTR("Erase Profile")); + erase_profile_dialog->set_title(TTR("Remove Profile")); erase_profile_dialog->connect("confirmed", callable_mp(this, &EditorFeatureProfileManager::_erase_selected_profile)); import_profiles = memnew(EditorFileDialog); diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h index 01e6a6a142..e118b5f287 100644 --- a/editor/editor_feature_profile.h +++ b/editor/editor_feature_profile.h @@ -34,6 +34,7 @@ #include "core/object/reference.h" #include "core/os/file_access.h" #include "editor/editor_file_dialog.h" +#include "editor_help.h" #include "scene/gui/dialogs.h" #include "scene/gui/option_button.h" #include "scene/gui/separator.h" @@ -60,8 +61,11 @@ private: Set<StringName> disabled_editors; Map<StringName, Set<StringName>> disabled_properties; + Set<StringName> collapsed_classes; + bool features_disabled[FEATURE_MAX]; static const char *feature_names[FEATURE_MAX]; + static const char *feature_descriptions[FEATURE_MAX]; static const char *feature_identifiers[FEATURE_MAX]; String _get_feature_name(Feature p_feature) { return get_feature_name(p_feature); } @@ -80,6 +84,9 @@ public: bool is_class_property_disabled(const StringName &p_class, const StringName &p_property) const; bool has_class_properties_disabled(const StringName &p_class) const; + void set_item_collapsed(const StringName &p_class, bool p_collapsed); + bool is_item_collapsed(const StringName &p_class) const; + void set_disable_feature(Feature p_feature, bool p_disable); bool is_feature_disabled(Feature p_feature) const; @@ -87,6 +94,7 @@ public: Error load_from_file(const String &p_path); static String get_feature_name(Feature p_feature); + static String get_feature_description(Feature p_feature); EditorFeatureProfile(); }; @@ -124,6 +132,7 @@ class EditorFeatureProfileManager : public AcceptDialog { Tree *class_list; VBoxContainer *property_list_vbc; Tree *property_list; + EditorHelpBit *description_bit; Label *no_profile_selected_help; EditorFileDialog *import_profiles; @@ -151,6 +160,7 @@ class EditorFeatureProfileManager : public AcceptDialog { void _class_list_item_selected(); void _class_list_item_edited(); + void _class_list_item_collapsed(Object *p_item); void _property_item_edited(); void _save_and_update(); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 495bdd42f7..69663b9ed9 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -506,7 +506,7 @@ bool EditorFileSystem::_update_scan_actions() { case ItemAction::ACTION_DIR_ADD: { int idx = 0; for (int i = 0; i < ia.dir->subdirs.size(); i++) { - if (ia.new_dir->name < ia.dir->subdirs[i]->name) { + if (ia.new_dir->name.naturalnocasecmp_to(ia.dir->subdirs[i]->name) < 0) { break; } idx++; @@ -528,7 +528,7 @@ bool EditorFileSystem::_update_scan_actions() { case ItemAction::ACTION_FILE_ADD: { int idx = 0; for (int i = 0; i < ia.dir->files.size(); i++) { - if (ia.new_file->file < ia.dir->files[i]->file) { + if (ia.new_file->file.naturalnocasecmp_to(ia.dir->files[i]->file) < 0) { break; } idx++; @@ -713,7 +713,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess int idx2 = 0; for (int i = 0; i < p_dir->subdirs.size(); i++) { - if (efd->name < p_dir->subdirs[i]->name) { + if (efd->name.naturalnocasecmp_to(p_dir->subdirs[i]->name) < 0) { break; } idx2++; @@ -1245,7 +1245,7 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector int idx2 = 0; for (int j = 0; j < fs->get_subdir_count(); j++) { - if (efsd->name < fs->get_subdir(j)->get_name()) { + if (efsd->name.naturalnocasecmp_to(fs->get_subdir(j)->get_name()) < 0) { break; } idx2++; @@ -1481,7 +1481,7 @@ void EditorFileSystem::update_file(const String &p_file) { String file_name = p_file.get_file(); for (int i = 0; i < fs->files.size(); i++) { - if (file_name < fs->files[i]->file) { + if (p_file.naturalnocasecmp_to(fs->files[i]->file) < 0) { break; } idx++; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 6039f64b7c..9361981db6 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -475,7 +475,7 @@ void EditorHelp::_update_doc() { String linktxt = (cd.tutorials[i].title.is_empty()) ? link : DTR(cd.tutorials[i].title); const int seppos = linktxt.find("//"); if (seppos != -1) { - linktxt = link.right(seppos + 2); + linktxt = link.substr(seppos + 2); } class_desc->push_color(symbol_color); @@ -1593,7 +1593,7 @@ void EditorHelp::_notification(int p_what) { _update_doc(); } break; case NOTIFICATION_THEME_CHANGED: { - if (is_visible_in_tree()) { + if (is_inside_tree()) { _class_desc_resized(); } } break; diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 23226ffa9b..b93ffa9321 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -334,7 +334,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() { for (int i = 0; i < class_doc.methods.size(); i++) { String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); if (method_name.find(term) > -1 || - (term.begins_with(".") && method_name.begins_with(term.right(1))) || + (term.begins_with(".") && method_name.begins_with(term.substr(1))) || (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i])); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 5bb3c8b4d0..f869031446 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -741,7 +741,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { if (use_keying_next()) { if (property == "frame_coords" && (object->is_class("Sprite2D") || object->is_class("Sprite3D"))) { - Vector2 new_coords = object->get(property); + Vector2i new_coords = object->get(property); new_coords.x++; if (new_coords.x >= object->get("hframes").operator int64_t()) { new_coords.x = 0; @@ -1626,7 +1626,7 @@ void EditorInspector::update_tree() { bool draw_red = false; - { + if (is_inside_tree()) { Node *nod = Object::cast_to<Node>(object); Node *es = EditorNode::get_singleton()->get_edited_scene(); if (nod && es != nod && nod->get_owner() != es) { @@ -1809,12 +1809,12 @@ void EditorInspector::update_tree() { basename = group + "/" + basename; } - String name = (basename.find("/") != -1) ? basename.right(basename.rfind("/") + 1) : basename; + String name = (basename.find("/") != -1) ? basename.substr(basename.rfind("/") + 1) : basename; if (capitalize_paths) { int dot = name.find("."); if (dot != -1) { - String ov = name.right(dot); + String ov = name.substr(dot); name = name.substr(0, dot); name = name.capitalize(); name += ov; @@ -1824,7 +1824,13 @@ void EditorInspector::update_tree() { } } - String path = basename.left(basename.rfind("/")); + String path; + { + int idx = basename.rfind("/"); + if (idx > -1) { + path = basename.left(idx); + } + } if (use_filter && filter != "") { String cat = path; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 7c485d53c5..35d8021394 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -234,8 +234,9 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) { if (p_replace_previous) { // Remove last line if replacing, as it will be replace by the next added line. - log->remove_line(log->get_line_count() - 1); - log->increment_line_count(); + // Why "- 2"? RichTextLabel is weird. When you add a line with add_newline(), it also adds an element to the list of lines which is null/blank, + // but it still counts as a line. So if you remove the last line (count - 1) you are actually removing nothing... + log->remove_line(log->get_paragraph_count() - 2); } switch (p_message.type) { @@ -269,13 +270,14 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) { } log->add_text(p_message.text); - log->add_newline(); // Need to use pop() to exit out of the RichTextLabels current "push" stack. // We only "push" in the above switch when message type != STD, so only pop when that is the case. if (p_message.type != MSG_TYPE_STD) { log->pop(); } + + log->add_newline(); } void EditorLog::_set_filter_active(bool p_active, MessageType p_message_type) { @@ -376,7 +378,7 @@ EditorLog::EditorLog() { collapse_button = memnew(Button); collapse_button->set_flat(true); collapse_button->set_focus_mode(FOCUS_NONE); - collapse_button->set_tooltip(TTR("Collapse duplicate messages into one log entry. Shows number of occurences.")); + collapse_button->set_tooltip(TTR("Collapse duplicate messages into one log entry. Shows number of occurrences.")); collapse_button->set_toggle_mode(true); collapse_button->set_pressed(false); collapse_button->connect("toggled", callable_mp(this, &EditorLog::_set_collapse)); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 7aed5b2b7f..aa632b90ad 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -80,8 +80,10 @@ #include "editor/editor_inspector.h" #include "editor/editor_layouts_dialog.h" #include "editor/editor_log.h" +#include "editor/editor_paths.h" #include "editor/editor_plugin.h" #include "editor/editor_properties.h" +#include "editor/editor_resource_picker.h" #include "editor/editor_resource_preview.h" #include "editor/editor_run_native.h" #include "editor/editor_run_script.h" @@ -628,7 +630,7 @@ void EditorNode::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); - theme = create_editor_theme(theme_base->get_theme()); + theme = create_custom_theme(theme_base->get_theme()); theme_base->set_theme(theme); gui_base->set_theme(theme); @@ -699,11 +701,11 @@ void EditorNode::_notification(int p_what) { p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_theme_icon("HelpSearch", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_DOCS), gui_base->get_theme_icon("Instance", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_QA), gui_base->get_theme_icon("Instance", "EditorIcons")); - p->set_item_icon(p->get_item_index(HELP_ABOUT), gui_base->get_theme_icon("Godot", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_REPORT_A_BUG), gui_base->get_theme_icon("Instance", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_SEND_DOCS_FEEDBACK), gui_base->get_theme_icon("Instance", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_COMMUNITY), gui_base->get_theme_icon("Instance", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_ABOUT), gui_base->get_theme_icon("Godot", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), gui_base->get_theme_icon("Heart", "EditorIcons")); _update_update_spinner(); } break; @@ -738,6 +740,18 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam push_item(script.operator->()); } +void EditorNode::_remove_plugin_from_enabled(const String &p_name) { + ProjectSettings *ps = ProjectSettings::get_singleton(); + PackedStringArray enabled_plugins = ps->get("editor_plugins/enabled"); + for (int i = 0; i < enabled_plugins.size(); ++i) { + if (enabled_plugins.get(i) == p_name) { + enabled_plugins.remove(i); + break; + } + } + ps->set("editor_plugins/enabled", enabled_plugins); +} + void EditorNode::_resources_changed(const Vector<String> &p_resources) { List<Ref<Resource>> changed; @@ -1444,7 +1458,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { img->convert(Image::FORMAT_RGB8); //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5 - String temp_path = EditorSettings::get_singleton()->get_cache_dir(); + String temp_path = EditorPaths::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); @@ -2732,10 +2746,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { settings_config_dialog->popup_edit_settings(); } break; case SETTINGS_EDITOR_DATA_FOLDER: { - OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_data_dir()); + OS::get_singleton()->shell_open(String("file://") + EditorPaths::get_singleton()->get_data_dir()); } break; case SETTINGS_EDITOR_CONFIG_FOLDER: { - OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_settings_dir()); + OS::get_singleton()->shell_open(String("file://") + EditorPaths::get_singleton()->get_settings_dir()); } break; case SETTINGS_MANAGE_EXPORT_TEMPLATES: { export_template_manager->popup_manager(); @@ -2794,6 +2808,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case HELP_ABOUT: { about->popup_centered(Size2(780, 500) * EDSCALE); } break; + case HELP_SUPPORT_GODOT_DEVELOPMENT: { + OS::get_singleton()->shell_open("https://godotengine.org/donate"); + } break; case SET_VIDEO_DRIVER_SAVE_AND_RESTART: { ProjectSettings::get_singleton()->set("rendering/driver/driver_name", video_driver_request); @@ -2876,7 +2893,7 @@ void EditorNode::_exit_editor() { _save_docks(); // Dim the editor window while it's quitting to make it clearer that it's busy - dim_editor(true, true); + dim_editor(true); get_tree()->quit(); } @@ -3078,10 +3095,11 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_chan if (p_config_changed) { p_editor->disable_plugin(); } - singleton->editor_plugins_over->get_plugins_list().erase(p_editor); + singleton->editor_plugins_over->remove_plugin(p_editor); + singleton->editor_plugins_force_over->remove_plugin(p_editor); + singleton->editor_plugins_force_input_forwarding->remove_plugin(p_editor); singleton->remove_child(p_editor); singleton->editor_data.remove_editor_plugin(p_editor); - singleton->get_editor_plugins_force_input_forwarding()->remove_plugin(p_editor); } void EditorNode::_update_addon_config() { @@ -3120,16 +3138,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, Ref<ConfigFile> cf; cf.instance(); if (!DirAccess::exists(p_addon.get_base_dir())) { - ProjectSettings *ps = ProjectSettings::get_singleton(); - PackedStringArray enabled_plugins = ps->get("editor_plugins/enabled"); - for (int i = 0; i < enabled_plugins.size(); ++i) { - if (enabled_plugins.get(i) == p_addon) { - enabled_plugins.remove(i); - break; - } - } - ps->set("editor_plugins/enabled", enabled_plugins); - ps->save(); + _remove_plugin_from_enabled(p_addon); WARN_PRINT("Addon '" + p_addon + "' failed to load. No directory found. Removing from enabled plugins."); return; } @@ -3159,7 +3168,8 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, // Errors in the script cause the base_type to be an empty string. if (String(script->get_instance_base_type()) == "") { - show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), script_path)); + show_warning(vformat(TTR("Unable to load addon script from path: '%s'. This might be due to a code error in that script.\nDisabling the addon at '%s' to prevent further errors."), script_path, p_addon)); + _remove_plugin_from_enabled(p_addon); return; } @@ -3718,10 +3728,15 @@ bool EditorNode::is_scene_in_use(const String &p_path) { return false; } +void EditorNode::register_editor_paths(bool p_for_project_manager) { + EditorPaths::create(p_for_project_manager); +} + void EditorNode::register_editor_types() { ResourceLoader::set_timestamp_on_load(true); ResourceSaver::set_timestamp_on_save(true); + ClassDB::register_class<EditorPaths>(); ClassDB::register_class<EditorPlugin>(); ClassDB::register_class<EditorTranslationParserPlugin>(); ClassDB::register_class<EditorImportPlugin>(); @@ -3750,6 +3765,8 @@ void EditorNode::register_editor_types() { ClassDB::register_class<ScriptCreateDialog>(); ClassDB::register_class<EditorFeatureProfile>(); ClassDB::register_class<EditorSpinSlider>(); + ClassDB::register_class<EditorResourcePicker>(); + ClassDB::register_class<EditorScriptPicker>(); ClassDB::register_class<EditorSceneImporterMesh>(); ClassDB::register_class<EditorSceneImporterMeshNode3D>(); @@ -3763,6 +3780,9 @@ void EditorNode::register_editor_types() { void EditorNode::unregister_editor_types() { _init_callbacks.clear(); + if (EditorPaths::get_singleton()) { + EditorPaths::free(); + } } void EditorNode::stop_child_process(OS::ProcessID p_pid) { @@ -5281,7 +5301,7 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) { void EditorNode::reload_scene(const String &p_path) { /* - * No longer necesary since scenes now reset and reload their internal resource if needed. + * No longer necessary since scenes now reset and reload their internal resource if needed. //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk List<Ref<Resource>> cached; @@ -5385,15 +5405,9 @@ void EditorNode::_open_imported() { load_scene(open_import_request, true, false, true, true); } -void EditorNode::dim_editor(bool p_dimming, bool p_force_dim) { - // Dimming can be forced regardless of the editor setting, which is useful when quitting the editor. - if ((p_force_dim || EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup")) && p_dimming) { - dimmed = true; - gui_base->set_modulate(Color(0.5, 0.5, 0.5)); - } else { - dimmed = false; - gui_base->set_modulate(Color(1, 1, 1)); - } +void EditorNode::dim_editor(bool p_dimming) { + dimmed = p_dimming; + gui_base->set_modulate(p_dimming ? Color(0.5, 0.5, 0.5) : Color(1, 1, 1)); } bool EditorNode::is_editor_dimmed() const { @@ -6367,13 +6381,14 @@ EditorNode::EditorNode() { p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1), HELP_SEARCH); #endif p->add_separator(); - p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Docs")), HELP_DOCS); - p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/q&a", TTR("Q&A")), HELP_QA); + p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Documentation")), HELP_DOCS); + p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/q&a", TTR("Questions & Answers")), HELP_QA); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/report_a_bug", TTR("Report a Bug")), HELP_REPORT_A_BUG); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/send_docs_feedback", TTR("Send Docs Feedback")), HELP_SEND_DOCS_FEEDBACK); p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/community", TTR("Community")), HELP_COMMUNITY); p->add_separator(); - p->add_icon_shortcut(gui_base->get_theme_icon("Godot", "EditorIcons"), ED_SHORTCUT("editor/about", TTR("About")), HELP_ABOUT); + p->add_icon_shortcut(gui_base->get_theme_icon("Godot", "EditorIcons"), ED_SHORTCUT("editor/about", TTR("About Godot")), HELP_ABOUT); + p->add_icon_shortcut(gui_base->get_theme_icon("Heart", "EditorIcons"), ED_SHORTCUT("editor/support_development", TTR("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT); HBoxContainer *play_hb = memnew(HBoxContainer); menu_hb->add_child(play_hb); diff --git a/editor/editor_node.h b/editor/editor_node.h index 07de183719..9625b318e0 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -196,6 +196,7 @@ private: HELP_SEND_DOCS_FEEDBACK, HELP_COMMUNITY, HELP_ABOUT, + HELP_SUPPORT_GODOT_DEVELOPMENT, SET_VIDEO_DRIVER_SAVE_AND_RESTART, @@ -460,6 +461,7 @@ private: void _update_file_menu_closed(); void _on_plugin_ready(Object *p_script, const String &p_activate_name); + void _remove_plugin_from_enabled(const String &p_name); void _fs_changed(); void _resources_reimported(const Vector<String> &p_resources); @@ -796,6 +798,7 @@ public: Error export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only); + static void register_editor_paths(bool p_for_project_manager); static void register_editor_types(); static void unregister_editor_types(); @@ -853,7 +856,7 @@ public: void notify_settings_changed(); - void dim_editor(bool p_dimming, bool p_force_dim = false); + void dim_editor(bool p_dimming); bool is_editor_dimmed() const; void edit_current() { _edit_current(); }; diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp new file mode 100644 index 0000000000..96469d3143 --- /dev/null +++ b/editor/editor_paths.cpp @@ -0,0 +1,156 @@ +/*************************************************************************/ +/* editor_paths.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_paths.h" +#include "core/os/dir_access.h" +#include "core/os/os.h" + +EditorPaths *EditorPaths::singleton = nullptr; + +bool EditorPaths::are_paths_valid() const { + return paths_valid; +} + +String EditorPaths::get_settings_dir() const { + return settings_dir; +} +String EditorPaths::get_data_dir() const { + return data_dir; +} +String EditorPaths::get_config_dir() const { + return config_dir; +} +String EditorPaths::get_cache_dir() const { + return cache_dir; +} +bool EditorPaths::is_self_contained() const { + return self_contained; +} +String EditorPaths::get_self_contained_file() const { + return self_contained_file; +} + +void EditorPaths::create(bool p_for_project_manager) { + ERR_FAIL_COND(singleton != nullptr); + memnew(EditorPaths(p_for_project_manager)); +} +void EditorPaths::free() { + ERR_FAIL_COND(singleton == nullptr); + memdelete(singleton); +} + +void EditorPaths::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_settings_dir"), &EditorPaths::get_settings_dir); + ClassDB::bind_method(D_METHOD("get_data_dir"), &EditorPaths::get_data_dir); + ClassDB::bind_method(D_METHOD("get_config_dir"), &EditorPaths::get_config_dir); + ClassDB::bind_method(D_METHOD("get_cache_dir"), &EditorPaths::get_cache_dir); + ClassDB::bind_method(D_METHOD("is_self_contained"), &EditorPaths::is_self_contained); + ClassDB::bind_method(D_METHOD("get_self_contained_file"), &EditorPaths::get_self_contained_file); +} + +EditorPaths::EditorPaths(bool p_for_project_mamanger) { + singleton = this; + + String exe_path = OS::get_singleton()->get_executable_path().get_base_dir(); + { + DirAccessRef d = DirAccess::create_for_path(exe_path); + + if (d->file_exists(exe_path + "/._sc_")) { + self_contained = true; + self_contained_file = exe_path + "/._sc_"; + } else if (d->file_exists(exe_path + "/_sc_")) { + self_contained = true; + self_contained_file = exe_path + "/_sc_"; + } + } + + String data_path; + String config_path; + String cache_path; + + if (self_contained) { + // editor is self contained, all in same folder + data_path = exe_path; + data_dir = data_path.plus_file("editor_data"); + config_path = exe_path; + config_dir = data_dir; + cache_path = exe_path; + cache_dir = data_dir.plus_file("cache"); + } else { + // Typically XDG_DATA_HOME or %APPDATA% + data_path = OS::get_singleton()->get_data_path(); + data_dir = data_path.plus_file(OS::get_singleton()->get_godot_dir_name()); + // Can be different from data_path e.g. on Linux or macOS + config_path = OS::get_singleton()->get_config_path(); + config_dir = config_path.plus_file(OS::get_singleton()->get_godot_dir_name()); + // Can be different from above paths, otherwise a subfolder of data_dir + cache_path = OS::get_singleton()->get_cache_path(); + if (cache_path == data_path) { + cache_dir = data_dir.plus_file("cache"); + } else { + cache_dir = cache_path.plus_file(OS::get_singleton()->get_godot_dir_name()); + } + } + + paths_valid = (data_path != "" && config_path != "" && cache_path != ""); + + if (paths_valid) { + DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (dir->change_dir(data_dir) != OK) { + dir->make_dir_recursive(data_dir); + if (dir->change_dir(data_dir) != OK) { + ERR_PRINT("Cannot create data directory!"); + paths_valid = false; + } + } + + // Validate/create cache dir + + if (dir->change_dir(EditorPaths::get_singleton()->get_cache_dir()) != OK) { + dir->make_dir_recursive(cache_dir); + if (dir->change_dir(cache_dir) != OK) { + ERR_PRINT("Cannot create cache directory!"); + } + } + + if (p_for_project_mamanger) { + Engine::get_singleton()->set_shader_cache_path(get_data_dir()); + } else { + DirAccessRef dir2 = DirAccess::open("res://"); + if (dir2->change_dir(".godot") != OK) { //ensure the .godot subdir exists + if (dir2->make_dir(".godot") != OK) { + ERR_PRINT("Cannot create res://.godot directory!"); + } + } + + Engine::get_singleton()->set_shader_cache_path("res://.godot"); + } + } +} diff --git a/platform/javascript/js/libs/library_godot_editor_tools.js b/editor/editor_paths.h index d7f1ad5ea1..096174943d 100644 --- a/platform/javascript/js/libs/library_godot_editor_tools.js +++ b/editor/editor_paths.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* library_godot_editor_tools.js */ +/* editor_paths.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,30 +28,45 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -const GodotEditorTools = { - godot_js_editor_download_file__deps: ['$FS'], - godot_js_editor_download_file__sig: 'viii', - godot_js_editor_download_file: function (p_path, p_name, p_mime) { - const path = GodotRuntime.parseString(p_path); - const name = GodotRuntime.parseString(p_name); - const mime = GodotRuntime.parseString(p_mime); - const size = FS.stat(path)['size']; - const buf = new Uint8Array(size); - const fd = FS.open(path, 'r'); - FS.read(fd, buf, 0, size); - FS.close(fd); - FS.unlink(path); - const blob = new Blob([buf], { type: mime }); - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = name; - a.style.display = 'none'; - document.body.appendChild(a); - a.click(); - a.remove(); - window.URL.revokeObjectURL(url); - }, +#ifndef EDITORPATHS_H +#define EDITORPATHS_H + +#include "core/config/engine.h" + +class EditorPaths : public Object { + GDCLASS(EditorPaths, Object) + + bool paths_valid = false; + String settings_dir; + String data_dir; //editor data dir + String config_dir; //editor config dir + String cache_dir; //editor cache dir + bool self_contained = false; //true if running self contained + String self_contained_file; //self contained file with configuration + + static EditorPaths *singleton; + +protected: + static void _bind_methods(); + +public: + bool are_paths_valid() const; + + String get_settings_dir() const; + String get_data_dir() const; + String get_config_dir() const; + String get_cache_dir() const; + bool is_self_contained() const; + String get_self_contained_file() const; + + static EditorPaths *get_singleton() { + return singleton; + } + + static void create(bool p_for_project_manager); + static void free(); + + EditorPaths(bool p_for_project_mamanger = false); }; -mergeInto(LibraryManager.library, GodotEditorTools); +#endif // EDITORPATHS_H diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 6b96cb0f5c..c5097a17a5 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -32,6 +32,7 @@ #include "editor/editor_export.h" #include "editor/editor_node.h" +#include "editor/editor_paths.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" #include "editor/project_settings_editor.h" @@ -257,6 +258,9 @@ EditorSelection *EditorInterface::get_selection() { Ref<EditorSettings> EditorInterface::get_editor_settings() { return EditorSettings::get_singleton(); } +EditorPaths *EditorInterface::get_editor_paths() { + return EditorPaths::get_singleton(); +} EditorResourcePreview *EditorInterface::get_resource_previewer() { return EditorResourcePreview::get_singleton(); @@ -335,6 +339,7 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_selected_path"), &EditorInterface::get_selected_path); ClassDB::bind_method(D_METHOD("get_current_path"), &EditorInterface::get_current_path); ClassDB::bind_method(D_METHOD("get_file_system_dock"), &EditorInterface::get_file_system_dock); + ClassDB::bind_method(D_METHOD("get_editor_paths"), &EditorInterface::get_editor_paths); ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled); ClassDB::bind_method(D_METHOD("is_plugin_enabled", "plugin"), &EditorInterface::is_plugin_enabled); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 37412e5ebe..3f72e468b2 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -54,6 +54,7 @@ class EditorNode3DGizmoPlugin; class EditorResourcePreview; class EditorFileSystem; class EditorToolAddons; +class EditorPaths; class FileSystemDock; class ScriptEditor; @@ -95,6 +96,7 @@ public: EditorSelection *get_selection(); //EditorImportExport *get_import_export(); Ref<EditorSettings> get_editor_settings(); + EditorPaths *get_editor_paths(); EditorResourcePreview *get_resource_previewer(); EditorFileSystem *get_resource_file_system(); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 6638962c72..7beff4147d 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -951,7 +951,7 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) { const Ref<InputEventMouseMotion> mm = p_ev; - if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { + if (dragging && mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { float rel = mm->get_relative().x; if (rel == 0) { return; @@ -2384,426 +2384,64 @@ EditorPropertyRID::EditorPropertyRID() { ////////////// RESOURCE ////////////////////// -void EditorPropertyResource::_file_selected(const String &p_path) { - RES res = ResourceLoader::load(p_path); - - ERR_FAIL_COND_MSG(res.is_null(), "Cannot load resource from path '" + p_path + "'."); - - List<PropertyInfo> prop_list; - get_edited_object()->get_property_list(&prop_list); - String property_types; - - for (List<PropertyInfo>::Element *E = prop_list.front(); E; E = E->next()) { - if (E->get().name == get_edited_property() && (E->get().hint & PROPERTY_HINT_RESOURCE_TYPE)) { - property_types = E->get().hint_string; - } - } - if (!property_types.is_empty()) { - bool any_type_matches = false; - const Vector<String> split_property_types = property_types.split(","); - for (int i = 0; i < split_property_types.size(); ++i) { - if (res->is_class(split_property_types[i])) { - any_type_matches = true; - break; - } - } - - if (!any_type_matches) { - EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), res->get_class(), property_types)); - } +void EditorPropertyResource::_resource_selected(const RES &p_resource) { + if (use_sub_inspector) { + bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property()); + get_edited_object()->editor_set_section_unfold(get_edited_property(), unfold); + update_property(); + } else { + emit_signal("resource_selected", get_edited_property(), p_resource); } - - emit_changed(get_edited_property(), res); - update_property(); } -void EditorPropertyResource::_menu_option(int p_which) { - //scene_tree->popup_scenetree_dialog(); - switch (p_which) { - case OBJ_MENU_LOAD: { - if (!file) { - file = memnew(EditorFileDialog); - file->connect("file_selected", callable_mp(this, &EditorPropertyResource::_file_selected)); - add_child(file); - } - file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - String type = base_type; - - List<String> extensions; - for (int i = 0; i < type.get_slice_count(","); i++) { - ResourceLoader::get_recognized_extensions_for_type(type.get_slice(",", i), &extensions); - } - - Set<String> valid_extensions; - for (List<String>::Element *E = extensions.front(); E; E = E->next()) { - valid_extensions.insert(E->get()); - } - - file->clear_filters(); - for (Set<String>::Element *E = valid_extensions.front(); E; E = E->next()) { - file->add_filter("*." + E->get() + " ; " + E->get().to_upper()); - } - - file->popup_file_dialog(); - } break; - - case OBJ_MENU_EDIT: { - RES res = get_edited_object()->get(get_edited_property()); +void EditorPropertyResource::_resource_changed(const RES &p_resource) { + // Make visual script the correct type. + Ref<Script> s = p_resource; + if (get_edited_object() && s.is_valid()) { + s->call("set_instance_base_type", get_edited_object()->get_class()); + } - if (!res.is_null()) { - emit_signal("resource_selected", get_edited_property(), res); - } - } break; - case OBJ_MENU_CLEAR: { + // Prevent the creation of invalid ViewportTextures when possible. + Ref<ViewportTexture> vpt = p_resource; + if (vpt.is_valid()) { + Resource *r = Object::cast_to<Resource>(get_edited_object()); + if (r && r->get_path().is_resource_file()) { + EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on resources saved as a file.\nResource needs to belong to a scene.")); emit_changed(get_edited_property(), RES()); update_property(); - - } break; - - case OBJ_MENU_MAKE_UNIQUE: { - RES res_orig = get_edited_object()->get(get_edited_property()); - if (res_orig.is_null()) { - return; - } - - List<PropertyInfo> property_list; - res_orig->get_property_list(&property_list); - List<Pair<String, Variant>> propvalues; - - for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { - Pair<String, Variant> p; - PropertyInfo &pi = E->get(); - if (pi.usage & PROPERTY_USAGE_STORAGE) { - p.first = pi.name; - p.second = res_orig->get(pi.name); - } - - propvalues.push_back(p); - } - - String orig_type = res_orig->get_class(); - - Object *inst = ClassDB::instance(orig_type); - - Ref<Resource> res = Ref<Resource>(Object::cast_to<Resource>(inst)); - - ERR_FAIL_COND(res.is_null()); - - for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { - Pair<String, Variant> &p = E->get(); - res->set(p.first, p.second); - } - - emit_changed(get_edited_property(), res); - update_property(); - - } break; - - case OBJ_MENU_SAVE: { - RES res = get_edited_object()->get(get_edited_property()); - if (res.is_null()) { - return; - } - EditorNode::get_singleton()->save_resource(res); - } break; - - case OBJ_MENU_COPY: { - RES res = get_edited_object()->get(get_edited_property()); - - EditorSettings::get_singleton()->set_resource_clipboard(res); - - } break; - case OBJ_MENU_PASTE: { - RES res = EditorSettings::get_singleton()->get_resource_clipboard(); - emit_changed(get_edited_property(), res); - update_property(); - - } break; - case OBJ_MENU_NEW_SCRIPT: { - if (Object::cast_to<Node>(get_edited_object())) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object()), false); - } - - } break; - case OBJ_MENU_EXTEND_SCRIPT: { - if (Object::cast_to<Node>(get_edited_object())) { - EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object()), true); - } - - } break; - case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { - RES res = get_edited_object()->get(get_edited_property()); - - FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); - file_system_dock->navigate_to_path(res->get_path()); - // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(file_system_dock->get_index()); - } break; - default: { - RES res = get_edited_object()->get(get_edited_property()); - - if (p_which >= CONVERT_BASE_ID) { - int to_type = p_which - CONVERT_BASE_ID; - - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res); - - ERR_FAIL_INDEX(to_type, conversions.size()); - - Ref<Resource> new_res = conversions[to_type]->convert(res); - - emit_changed(get_edited_property(), new_res); - update_property(); - break; - } - ERR_FAIL_COND(inheritors_array.is_empty()); - - String intype = inheritors_array[p_which - TYPE_BASE_ID]; - - if (intype == "ViewportTexture") { - Resource *r = Object::cast_to<Resource>(get_edited_object()); - if (r && r->get_path().is_resource_file()) { - EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on resources saved as a file.\nResource needs to belong to a scene.")); - return; - } - - if (r && !r->is_local_to_scene()) { - EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on this resource because it's not set as local to scene.\nPlease switch on the 'local to scene' property on it (and all resources containing it up to a node).")); - return; - } - - if (!scene_tree) { - scene_tree = memnew(SceneTreeDialog); - Vector<StringName> valid_types; - valid_types.push_back("Viewport"); - scene_tree->get_scene_tree()->set_valid_types(valid_types); - scene_tree->get_scene_tree()->set_show_enabled_subscene(true); - add_child(scene_tree); - scene_tree->connect("selected", callable_mp(this, &EditorPropertyResource::_viewport_selected)); - scene_tree->set_title(TTR("Pick a Viewport")); - } - scene_tree->popup_scenetree_dialog(); - - return; - } - - Variant obj; - - if (ScriptServer::is_global_class(intype)) { - obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype)); - if (obj) { - Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); - if (script.is_valid()) { - ((Object *)obj)->set_script(script); - } - } - } else { - obj = ClassDB::instance(intype); - } - - if (!obj) { - obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); - } - - Resource *resp = Object::cast_to<Resource>(obj); - ERR_BREAK(!resp); - if (get_edited_object() && base_type != String() && base_type == "Script") { - //make visual script the right type - resp->call("set_instance_base_type", get_edited_object()->get_class()); - } - - res = RES(resp); - emit_changed(get_edited_property(), res); - update_property(); - - } break; - } -} - -void EditorPropertyResource::_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj) { - RES p = get_edited_object()->get(get_edited_property()); - if (p.is_valid() && p->get_instance_id() == p_obj) { - String type = p->get_class_name(); - - if (ClassDB::is_parent_class(type, "Script")) { - assign->set_text(p->get_path().get_file()); return; } - if (p_preview.is_valid()) { - preview->set_offset(SIDE_LEFT, assign->get_icon()->get_width() + assign->get_theme_stylebox("normal")->get_default_margin(SIDE_LEFT) + get_theme_constant("hseparation", "Button")); - if (type == "GradientTexture") { - preview->set_stretch_mode(TextureRect::STRETCH_SCALE); - assign->set_custom_minimum_size(Size2(1, 1)); - } else { - preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; - assign->set_custom_minimum_size(Size2(1, thumbnail_size)); - } - preview->set_texture(p_preview); - assign->set_text(""); - } - } -} - -void EditorPropertyResource::_update_menu_items() { - //////////////////// UPDATE MENU ////////////////////////// - RES res = get_edited_object()->get(get_edited_property()); - - menu->clear(); - - if (get_edited_property() == "script" && base_type == "Script" && Object::cast_to<Node>(get_edited_object())) { - menu->add_icon_item(get_theme_icon("ScriptCreate", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); - menu->add_icon_item(get_theme_icon("ScriptExtend", "EditorIcons"), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); - menu->add_separator(); - } else if (base_type != "") { - int idx = 0; - - Vector<EditorData::CustomType> custom_resources; - - if (EditorNode::get_editor_data().get_custom_types().has("Resource")) { - custom_resources = EditorNode::get_editor_data().get_custom_types()["Resource"]; - } - - for (int i = 0; i < base_type.get_slice_count(","); i++) { - String base = base_type.get_slice(",", i); - - Set<String> valid_inheritors; - valid_inheritors.insert(base); - List<StringName> inheritors; - ClassDB::get_inheriters_from_class(base.strip_edges(), &inheritors); - - for (int j = 0; j < custom_resources.size(); j++) { - inheritors.push_back(custom_resources[j].name); - } - - List<StringName>::Element *E = inheritors.front(); - while (E) { - valid_inheritors.insert(E->get()); - E = E->next(); - } - - List<StringName> global_classes; - ScriptServer::get_global_class_list(&global_classes); - E = global_classes.front(); - while (E) { - if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base_type)) { - valid_inheritors.insert(E->get()); - } - E = E->next(); - } - - for (Set<String>::Element *F = valid_inheritors.front(); F; F = F->next()) { - const String &t = F->get(); - - bool is_custom_resource = false; - Ref<Texture2D> icon; - if (!custom_resources.is_empty()) { - for (int j = 0; j < custom_resources.size(); j++) { - if (custom_resources[j].name == t) { - is_custom_resource = true; - if (custom_resources[j].icon.is_valid()) { - icon = custom_resources[j].icon; - } - break; - } - } - } - - if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t))) { - continue; - } - - inheritors_array.push_back(t); - - if (!icon.is_valid()) { - icon = get_theme_icon(has_theme_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); - } - - int id = TYPE_BASE_ID + idx; - menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); - - idx++; - } - } - - if (menu->get_item_count()) { - menu->add_separator(); - } - } - - menu->add_icon_item(get_theme_icon("Load", "EditorIcons"), TTR("Load"), OBJ_MENU_LOAD); - - if (!res.is_null()) { - menu->add_icon_item(get_theme_icon("Edit", "EditorIcons"), TTR("Edit"), OBJ_MENU_EDIT); - menu->add_icon_item(get_theme_icon("Clear", "EditorIcons"), TTR("Clear"), OBJ_MENU_CLEAR); - menu->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); - menu->add_icon_item(get_theme_icon("Save", "EditorIcons"), TTR("Save"), OBJ_MENU_SAVE); - RES r = res; - if (r.is_valid() && r->get_path().is_resource_file()) { - menu->add_separator(); - menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM); - } - } - - RES cb = EditorSettings::get_singleton()->get_resource_clipboard(); - bool paste_valid = false; - if (cb.is_valid()) { - if (base_type == "") { - paste_valid = true; - } else { - for (int i = 0; i < base_type.get_slice_count(","); i++) { - if (ClassDB::is_parent_class(cb->get_class(), base_type.get_slice(",", i))) { - paste_valid = true; - break; - } - } + if (r && !r->is_local_to_scene()) { + EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on this resource because it's not set as local to scene.\nPlease switch on the 'local to scene' property on it (and all resources containing it up to a node).")); + emit_changed(get_edited_property(), RES()); + update_property(); + return; } } - if (!res.is_null() || paste_valid) { - menu->add_separator(); + emit_changed(get_edited_property(), p_resource); + update_property(); - if (!res.is_null()) { - menu->add_item(TTR("Copy"), OBJ_MENU_COPY); - } + // Automatically suggest setting up the path for a ViewportTexture. + if (vpt.is_valid() && vpt->get_viewport_path_in_scene().is_empty()) { + if (!scene_tree) { + scene_tree = memnew(SceneTreeDialog); + scene_tree->set_title(TTR("Pick a Viewport")); - if (paste_valid) { - menu->add_item(TTR("Paste"), OBJ_MENU_PASTE); - } - } + Vector<StringName> valid_types; + valid_types.push_back("Viewport"); + scene_tree->get_scene_tree()->set_valid_types(valid_types); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); - if (!res.is_null()) { - Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res); - if (conversions.size()) { - menu->add_separator(); + add_child(scene_tree); + scene_tree->connect("selected", callable_mp(this, &EditorPropertyResource::_viewport_selected)); } - for (int i = 0; i < conversions.size(); i++) { - String what = conversions[i]->converts_to(); - Ref<Texture2D> icon; - if (has_theme_icon(what, "EditorIcons")) { - icon = get_theme_icon(what, "EditorIcons"); - } else { - icon = get_theme_icon(what, "Resource"); - } - menu->add_icon_item(icon, vformat(TTR("Convert To %s"), what), CONVERT_BASE_ID + i); - } + scene_tree->popup_scenetree_dialog(); } } -void EditorPropertyResource::_update_menu() { - _update_menu_items(); - - Rect2 gt = edit->get_screen_rect(); - menu->set_as_minsize(); - int ms = menu->get_contents_minimum_size().width; - Vector2 popup_pos = gt.position + gt.size - Vector2(ms, 0); - menu->set_position(popup_pos); - menu->popup(); -} - void EditorPropertyResource::_sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool) { emit_signal("property_keyed_with_value", String(get_edited_property()) + ":" + p_property, p_value, false); } @@ -2816,24 +2454,11 @@ void EditorPropertyResource::_sub_inspector_object_id_selected(int p_id) { emit_signal("object_id_selected", get_edited_property(), p_id); } -void EditorPropertyResource::_button_input(const Ref<InputEvent> &p_event) { - Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { - _update_menu_items(); - Vector2 pos = get_screen_position() + mb->get_position(); - //pos = assign->get_global_transform().xform(pos); - menu->set_as_minsize(); - menu->set_position(pos); - menu->popup(); - } - } -} - void EditorPropertyResource::_open_editor_pressed() { RES res = get_edited_object()->get(get_edited_property()); if (res.is_valid()) { - EditorNode::get_singleton()->call_deferred("edit_item_resource", res); //may clear the editor so do it deferred + // May clear the editor so do it deferred. + EditorNode::get_singleton()->call_deferred("edit_item_resource", res); } } @@ -2843,28 +2468,28 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) { } RES res = get_edited_object()->get(get_edited_property()); - if (!res.is_valid()) { return; } + bool use_editor = false; for (int i = 0; i < EditorNode::get_editor_data().get_editor_plugin_count(); i++) { EditorPlugin *ep = EditorNode::get_editor_data().get_editor_plugin(i); if (ep->handles(res.ptr())) { use_editor = true; + break; } } - if (!use_editor) { return; } - bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property()); opened_editor = false; + bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property()); if (unfolded) { - //refold - assign->set_pressed(false); + // Refold. + resource_picker->set_toggle_pressed(false); get_edited_object()->editor_set_section_unfold(get_edited_property(), false); update_property(); } @@ -2876,6 +2501,7 @@ void EditorPropertyResource::_update_property_bg() { } updating_theme = true; + if (sub_inspector != nullptr) { int count_subinspectors = 0; Node *n = get_parent(); @@ -2905,12 +2531,60 @@ void EditorPropertyResource::_update_property_bg() { updating_theme = false; update(); } + +void EditorPropertyResource::_viewport_selected(const NodePath &p_path) { + Node *to_node = get_node(p_path); + if (!Object::cast_to<Viewport>(to_node)) { + EditorNode::get_singleton()->show_warning(TTR("Selected node is not a Viewport!")); + return; + } + + Ref<ViewportTexture> vt; + vt.instance(); + vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node)); + vt->setup_local_to_scene(); + + emit_changed(get_edited_property(), vt); + update_property(); +} + +void EditorPropertyResource::setup(Object *p_object, const String &p_path, const String &p_base_type) { + if (resource_picker) { + resource_picker->disconnect("resource_selected", callable_mp(this, &EditorPropertyResource::_resource_selected)); + resource_picker->disconnect("resource_changed", callable_mp(this, &EditorPropertyResource::_resource_changed)); + memdelete(resource_picker); + } + + if (p_path == "script" && p_base_type == "Script" && Object::cast_to<Node>(p_object)) { + EditorScriptPicker *script_picker = memnew(EditorScriptPicker); + script_picker->set_script_owner(Object::cast_to<Node>(p_object)); + resource_picker = script_picker; + } else { + resource_picker = memnew(EditorResourcePicker); + } + + resource_picker->set_base_type(p_base_type); + resource_picker->set_editable(true); + resource_picker->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(resource_picker); + + resource_picker->connect("resource_selected", callable_mp(this, &EditorPropertyResource::_resource_selected)); + resource_picker->connect("resource_changed", callable_mp(this, &EditorPropertyResource::_resource_changed)); + + for (int i = 0; i < resource_picker->get_child_count(); i++) { + Button *b = Object::cast_to<Button>(resource_picker->get_child(i)); + if (b) { + add_focusable(b); + } + } +} + void EditorPropertyResource::update_property() { RES res = get_edited_object()->get(get_edited_property()); if (use_sub_inspector) { - if (res.is_valid() != assign->is_toggle_mode()) { - assign->set_toggle_mode(res.is_valid()); + if (res.is_valid() != resource_picker->is_toggle_mode()) { + resource_picker->set_toggle_mode(res.is_valid()); } if (res.is_valid() && get_edited_object()->editor_is_section_unfolded(get_edited_property())) { @@ -2935,7 +2609,7 @@ void EditorPropertyResource::update_property() { set_bottom_editor(sub_inspector_vbox); sub_inspector_vbox->add_child(sub_inspector); - assign->set_pressed(true); + resource_picker->set_toggle_pressed(true); bool use_editor = false; for (int i = 0; i < EditorNode::get_editor_data().get_editor_plugin_count(); i++) { @@ -2946,7 +2620,7 @@ void EditorPropertyResource::update_property() { } if (use_editor) { - //open editor directly and hide other open of these + // Open editor directly and hide other such editors which are currently open. _open_editor_pressed(); if (is_inside_tree()) { get_tree()->call_deferred("call_group", "_editor_resource_properties", "_fold_other_editors", this); @@ -2967,102 +2641,18 @@ void EditorPropertyResource::update_property() { memdelete(sub_inspector_vbox); sub_inspector = nullptr; sub_inspector_vbox = nullptr; + if (opened_editor) { EditorNode::get_singleton()->hide_top_editors(); opened_editor = false; } + _update_property_bg(); } } } - preview->set_texture(Ref<Texture2D>()); - if (res == RES()) { - assign->set_icon(Ref<Texture2D>()); - assign->set_text(TTR("[empty]")); - assign->set_custom_minimum_size(Size2(1, 1)); - } else { - assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Object")); - - if (res->get_name() != String()) { - assign->set_text(res->get_name()); - } else if (res->get_path().is_resource_file()) { - assign->set_text(res->get_path().get_file()); - assign->set_tooltip(res->get_path()); - } else { - assign->set_text(res->get_class()); - } - - if (res->get_path().is_resource_file()) { - assign->set_tooltip(res->get_path()); - } - - //preview will override the above, so called at the end - EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_resource_preview", res->get_instance_id()); - } -} - -void EditorPropertyResource::_resource_selected() { - RES res = get_edited_object()->get(get_edited_property()); - - if (res.is_null()) { - edit->set_pressed(true); - _update_menu(); - return; - } - - if (use_sub_inspector) { - bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property()); - get_edited_object()->editor_set_section_unfold(get_edited_property(), unfold); - update_property(); - } else { - emit_signal("resource_selected", get_edited_property(), res); - } -} - -void EditorPropertyResource::setup(const String &p_base_type) { - base_type = p_base_type; -} - -void EditorPropertyResource::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - if (updating_theme) { - return; - } - Ref<Texture2D> t = get_theme_icon("select_arrow", "Tree"); - edit->set_icon(t); - _update_property_bg(); - } - - if (p_what == NOTIFICATION_DRAG_BEGIN) { - if (_is_drop_valid(get_viewport()->gui_get_drag_data())) { - dropping = true; - assign->update(); - } - } - - if (p_what == NOTIFICATION_DRAG_END) { - if (dropping) { - dropping = false; - assign->update(); - } - } -} - -void EditorPropertyResource::_viewport_selected(const NodePath &p_path) { - Node *to_node = get_node(p_path); - if (!Object::cast_to<Viewport>(to_node)) { - EditorNode::get_singleton()->show_warning(TTR("Selected node is not a Viewport!")); - return; - } - - Ref<ViewportTexture> vt; - vt.instance(); - vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node)); - vt->setup_local_to_scene(); - - emit_changed(get_edited_property(), vt); - update_property(); + resource_picker->set_edited_resource(res); } void EditorPropertyResource::collapse_all_folding() { @@ -3077,204 +2667,29 @@ void EditorPropertyResource::expand_all_folding() { } } -void EditorPropertyResource::_button_draw() { - if (dropping) { - Color color = get_theme_color("accent_color", "Editor"); - assign->draw_rect(Rect2(Point2(), assign->get_size()), color, false); - } -} - -Variant EditorPropertyResource::get_drag_data_fw(const Point2 &p_point, Control *p_from) { - RES res = get_edited_object()->get(get_edited_property()); - if (res.is_valid()) { - return EditorNode::get_singleton()->drag_resource(res, p_from); - } - - return Variant(); -} - -bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const { - Vector<String> allowed_types = base_type.split(","); - int size = allowed_types.size(); - for (int i = 0; i < size; i++) { - String at = allowed_types[i].strip_edges(); - if (at == "StandardMaterial3D") { - allowed_types.append("Texture2D"); - } else if (at == "ShaderMaterial") { - allowed_types.append("Shader"); - } else if (at == "Font") { - allowed_types.append("FontData"); - } - } - - Dictionary drag_data = p_drag_data; - - Ref<Resource> res; - if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { - ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]); - res = se->get_edited_resource(); - } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - res = drag_data["resource"]; - } - - if (res.is_valid()) { - for (int i = 0; i < allowed_types.size(); i++) { - String at = allowed_types[i].strip_edges(); - if (ClassDB::is_parent_class(res->get_class(), at)) { - return true; - } - } - } - - if (drag_data.has("type") && String(drag_data["type"]) == "files") { - Vector<String> files = drag_data["files"]; - - if (files.size() == 1) { - String file = files[0]; - String ftype = EditorFileSystem::get_singleton()->get_file_type(file); - - if (ftype != "") { - for (int i = 0; i < allowed_types.size(); i++) { - String at = allowed_types[i].strip_edges(); - if (ClassDB::is_parent_class(ftype, at)) { - return true; - } - } - } - } - } - - return false; -} - -bool EditorPropertyResource::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { - return _is_drop_valid(p_data); +void EditorPropertyResource::set_use_sub_inspector(bool p_enable) { + use_sub_inspector = p_enable; } -void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - ERR_FAIL_COND(!_is_drop_valid(p_data)); - - Dictionary drag_data = p_data; - - Ref<Resource> res; - if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { - ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]); - res = se->get_edited_resource(); - } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - res = drag_data["resource"]; - } - - if (!res.is_valid() && drag_data.has("type") && String(drag_data["type"]) == "files") { - Vector<String> files = drag_data["files"]; - - if (files.size() == 1) { - String file = files[0]; - res = ResourceLoader::load(file); - } - } - - if (res.is_valid()) { - bool need_convert = true; - - Vector<String> allowed_types = base_type.split(","); - for (int i = 0; i < allowed_types.size(); i++) { - String at = allowed_types[i].strip_edges(); - if (ClassDB::is_parent_class(res->get_class(), at)) { - need_convert = false; - break; - } - } - - if (need_convert) { - for (int i = 0; i < allowed_types.size(); i++) { - String at = allowed_types[i].strip_edges(); - if (at == "StandardMaterial3D" && ClassDB::is_parent_class(res->get_class(), "Texture2D")) { - Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); - mat->set_texture(StandardMaterial3D::TextureParam::TEXTURE_ALBEDO, res); - res = mat; - break; - } - - if (at == "ShaderMaterial" && ClassDB::is_parent_class(res->get_class(), "Shader")) { - Ref<ShaderMaterial> mat = memnew(ShaderMaterial); - mat->set_shader(res); - res = mat; - break; - } - - if (at == "Font" && ClassDB::is_parent_class(res->get_class(), "FontData")) { - Ref<Font> font = memnew(Font); - font->add_data(res); - res = font; - break; - } +void EditorPropertyResource::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + if (!updating_theme) { + _update_property_bg(); } - } - - emit_changed(get_edited_property(), res); - update_property(); - return; + } break; } } -void EditorPropertyResource::set_use_sub_inspector(bool p_enable) { - use_sub_inspector = p_enable; -} - void EditorPropertyResource::_bind_methods() { - ClassDB::bind_method(D_METHOD("_resource_preview"), &EditorPropertyResource::_resource_preview); - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &EditorPropertyResource::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &EditorPropertyResource::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &EditorPropertyResource::drop_data_fw); ClassDB::bind_method(D_METHOD("_open_editor_pressed"), &EditorPropertyResource::_open_editor_pressed); ClassDB::bind_method(D_METHOD("_fold_other_editors"), &EditorPropertyResource::_fold_other_editors); } EditorPropertyResource::EditorPropertyResource() { - opened_editor = false; - sub_inspector = nullptr; - sub_inspector_vbox = nullptr; use_sub_inspector = bool(EDITOR_GET("interface/inspector/open_resources_in_current_inspector")); - HBoxContainer *hbc = memnew(HBoxContainer); - add_child(hbc); - assign = memnew(Button); - assign->set_flat(true); - assign->set_h_size_flags(SIZE_EXPAND_FILL); - assign->set_clip_text(true); - assign->connect("pressed", callable_mp(this, &EditorPropertyResource::_resource_selected)); - assign->set_drag_forwarding(this); - assign->connect("draw", callable_mp(this, &EditorPropertyResource::_button_draw)); - hbc->add_child(assign); - add_focusable(assign); - - preview = memnew(TextureRect); - preview->set_expand(true); - preview->set_anchors_and_offsets_preset(PRESET_WIDE); - preview->set_offset(SIDE_TOP, 1); - preview->set_offset(SIDE_BOTTOM, -1); - preview->set_offset(SIDE_RIGHT, -1); - // This is required to draw the focus outline in front of the preview, rather than behind. - preview->set_draw_behind_parent(true); - assign->add_child(preview); - assign->connect("gui_input", callable_mp(this, &EditorPropertyResource::_button_input)); - - menu = memnew(PopupMenu); - add_child(menu); - edit = memnew(Button); - edit->set_flat(true); - edit->set_toggle_mode(true); - menu->connect("id_pressed", callable_mp(this, &EditorPropertyResource::_menu_option)); - menu->connect("popup_hide", callable_mp((BaseButton *)edit, &BaseButton::set_pressed), varray(false)); - edit->connect("pressed", callable_mp(this, &EditorPropertyResource::_update_menu)); - hbc->add_child(edit); - edit->connect("gui_input", callable_mp(this, &EditorPropertyResource::_button_input)); - add_focusable(edit); - - file = nullptr; - scene_tree = nullptr; - dropping = false; - add_to_group("_editor_resource_properties"); } @@ -3751,7 +3166,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } break; case Variant::OBJECT: { EditorPropertyResource *editor = memnew(EditorPropertyResource); - editor->setup(p_hint == PROPERTY_HINT_RESOURCE_TYPE ? p_hint_text : "Resource"); + editor->setup(p_object, p_path, p_hint == PROPERTY_HINT_RESOURCE_TYPE ? p_hint_text : "Resource"); if (p_hint == PROPERTY_HINT_RESOURCE_TYPE) { String open_in_new = EDITOR_GET("interface/inspector/resources_to_open_in_new_inspector"); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 07a1e72319..07f496f54d 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -33,6 +33,7 @@ #include "editor/create_dialog.h" #include "editor/editor_inspector.h" +#include "editor/editor_resource_picker.h" #include "editor/editor_spin_slider.h" #include "editor/property_selector.h" #include "editor/scene_tree_editor.h" @@ -599,64 +600,26 @@ public: class EditorPropertyResource : public EditorProperty { GDCLASS(EditorPropertyResource, EditorProperty); - enum MenuOption { - OBJ_MENU_LOAD = 0, - OBJ_MENU_EDIT = 1, - OBJ_MENU_CLEAR = 2, - OBJ_MENU_MAKE_UNIQUE = 3, - OBJ_MENU_SAVE = 4, - OBJ_MENU_COPY = 5, - OBJ_MENU_PASTE = 6, - OBJ_MENU_NEW_SCRIPT = 7, - OBJ_MENU_EXTEND_SCRIPT = 8, - OBJ_MENU_SHOW_IN_FILE_SYSTEM = 9, - TYPE_BASE_ID = 100, - CONVERT_BASE_ID = 1000 + EditorResourcePicker *resource_picker = nullptr; + SceneTreeDialog *scene_tree = nullptr; - }; - - Button *assign; - TextureRect *preview; - Button *edit; - PopupMenu *menu; - EditorFileDialog *file; - Vector<String> inheritors_array; - EditorInspector *sub_inspector; - VBoxContainer *sub_inspector_vbox; - - bool use_sub_inspector; - bool dropping; - String base_type; + bool use_sub_inspector = false; + EditorInspector *sub_inspector = nullptr; + VBoxContainer *sub_inspector_vbox = nullptr; + bool updating_theme = false; + bool opened_editor = false; - SceneTreeDialog *scene_tree; + void _resource_selected(const RES &p_resource); + void _resource_changed(const RES &p_resource); - void _file_selected(const String &p_path); - void _menu_option(int p_which); - void _resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj); - void _resource_selected(); void _viewport_selected(const NodePath &p_path); - void _update_menu_items(); - - void _update_menu(); - void _sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool); void _sub_inspector_resource_selected(const RES &p_resource, const String &p_property); void _sub_inspector_object_id_selected(int p_id); - void _button_draw(); - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); - bool _is_drop_valid(const Dictionary &p_drag_data) const; - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; - void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); - - void _button_input(const Ref<InputEvent> &p_event); void _open_editor_pressed(); void _fold_other_editors(Object *p_self); - - bool opened_editor; - - bool updating_theme = false; void _update_property_bg(); protected: @@ -665,7 +628,7 @@ protected: public: virtual void update_property() override; - void setup(const String &p_base_type); + void setup(Object *p_object, const String &p_path, const String &p_base_type); void collapse_all_folding() override; void expand_all_folding() override; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index fb2980c948..3bc29856f1 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -902,7 +902,7 @@ void EditorPropertyDictionary::update_property() { } else { EditorPropertyResource *editor = memnew(EditorPropertyResource); - editor->setup("Resource"); + editor->setup(object.ptr(), prop_name, "Resource"); prop = editor; } diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp new file mode 100644 index 0000000000..d1a0bfeded --- /dev/null +++ b/editor/editor_resource_picker.cpp @@ -0,0 +1,864 @@ +/*************************************************************************/ +/* editor_resource_picker.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_resource_picker.h" + +#include "editor/editor_resource_preview.h" +#include "editor_node.h" +#include "editor_scale.h" +#include "editor_settings.h" +#include "filesystem_dock.h" + +void EditorResourcePicker::_update_resource() { + preview_rect->set_texture(Ref<Texture2D>()); + assign_button->set_custom_minimum_size(Size2(1, 1)); + + if (edited_resource == RES()) { + assign_button->set_icon(Ref<Texture2D>()); + assign_button->set_text(TTR("[empty]")); + } else { + assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); + + if (edited_resource->get_name() != String()) { + assign_button->set_text(edited_resource->get_name()); + } else if (edited_resource->get_path().is_resource_file()) { + assign_button->set_text(edited_resource->get_path().get_file()); + assign_button->set_tooltip(edited_resource->get_path()); + } else { + assign_button->set_text(edited_resource->get_class()); + } + + if (edited_resource->get_path().is_resource_file()) { + assign_button->set_tooltip(edited_resource->get_path()); + } + + // Preview will override the above, so called at the end. + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); + } +} + +void EditorResourcePicker::_update_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj) { + if (!edited_resource.is_valid() || edited_resource->get_instance_id() != p_obj) { + return; + } + + String type = edited_resource->get_class_name(); + if (ClassDB::is_parent_class(type, "Script")) { + assign_button->set_text(edited_resource->get_path().get_file()); + return; + } + + if (p_preview.is_valid()) { + preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox("normal")->get_default_margin(SIDE_LEFT) + get_theme_constant("hseparation", "Button")); + + if (type == "GradientTexture") { + preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE); + assign_button->set_custom_minimum_size(Size2(1, 1)); + } else { + preview_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size *= EDSCALE; + assign_button->set_custom_minimum_size(Size2(1, thumbnail_size)); + } + + preview_rect->set_texture(p_preview); + assign_button->set_text(""); + } +} + +void EditorResourcePicker::_resource_selected() { + if (edited_resource.is_null()) { + edit_button->set_pressed(true); + _update_menu(); + return; + } + + emit_signal("resource_selected", edited_resource); +} + +void EditorResourcePicker::_file_selected(const String &p_path) { + RES loaded_resource = ResourceLoader::load(p_path); + ERR_FAIL_COND_MSG(loaded_resource.is_null(), "Cannot load resource from path '" + p_path + "'."); + + if (base_type != "") { + bool any_type_matches = false; + + for (int i = 0; i < base_type.get_slice_count(","); i++) { + String base = base_type.get_slice(",", i); + if (loaded_resource->is_class(base)) { + any_type_matches = true; + break; + } + } + + if (!any_type_matches) { + EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), loaded_resource->get_class(), base_type)); + return; + } + } + + edited_resource = loaded_resource; + emit_signal("resource_changed", edited_resource); + _update_resource(); +} + +void EditorResourcePicker::_update_menu() { + _update_menu_items(); + + Rect2 gt = edit_button->get_screen_rect(); + edit_menu->set_as_minsize(); + int ms = edit_menu->get_contents_minimum_size().width; + Vector2 popup_pos = gt.position + gt.size - Vector2(ms, 0); + edit_menu->set_position(popup_pos); + edit_menu->popup(); +} + +void EditorResourcePicker::_update_menu_items() { + edit_menu->clear(); + + // Add options for creating specific subtypes of the base resource type. + set_create_options(edit_menu); + + // Add an option to load a resource from a file. + edit_menu->add_icon_item(get_theme_icon("Load", "EditorIcons"), TTR("Load"), OBJ_MENU_LOAD); + + // Add options for changing existing value of the resource. + if (edited_resource.is_valid()) { + edit_menu->add_icon_item(get_theme_icon("Edit", "EditorIcons"), TTR("Edit"), OBJ_MENU_EDIT); + edit_menu->add_icon_item(get_theme_icon("Clear", "EditorIcons"), TTR("Clear"), OBJ_MENU_CLEAR); + edit_menu->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); + edit_menu->add_icon_item(get_theme_icon("Save", "EditorIcons"), TTR("Save"), OBJ_MENU_SAVE); + + if (edited_resource->get_path().is_resource_file()) { + edit_menu->add_separator(); + edit_menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM); + } + } + + // Add options to copy/paste resource. + RES cb = EditorSettings::get_singleton()->get_resource_clipboard(); + bool paste_valid = false; + if (cb.is_valid()) { + if (base_type == "") { + paste_valid = true; + } else { + for (int i = 0; i < base_type.get_slice_count(","); i++) { + if (ClassDB::is_parent_class(cb->get_class(), base_type.get_slice(",", i))) { + paste_valid = true; + break; + } + } + } + } + + if (edited_resource.is_valid() || paste_valid) { + edit_menu->add_separator(); + + if (edited_resource.is_valid()) { + edit_menu->add_item(TTR("Copy"), OBJ_MENU_COPY); + } + + if (paste_valid) { + edit_menu->add_item(TTR("Paste"), OBJ_MENU_PASTE); + } + } + + // Add options to convert existing resource to another type of resource. + if (edited_resource.is_valid()) { + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(edited_resource); + if (conversions.size()) { + edit_menu->add_separator(); + } + for (int i = 0; i < conversions.size(); i++) { + String what = conversions[i]->converts_to(); + Ref<Texture2D> icon; + if (has_theme_icon(what, "EditorIcons")) { + icon = get_theme_icon(what, "EditorIcons"); + } else { + icon = get_theme_icon(what, "Resource"); + } + + edit_menu->add_icon_item(icon, vformat(TTR("Convert To %s"), what), CONVERT_BASE_ID + i); + } + } +} + +void EditorResourcePicker::_edit_menu_cbk(int p_which) { + switch (p_which) { + case OBJ_MENU_LOAD: { + List<String> extensions; + for (int i = 0; i < base_type.get_slice_count(","); i++) { + String base = base_type.get_slice(",", i); + ResourceLoader::get_recognized_extensions_for_type(base, &extensions); + } + + Set<String> valid_extensions; + for (List<String>::Element *E = extensions.front(); E; E = E->next()) { + valid_extensions.insert(E->get()); + } + + if (!file_dialog) { + file_dialog = memnew(EditorFileDialog); + file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); + add_child(file_dialog); + file_dialog->connect("file_selected", callable_mp(this, &EditorResourcePicker::_file_selected)); + } + + file_dialog->clear_filters(); + for (Set<String>::Element *E = valid_extensions.front(); E; E = E->next()) { + file_dialog->add_filter("*." + E->get() + " ; " + E->get().to_upper()); + } + + file_dialog->popup_file_dialog(); + } break; + + case OBJ_MENU_EDIT: { + if (edited_resource.is_valid()) { + emit_signal("resource_selected", edited_resource); + } + } break; + + case OBJ_MENU_CLEAR: { + edited_resource = RES(); + emit_signal("resource_changed", edited_resource); + _update_resource(); + } break; + + case OBJ_MENU_MAKE_UNIQUE: { + if (edited_resource.is_null()) { + return; + } + + List<PropertyInfo> property_list; + edited_resource->get_property_list(&property_list); + List<Pair<String, Variant>> propvalues; + for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { + Pair<String, Variant> p; + PropertyInfo &pi = E->get(); + if (pi.usage & PROPERTY_USAGE_STORAGE) { + p.first = pi.name; + p.second = edited_resource->get(pi.name); + } + + propvalues.push_back(p); + } + + String orig_type = edited_resource->get_class(); + Object *inst = ClassDB::instance(orig_type); + Ref<Resource> unique_resource = Ref<Resource>(Object::cast_to<Resource>(inst)); + ERR_FAIL_COND(unique_resource.is_null()); + + for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) { + Pair<String, Variant> &p = E->get(); + unique_resource->set(p.first, p.second); + } + + edited_resource = unique_resource; + emit_signal("resource_changed", edited_resource); + _update_resource(); + } break; + + case OBJ_MENU_SAVE: { + if (edited_resource.is_null()) { + return; + } + EditorNode::get_singleton()->save_resource(edited_resource); + } break; + + case OBJ_MENU_COPY: { + EditorSettings::get_singleton()->set_resource_clipboard(edited_resource); + } break; + + case OBJ_MENU_PASTE: { + edited_resource = EditorSettings::get_singleton()->get_resource_clipboard(); + emit_signal("resource_changed", edited_resource); + _update_resource(); + } break; + + case OBJ_MENU_SHOW_IN_FILE_SYSTEM: { + FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock(); + file_system_dock->navigate_to_path(edited_resource->get_path()); + + // Ensure that the FileSystem dock is visible. + TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); + tab_container->set_current_tab(file_system_dock->get_index()); + } break; + + default: { + // Allow subclasses to handle their own options first, only then fallback on the default branch logic. + if (handle_menu_selected(p_which)) { + break; + } + + if (p_which >= CONVERT_BASE_ID) { + int to_type = p_which - CONVERT_BASE_ID; + Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(edited_resource); + ERR_FAIL_INDEX(to_type, conversions.size()); + + edited_resource = conversions[to_type]->convert(edited_resource); + emit_signal("resource_changed", edited_resource); + _update_resource(); + break; + } + + ERR_FAIL_COND(inheritors_array.is_empty()); + + String intype = inheritors_array[p_which - TYPE_BASE_ID]; + Variant obj; + + if (ScriptServer::is_global_class(intype)) { + obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype)); + if (obj) { + Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); + if (script.is_valid()) { + ((Object *)obj)->set_script(script); + } + } + } else { + obj = ClassDB::instance(intype); + } + + if (!obj) { + obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource"); + } + + Resource *resp = Object::cast_to<Resource>(obj); + ERR_BREAK(!resp); + + edited_resource = RES(resp); + emit_signal("resource_changed", edited_resource); + _update_resource(); + } break; + } +} + +void EditorResourcePicker::set_create_options(Object *p_menu_node) { + // If a subclass implements this method, use it to replace all create items. + if (get_script_instance() && get_script_instance()->has_method("set_create_options")) { + get_script_instance()->call("set_create_options", p_menu_node); + return; + } + + // By default provide generic "New ..." options. + if (base_type != "") { + int idx = 0; + + Set<String> allowed_types; + _get_allowed_types(false, &allowed_types); + + Vector<EditorData::CustomType> custom_resources; + if (EditorNode::get_editor_data().get_custom_types().has("Resource")) { + custom_resources = EditorNode::get_editor_data().get_custom_types()["Resource"]; + } + + for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) { + const String &t = E->get(); + + bool is_custom_resource = false; + Ref<Texture2D> icon; + if (!custom_resources.is_empty()) { + for (int j = 0; j < custom_resources.size(); j++) { + if (custom_resources[j].name == t) { + is_custom_resource = true; + if (custom_resources[j].icon.is_valid()) { + icon = custom_resources[j].icon; + } + break; + } + } + } + + if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t))) { + continue; + } + + inheritors_array.push_back(t); + + if (!icon.is_valid()) { + icon = get_theme_icon(has_theme_icon(t, "EditorIcons") ? t : "Object", "EditorIcons"); + } + + int id = TYPE_BASE_ID + idx; + edit_menu->add_icon_item(icon, vformat(TTR("New %s"), t), id); + + idx++; + } + + if (edit_menu->get_item_count()) { + edit_menu->add_separator(); + } + } +} + +bool EditorResourcePicker::handle_menu_selected(int p_which) { + if (get_script_instance() && get_script_instance()->has_method("handle_menu_selected")) { + return get_script_instance()->call("handle_menu_selected", p_which); + } + + return false; +} + +void EditorResourcePicker::_button_draw() { + if (dropping) { + Color color = get_theme_color("accent_color", "Editor"); + assign_button->draw_rect(Rect2(Point2(), assign_button->get_size()), color, false); + } +} + +void EditorResourcePicker::_button_input(const Ref<InputEvent> &p_event) { + if (!editable) { + return; + } + + Ref<InputEventMouseButton> mb = p_event; + + if (mb.is_valid()) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) { + _update_menu_items(); + + Vector2 pos = get_screen_position() + mb->get_position(); + edit_menu->set_as_minsize(); + edit_menu->set_position(pos); + edit_menu->popup(); + } + } +} + +void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set<String> *p_vector) const { + Vector<String> allowed_types = base_type.split(","); + int size = allowed_types.size(); + + List<StringName> global_classes; + ScriptServer::get_global_class_list(&global_classes); + + for (int i = 0; i < size; i++) { + String base = allowed_types[i].strip_edges(); + p_vector->insert(base); + + List<StringName> inheriters; + + ClassDB::get_inheriters_from_class(base, &inheriters); + for (List<StringName>::Element *E = inheriters.front(); E; E = E->next()) { + p_vector->insert(E->get()); + } + + for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { + if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base)) { + p_vector->insert(E->get()); + } + } + + if (p_with_convert) { + if (base == "StandardMaterial3D") { + p_vector->insert("Texture2D"); + } else if (base == "ShaderMaterial") { + p_vector->insert("Shader"); + } else if (base == "Font") { + p_vector->insert("FontData"); + } + } + } + + if (EditorNode::get_editor_data().get_custom_types().has("Resource")) { + Vector<EditorData::CustomType> custom_resources = EditorNode::get_editor_data().get_custom_types()["Resource"]; + + for (int i = 0; i < custom_resources.size(); i++) { + p_vector->insert(custom_resources[i].name); + } + } +} + +bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const { + if (base_type.is_empty()) { + return true; + } + + Dictionary drag_data = p_drag_data; + + Ref<Resource> res; + if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { + ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]); + res = se->get_edited_resource(); + } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { + res = drag_data["resource"]; + } + + Set<String> allowed_types; + _get_allowed_types(true, &allowed_types); + + if (res.is_valid() && _is_type_valid(res->get_class(), allowed_types)) { + return true; + } + + if (res.is_valid() && res->get_script()) { + StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res->get_script()); + if (_is_type_valid(custom_class, allowed_types)) { + return true; + } + } + + if (drag_data.has("type") && String(drag_data["type"]) == "files") { + Vector<String> files = drag_data["files"]; + + if (files.size() == 1) { + String file = files[0]; + + String file_type = EditorFileSystem::get_singleton()->get_file_type(file); + if (file_type != "" && _is_type_valid(file_type, allowed_types)) { + return true; + } + } + } + + return false; +} + +bool EditorResourcePicker::_is_type_valid(const String p_type_name, Set<String> p_allowed_types) const { + for (Set<String>::Element *E = p_allowed_types.front(); E; E = E->next()) { + String at = E->get().strip_edges(); + if (p_type_name == at || ClassDB::is_parent_class(p_type_name, at) || EditorNode::get_editor_data().script_class_is_parent(p_type_name, at)) { + return true; + } + } + + return false; +} + +Variant EditorResourcePicker::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + if (edited_resource.is_valid()) { + return EditorNode::get_singleton()->drag_resource(edited_resource, p_from); + } + + return Variant(); +} + +bool EditorResourcePicker::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + return editable && _is_drop_valid(p_data); +} + +void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + ERR_FAIL_COND(!_is_drop_valid(p_data)); + + Dictionary drag_data = p_data; + + Ref<Resource> dropped_resource; + if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") { + ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]); + dropped_resource = se->get_edited_resource(); + } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { + dropped_resource = drag_data["resource"]; + } + + if (!dropped_resource.is_valid() && drag_data.has("type") && String(drag_data["type"]) == "files") { + Vector<String> files = drag_data["files"]; + + if (files.size() == 1) { + String file = files[0]; + dropped_resource = ResourceLoader::load(file); + } + } + + if (dropped_resource.is_valid()) { + Set<String> allowed_types; + _get_allowed_types(false, &allowed_types); + + // If the accepted dropped resource is from the extended list, it requires conversion. + if (!_is_type_valid(dropped_resource->get_class(), allowed_types)) { + for (Set<String>::Element *E = allowed_types.front(); E; E = E->next()) { + String at = E->get().strip_edges(); + + if (at == "StandardMaterial3D" && ClassDB::is_parent_class(dropped_resource->get_class(), "Texture2D")) { + Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); + mat->set_texture(StandardMaterial3D::TextureParam::TEXTURE_ALBEDO, dropped_resource); + dropped_resource = mat; + break; + } + + if (at == "ShaderMaterial" && ClassDB::is_parent_class(dropped_resource->get_class(), "Shader")) { + Ref<ShaderMaterial> mat = memnew(ShaderMaterial); + mat->set_shader(dropped_resource); + dropped_resource = mat; + break; + } + + if (at == "Font" && ClassDB::is_parent_class(dropped_resource->get_class(), "FontData")) { + Ref<Font> font = memnew(Font); + font->add_data(dropped_resource); + dropped_resource = font; + break; + } + } + } + + edited_resource = dropped_resource; + emit_signal("resource_changed", edited_resource); + _update_resource(); + } +} + +void EditorResourcePicker::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update_resource_preview"), &EditorResourcePicker::_update_resource_preview); + ClassDB::bind_method(D_METHOD("get_drag_data_fw", "position", "from"), &EditorResourcePicker::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw", "position", "data", "from"), &EditorResourcePicker::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw", "position", "data", "from"), &EditorResourcePicker::drop_data_fw); + + ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &EditorResourcePicker::set_base_type); + ClassDB::bind_method(D_METHOD("get_base_type"), &EditorResourcePicker::get_base_type); + ClassDB::bind_method(D_METHOD("get_allowed_types"), &EditorResourcePicker::get_allowed_types); + ClassDB::bind_method(D_METHOD("set_edited_resource", "resource"), &EditorResourcePicker::set_edited_resource); + ClassDB::bind_method(D_METHOD("get_edited_resource"), &EditorResourcePicker::get_edited_resource); + ClassDB::bind_method(D_METHOD("set_toggle_mode", "enable"), &EditorResourcePicker::set_toggle_mode); + ClassDB::bind_method(D_METHOD("is_toggle_mode"), &EditorResourcePicker::is_toggle_mode); + ClassDB::bind_method(D_METHOD("set_toggle_pressed", "pressed"), &EditorResourcePicker::set_toggle_pressed); + ClassDB::bind_method(D_METHOD("set_editable", "enable"), &EditorResourcePicker::set_editable); + ClassDB::bind_method(D_METHOD("is_editable"), &EditorResourcePicker::is_editable); + + ClassDB::add_virtual_method(get_class_static(), MethodInfo("set_create_options", PropertyInfo(Variant::OBJECT, "menu_node"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo("handle_menu_selected", PropertyInfo(Variant::INT, "id"))); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type"), "set_base_type", "get_base_type"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource", 0), "set_edited_resource", "get_edited_resource"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); + + ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); + ADD_SIGNAL(MethodInfo("resource_changed", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); +} + +void EditorResourcePicker::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + _update_resource(); + [[fallthrough]]; + } + case NOTIFICATION_THEME_CHANGED: { + edit_button->set_icon(get_theme_icon("select_arrow", "Tree")); + } break; + + case NOTIFICATION_DRAW: { + draw_style_box(get_theme_stylebox("bg", "Tree"), Rect2(Point2(), get_size())); + } break; + + case NOTIFICATION_DRAG_BEGIN: { + if (editable && _is_drop_valid(get_viewport()->gui_get_drag_data())) { + dropping = true; + assign_button->update(); + } + } break; + + case NOTIFICATION_DRAG_END: { + if (dropping) { + dropping = false; + assign_button->update(); + } + } break; + } +} + +void EditorResourcePicker::set_base_type(const String &p_base_type) { + base_type = p_base_type; + + // There is a possibility that the new base type is conflicting with the existing value. + // Keep the value, but warn the user that there is a potential mistake. + if (!base_type.is_empty() && edited_resource.is_valid()) { + Set<String> allowed_types; + _get_allowed_types(true, &allowed_types); + + StringName custom_class; + bool is_custom = false; + if (edited_resource->get_script()) { + custom_class = EditorNode::get_singleton()->get_object_custom_type_name(edited_resource->get_script()); + is_custom = _is_type_valid(custom_class, allowed_types); + } + + if (!is_custom && !_is_type_valid(edited_resource->get_class(), allowed_types)) { + String class_str = (custom_class == StringName() ? edited_resource->get_class() : vformat("%s (%s)", custom_class, edited_resource->get_class())); + WARN_PRINT(vformat("Value mismatch between the new base type of this EditorResourcePicker, '%s', and the type of the value it already has, '%s'.", base_type, class_str)); + } + } +} + +String EditorResourcePicker::get_base_type() const { + return base_type; +} + +Vector<String> EditorResourcePicker::get_allowed_types() const { + Set<String> allowed_types; + _get_allowed_types(false, &allowed_types); + + Vector<String> types; + types.resize(allowed_types.size()); + + int i = 0; + String *w = types.ptrw(); + for (Set<String>::Element *E = allowed_types.front(); E; E = E->next(), i++) { + w[i] = E->get(); + } + + return types; +} + +void EditorResourcePicker::set_edited_resource(RES p_resource) { + if (!p_resource.is_valid()) { + edited_resource = RES(); + _update_resource(); + return; + } + + if (!base_type.is_empty()) { + Set<String> allowed_types; + _get_allowed_types(true, &allowed_types); + + StringName custom_class; + bool is_custom = false; + if (p_resource->get_script()) { + custom_class = EditorNode::get_singleton()->get_object_custom_type_name(p_resource->get_script()); + is_custom = _is_type_valid(custom_class, allowed_types); + } + + if (!is_custom && !_is_type_valid(p_resource->get_class(), allowed_types)) { + String class_str = (custom_class == StringName() ? p_resource->get_class() : vformat("%s (%s)", custom_class, p_resource->get_class())); + ERR_FAIL_MSG(vformat("Failed to set a resource of the type '%s' because this EditorResourcePicker only accepts '%s' and its derivatives.", class_str, base_type)); + } + } + + edited_resource = p_resource; + _update_resource(); +} + +RES EditorResourcePicker::get_edited_resource() { + return edited_resource; +} + +void EditorResourcePicker::set_toggle_mode(bool p_enable) { + assign_button->set_toggle_mode(p_enable); +} + +bool EditorResourcePicker::is_toggle_mode() const { + return assign_button->is_toggle_mode(); +} + +void EditorResourcePicker::set_toggle_pressed(bool p_pressed) { + if (!is_toggle_mode()) { + return; + } + + assign_button->set_pressed(p_pressed); +} + +void EditorResourcePicker::set_editable(bool p_editable) { + editable = p_editable; + assign_button->set_disabled(!editable); + edit_button->set_visible(editable); +} + +bool EditorResourcePicker::is_editable() const { + return editable; +} + +EditorResourcePicker::EditorResourcePicker() { + assign_button = memnew(Button); + assign_button->set_flat(true); + assign_button->set_h_size_flags(SIZE_EXPAND_FILL); + assign_button->set_clip_text(true); + assign_button->set_drag_forwarding(this); + add_child(assign_button); + assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected)); + assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw)); + assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); + + preview_rect = memnew(TextureRect); + preview_rect->set_expand(true); + preview_rect->set_anchors_and_offsets_preset(PRESET_WIDE); + preview_rect->set_offset(SIDE_TOP, 1); + preview_rect->set_offset(SIDE_BOTTOM, -1); + preview_rect->set_offset(SIDE_RIGHT, -1); + assign_button->add_child(preview_rect); + + edit_button = memnew(Button); + edit_button->set_flat(true); + edit_button->set_toggle_mode(true); + edit_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_update_menu)); + add_child(edit_button); + edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); + edit_menu = memnew(PopupMenu); + add_child(edit_menu); + edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); + edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); +} + +void EditorScriptPicker::set_create_options(Object *p_menu_node) { + PopupMenu *menu_node = Object::cast_to<PopupMenu>(p_menu_node); + if (!menu_node) { + return; + } + + menu_node->add_icon_item(get_theme_icon("ScriptCreate", "EditorIcons"), TTR("New Script"), OBJ_MENU_NEW_SCRIPT); + menu_node->add_icon_item(get_theme_icon("ScriptExtend", "EditorIcons"), TTR("Extend Script"), OBJ_MENU_EXTEND_SCRIPT); + menu_node->add_separator(); +} + +bool EditorScriptPicker::handle_menu_selected(int p_which) { + switch (p_which) { + case OBJ_MENU_NEW_SCRIPT: { + if (script_owner) { + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, false); + } + return true; + } + + case OBJ_MENU_EXTEND_SCRIPT: { + if (script_owner) { + EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(script_owner, true); + } + return true; + } + } + + return false; +} + +void EditorScriptPicker::set_script_owner(Node *p_owner) { + script_owner = p_owner; +} + +Node *EditorScriptPicker::get_script_owner() const { + return script_owner; +} + +void EditorScriptPicker::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_script_owner", "owner_node"), &EditorScriptPicker::set_script_owner); + ClassDB::bind_method(D_METHOD("get_script_owner"), &EditorScriptPicker::get_script_owner); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "script_owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_script_owner", "get_script_owner"); +} + +EditorScriptPicker::EditorScriptPicker() { +} diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h new file mode 100644 index 0000000000..9a4b945bc7 --- /dev/null +++ b/editor/editor_resource_picker.h @@ -0,0 +1,141 @@ +/*************************************************************************/ +/* editor_resource_picker.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_RESOURCE_PICKER_H +#define EDITOR_RESOURCE_PICKER_H + +#include "editor_file_dialog.h" +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/popup_menu.h" +#include "scene/gui/texture_rect.h" + +class EditorResourcePicker : public HBoxContainer { + GDCLASS(EditorResourcePicker, HBoxContainer); + + String base_type; + RES edited_resource; + + bool editable = true; + bool dropping = false; + + Vector<String> inheritors_array; + + Button *assign_button; + TextureRect *preview_rect; + Button *edit_button; + EditorFileDialog *file_dialog = nullptr; + + enum MenuOption { + OBJ_MENU_LOAD, + OBJ_MENU_EDIT, + OBJ_MENU_CLEAR, + OBJ_MENU_MAKE_UNIQUE, + OBJ_MENU_SAVE, + OBJ_MENU_COPY, + OBJ_MENU_PASTE, + OBJ_MENU_SHOW_IN_FILE_SYSTEM, + + TYPE_BASE_ID = 100, + CONVERT_BASE_ID = 1000, + }; + + PopupMenu *edit_menu; + + void _update_resource(); + void _update_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj); + + void _resource_selected(); + void _file_selected(const String &p_path); + + void _update_menu(); + void _update_menu_items(); + void _edit_menu_cbk(int p_which); + + void _button_draw(); + void _button_input(const Ref<InputEvent> &p_event); + + void _get_allowed_types(bool p_with_convert, Set<String> *p_vector) const; + bool _is_drop_valid(const Dictionary &p_drag_data) const; + bool _is_type_valid(const String p_type_name, Set<String> p_allowed_types) const; + + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + void set_base_type(const String &p_base_type); + String get_base_type() const; + Vector<String> get_allowed_types() const; + + void set_edited_resource(RES p_resource); + RES get_edited_resource(); + + void set_toggle_mode(bool p_enable); + bool is_toggle_mode() const; + void set_toggle_pressed(bool p_pressed); + + void set_editable(bool p_editable); + bool is_editable() const; + + virtual void set_create_options(Object *p_menu_node); + virtual bool handle_menu_selected(int p_which); + + EditorResourcePicker(); +}; + +class EditorScriptPicker : public EditorResourcePicker { + GDCLASS(EditorScriptPicker, EditorResourcePicker); + + enum ExtraMenuOption { + OBJ_MENU_NEW_SCRIPT = 10, + OBJ_MENU_EXTEND_SCRIPT = 11 + }; + + Node *script_owner = nullptr; + +protected: + static void _bind_methods(); + +public: + virtual void set_create_options(Object *p_menu_node) override; + virtual bool handle_menu_selected(int p_which) override; + + void set_script_owner(Node *p_owner); + Node *get_script_owner() const; + + EditorScriptPicker(); +}; + +#endif // EDITOR_RESOURCE_PICKER_H diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 138830cdc6..35cf08b4d7 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -241,7 +241,7 @@ void EditorResourcePreview::_thread() { _preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, small_texture, item.id, item.function, item.userdata); } else { - String temp_path = EditorSettings::get_singleton()->get_cache_dir(); + String temp_path = EditorPaths::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(item.path).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index c4e796dcf1..ffeb22162e 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -101,7 +101,8 @@ protected: public: static EditorResourcePreview *get_singleton(); - //callback function is callback(String p_path,Ref<Texture2D> preview,Variant udata) preview null if could not load + // p_receiver_func callback has signature (String p_path, Ref<Texture2D> p_preview, Ref<Texture2D> p_preview_small, Variant p_userdata) + // p_preview will be null if there was an error void queue_resource_preview(const String &p_path, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata); void queue_edited_resource_preview(const Ref<Resource> &p_res, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata); diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index f81c87be9e..7532f1c796 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -135,7 +135,7 @@ void SectionedInspector::_section_selected() { } selected_category = sections->get_selected()->get_metadata(0); - filter->set_section(selected_category, sections->get_selected()->get_children() == nullptr); + filter->set_section(selected_category, sections->get_selected()->get_first_child() == nullptr); inspector->set_property_prefix(selected_category + "/"); } @@ -187,8 +187,8 @@ void SectionedInspector::edit(Object *p_object) { TreeItem *first_item = sections->get_root(); if (first_item) { - while (first_item->get_children()) { - first_item = first_item->get_children(); + while (first_item->get_first_child()) { + first_item = first_item->get_first_child(); } first_item->select(0); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index aba14df812..1255526a4a 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -419,7 +419,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/editor/main_font_bold"] = PropertyInfo(Variant::STRING, "interface/editor/main_font_bold", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT); _initial_set("interface/editor/code_font", ""); hints["interface/editor/code_font"] = PropertyInfo(Variant::STRING, "interface/editor/code_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT); - _initial_set("interface/editor/dim_editor_on_dialog_popup", true); _initial_set("interface/editor/low_processor_mode_sleep_usec", 6900); // ~144 FPS hints["interface/editor/low_processor_mode_sleep_usec"] = PropertyInfo(Variant::FLOAT, "interface/editor/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "1,100000,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/unfocused_low_processor_mode_sleep_usec", 50000); // 20 FPS @@ -503,12 +502,12 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { /* Text editor */ // Theme - _initial_set("text_editor/theme/color_theme", "Adaptive"); - hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Adaptive,Default,Custom"); + _initial_set("text_editor/theme/color_theme", "Default"); + hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Default,Godot 2,Custom"); _initial_set("text_editor/theme/line_spacing", 6); hints["text_editor/theme/line_spacing"] = PropertyInfo(Variant::INT, "text_editor/theme/line_spacing", PROPERTY_HINT_RANGE, "0,50,1"); - _load_default_text_editor_theme(); + _load_godot2_text_editor_theme(); // Highlighting _initial_set("text_editor/highlighting/highlight_all_occurrences", true); @@ -704,6 +703,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/scroll_to_pan", false); _initial_set("editors/2d/pan_speed", 20); + // Tiles editor + _initial_set("editors/tiles_editor/display_grid", true); + _initial_set("editors/tiles_editor/grid_color", Color(1.0, 0.5, 0.2, 0.5)); + // Polygon editor _initial_set("editors/poly_editor/point_grab_radius", 8); _initial_set("editors/poly_editor/show_previous_outline", true); @@ -782,9 +785,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { }; } -void EditorSettings::_load_default_text_editor_theme() { - bool dark_theme = is_dark_theme(); - +void EditorSettings::_load_godot2_text_editor_theme() { + // Godot 2 is only a dark theme; it doesn't have a light theme counterpart. _initial_set("text_editor/highlighting/symbol_color", Color(0.73, 0.87, 1.0)); _initial_set("text_editor/highlighting/keyword_color", Color(1.0, 1.0, 0.7)); _initial_set("text_editor/highlighting/control_flow_keyword_color", Color(1.0, 0.85, 0.7)); @@ -793,7 +795,7 @@ void EditorSettings::_load_default_text_editor_theme() { _initial_set("text_editor/highlighting/user_type_color", Color(0.42, 0.67, 0.93)); _initial_set("text_editor/highlighting/comment_color", Color(0.4, 0.4, 0.4)); _initial_set("text_editor/highlighting/string_color", Color(0.94, 0.43, 0.75)); - _initial_set("text_editor/highlighting/background_color", dark_theme ? Color(0.0, 0.0, 0.0, 0.23) : Color(0.2, 0.23, 0.31)); + _initial_set("text_editor/highlighting/background_color", Color(0.13, 0.12, 0.15)); _initial_set("text_editor/highlighting/completion_background_color", Color(0.17, 0.16, 0.2)); _initial_set("text_editor/highlighting/completion_selected_color", Color(0.26, 0.26, 0.27)); _initial_set("text_editor/highlighting/completion_existing_color", Color(0.13, 0.87, 0.87, 0.87)); @@ -843,7 +845,7 @@ bool EditorSettings::_save_text_editor_theme(String p_file) { } bool EditorSettings::_is_default_text_editor_theme(String p_theme_name) { - return p_theme_name == "default" || p_theme_name == "adaptive" || p_theme_name == "custom"; + return p_theme_name == "default" || p_theme_name == "godot 2" || p_theme_name == "custom"; } static Dictionary _get_builtin_script_templates() { @@ -898,67 +900,26 @@ void EditorSettings::create() { return; //pointless } - DirAccess *dir = nullptr; - - String data_path; - String data_dir; - String config_path; - String config_dir; - String cache_path; - String cache_dir; - Ref<ConfigFile> extra_config = memnew(ConfigFile); - String exe_path = OS::get_singleton()->get_executable_path().get_base_dir(); - DirAccess *d = DirAccess::create_for_path(exe_path); - bool self_contained = false; - - if (d->file_exists(exe_path + "/._sc_")) { - self_contained = true; - Error err = extra_config->load(exe_path + "/._sc_"); + if (EditorPaths::get_singleton()->is_self_contained()) { + Error err = extra_config->load(EditorPaths::get_singleton()->get_self_contained_file()); if (err != OK) { - ERR_PRINT("Can't load config from path '" + exe_path + "/._sc_'."); - } - } else if (d->file_exists(exe_path + "/_sc_")) { - self_contained = true; - Error err = extra_config->load(exe_path + "/_sc_"); - if (err != OK) { - ERR_PRINT("Can't load config from path '" + exe_path + "/_sc_'."); + ERR_PRINT("Can't load extra config from path :" + EditorPaths::get_singleton()->get_self_contained_file()); } } - memdelete(d); - if (self_contained) { - // editor is self contained, all in same folder - data_path = exe_path; - data_dir = data_path.plus_file("editor_data"); - config_path = exe_path; - config_dir = data_dir; - cache_path = exe_path; - cache_dir = data_dir.plus_file("cache"); - } else { - // Typically XDG_DATA_HOME or %APPDATA% - data_path = OS::get_singleton()->get_data_path(); - data_dir = data_path.plus_file(OS::get_singleton()->get_godot_dir_name()); - // Can be different from data_path e.g. on Linux or macOS - config_path = OS::get_singleton()->get_config_path(); - config_dir = config_path.plus_file(OS::get_singleton()->get_godot_dir_name()); - // Can be different from above paths, otherwise a subfolder of data_dir - cache_path = OS::get_singleton()->get_cache_path(); - if (cache_path == data_path) { - cache_dir = data_dir.plus_file("cache"); - } else { - cache_dir = cache_path.plus_file(OS::get_singleton()->get_godot_dir_name()); - } - } + DirAccess *dir = nullptr; ClassDB::register_class<EditorSettings>(); //otherwise it can't be unserialized String config_file_path; - if (data_path != "" && config_path != "" && cache_path != "") { + if (EditorPaths::get_singleton()->are_paths_valid()) { // Validate/create data dir and subdirectories + String data_dir = EditorPaths::get_singleton()->get_data_dir(); + dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (dir->change_dir(data_dir) != OK) { dir->make_dir_recursive(data_dir); @@ -975,22 +936,11 @@ void EditorSettings::create() { dir->change_dir(".."); } - // Validate/create cache dir - - if (dir->change_dir(cache_dir) != OK) { - dir->make_dir_recursive(cache_dir); - if (dir->change_dir(cache_dir) != OK) { - ERR_PRINT("Cannot create cache directory!"); - memdelete(dir); - goto fail; - } - } - // Validate/create config dir and subdirectories - if (dir->change_dir(config_dir) != OK) { - dir->make_dir_recursive(config_dir); - if (dir->change_dir(config_dir) != OK) { + if (dir->change_dir(EditorPaths::get_singleton()->get_config_dir()) != OK) { + dir->make_dir_recursive(EditorPaths::get_singleton()->get_config_dir()); + if (dir->change_dir(EditorPaths::get_singleton()->get_config_dir()) != OK) { ERR_PRINT("Cannot create config directory!"); memdelete(dir); goto fail; @@ -1031,7 +981,7 @@ void EditorSettings::create() { // Validate editor config file String config_file_name = "editor_settings-" + itos(VERSION_MAJOR) + ".tres"; - config_file_path = config_dir.plus_file(config_file_name); + config_file_path = EditorPaths::get_singleton()->get_config_dir().plus_file(config_file_name); if (!dir->file_exists(config_file_name)) { memdelete(dir); goto fail; @@ -1048,9 +998,6 @@ void EditorSettings::create() { singleton->save_changed_setting = true; singleton->config_file_path = config_file_path; - singleton->settings_dir = config_dir; - singleton->data_dir = data_dir; - singleton->cache_dir = cache_dir; print_verbose("EditorSettings: Load OK!"); @@ -1065,6 +1012,8 @@ void EditorSettings::create() { fail: // patch init projects + String exe_path = OS::get_singleton()->get_executable_path().get_base_dir(); + if (extra_config->has_section("init_projects")) { Vector<String> list = extra_config->get_value("init_projects", "list"); for (int i = 0; i < list.size(); i++) { @@ -1076,9 +1025,6 @@ fail: singleton = Ref<EditorSettings>(memnew(EditorSettings)); singleton->save_changed_setting = true; singleton->config_file_path = config_file_path; - singleton->settings_dir = config_dir; - singleton->data_dir = data_dir; - singleton->cache_dir = cache_dir; singleton->_load_defaults(extra_config); singleton->setup_language(); singleton->setup_network(); @@ -1308,30 +1254,22 @@ void EditorSettings::add_property_hint(const PropertyInfo &p_hint) { // Data directories -String EditorSettings::get_data_dir() const { - return data_dir; -} - String EditorSettings::get_templates_dir() const { - return get_data_dir().plus_file("templates"); + return EditorPaths::get_singleton()->get_data_dir().plus_file("templates"); } // Config directories -String EditorSettings::get_settings_dir() const { - return settings_dir; -} - String EditorSettings::get_project_settings_dir() const { return EditorSettings::PROJECT_EDITOR_SETTINGS_PATH; } String EditorSettings::get_text_editor_themes_dir() const { - return get_settings_dir().plus_file("text_editor_themes"); + return EditorPaths::get_singleton()->get_settings_dir().plus_file("text_editor_themes"); } String EditorSettings::get_script_templates_dir() const { - return get_settings_dir().plus_file("script_templates"); + return EditorPaths::get_singleton()->get_settings_dir().plus_file("script_templates"); } String EditorSettings::get_project_script_templates_dir() const { @@ -1340,12 +1278,8 @@ String EditorSettings::get_project_script_templates_dir() const { // Cache directory -String EditorSettings::get_cache_dir() const { - return cache_dir; -} - String EditorSettings::get_feature_profiles_dir() const { - return get_settings_dir().plus_file("feature_profiles"); + return EditorPaths::get_singleton()->get_settings_dir().plus_file("feature_profiles"); } // Metadata @@ -1432,7 +1366,7 @@ bool EditorSettings::is_dark_theme() { } void EditorSettings::list_text_editor_themes() { - String themes = "Adaptive,Default,Custom"; + String themes = "Default,Godot 2,Custom"; DirAccess *d = DirAccess::open(get_text_editor_themes_dir()); if (d) { @@ -1460,8 +1394,8 @@ void EditorSettings::load_text_editor_theme() { String p_file = get("text_editor/theme/color_theme"); if (_is_default_text_editor_theme(p_file.get_file().to_lower())) { - if (p_file == "Default") { - _load_default_text_editor_theme(); + if (p_file == "Godot 2") { + _load_godot2_text_editor_theme(); } return; // sorry for "Settings changed" console spam } @@ -1572,7 +1506,7 @@ Vector<String> EditorSettings::get_script_templates(const String &p_extension, c } String EditorSettings::get_editor_layouts_config() const { - return get_settings_dir().plus_file("editor_layouts.cfg"); + return EditorPaths::get_singleton()->get_settings_dir().plus_file("editor_layouts.cfg"); } // Shortcuts @@ -1656,10 +1590,10 @@ Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p ie->set_unicode(p_keycode & KEY_CODE_MASK); ie->set_keycode(p_keycode & KEY_CODE_MASK); - ie->set_shift(bool(p_keycode & KEY_MASK_SHIFT)); - ie->set_alt(bool(p_keycode & KEY_MASK_ALT)); - ie->set_control(bool(p_keycode & KEY_MASK_CTRL)); - ie->set_metakey(bool(p_keycode & KEY_MASK_META)); + ie->set_shift_pressed(bool(p_keycode & KEY_MASK_SHIFT)); + ie->set_alt_pressed(bool(p_keycode & KEY_MASK_ALT)); + ie->set_ctrl_pressed(bool(p_keycode & KEY_MASK_CTRL)); + ie->set_meta_pressed(bool(p_keycode & KEY_MASK_META)); } if (!EditorSettings::get_singleton()) { @@ -1774,7 +1708,6 @@ void EditorSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &EditorSettings::property_get_revert); ClassDB::bind_method(D_METHOD("add_property_info", "info"), &EditorSettings::_add_property_info_bind); - ClassDB::bind_method(D_METHOD("get_settings_dir"), &EditorSettings::get_settings_dir); ClassDB::bind_method(D_METHOD("get_project_settings_dir"), &EditorSettings::get_project_settings_dir); ClassDB::bind_method(D_METHOD("set_project_metadata", "section", "key", "data"), &EditorSettings::set_project_metadata); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index e5f8527faf..4c361403a9 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -36,6 +36,7 @@ #include "core/object/class_db.h" #include "core/os/thread_safe.h" #include "core/string/translation.h" +#include "editor/editor_paths.h" #include "scene/gui/shortcut.h" class EditorPlugin; @@ -87,12 +88,7 @@ private: mutable Map<String, Ref<Shortcut>> shortcuts; Map<String, List<Ref<InputEvent>>> builtin_action_overrides; - String resource_path; - String settings_dir; - String data_dir; - String cache_dir; String config_file_path; - String project_config_dir; Vector<String> favorites; Vector<String> recent_dirs; @@ -108,7 +104,7 @@ private: void _add_property_info_bind(const Dictionary &p_info); void _load_defaults(Ref<ConfigFile> p_extra_config = Ref<ConfigFile>()); - void _load_default_text_editor_theme(); + void _load_godot2_text_editor_theme(); bool _save_text_editor_theme(String p_file); bool _is_default_text_editor_theme(String p_theme_name); @@ -153,12 +149,10 @@ public: String get_data_dir() const; String get_templates_dir() const; - String get_settings_dir() const; String get_project_settings_dir() const; String get_text_editor_themes_dir() const; String get_script_templates_dir() const; String get_project_script_templates_dir() const; - String get_cache_dir() const; String get_feature_profiles_dir() const; void set_project_metadata(const String &p_section, const String &p_key, Variant p_data); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index dba53a9708..657dcfa760 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -70,6 +70,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { grabbing_spinner_dist_cache = 0; pre_grab_value = get_value(); grabbing_spinner = false; + grabbing_spinner_mouse_pos = get_global_mouse_position(); } } else { if (grabbing_spinner_attempt) { @@ -96,7 +97,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid()) { if (grabbing_spinner_attempt) { double diff_x = mm->get_relative().x; - if (mm->get_shift() && grabbing_spinner) { + if (mm->is_shift_pressed() && grabbing_spinner) { diff_x *= 0.1; } grabbing_spinner_dist_cache += diff_x; @@ -115,7 +116,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) { pre_grab_value = get_max(); } - if (mm->get_control()) { + if (mm->is_ctrl_pressed()) { // If control was just pressed, don't make the value do a huge jump in magnitude. if (grabbing_spinner_dist_cache != 0) { pre_grab_value += grabbing_spinner_dist_cache * get_step(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index d5ad638436..7971dfc313 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -144,70 +144,70 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = Set<StringName> exceptions; if (!p_dark_theme) { - // convert color: FROM TO - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // common icon color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#414141"); // white - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#363636"); // script darker color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f9f9f9", "#606060"); // scrollbar grabber highlight color - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cea4f1", "#a85de9"); // animation - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc9c9c", "#cd3838"); // spatial - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5b7f3", "#3d64dd"); // 2d - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#708cea", "#1a3eac"); // 2d dark - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5efac", "#2fa139"); // control - - // rainbow - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff7070", "#ff2929"); // red - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffeb70", "#ffe337"); // yellow - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9dff70", "#74ff34"); // green - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70ffb9", "#2cff98"); // aqua - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70deff", "#22ccff"); // blue - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9f70ff", "#702aff"); // purple - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff70ac", "#ff2781"); // pink - - // audio gradient - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff4040"); // red - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1dc7a", "#d6cf4b"); // yellow - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00f010"); // green - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffd684", "#fea900"); // mesh (orange) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#40a2ff", "#68b6ff"); // shape (blue) - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff3333"); // remove (red) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00db50"); // add (green) - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84c2ff", "#5caeff"); // selection (blue) + // Convert color: FROM TO + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // Common icon color + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#414141"); // White + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#363636"); // Script darker color + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f9f9f9", "#606060"); // Scrollbar grabber highlight color + + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c38ef1", "#a85de9"); // Animation + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc7f7f", "#cd3838"); // Spatial + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8da5f3", "#3d64dd"); // 2D + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4b70ea", "#1a3eac"); // 2D Dark + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8eef97", "#2fa139"); // Control + + // Rainbow + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff4545", "#ff2929"); // Red + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffe345", "#ffe337"); // Yellow + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#80ff45", "#74ff34"); // Green + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#45ffa2", "#2cff98"); // Aqua + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#45d7ff", "#22ccff"); // Blue + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8045ff", "#702aff"); // Purple + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff4596", "#ff2781"); // Pink + + // Audio gradient + // Red is defined further below. + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1da5b", "#d6cf4b"); // Yellow + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fff97", "#00f010"); // Green + + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffca5f", "#fea900"); // Mesh resource (orange) + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0787ff", "#68b6ff"); // Shape resource (blue) + + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff5f5f", "#ff3333"); // Red audio gradient + remove (red) + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fff97", "#00db50"); // Add (green) + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fb2ff", "#5caeff"); // Selection (blue) // Animation editor tracks - // The property track icon color is set by the common icon color - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea9568", "#bd5e2c"); // 3D Transform track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#66f376", "#16a827"); // Call Method track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5792f6", "#236be6"); // Bezier Curve track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eae668", "#9f9722"); // Audio Playback track - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b76ef0", "#9853ce"); // Animation Playback track + // The property track icon color is set by the common icon color. + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea7940", "#bd5e2c"); // 3D Transform track + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#3cf34e", "#16a827"); // Call Method track + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#2877f6", "#236be6"); // Bezier Curve track + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eae440", "#9f9722"); // Audio Playback track + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a448f0", "#9853ce"); // Animation Playback track // TileSet editor icons - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fce844", "#aa8d24"); // New Single Tile - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4490fc", "#0350bd"); // New Autotile - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c9cfd4", "#828f9b"); // New Atlas - - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#69ecbd", "#25e3a0"); // VS variant - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8da6f0", "#6d8eeb"); // VS bool - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#7dc6ef", "#4fb2e9"); // VS int - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#61daf4", "#27ccf0"); // VS float - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#6ba7ec", "#4690e7"); // VS string - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#bd91f1", "#ad76ee"); // VS vector2 - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f191a5", "#ee758e"); // VS rect - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e286f0", "#dc6aed"); // VS vector3 - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c4ec69", "#96ce1a"); // VS transform2D - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f77070", "#f77070"); // VS plane - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ec69a3", "#ec69a3"); // VS quat - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ee7991", "#ee7991"); // VS aabb - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e3ec69", "#b2bb19"); // VS basis - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f6a86e", "#f49047"); // VS transform - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#6993ec", "#6993ec"); // VS path - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#69ec9a", "#2ce573"); // VS rid - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#79f3e8", "#12d5c3"); // VS object - ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#77edb1", "#57e99f"); // VS dict + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fce00e", "#aa8d24"); // New Single Tile + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0e71fc", "#0350bd"); // New Autotile + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c6ced4", "#828f9b"); // New Atlas + + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#41ecad", "#25e3a0"); // VisualScript variant + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#6f91f0", "#6d8eeb"); // VisualScript bool + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5abbef", "#4fb2e9"); // VisualScript int + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#35d4f4", "#27ccf0"); // VisualScript float + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4593ec", "#4690e7"); // VisualScript String + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ac73f1", "#ad76ee"); // VisualScript Vector2 + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f1738f", "#ee758e"); // VisualScript Rect2 + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#de66f0", "#dc6aed"); // VisualScript Vector3 + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b9ec41", "#96ce1a"); // VisualScript Transform2D + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f74949", "#f77070"); // VisualScript Plane + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ec418e", "#ec69a3"); // VisualScript Quat + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ee5677", "#ee7991"); // VisualScript AABB + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1ec41", "#b2bb19"); // VisualScript Basis + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f68f45", "#f49047"); // VisualScript Transform + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#417aec", "#6993ec"); // VisualScript NodePath + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#41ec80", "#2ce573"); // VisualScript RID + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#55f3e3", "#12d5c3"); // VisualScript Object + ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#54ed9e", "#57e99f"); // VisualScript Dictionary exceptions.insert("EditorPivot"); exceptions.insert("EditorHandle"); @@ -216,6 +216,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = exceptions.insert("Sky"); exceptions.insert("EditorControlAnchor"); exceptions.insert("DefaultProjectIcon"); + exceptions.insert("GuiChecked"); exceptions.insert("GuiCloseCustomizable"); exceptions.insert("GuiGraphNodePort"); exceptions.insert("GuiResizer"); @@ -328,16 +329,18 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { preset_contrast = default_contrast; } else if (preset == "Light") { preset_accent_color = Color(0.18, 0.50, 1.00); - preset_base_color = Color(1.00, 1.00, 1.00); - preset_contrast = 0.08; + preset_base_color = Color(0.9, 0.9, 0.9); + // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". + preset_contrast = -0.08; } else if (preset == "Solarized (Dark)") { preset_accent_color = Color(0.15, 0.55, 0.82); preset_base_color = Color(0.04, 0.23, 0.27); preset_contrast = default_contrast; } else if (preset == "Solarized (Light)") { preset_accent_color = Color(0.15, 0.55, 0.82); - preset_base_color = Color(0.99, 0.96, 0.89); - preset_contrast = 0.08; + preset_base_color = Color(0.89, 0.86, 0.79); + // A negative contrast rate looks better for light themes, since it better follows the natural order of UI "elevation". + preset_contrast = -0.08; } else { // Default preset_accent_color = Color(0.44, 0.73, 0.98); preset_base_color = Color(0.21, 0.24, 0.29); @@ -560,9 +563,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tab_unselected->set_bg_color(dark_color_1); style_tab_unselected->set_expand_margin_size(SIDE_BOTTOM, 0); // Add some spacing between unselected tabs to make them easier to distinguish from each other - style_tab_unselected->set_border_color(dark_color_2); - style_tab_unselected->set_border_width(SIDE_LEFT, Math::round(2 * EDSCALE)); - style_tab_unselected->set_border_width(SIDE_RIGHT, Math::round(2 * EDSCALE)); + style_tab_unselected->set_border_color(Color(0, 0, 0, 0)); + style_tab_unselected->set_border_width(SIDE_LEFT, Math::round(1 * EDSCALE)); + style_tab_unselected->set_border_width(SIDE_RIGHT, Math::round(1 * EDSCALE)); + style_tab_unselected->set_default_margin(SIDE_LEFT, widget_default_margin.x + 2 * EDSCALE); + style_tab_unselected->set_default_margin(SIDE_RIGHT, widget_default_margin.x + 2 * EDSCALE); Ref<StyleBoxFlat> style_tab_disabled = style_tab_selected->duplicate(); style_tab_disabled->set_bg_color(disabled_bg_color); @@ -597,15 +602,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("focus", "MenuButton", style_menu); theme->set_stylebox("disabled", "MenuButton", style_menu); - theme->set_stylebox("normal", "PopupMenu", style_menu); - - Ref<StyleBoxFlat> style_menu_hover = style_widget_hover->duplicate(); - // Don't use rounded corners for hover highlights since the StyleBox touches the PopupMenu's edges. - style_menu_hover->set_corner_radius_all(0); - theme->set_stylebox("hover", "PopupMenu", style_menu_hover); - theme->set_stylebox("focus", "PopupMenu", style_menu); - theme->set_stylebox("disabled", "PopupMenu", style_menu); - theme->set_color("font_color", "MenuButton", font_color); theme->set_color("font_hover_color", "MenuButton", font_hover_color); @@ -711,8 +707,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_popup_menu->set_default_margin(SIDE_TOP, popup_menu_margin_size); style_popup_menu->set_default_margin(SIDE_RIGHT, 1 * EDSCALE); style_popup_menu->set_default_margin(SIDE_BOTTOM, popup_menu_margin_size); - + // Always display a border for PopupMenus so they can be distinguished from their background. + style_popup_menu->set_border_width_all(1 * EDSCALE); + style_popup_menu->set_border_color(dark_color_2); theme->set_stylebox("panel", "PopupMenu", style_popup_menu); + + Ref<StyleBoxFlat> style_menu_hover = style_widget_hover->duplicate(); + // Don't use rounded corners for hover highlights since the StyleBox touches the PopupMenu's edges. + style_menu_hover->set_corner_radius_all(0); + theme->set_stylebox("hover", "PopupMenu", style_menu_hover); + theme->set_stylebox("separator", "PopupMenu", style_popup_separator); theme->set_stylebox("labeled_separator_left", "PopupMenu", style_popup_labeled_separator_left); theme->set_stylebox("labeled_separator_right", "PopupMenu", style_popup_labeled_separator_right); @@ -797,8 +801,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tree_bg->set_border_color(dark_color_3); theme->set_stylebox("bg", "Tree", style_tree_bg); - const Color guide_color = mono_color * Color(1, 1, 1, 0.05); - Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); // Tree theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons")); @@ -815,19 +817,33 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color", "Tree", font_color); theme->set_color("font_selected_color", "Tree", mono_color); theme->set_color("title_button_color", "Tree", font_color); - theme->set_color("guide_color", "Tree", guide_color); - theme->set_color("relationship_line_color", "Tree", relationship_line_color); theme->set_color("drop_position_color", "Tree", accent_color); theme->set_constant("vseparation", "Tree", widget_default_margin.y - EDSCALE); theme->set_constant("hseparation", "Tree", 6 * EDSCALE); theme->set_constant("guide_width", "Tree", border_width); theme->set_constant("item_margin", "Tree", 3 * default_margin_size * EDSCALE); theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); - theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01); - theme->set_constant("draw_guides", "Tree", relationship_line_opacity < 0.01); theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); theme->set_constant("scroll_speed", "Tree", 12); + const Color guide_color = mono_color * Color(1, 1, 1, 0.05); + Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); + + theme->set_constant("draw_guides", "Tree", relationship_line_opacity < 0.01); + theme->set_color("guide_color", "Tree", guide_color); + + int relationship_line_width = 1; + Color parent_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.45, 0.0, 1.0)); + Color children_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.25, 0.0, 1.0)); + theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01); + theme->set_constant("relationship_line_width", "Tree", relationship_line_width); + theme->set_constant("parent_hl_line_width", "Tree", relationship_line_width * 2); + theme->set_constant("children_hl_line_width", "Tree", relationship_line_width); + theme->set_constant("parent_hl_line_margin", "Tree", relationship_line_width * 3); + theme->set_color("relationship_line_color", "Tree", relationship_line_color); + theme->set_color("parent_hl_line_color", "Tree", parent_line_color); + theme->set_color("children_hl_line_color", "Tree", children_line_color); + Ref<StyleBoxFlat> style_tree_btn = style_default->duplicate(); style_tree_btn->set_bg_color(highlight_color); style_tree_btn->set_border_width_all(0); @@ -929,6 +945,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_content_panel->set_default_margin(SIDE_RIGHT, margin_size_extra * EDSCALE); style_content_panel->set_default_margin(SIDE_BOTTOM, margin_size_extra * EDSCALE); style_content_panel->set_default_margin(SIDE_LEFT, margin_size_extra * EDSCALE); + // Display border to visually split the body of the container from its possible backgrounds. + style_content_panel->set_border_width(Side::SIDE_TOP, Math::round(2 * EDSCALE)); + style_content_panel->set_border_color(dark_color_2); + theme->set_stylebox("panel", "TabContainer", style_content_panel); // this is the stylebox used in 3d and 2d viewports (no borders) Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate(); @@ -936,9 +956,17 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_content_panel_vp->set_default_margin(SIDE_TOP, default_margin_size * EDSCALE); style_content_panel_vp->set_default_margin(SIDE_RIGHT, border_width * 2); style_content_panel_vp->set_default_margin(SIDE_BOTTOM, border_width * 2); - theme->set_stylebox("panel", "TabContainer", style_content_panel); theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp); + // These styleboxes can be used on tabs against the base color background (e.g. nested tabs). + Ref<StyleBoxFlat> style_tab_selected_odd = style_tab_selected->duplicate(); + style_tab_selected_odd->set_bg_color(disabled_bg_color); + theme->set_stylebox("tab_selected_odd", "TabContainer", style_tab_selected_odd); + + Ref<StyleBoxFlat> style_content_panel_odd = style_content_panel->duplicate(); + style_content_panel_odd->set_bg_color(disabled_bg_color); + theme->set_stylebox("panel_odd", "TabContainer", style_content_panel_odd); + // Separators theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width))); theme->set_stylebox("separator", "VSeparator", make_line_stylebox(separator_color, MAX(Math::round(EDSCALE), border_width), 0, 0, true)); @@ -1329,7 +1357,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color comment_color = dim_color; const Color string_color = (dark_theme ? Color(1.0, 0.85, 0.26) : Color(1.0, 0.82, 0.09)).lerp(mono_color, dark_theme ? 0.5 : 0.3); - const Color te_background_color = dark_theme ? background_color : base_color; + // Use the brightest background color on a light theme (which generally uses a negative contrast rate). + const Color te_background_color = dark_theme ? background_color : dark_color_3; const Color completion_background_color = dark_theme ? base_color : background_color; const Color completion_selected_color = alpha1; const Color completion_existing_color = alpha2; @@ -1358,7 +1387,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { EditorSettings *setting = EditorSettings::get_singleton(); String text_editor_color_theme = setting->get("text_editor/theme/color_theme"); - if (text_editor_color_theme == "Adaptive") { + if (text_editor_color_theme == "Default") { setting->set_initial_value("text_editor/highlighting/symbol_color", symbol_color, true); setting->set_initial_value("text_editor/highlighting/keyword_color", keyword_color, true); setting->set_initial_value("text_editor/highlighting/control_flow_keyword_color", control_flow_keyword_color, true); @@ -1394,7 +1423,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { setting->set_initial_value("text_editor/highlighting/code_folding_color", code_folding_color, true); setting->set_initial_value("text_editor/highlighting/search_result_color", search_result_color, true); setting->set_initial_value("text_editor/highlighting/search_result_border_color", search_result_border_color, true); - } else if (text_editor_color_theme == "Default") { + } else if (text_editor_color_theme == "Godot 2") { setting->load_text_editor_theme(); } diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 0f5c01be0e..6e0ae403a2 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -444,7 +444,7 @@ void ExportTemplateManager::_begin_template_download(const String &p_url) { } download_data.clear(); - download_templates->set_download_file(EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_templates.tpz")); + download_templates->set_download_file(EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_templates.tpz")); download_templates->set_use_threads(true); Error err = download_templates->request(p_url); diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index d80003a12a..654915e3e5 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -200,7 +200,7 @@ void EditorFileServer::_subthread_start(void *s) { cd->connection->put_data(buf4, 4); encode_uint32(OK, buf4); cd->connection->put_data(buf4, 4); - encode_uint64(fa->get_len(), buf4); + encode_uint64(fa->get_length(), buf4); cd->connection->put_data(buf4, 8); cd->files[id] = fa; @@ -230,8 +230,7 @@ void EditorFileServer::_subthread_start(void *s) { cd->files[id]->seek(offset); Vector<uint8_t> buf; buf.resize(blocklen); - int read = cd->files[id]->get_buffer(buf.ptrw(), blocklen); - ERR_CONTINUE(read < 0); + uint32_t read = cd->files[id]->get_buffer(buf.ptrw(), blocklen); print_verbose("GET BLOCK - offset: " + itos(offset) + ", blocklen: " + itos(blocklen)); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 6cd45fdf97..a21a33a44a 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -180,12 +180,12 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { Vector<String> uncollapsed_paths; TreeItem *root = tree->get_root(); if (root) { - TreeItem *favorites_item = root->get_children(); + TreeItem *favorites_item = root->get_first_child(); if (!favorites_item->is_collapsed()) { uncollapsed_paths.push_back(favorites_item->get_metadata(0)); } - TreeItem *resTree = root->get_children()->get_next(); + TreeItem *resTree = root->get_first_child()->get_next(); if (resTree) { Vector<TreeItem *> needs_check; needs_check.push_back(resTree); @@ -193,7 +193,7 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { while (needs_check.size()) { if (!needs_check[0]->is_collapsed()) { uncollapsed_paths.push_back(needs_check[0]->get_metadata(0)); - TreeItem *child = needs_check[0]->get_children(); + TreeItem *child = needs_check[0]->get_first_child(); while (child) { needs_check.push_back(child); child = child->get_next(); @@ -464,7 +464,7 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s return; } - TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *favorites_item = tree->get_root()->get_first_child(); if (selected->get_parent() == favorites_item && !String(selected->get_metadata(0)).ends_with("/")) { // Go to the favorites if we click in the favorites and the path has changed. path = "Favorites"; @@ -860,7 +860,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { file_list.push_back(fi); } } - file_list.sort(); } // Sort the file list if needed. @@ -1644,7 +1643,7 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { // Build a list of selected items with the active one at the first position. Vector<String> selected_strings; - TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *favorites_item = tree->get_root()->get_first_child(); TreeItem *active_selected = tree->get_selected(); if (active_selected && active_selected != favorites_item) { selected_strings.push_back(active_selected->get_metadata(0)); @@ -1700,7 +1699,7 @@ void FileSystemDock::_tree_rmb_option(int p_option) { while (needs_check.size()) { needs_check[0]->set_collapsed(is_collapsed); - TreeItem *child = needs_check[0]->get_children(); + TreeItem *child = needs_check[0]->get_first_child(); while (child) { needs_check.push_back(child); child = child->get_next(); @@ -1986,6 +1985,20 @@ void FileSystemDock::_resource_created() { editor->save_resource_as(RES(r), fpath); } +void FileSystemDock::_focus_current_search_box() { + LineEdit *current_search_box = nullptr; + if (display_mode == DISPLAY_MODE_TREE_ONLY) { + current_search_box = tree_search_box; + } else if (display_mode == DISPLAY_MODE_SPLIT) { + current_search_box = file_list_search_box; + } + + if (current_search_box) { + current_search_box->grab_focus(); + current_search_box->select_all(); + } +} + void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { if (searched_string.length() == 0) { // Register the uncollapsed paths before they change. @@ -2048,13 +2061,13 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) // Check if the first selected is in favorite. TreeItem *selected = tree->get_next_selected(tree->get_root()); while (selected) { - TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *favorites_item = tree->get_root()->get_first_child(); if (selected == favorites_item) { // The "Favorites" item is not draggable. return Variant(); } - bool is_favorite = selected->get_parent() != nullptr && tree->get_root()->get_children() == selected->get_parent(); + bool is_favorite = selected->get_parent() != nullptr && tree->get_root()->get_first_child() == selected->get_parent(); all_favorites &= is_favorite; all_not_favorites &= !is_favorite; selected = tree->get_next_selected(selected); @@ -2100,7 +2113,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da } int drop_section = tree->get_drop_section_at_position(p_point); - TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *favorites_item = tree->get_root()->get_first_child(); TreeItem *resources_item = favorites_item->get_next(); @@ -2176,7 +2189,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, int drop_position; Vector<String> files = drag_data["files"]; - TreeItem *favorites_item = tree->get_root()->get_children(); + TreeItem *favorites_item = tree->get_root()->get_first_child(); TreeItem *resources_item = favorites_item->get_next(); if (ti == favorites_item) { @@ -2250,7 +2263,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } } if (!to_move.is_empty()) { - if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CTRL)) { for (int i = 0; i < to_move.size(); i++) { String new_path; String new_path_base; @@ -2314,10 +2327,10 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori int section = tree->get_drop_section_at_position(p_point); if (ti) { // Check the favorites first. - if (ti == tree->get_root()->get_children() && section >= 0) { + if (ti == tree->get_root()->get_first_child() && section >= 0) { target_favorites = true; return; - } else if (ti->get_parent() == tree->get_root()->get_children()) { + } else if (ti->get_parent() == tree->get_root()->get_first_child()) { target_favorites = true; return; } else { @@ -2333,7 +2346,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori return; } } else { - if (ti->get_parent() != tree->get_root()->get_children()) { + if (ti->get_parent() != tree->get_root()->get_first_child()) { // Not in the favorite section. if (fpath != "res://") { // We drop between two files @@ -2576,6 +2589,8 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { _tree_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { _tree_rmb_option(FILE_RENAME); + } else if (ED_IS_SHORTCUT("editor/open_search", p_event)) { + _focus_current_search_box(); } else { return; } @@ -2595,6 +2610,8 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { _file_list_rmb_option(FILE_REMOVE); } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { _file_list_rmb_option(FILE_RENAME); + } else if (ED_IS_SHORTCUT("editor/open_search", p_event)) { + _focus_current_search_box(); } else { return; } @@ -2717,12 +2734,12 @@ MenuButton *FileSystemDock::_create_file_menu_button() { PopupMenu *p = button->get_popup(); p->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_sort_popup)); - p->add_radio_check_item("Sort by Name (Ascending)", FILE_SORT_NAME); - p->add_radio_check_item("Sort by Name (Descending)", FILE_SORT_NAME_REVERSE); - p->add_radio_check_item("Sort by Type (Ascending)", FILE_SORT_TYPE); - p->add_radio_check_item("Sort by Type (Descending)", FILE_SORT_TYPE_REVERSE); - p->add_radio_check_item("Sort by Last Modified", FILE_SORT_MODIFIED_TIME); - p->add_radio_check_item("Sort by First Modified", FILE_SORT_MODIFIED_TIME_REVERSE); + p->add_radio_check_item(TTR("Sort by Name (Ascending)"), FILE_SORT_NAME); + p->add_radio_check_item(TTR("Sort by Name (Descending)"), FILE_SORT_NAME_REVERSE); + p->add_radio_check_item(TTR("Sort by Type (Ascending)"), FILE_SORT_TYPE); + p->add_radio_check_item(TTR("Sort by Type (Descending)"), FILE_SORT_TYPE_REVERSE); + p->add_radio_check_item(TTR("Sort by Last Modified"), FILE_SORT_MODIFIED_TIME); + p->add_radio_check_item(TTR("Sort by First Modified"), FILE_SORT_MODIFIED_TIME_REVERSE); p->set_item_checked(file_sort, true); return button; } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 39dc4784b8..8783c402cd 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -253,6 +253,7 @@ private: void _toggle_split_mode(bool p_active); + void _focus_current_search_box(); void _search_changed(const String &p_text, const Control *p_from); MenuButton *_create_file_menu_button(); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index 47079a92b7..d9b956ed08 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -530,7 +530,7 @@ void FindInFilesDialog::_on_replace_text_entered(String text) { void FindInFilesDialog::_on_folder_selected(String path) { int i = path.find("://"); if (i != -1) { - path = path.right(i + 3); + path = path.substr(i + 3); } _folder_line_edit->set_text(path); } @@ -763,8 +763,10 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) { match_rect.position.y += 1 * EDSCALE; match_rect.size.y -= 2 * EDSCALE; - _results_display->draw_rect(match_rect, Color(0, 0, 0, 0.5)); - // Text is drawn by Tree already + // Use the inverted accent color to help match rectangles stand out even on the currently selected line. + _results_display->draw_rect(match_rect, get_theme_color("accent_color", "Editor").inverted() * Color(1, 1, 1, 0.5)); + + // Text is drawn by Tree already. } void FindInFilesPanel::_on_item_edited() { @@ -838,7 +840,7 @@ void FindInFilesPanel::_on_replace_all_clicked() { String fpath = file_item->get_metadata(0); Vector<Result> locations; - for (TreeItem *item = file_item->get_children(); item; item = item->get_next()) { + for (TreeItem *item = file_item->get_first_child(); item; item = item->get_next()) { if (!item->is_checked(0)) { continue; } @@ -932,7 +934,7 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result> continue; } - line = line.left(repl_begin) + new_text + line.right(repl_end); + line = line.left(repl_begin) + new_text + line.substr(repl_end); // keep an offset in case there are successive replaces in the same line offset += new_text.length() - (repl_end - repl_begin); } diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index f2a110ca03..d8e5a05c5d 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -52,7 +52,7 @@ void GroupDialog::_group_selected() { selected_group = groups->get_selected()->get_text(0); _load_nodes(scene_tree->get_edited_scene_root()); - group_empty->set_visible(!remove_node_root->get_children()); + group_empty->set_visible(!remove_node_root->get_first_child()); } void GroupDialog::_load_nodes(Node *p_current) { @@ -217,7 +217,7 @@ void GroupDialog::_group_renamed() { } const String name = renamed_group->get_text(0).strip_edges(); - for (TreeItem *E = groups_root->get_children(); E; E = E->get_next()) { + for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) { if (E != renamed_group && E->get_text(0) == name) { renamed_group->set_text(0, selected_group); error->set_text(TTR("Group name already exists.")); @@ -274,7 +274,7 @@ void GroupDialog::_rename_group_item(const String &p_old_name, const String &p_n selected_group = p_new_name; - for (TreeItem *E = groups_root->get_children(); E; E = E->get_next()) { + for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) { if (E->get_text(0) == p_old_name) { E->set_text(0, p_new_name); return; @@ -351,7 +351,7 @@ void GroupDialog::_delete_group_item(const String &p_name) { selected_group = ""; } - for (TreeItem *E = groups_root->get_children(); E; E = E->get_next()) { + for (TreeItem *E = groups_root->get_first_child(); E; E = E->get_next()) { if (E->get_text(0) == p_name) { groups_root->remove_child(E); return; diff --git a/editor/icons/AABB.svg b/editor/icons/AABB.svg index 03ec25caf2..7db093cc0d 100644 --- a/editor/icons/AABB.svg +++ b/editor/icons/AABB.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1a3 3 0 0 0 -3 3 3 3 0 0 0 .77734 2.0117 3 3 0 0 0 -2.7773 2.9883 3 3 0 0 0 3 3h2v-5h2v-6h-2zm6 0v5.1738a3 3 0 0 0 -1-.17383v-2h-2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2h-2zm-6 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm8 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm-10 3v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm7 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#ee7991"/><path d="m8 4v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm-5 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm0 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm7 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#fff" fill-opacity=".23529"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1a3 3 0 0 0 -3 3 3 3 0 0 0 .77734 2.0117 3 3 0 0 0 -2.7773 2.9883 3 3 0 0 0 3 3h2v-5h2v-6h-2zm6 0v5.1738a3 3 0 0 0 -1-.17383v-2h-2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2h-2zm-6 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm8 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm-10 3v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm7 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#ee5677"/><path d="m8 4v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm-5 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm0 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm7 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#fff" fill-opacity=".23529"/></svg> diff --git a/editor/icons/AddSplit.svg b/editor/icons/AddSplit.svg index 5c034d8d12..e46949182c 100644 --- a/editor/icons/AddSplit.svg +++ b/editor/icons/AddSplit.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 13 10-10" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/><circle cx="4" cy="12" fill="none" r="2"/><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-10 10a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 13 10-10" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/><circle cx="4" cy="12" fill="none" r="2"/><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-10 10a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Anchor.svg b/editor/icons/Anchor.svg index cb40970ba3..37bad8bec6 100644 --- a/editor/icons/Anchor.svg +++ b/editor/icons/Anchor.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8262v.17383h-2v2h2v3.8984a5 5 0 0 1 -3.8281-3.6035l-1.9336.51758a7 7 0 0 0 6.7617 5.1875 7 7 0 0 0 6.7617-5.1875l-1.9375-.51953a5 5 0 0 1 -3.8242 3.6035v-3.8965h2v-2h-2v-.17578a3 3 0 0 0 2-2.8242 3 3 0 0 0 -3-3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8262v.17383h-2v2h2v3.8984a5 5 0 0 1 -3.8281-3.6035l-1.9336.51758a7 7 0 0 0 6.7617 5.1875 7 7 0 0 0 6.7617-5.1875l-1.9375-.51953a5 5 0 0 1 -3.8242 3.6035v-3.8965h2v-2h-2v-.17578a3 3 0 0 0 2-2.8242 3 3 0 0 0 -3-3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/AnimatedSprite2D.svg b/editor/icons/AnimatedSprite2D.svg index 0c9d2933ee..b22aeadeb6 100644 --- a/editor/icons/AnimatedSprite2D.svg +++ b/editor/icons/AnimatedSprite2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#a5b7f3"><path d="m7 0c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v6c1.108 0 2-.89199 2-2v-6c0-1.108-.89199-2-2-2z" fill-opacity=".39216"/><path d="m5 2c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2z" fill-opacity=".58824"/><path d="m3 4c-1.108 0-2 .89199-2 2v7c0 1.108.89199 2 2 2h7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2zm0 4c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm7 0c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25-1.7324z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#8da5f3"><path d="m7 0c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v6c1.108 0 2-.89199 2-2v-6c0-1.108-.89199-2-2-2z" fill-opacity=".39216"/><path d="m5 2c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2z" fill-opacity=".58824"/><path d="m3 4c-1.108 0-2 .89199-2 2v7c0 1.108.89199 2 2 2h7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2zm0 4c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm7 0c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25-1.7324z"/></g></svg> diff --git a/editor/icons/AnimatedSprite3D.svg b/editor/icons/AnimatedSprite3D.svg index b25ebae683..99520a3bc2 100644 --- a/editor/icons/AnimatedSprite3D.svg +++ b/editor/icons/AnimatedSprite3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c"><path d="m7 0c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v6c1.108 0 2-.89199 2-2v-6c0-1.108-.89199-2-2-2z" fill-opacity=".39216"/><path d="m5 2c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2z" fill-opacity=".58824"/><path d="m3 4c-1.108 0-2 .89199-2 2v7c0 1.108.89199 2 2 2h7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2zm0 4c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm7 0c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25-1.7324z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m7 0c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v6c1.108 0 2-.89199 2-2v-6c0-1.108-.89199-2-2-2z" fill-opacity=".39216"/><path d="m5 2c-1.108 0-2 .89199-2 2h7c1.108 0 2 .89199 2 2v7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2z" fill-opacity=".58824"/><path d="m3 4c-1.108 0-2 .89199-2 2v7c0 1.108.89199 2 2 2h7c1.108 0 2-.89199 2-2v-7c0-1.108-.89199-2-2-2zm0 4c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm7 0c.554 0 1 .446 1 1v1c0 .554-.446 1-1 1s-1-.446-1-1v-1c0-.554.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25-1.7324z"/></g></svg> diff --git a/editor/icons/AnimationPlayer.svg b/editor/icons/AnimationPlayer.svg index 52b6b02c15..68a2c82dd0 100644 --- a/editor/icons/AnimationPlayer.svg +++ b/editor/icons/AnimationPlayer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1037.4v14h1.1667v-2h1.8333v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.8333v-2zm1.1667 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2zm-9.8333 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2z" fill="#cea4f1" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1037.4v14h1.1667v-2h1.8333v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.8333v-2zm1.1667 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2zm-9.8333 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2z" fill="#c38ef1" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/AnimationTree.svg b/editor/icons/AnimationTree.svg index d6484097c9..04c4d60402 100644 --- a/editor/icons/AnimationTree.svg +++ b/editor/icons/AnimationTree.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h1.166v-2h1.834v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.834v-2zm4 3h2v1 1h1 3v2h-2v1 1h1 1v2h-1-2a1.0001 1.0001 0 0 1 -1-1v-1-2h-1a1.0001 1.0001 0 0 1 -1-1v-1-1zm-2.834 1h1.834v2h-1.834zm9.834 0h2v2h-2zm-9.834 4h1.834v2h-1.834zm9.834 0h2v2h-2z" fill="#cea4f1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h1.166v-2h1.834v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.834v-2zm4 3h2v1 1h1 3v2h-2v1 1h1 1v2h-1-2a1.0001 1.0001 0 0 1 -1-1v-1-2h-1a1.0001 1.0001 0 0 1 -1-1v-1-1zm-2.834 1h1.834v2h-1.834zm9.834 0h2v2h-2zm-9.834 4h1.834v2h-1.834zm9.834 0h2v2h-2z" fill="#c38ef1"/></svg> diff --git a/editor/icons/Area2D.svg b/editor/icons/Area2D.svg index 005f70ed48..2150a582d2 100644 --- a/editor/icons/Area2D.svg +++ b/editor/icons/Area2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 2h2v-2h2v-2zm10 0v2h2v2h2v-4zm-7 3v2 4 2h8v-2-6zm2 2h4v4h-4zm-5 5v2 2h2 2v-2h-2v-2zm12 0v2h-2v2h4v-2-2z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 2h2v-2h2v-2zm10 0v2h2v2h2v-4zm-7 3v2 4 2h8v-2-6zm2 2h4v4h-4zm-5 5v2 2h2 2v-2h-2v-2zm12 0v2h-2v2h4v-2-2z" fill="#8da5f3"/></svg> diff --git a/editor/icons/Area3D.svg b/editor/icons/Area3D.svg index 4be8a2cced..88b6a42b23 100644 --- a/editor/icons/Area3D.svg +++ b/editor/icons/Area3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 2h2v-2h2v-2zm10 0v2h2v2h2v-4zm-7 3v2 4 2h8v-2-6zm2 2h4v4h-4zm-5 5v2 2h2 2v-2h-2v-2zm12 0v2h-2v2h4v-2-2z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 2h2v-2h2v-2zm10 0v2h2v2h2v-4zm-7 3v2 4 2h8v-2-6zm2 2h4v4h-4zm-5 5v2 2h2 2v-2h-2v-2zm12 0v2h-2v2h4v-2-2z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/ArrayMesh.svg b/editor/icons/ArrayMesh.svg index 3a33a966aa..2494a519fb 100644 --- a/editor/icons/ArrayMesh.svg +++ b/editor/icons/ArrayMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffca5f"/></svg> diff --git a/editor/icons/AspectRatioContainer.svg b/editor/icons/AspectRatioContainer.svg index a7aef8e028..d28bcc7193 100644 --- a/editor/icons/AspectRatioContainer.svg +++ b/editor/icons/AspectRatioContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-8 4v2h2v-2zm8 0v2h2v-2zm-8 4v2h2v-2zm8 0v2h2v-2zm-8 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2zm4 0v2c1.1046 0 2-.89543 2-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-8 4v2h2v-2zm8 0v2h2v-2zm-8 4v2h2v-2zm8 0v2h2v-2zm-8 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2zm4 0v2c1.1046 0 2-.89543 2-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/AudioBusLayout.svg b/editor/icons/AudioBusLayout.svg index 3b1f3e7a0d..9928f369e7 100644 --- a/editor/icons/AudioBusLayout.svg +++ b/editor/icons/AudioBusLayout.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m3 1c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm8 0c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm-8 1h2c.55401 0 1 .44599 1 1v10c0 .55401-.44599 1-1 1h-2c-.55401 0-1-.44599-1-1v-10c0-.55401.44599-1 1-1z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m3 1c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm8 0c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm-8 1h2c.55401 0 1 .44599 1 1v10c0 .55401-.44599 1-1 1h-2c-.55401 0-1-.44599-1-1v-10c0-.55401.44599-1 1-1z" fill="url(#a)"/></svg> diff --git a/editor/icons/AudioStreamMP3.svg b/editor/icons/AudioStreamMP3.svg index 900d5873fe..dc034c90de 100644 --- a/editor/icons/AudioStreamMP3.svg +++ b/editor/icons/AudioStreamMP3.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg> diff --git a/editor/icons/AudioStreamOGGVorbis.svg b/editor/icons/AudioStreamOGGVorbis.svg index 900d5873fe..dc034c90de 100644 --- a/editor/icons/AudioStreamOGGVorbis.svg +++ b/editor/icons/AudioStreamOGGVorbis.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg> diff --git a/editor/icons/AudioStreamPlayer.svg b/editor/icons/AudioStreamPlayer.svg index 48aa7c2904..6d074c0744 100644 --- a/editor/icons/AudioStreamPlayer.svg +++ b/editor/icons/AudioStreamPlayer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#e0e0e0"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#e0e0e0"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/AudioStreamPlayer2D.svg b/editor/icons/AudioStreamPlayer2D.svg index 21cf751c92..0bf091de29 100644 --- a/editor/icons/AudioStreamPlayer2D.svg +++ b/editor/icons/AudioStreamPlayer2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#a5b7f3"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#8da5f3"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/AudioStreamPlayer3D.svg b/editor/icons/AudioStreamPlayer3D.svg index d1e39e62f3..ebe3128a21 100644 --- a/editor/icons/AudioStreamPlayer3D.svg +++ b/editor/icons/AudioStreamPlayer3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#fc9c9c"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#fc7f7f"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/AudioStreamSample.svg b/editor/icons/AudioStreamSample.svg index 900d5873fe..dc034c90de 100644 --- a/editor/icons/AudioStreamSample.svg +++ b/editor/icons/AudioStreamSample.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg> diff --git a/editor/icons/BackBufferCopy.svg b/editor/icons/BackBufferCopy.svg index 9bd40395c0..c85a35a410 100644 --- a/editor/icons/BackBufferCopy.svg +++ b/editor/icons/BackBufferCopy.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v11h5v-2h-3v-7h6v-2zm6 3v11h8v-11zm2 2h4v7h-4z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v11h5v-2h-3v-7h6v-2zm6 3v11h8v-11zm2 2h4v7h-4z" fill="#8da5f3"/></svg> diff --git a/editor/icons/BakedLightmap.svg b/editor/icons/BakedLightmap.svg index ea9efa55ba..78f0a64a7b 100644 --- a/editor/icons/BakedLightmap.svg +++ b/editor/icons/BakedLightmap.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v2h12v-2zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9zm2 1h1v1h-1zm3 0h1v1h-1zm3 0h1v1h-1zm3 0h1v1h-1zm-9 2h10v6h-10zm3 1v1h4v-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v2h12v-2zm-1 3v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9zm2 1h1v1h-1zm3 0h1v1h-1zm3 0h1v1h-1zm3 0h1v1h-1zm-9 2h10v6h-10zm3 1v1h4v-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Basis.svg b/editor/icons/Basis.svg index 5ff892888a..e425cf3bcd 100644 --- a/editor/icons/Basis.svg +++ b/editor/icons/Basis.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm10 0v2h2v-2zm-3 2a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2zm7 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v-2h-2v4h4a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2zm-12 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#e3ec69"/><path d="m10 2v2h2v-2zm0 4v4h2v-4z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm10 0v2h2v-2zm-3 2a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2zm7 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v-2h-2v4h4a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2zm-12 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#e1ec41"/><path d="m10 2v2h2v-2zm0 4v4h2v-4z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/BezierHandlesBalanced.svg b/editor/icons/BezierHandlesBalanced.svg index e4b8ae12e3..911029e431 100644 --- a/editor/icons/BezierHandlesBalanced.svg +++ b/editor/icons/BezierHandlesBalanced.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.7627119 13.627119s1.2881355-6.847458 6.5762712-8.1355935c5.0847459.9491522 5.9661009 8.1355925 5.9661009 8.1355925" fill="none" stroke="#84c2ff" stroke-miterlimit="4.9" stroke-width="1.7"/><ellipse cx="1.898304" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><ellipse cx="14.237288" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><path d="m7.4559186 5.1473018-4.7355323 1.5541798" fill="none" stroke="#84c2ff" stroke-width=".618"/><path d="m10.790357 4.2063094-2.5009748.9433136" fill="none" stroke="#84c2ff" stroke-width=".614897"/><g fill="#e0e0e0"><ellipse cx="8.271187" cy="4.779661" rx="1.267586" ry="1.199789"/><path d="m1.7157324 5.8754878a1.2675855 1.1997888 0 0 0 -1.26757806 1.1992188 1.2675855 1.1997888 0 0 0 1.26757806 1.1992187 1.2675855 1.1997888 0 0 0 1.2675781-1.1992187 1.2675855 1.1997888 0 0 0 -1.2675781-1.1992188zm.00195.4238282a.84677333.80148375 0 0 1 .8476593.8007812.84677333.80148375 0 0 1 -.8476562.8007812.84677333.80148375 0 0 1 -.84765616-.8007812.84677333.80148375 0 0 1 .84765616-.8007812z"/><path d="m11.909414 2.4642073a1.2836218 1.231838 0 0 0 -1.283614 1.2312528 1.2836218 1.231838 0 0 0 1.283614 1.2312527 1.2836218 1.231838 0 0 0 1.283614-1.2312527 1.2836218 1.231838 0 0 0 -1.283614-1.2312528zm.002.4351497a.85748593.82289328 0 0 1 .858383.8221719.85748593.82289328 0 0 1 -.85838.822172.85748593.82289328 0 0 1 -.858379-.822172.85748593.82289328 0 0 1 .858379-.8221719z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.7627119 13.627119s1.2881355-6.847458 6.5762712-8.1355935c5.0847459.9491522 5.9661009 8.1355925 5.9661009 8.1355925" fill="none" stroke="#5fb2ff" stroke-miterlimit="4.9" stroke-width="1.7"/><ellipse cx="1.898304" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><ellipse cx="14.237288" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><path d="m7.4559186 5.1473018-4.7355323 1.5541798" fill="none" stroke="#5fb2ff" stroke-width=".618"/><path d="m10.790357 4.2063094-2.5009748.9433136" fill="none" stroke="#5fb2ff" stroke-width=".614897"/><g fill="#e0e0e0"><ellipse cx="8.271187" cy="4.779661" rx="1.267586" ry="1.199789"/><path d="m1.7157324 5.8754878a1.2675855 1.1997888 0 0 0 -1.26757806 1.1992188 1.2675855 1.1997888 0 0 0 1.26757806 1.1992187 1.2675855 1.1997888 0 0 0 1.2675781-1.1992187 1.2675855 1.1997888 0 0 0 -1.2675781-1.1992188zm.00195.4238282a.84677333.80148375 0 0 1 .8476593.8007812.84677333.80148375 0 0 1 -.8476562.8007812.84677333.80148375 0 0 1 -.84765616-.8007812.84677333.80148375 0 0 1 .84765616-.8007812z"/><path d="m11.909414 2.4642073a1.2836218 1.231838 0 0 0 -1.283614 1.2312528 1.2836218 1.231838 0 0 0 1.283614 1.2312527 1.2836218 1.231838 0 0 0 1.283614-1.2312527 1.2836218 1.231838 0 0 0 -1.283614-1.2312528zm.002.4351497a.85748593.82289328 0 0 1 .858383.8221719.85748593.82289328 0 0 1 -.85838.822172.85748593.82289328 0 0 1 -.858379-.822172.85748593.82289328 0 0 1 .858379-.8221719z"/></g></svg> diff --git a/editor/icons/BezierHandlesFree.svg b/editor/icons/BezierHandlesFree.svg index 88f8146871..6e91288c79 100644 --- a/editor/icons/BezierHandlesFree.svg +++ b/editor/icons/BezierHandlesFree.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.7627119 13.627119s1.2881355-6.847458 6.5762712-8.1355935c5.0847459.9491522 5.9661009 8.1355925 5.9661009 8.1355925" fill="none" stroke="#84c2ff" stroke-miterlimit="4.9" stroke-width="1.7"/><ellipse cx="1.898304" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><ellipse cx="14.237288" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><path d="m7.6850253 4.7560401-3.776127.6607599" fill="none" stroke="#84c2ff" stroke-width=".805138"/><path d="m11.695505 2.3941651-2.999121 2.2935078" fill="none" stroke="#84c2ff" stroke-width=".730798"/><g fill="#e0e0e0"><ellipse cx="8.271187" cy="4.779661" rx="1.267586" ry="1.199789"/><path d="m2.4961199 4.3976698a1.1997888 1.2675855 80.074672 0 0 -1.0419038 1.3997559 1.1997888 1.2675855 80.074672 0 0 1.4553094.9627848 1.1997888 1.2675855 80.074672 0 0 1.0419037-1.3997558 1.1997888 1.2675855 80.074672 0 0 -1.4553093-.9627849zm.074974.4171488a.80148375.84677333 80.074672 0 1 .9729986.6426896.80148375.84677333 80.074672 0 1 -.6969432.934902.80148375.84677333 80.074672 0 1 -.9729958-.6426902.80148375.84677333 80.074672 0 1 .6969432-.934902z"/><path d="m11.838896.64428913a1.231838 1.2836218 52.593897 0 0 -.271701 1.75779027 1.231838 1.2836218 52.593897 0 0 1.767576.1983008 1.231838 1.2836218 52.593897 0 0 .271701-1.75779027 1.231838 1.2836218 52.593897 0 0 -1.767576-.1983008zm.265925.3444462a.82289328.85748593 52.593897 0 1 1.181294.13165847.82289328.85748593 52.593897 0 1 -.182417 1.1745241.82289328.85748593 52.593897 0 1 -1.181291-.1316609.82289328.85748593 52.593897 0 1 .182417-1.17452347z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.7627119 13.627119s1.2881355-6.847458 6.5762712-8.1355935c5.0847459.9491522 5.9661009 8.1355925 5.9661009 8.1355925" fill="none" stroke="#5fb2ff" stroke-miterlimit="4.9" stroke-width="1.7"/><ellipse cx="1.898304" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><ellipse cx="14.237288" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><path d="m7.6850253 4.7560401-3.776127.6607599" fill="none" stroke="#5fb2ff" stroke-width=".805138"/><path d="m11.695505 2.3941651-2.999121 2.2935078" fill="none" stroke="#5fb2ff" stroke-width=".730798"/><g fill="#e0e0e0"><ellipse cx="8.271187" cy="4.779661" rx="1.267586" ry="1.199789"/><path d="m2.4961199 4.3976698a1.1997888 1.2675855 80.074672 0 0 -1.0419038 1.3997559 1.1997888 1.2675855 80.074672 0 0 1.4553094.9627848 1.1997888 1.2675855 80.074672 0 0 1.0419037-1.3997558 1.1997888 1.2675855 80.074672 0 0 -1.4553093-.9627849zm.074974.4171488a.80148375.84677333 80.074672 0 1 .9729986.6426896.80148375.84677333 80.074672 0 1 -.6969432.934902.80148375.84677333 80.074672 0 1 -.9729958-.6426902.80148375.84677333 80.074672 0 1 .6969432-.934902z"/><path d="m11.838896.64428913a1.231838 1.2836218 52.593897 0 0 -.271701 1.75779027 1.231838 1.2836218 52.593897 0 0 1.767576.1983008 1.231838 1.2836218 52.593897 0 0 .271701-1.75779027 1.231838 1.2836218 52.593897 0 0 -1.767576-.1983008zm.265925.3444462a.82289328.85748593 52.593897 0 1 1.181294.13165847.82289328.85748593 52.593897 0 1 -.182417 1.1745241.82289328.85748593 52.593897 0 1 -1.181291-.1316609.82289328.85748593 52.593897 0 1 .182417-1.17452347z"/></g></svg> diff --git a/editor/icons/BezierHandlesMirror.svg b/editor/icons/BezierHandlesMirror.svg index 3a4b75ee96..9180e31921 100644 --- a/editor/icons/BezierHandlesMirror.svg +++ b/editor/icons/BezierHandlesMirror.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.7627119 13.627119s1.2881355-6.847458 6.5762712-8.1355935c5.0847459.9491522 5.9661009 8.1355925 5.9661009 8.1355925" fill="none" stroke="#84c2ff" stroke-miterlimit="4.9" stroke-width="1.7"/><ellipse cx="1.898304" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><ellipse cx="14.237288" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><path d="m8.2033896 4.6779662h-3.8335021" fill="none" stroke="#84c2ff" stroke-width=".805138"/><path d="m11.931789 4.6440679h-3.7283994" fill="none" stroke="#84c2ff" stroke-width=".716709"/><g fill="#e0e0e0"><ellipse cx="8.271187" cy="4.779661" rx="1.267586" ry="1.199789"/><path d="m3.1539157 3.4305762a1.2675855 1.1997888 0 0 0 -1.2675781 1.1992188 1.2675855 1.1997888 0 0 0 1.2675781 1.1992187 1.2675855 1.1997888 0 0 0 1.2675781-1.1992187 1.2675855 1.1997888 0 0 0 -1.2675781-1.1992188zm.00195.4238282a.84677333.80148375 0 0 1 .8476593.8007812.84677333.80148375 0 0 1 -.8476562.8007812.84677333.80148375 0 0 1 -.8476562-.8007812.84677333.80148375 0 0 1 .8476562-.8007812z"/><path d="m13.093969 3.3750567a1.2675855 1.1997888 0 0 0 -1.267578 1.1992188 1.2675855 1.1997888 0 0 0 1.267578 1.1992187 1.2675855 1.1997888 0 0 0 1.267578-1.1992187 1.2675855 1.1997888 0 0 0 -1.267578-1.1992188zm.002.4238282a.84677333.80148375 0 0 1 .847659.8007812.84677333.80148375 0 0 1 -.847656.8007812.84677333.80148375 0 0 1 -.847656-.8007812.84677333.80148375 0 0 1 .847656-.8007812z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.7627119 13.627119s1.2881355-6.847458 6.5762712-8.1355935c5.0847459.9491522 5.9661009 8.1355925 5.9661009 8.1355925" fill="none" stroke="#5fb2ff" stroke-miterlimit="4.9" stroke-width="1.7"/><ellipse cx="1.898304" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><ellipse cx="14.237288" cy="13.491526" fill="#e0e0e0" rx="1.267586" ry="1.199789"/><path d="m8.2033896 4.6779662h-3.8335021" fill="none" stroke="#5fb2ff" stroke-width=".805138"/><path d="m11.931789 4.6440679h-3.7283994" fill="none" stroke="#5fb2ff" stroke-width=".716709"/><g fill="#e0e0e0"><ellipse cx="8.271187" cy="4.779661" rx="1.267586" ry="1.199789"/><path d="m3.1539157 3.4305762a1.2675855 1.1997888 0 0 0 -1.2675781 1.1992188 1.2675855 1.1997888 0 0 0 1.2675781 1.1992187 1.2675855 1.1997888 0 0 0 1.2675781-1.1992187 1.2675855 1.1997888 0 0 0 -1.2675781-1.1992188zm.00195.4238282a.84677333.80148375 0 0 1 .8476593.8007812.84677333.80148375 0 0 1 -.8476562.8007812.84677333.80148375 0 0 1 -.8476562-.8007812.84677333.80148375 0 0 1 .8476562-.8007812z"/><path d="m13.093969 3.3750567a1.2675855 1.1997888 0 0 0 -1.267578 1.1992188 1.2675855 1.1997888 0 0 0 1.267578 1.1992187 1.2675855 1.1997888 0 0 0 1.267578-1.1992187 1.2675855 1.1997888 0 0 0 -1.267578-1.1992188zm.002.4238282a.84677333.80148375 0 0 1 .847659.8007812.84677333.80148375 0 0 1 -.847656.8007812.84677333.80148375 0 0 1 -.847656-.8007812.84677333.80148375 0 0 1 .847656-.8007812z"/></g></svg> diff --git a/editor/icons/Bone2D.svg b/editor/icons/Bone2D.svg index 2298022d6a..efbe9ca5b0 100644 --- a/editor/icons/Bone2D.svg +++ b/editor/icons/Bone2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#a5b7f3" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#8da5f3" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/BoneAttachment3D.svg b/editor/icons/BoneAttachment3D.svg index 2f2a9cdae5..be15631b5e 100644 --- a/editor/icons/BoneAttachment3D.svg +++ b/editor/icons/BoneAttachment3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#fc9c9c" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#fc7f7f" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/BoneTrack.svg b/editor/icons/BoneTrack.svg index 34fb76e696..69a32f3595 100644 --- a/editor/icons/BoneTrack.svg +++ b/editor/icons/BoneTrack.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#cea4f1" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804.7205 2.4664 2.4663 0 0 0 -.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397.6955 2.4664 2.4663 0 0 0 .69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 .31408-3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004-.3102 2.4664 2.4663 0 0 0 0-3.4875 2.4664 2.4663 0 0 0 -1.397-.6974 2.4664 2.4663 0 0 0 -.69561-1.3971 2.4664 2.4663 0 0 0 -1.7072-.7205z" fill="#c38ef1" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/BoxMesh.svg b/editor/icons/BoxMesh.svg index d540858248..6809b989cc 100644 --- a/editor/icons/BoxMesh.svg +++ b/editor/icons/BoxMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .88867-7 3.5v7.2227l7 3.5 7-3.5v-7.2227zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002zm10 0v3.9395l-4 2.002v-3.9414z" fill="#ffd684" stroke-width="1.0667" transform="scale(.9375)"/></svg> +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .88867-7 3.5v7.2227l7 3.5 7-3.5v-7.2227zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002zm10 0v3.9395l-4 2.002v-3.9414z" fill="#ffca5f" stroke-width="1.0667" transform="scale(.9375)"/></svg> diff --git a/editor/icons/BusVuEmpty.svg b/editor/icons/BusVuEmpty.svg index 32a27e26b5..cc72e7cd36 100644 --- a/editor/icons/BusVuEmpty.svg +++ b/editor/icons/BusVuEmpty.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="926.36" y2="1050.36"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -924.36)"><path d="m3 926.36c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill-opacity=".19608" transform="translate(0 924.36)"/></g></svg> +<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="926.36" y2="1050.36"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -924.36)"><path d="m3 926.36c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill-opacity=".19608" transform="translate(0 924.36)"/></g></svg> diff --git a/editor/icons/BusVuFull.svg b/editor/icons/BusVuFull.svg index acfa742d18..34396c3c18 100644 --- a/editor/icons/BusVuFull.svg +++ b/editor/icons/BusVuFull.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="2" y2="126"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1dc7a"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/></svg> +<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="2" y2="126"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/></svg> diff --git a/editor/icons/Button.svg b/editor/icons/Button.svg index 6046038289..a856b29a02 100644 --- a/editor/icons/Button.svg +++ b/editor/icons/Button.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3.1328l-1.4453-.96484-1.1094 1.6641 3 2a1.0001 1.0001 0 0 0 1.1094 0l3-2-1.1094-1.6641-1.4453.96484v-3.1328zm-1.5 8c-.831 0-1.5.669-1.5 1.5v1.5h-2v2h12v-2h-2v-1.5c0-.831-.669-1.5-1.5-1.5z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3.1328l-1.4453-.96484-1.1094 1.6641 3 2a1.0001 1.0001 0 0 0 1.1094 0l3-2-1.1094-1.6641-1.4453.96484v-3.1328zm-1.5 8c-.831 0-1.5.669-1.5 1.5v1.5h-2v2h12v-2h-2v-1.5c0-.831-.669-1.5-1.5-1.5z" fill="#8eef97"/></svg> diff --git a/editor/icons/CPUParticles3D.svg b/editor/icons/CPUParticles3D.svg index 072703cfa9..d7ced5fc6b 100644 --- a/editor/icons/CPUParticles3D.svg +++ b/editor/icons/CPUParticles3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#fc9c9c" fill-opacity=".996078"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#fc7f7f" fill-opacity=".996078"/></svg> diff --git a/editor/icons/Camera2D.svg b/editor/icons/Camera2D.svg index b6aa869be3..6b0f8e603f 100644 --- a/editor/icons/Camera2D.svg +++ b/editor/icons/Camera2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117-.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3z" fill="#a5b7f3" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117-.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3z" fill="#8da5f3" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/Camera3D.svg b/editor/icons/Camera3D.svg index f6e99cb56e..a8dee93de2 100644 --- a/editor/icons/Camera3D.svg +++ b/editor/icons/Camera3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117-.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3z" fill="#fc9c9c" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1038.4a3 3 0 0 0 -2.9883 2.7774 3 3 0 0 0 -2.0117-.7774 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8243v2.1757c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3z" fill="#fc7f7f" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/CameraEffects.svg b/editor/icons/CameraEffects.svg index de1d55e1a9..1ee7e15c87 100644 --- a/editor/icons/CameraEffects.svg +++ b/editor/icons/CameraEffects.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.9492188 2a3 3 0 0 0 -2.9492188 3 3 3 0 0 0 1 2.2304688v1.7695312l-3-2v6l3-2v1c0 .554.44599 1 1 1h3c.0076117-.045309.0115938-.096059.0214844-.134766.0773621-.302758.1860981-.478282.2832031-.625.1397097-.211089.2814954-.338835.4257813-.480468-.1445165-.141692-.2879205-.269839-.4277344-.480469-.0971224-.146315-.2052562-.321748-.2832032-.623047-.0777157-.300405-.1044198-.8152648.1640626-1.2910156.2700589-.4775976.7340166-.7239536 1.0371093-.8105469.3037241-.0867737.5108695-.0808838.6875-.0703125.2608449.0156115.4500479.0763383.6503909.1328125.049596-.1859081.086921-.3641449.195312-.5800781.078477-.1563394.174637-.3364783.396485-.5527344.221847-.2162561.652628-.4930277 1.195312-.4980469a1.6124973 1.6124973 0 0 1 .033203 0c.542861.0056205.97185.2837448 1.19336.5.146452.1429781.230167.265896.298828.3808594a3 3 0 0 0 .128906-.8671875 3 3 0 0 0 -3-3 3 3 0 0 0 -2.0117188.7773438 3 3 0 0 0 -2.9882812-2.7773438 3 3 0 0 0 -.0507812 0z" fill="#e0e0e0"/><path d="m12.36062 8.59795a.53334 3.2001 0 0 0 -.50976 2.2754 3.2001.53334 30 0 0 -2.2656-.71484 3.2001.53334 30 0 0 1.75 1.6016.53334 3.2001 60 0 0 -1.7461 1.5996.53334 3.2001 60 0 0 2.2578-.71094.53334 3.2001 0 0 0 .51367 2.3496.53334 3.2001 0 0 0 .51367-2.3516 3.2001.53334 30 0 0 2.2539.71094 3.2001.53334 30 0 0 -1.7441-1.5977.53334 3.2001 60 0 0 1.748-1.5996.53334 3.2001 60 0 0 -2.2617.71484.53334 3.2001 0 0 0 -.50977-2.2773z" fill="#cea4f1" stroke-width="1.0667"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.9492188 2a3 3 0 0 0 -2.9492188 3 3 3 0 0 0 1 2.2304688v1.7695312l-3-2v6l3-2v1c0 .554.44599 1 1 1h3c.0076117-.045309.0115938-.096059.0214844-.134766.0773621-.302758.1860981-.478282.2832031-.625.1397097-.211089.2814954-.338835.4257813-.480468-.1445165-.141692-.2879205-.269839-.4277344-.480469-.0971224-.146315-.2052562-.321748-.2832032-.623047-.0777157-.300405-.1044198-.8152648.1640626-1.2910156.2700589-.4775976.7340166-.7239536 1.0371093-.8105469.3037241-.0867737.5108695-.0808838.6875-.0703125.2608449.0156115.4500479.0763383.6503909.1328125.049596-.1859081.086921-.3641449.195312-.5800781.078477-.1563394.174637-.3364783.396485-.5527344.221847-.2162561.652628-.4930277 1.195312-.4980469a1.6124973 1.6124973 0 0 1 .033203 0c.542861.0056205.97185.2837448 1.19336.5.146452.1429781.230167.265896.298828.3808594a3 3 0 0 0 .128906-.8671875 3 3 0 0 0 -3-3 3 3 0 0 0 -2.0117188.7773438 3 3 0 0 0 -2.9882812-2.7773438 3 3 0 0 0 -.0507812 0z" fill="#e0e0e0"/><path d="m12.36062 8.59795a.53334 3.2001 0 0 0 -.50976 2.2754 3.2001.53334 30 0 0 -2.2656-.71484 3.2001.53334 30 0 0 1.75 1.6016.53334 3.2001 60 0 0 -1.7461 1.5996.53334 3.2001 60 0 0 2.2578-.71094.53334 3.2001 0 0 0 .51367 2.3496.53334 3.2001 0 0 0 .51367-2.3516 3.2001.53334 30 0 0 2.2539.71094 3.2001.53334 30 0 0 -1.7441-1.5977.53334 3.2001 60 0 0 1.748-1.5996.53334 3.2001 60 0 0 -2.2617.71484.53334 3.2001 0 0 0 -.50977-2.2773z" fill="#c38ef1" stroke-width="1.0667"/></svg> diff --git a/editor/icons/CanvasItemMaterial.svg b/editor/icons/CanvasItemMaterial.svg index 241184f8b9..9a7a89431c 100644 --- a/editor/icons/CanvasItemMaterial.svg +++ b/editor/icons/CanvasItemMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.1035 3a7 7 0 0 0 -1.418 2h12.631a7 7 0 0 0 -1.4277-2h-9.7852z" fill="#ffeb70"/><path d="m1.6855 5a7 7 0 0 0 -.60547 2h13.842a7 7 0 0 0 -.60547-2h-12.631z" fill="#9dff70"/><path d="m1.0801 7a7 7 0 0 0 -.080078 1 7 7 0 0 0 .078125 1h13.842a7 7 0 0 0 .080078-1 7 7 0 0 0 -.078125-1z" fill="#70ffb9"/><path d="m1.0781 9a7 7 0 0 0 .60547 2h12.631a7 7 0 0 0 .60547-2h-13.842z" fill="#70deff"/><path d="m3.1113 13a7 7 0 0 0 4.8887 2 7 7 0 0 0 4.8965-2z" fill="#ff70ac"/><path d="m1.6836 11a7 7 0 0 0 1.4277 2h9.7852a7 7 0 0 0 1.418-2h-12.631z" fill="#9f70ff"/><path d="m8 1a7 7 0 0 0 -4.8965 2h9.7852a7 7 0 0 0 -4.8887-2z" fill="#ff7070"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.1035 3a7 7 0 0 0 -1.418 2h12.631a7 7 0 0 0 -1.4277-2h-9.7852z" fill="#ffe345"/><path d="m1.6855 5a7 7 0 0 0 -.60547 2h13.842a7 7 0 0 0 -.60547-2h-12.631z" fill="#80ff45"/><path d="m1.0801 7a7 7 0 0 0 -.080078 1 7 7 0 0 0 .078125 1h13.842a7 7 0 0 0 .080078-1 7 7 0 0 0 -.078125-1z" fill="#45ffa2"/><path d="m1.0781 9a7 7 0 0 0 .60547 2h12.631a7 7 0 0 0 .60547-2h-13.842z" fill="#45d7ff"/><path d="m3.1113 13a7 7 0 0 0 4.8887 2 7 7 0 0 0 4.8965-2z" fill="#ff4596"/><path d="m1.6836 11a7 7 0 0 0 1.4277 2h9.7852a7 7 0 0 0 1.418-2h-12.631z" fill="#8045ff"/><path d="m8 1a7 7 0 0 0 -4.8965 2h9.7852a7 7 0 0 0 -4.8887-2z" fill="#ff4545"/></svg> diff --git a/editor/icons/CanvasItemShader.svg b/editor/icons/CanvasItemShader.svg index b8b1588843..9aeb2f0fdc 100644 --- a/editor/icons/CanvasItemShader.svg +++ b/editor/icons/CanvasItemShader.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.303 1c-.4344 0-.86973.16881-1.2012.50586l-1.4688 1.4941h4.3418c.082839-.52789-.072596-1.0872-.47266-1.4941-.33144-.33705-.76482-.50586-1.1992-.50586z" fill="#ff7070"/><path d="m10.633 3-1.9668 2h4.8008l1.0352-1.0527c.2628-.2673.41824-.60049.47266-.94727h-4.3418z" fill="#ffeb70"/><path d="m8.666 5-1.9648 2h4.7988l1.9668-2z" fill="#9dff70"/><path d="m6.7012 7-1.4004 1.4238.56641.57617h3.668l1.9648-2h-4.7988z" fill="#70ffb9"/><path d="m5.8672 9 1.834 1.8652 1.834-1.8652zm-1.752.57812c-.48501-.048725-.90521.12503-1.1953.45508-.21472.24426-.35243.57797-.39844.9668h3.5625c-.10223-.1935-.22224-.37965-.38281-.54297-.55011-.55955-1.1009-.83018-1.5859-.87891z" fill="#70deff"/><path d="m1.3242 13c.18414.24071.43707.53374.83789.94141.88382.899 2.6552.67038 3.5391-.22852.20747-.21103.36064-.45476.4707-.71289h-4.8477z" fill="#ff70ac"/><path d="m2.5215 11c-.0105.088737-.021484.17696-.021484.27148 0 1.3947-2.2782.28739-1.1758 1.7285h4.8477c.27363-.64173.24047-1.3785-.087891-2h-3.5625z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.303 1c-.4344 0-.86973.16881-1.2012.50586l-1.4688 1.4941h4.3418c.082839-.52789-.072596-1.0872-.47266-1.4941-.33144-.33705-.76482-.50586-1.1992-.50586z" fill="#ff4545"/><path d="m10.633 3-1.9668 2h4.8008l1.0352-1.0527c.2628-.2673.41824-.60049.47266-.94727h-4.3418z" fill="#ffe345"/><path d="m8.666 5-1.9648 2h4.7988l1.9668-2z" fill="#80ff45"/><path d="m6.7012 7-1.4004 1.4238.56641.57617h3.668l1.9648-2h-4.7988z" fill="#45ffa2"/><path d="m5.8672 9 1.834 1.8652 1.834-1.8652zm-1.752.57812c-.48501-.048725-.90521.12503-1.1953.45508-.21472.24426-.35243.57797-.39844.9668h3.5625c-.10223-.1935-.22224-.37965-.38281-.54297-.55011-.55955-1.1009-.83018-1.5859-.87891z" fill="#45d7ff"/><path d="m1.3242 13c.18414.24071.43707.53374.83789.94141.88382.899 2.6552.67038 3.5391-.22852.20747-.21103.36064-.45476.4707-.71289h-4.8477z" fill="#ff4596"/><path d="m2.5215 11c-.0105.088737-.021484.17696-.021484.27148 0 1.3947-2.2782.28739-1.1758 1.7285h4.8477c.27363-.64173.24047-1.3785-.087891-2h-3.5625z" fill="#8045ff"/></svg> diff --git a/editor/icons/CanvasItemShaderGraph.svg b/editor/icons/CanvasItemShaderGraph.svg index 838ca45178..70db53a4ba 100644 --- a/editor/icons/CanvasItemShaderGraph.svg +++ b/editor/icons/CanvasItemShaderGraph.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m8.0625 1025.9a3.375 3 0 0 0 -3.375 3 3.375 3 0 0 0 1.6875 2.5957v9.8115a3.375 3 0 0 0 -1.6875 2.5928 3.375 3 0 0 0 3.375 3 3.375 3 0 0 0 3.375-3 3.375 3 0 0 0 -1.6875-2.5957v-8.7832l11.931 10.605a3.375 3 0 0 0 -.11865.7735 3.375 3 0 0 0 3.375 3 3.375 3 0 0 0 3.375-3 3.375 3 0 0 0 -3.375-3 3.375 3 0 0 0 -.87341.1025l-11.928-10.602h9.8844a3.375 3 0 0 0 2.9169 1.5 3.375 3 0 0 0 3.375-3 3.375 3 0 0 0 -3.375-3 3.375 3 0 0 0 -2.9202 1.5h-11.038a3.375 3 0 0 0 -2.9169-1.5z"/></clipPath><g transform="translate(0 -1036.4)"><g clip-path="url(#a)" transform="matrix(.59259 0 0 .66667 -1.7778 353.45)"><path d="m3 1025.9h27v3h-27z" fill="#ff7070"/><path d="m3 1028.9h27v3h-27z" fill="#ffeb70"/><path d="m3 1031.9h27v3h-27z" fill="#9dff70"/><path d="m3 1034.9h27v3h-27z" fill="#70ffb9"/><path d="m3 1037.9h27v3h-27z" fill="#70deff"/><path d="m3 1043.9h27v3h-27z" fill="#ff70ac"/><path d="m3 1040.9h27v3h-27z" fill="#9f70ff"/></g><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m8.0625 1025.9a3.375 3 0 0 0 -3.375 3 3.375 3 0 0 0 1.6875 2.5957v9.8115a3.375 3 0 0 0 -1.6875 2.5928 3.375 3 0 0 0 3.375 3 3.375 3 0 0 0 3.375-3 3.375 3 0 0 0 -1.6875-2.5957v-8.7832l11.931 10.605a3.375 3 0 0 0 -.11865.7735 3.375 3 0 0 0 3.375 3 3.375 3 0 0 0 3.375-3 3.375 3 0 0 0 -3.375-3 3.375 3 0 0 0 -.87341.1025l-11.928-10.602h9.8844a3.375 3 0 0 0 2.9169 1.5 3.375 3 0 0 0 3.375-3 3.375 3 0 0 0 -3.375-3 3.375 3 0 0 0 -2.9202 1.5h-11.038a3.375 3 0 0 0 -2.9169-1.5z"/></clipPath><g transform="translate(0 -1036.4)"><g clip-path="url(#a)" transform="matrix(.59259 0 0 .66667 -1.7778 353.45)"><path d="m3 1025.9h27v3h-27z" fill="#ff4545"/><path d="m3 1028.9h27v3h-27z" fill="#ffe345"/><path d="m3 1031.9h27v3h-27z" fill="#80ff45"/><path d="m3 1034.9h27v3h-27z" fill="#45ffa2"/><path d="m3 1037.9h27v3h-27z" fill="#45d7ff"/><path d="m3 1043.9h27v3h-27z" fill="#ff4596"/><path d="m3 1040.9h27v3h-27z" fill="#8045ff"/></g><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg> diff --git a/editor/icons/CanvasModulate.svg b/editor/icons/CanvasModulate.svg index 6096beb732..a96fb75643 100644 --- a/editor/icons/CanvasModulate.svg +++ b/editor/icons/CanvasModulate.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1037.4v14h14v-14zm2 2h10v10h-10z" fill="#a5b7f3"/><g fill-rule="evenodd"><path d="m12 1048.4h-5l5-5z" fill="#70bfff"/><path d="m4 1040.4h5l-5 5z" fill="#ff7070"/><path d="m4 1048.4v-3l5-5h3v3l-5 5z" fill="#7aff70"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1037.4v14h14v-14zm2 2h10v10h-10z" fill="#8da5f3"/><g fill-rule="evenodd"><path d="m12 1048.4h-5l5-5z" fill="#70bfff"/><path d="m4 1040.4h5l-5 5z" fill="#ff4545"/><path d="m4 1048.4v-3l5-5h3v3l-5 5z" fill="#7aff70"/></g></g></svg> diff --git a/editor/icons/CapsuleMesh.svg b/editor/icons/CapsuleMesh.svg index f7424310aa..0bc7814bea 100644 --- a/editor/icons/CapsuleMesh.svg +++ b/editor/icons/CapsuleMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922s5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903zm-1.0059 2.1264v4.8576c-.66556-.1047-1.2973-.372-1.9941-.6618v-1.3222c0-1.3474.79838-2.4648 1.9941-2.8736zm2.0118 0c1.1957.4088 1.9941 1.5262 1.9941 2.8736v1.3451c-.68406.3054-1.3142.5732-1.9941.6663zm-4.0059 6.334c.67836.2231 1.3126.447 1.9941.5264v2.8848c-1.1957-.4092-1.9941-1.5242-1.9941-2.8716zm6 .03v.5094c0 1.3474-.79838 2.4619-1.9941 2.8711v-2.8711c.68606-.068 1.3207-.2828 1.9941-.5094z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922s5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903zm-1.0059 2.1264v4.8576c-.66556-.1047-1.2973-.372-1.9941-.6618v-1.3222c0-1.3474.79838-2.4648 1.9941-2.8736zm2.0118 0c1.1957.4088 1.9941 1.5262 1.9941 2.8736v1.3451c-.68406.3054-1.3142.5732-1.9941.6663zm-4.0059 6.334c.67836.2231 1.3126.447 1.9941.5264v2.8848c-1.1957-.4092-1.9941-1.5242-1.9941-2.8716zm6 .03v.5094c0 1.3474-.79838 2.4619-1.9941 2.8711v-2.8711c.68606-.068 1.3207-.2828 1.9941-.5094z" fill="#ffca5f"/></svg> diff --git a/editor/icons/CenterContainer.svg b/editor/icons/CenterContainer.svg index af1958c2d8..990f63b6c2 100644 --- a/editor/icons/CenterContainer.svg +++ b/editor/icons/CenterContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm3 1 2 2 2-2zm-2 2v4l2-2zm8 0-2 2 2 2zm-4 4-2 2h4z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm3 1 2 2 2-2zm-2 2v4l2-2zm8 0-2 2 2 2zm-4 4-2 2h4z" fill="#8eef97"/></svg> diff --git a/editor/icons/CheckBox.svg b/editor/icons/CheckBox.svg index 8707dfce0c..32eaf2d212 100644 --- a/editor/icons/CheckBox.svg +++ b/editor/icons/CheckBox.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-1.1046 0-2 .89543-2 2v9c0 1.1046.89543 2 2 2h9c1.1046 0 2-.89543 2-2v-4.9277l-2 2v2.9277h-9v-9h6.5859l2-2zm9.3633 2.0508-4.9492 4.9492-1.4141-1.4141-1.4141 1.4141 2.8281 2.8281 6.3633-6.3633z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2c-1.1046 0-2 .89543-2 2v9c0 1.1046.89543 2 2 2h9c1.1046 0 2-.89543 2-2v-4.9277l-2 2v2.9277h-9v-9h6.5859l2-2zm9.3633 2.0508-4.9492 4.9492-1.4141-1.4141-1.4141 1.4141 2.8281 2.8281 6.3633-6.3633z" fill="#8eef97"/></svg> diff --git a/editor/icons/CheckButton.svg b/editor/icons/CheckButton.svg index 4b8106ecc0..91367e2a2a 100644 --- a/editor/icons/CheckButton.svg +++ b/editor/icons/CheckButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4h6a4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 2h2.541a4 4 0 0 0 -.54102 2 4 4 0 0 0 .54102 2h-2.541a2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4h6a4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 2h2.541a4 4 0 0 0 -.54102 2 4 4 0 0 0 .54102 2h-2.541a2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/ClippedCamera3D.svg b/editor/icons/ClippedCamera3D.svg index a66f7844a9..44d656e8ba 100644 --- a/editor/icons/ClippedCamera3D.svg +++ b/editor/icons/ClippedCamera3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6.5 12v4h3v-1h-2v-3zm-1 0h-2c-.5 0-1 .5-1 1v2c-.01829.53653.5 1 1 1h2v-1h-2v-2h2zm4-12c-1.5691.0017903-2.8718 1.2125-2.9883 2.7773-.55103-.49952-1.268-.77655-2.0117-.77734-1.6569 0-3 1.3431-3 3 .00179 1.2698.80282 2.4009 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695c.63486-.56783.99842-1.3788 1-2.2305 0-1.6569-1.3431-3-3-3zm1 12v4h1v-1h1c.55228 0 1-.44772 1-1v-1c0-.55228-.44775-.99374-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6.5 12v4h3v-1h-2v-3zm-1 0h-2c-.5 0-1 .5-1 1v2c-.01829.53653.5 1 1 1h2v-1h-2v-2h2zm4-12c-1.5691.0017903-2.8718 1.2125-2.9883 2.7773-.55103-.49952-1.268-.77655-2.0117-.77734-1.6569 0-3 1.3431-3 3 .00179 1.2698.80282 2.4009 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695c.63486-.56783.99842-1.3788 1-2.2305 0-1.6569-1.3431-3-3-3zm1 12v4h1v-1h1c.55228 0 1-.44772 1-1v-1c0-.55228-.44775-.99374-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/CodeEdit.svg b/editor/icons/CodeEdit.svg index 0750b072e7..7f08340ffb 100644 --- a/editor/icons/CodeEdit.svg +++ b/editor/icons/CodeEdit.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm2 1-1 1 1 1-1 1 1 1 2-2zm2 3v1h2v-1z" fill="#a5efac" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm2 1-1 1 1 1-1 1 1 1 2-2zm2 3v1h2v-1z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/CollisionPolygon2D.svg b/editor/icons/CollisionPolygon2D.svg index 524efd1e65..a882943847 100644 --- a/editor/icons/CollisionPolygon2D.svg +++ b/editor/icons/CollisionPolygon2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#a5b7f3" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#8da5f3" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/CollisionPolygon3D.svg b/editor/icons/CollisionPolygon3D.svg index 9b8b13c514..57531fa9f4 100644 --- a/editor/icons/CollisionPolygon3D.svg +++ b/editor/icons/CollisionPolygon3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/CollisionShape2D.svg b/editor/icons/CollisionShape2D.svg index d366ddb630..0acad74379 100644 --- a/editor/icons/CollisionShape2D.svg +++ b/editor/icons/CollisionShape2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12z" fill="none" stroke="#a5b7f3" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12z" fill="none" stroke="#8da5f3" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/CollisionShape3D.svg b/editor/icons/CollisionShape3D.svg index cf5925ce79..7a8bbf8050 100644 --- a/editor/icons/CollisionShape3D.svg +++ b/editor/icons/CollisionShape3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1050.4-6-3v-6l6-3 6 3v6z" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.399988)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1050.4-6-3v-6l6-3 6 3v6z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2" transform="translate(0 -1036.399988)"/></svg> diff --git a/editor/icons/Color.svg b/editor/icons/Color.svg index 91bc0d1d2d..5c6fca1876 100644 --- a/editor/icons/Color.svg +++ b/editor/icons/Color.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff8484"/><path d="m14 4a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#84c2ff"/><path d="m6 2v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-5z" fill="#84ffb1"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff5f5f"/><path d="m14 4a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#5fb2ff"/><path d="m6 2v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-5z" fill="#5fff97"/></svg> diff --git a/editor/icons/ColorPicker.svg b/editor/icons/ColorPicker.svg index c4f48cd347..ce1f4fef96 100644 --- a/editor/icons/ColorPicker.svg +++ b/editor/icons/ColorPicker.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-1.108 0-2 .892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1-1.7305v-5h1v-2h-1v-2c0-1.108-.892-2-2-2zm-1 6h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-1.108 0-2 .892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1-1.7305v-5h1v-2h-1v-2c0-1.108-.892-2-2-2zm-1 6h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/ColorPickerButton.svg b/editor/icons/ColorPickerButton.svg index fa2a615428..ced130b1ce 100644 --- a/editor/icons/ColorPickerButton.svg +++ b/editor/icons/ColorPickerButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1c-1.108 0-2 .892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1-1.7305v-5h1v-2h-1v-2c0-1.108-.892-2-2-2zm-9 1v3.1328l-1.4453-.96484-1.1094 1.6641 3 2c.3359.2239.77347.2239 1.1094 0l3-2-1.1094-1.6641-1.4453.96484v-3.1328zm8 5h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1zm-8.5 3c-.831 0-1.5.669-1.5 1.5v.5 1h-1v2h8v-2h-1v-1-.5c0-.831-.669-1.5-1.5-1.5z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1c-1.108 0-2 .892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1-1.7305v-5h1v-2h-1v-2c0-1.108-.892-2-2-2zm-9 1v3.1328l-1.4453-.96484-1.1094 1.6641 3 2c.3359.2239.77347.2239 1.1094 0l3-2-1.1094-1.6641-1.4453.96484v-3.1328zm8 5h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1zm-8.5 3c-.831 0-1.5.669-1.5 1.5v.5 1h-1v2h8v-2h-1v-1-.5c0-.831-.669-1.5-1.5-1.5z" fill="#8eef97"/></svg> diff --git a/editor/icons/ColorRect.svg b/editor/icons/ColorRect.svg index 306401191a..f08b17ed1f 100644 --- a/editor/icons/ColorRect.svg +++ b/editor/icons/ColorRect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1v14h14v-14zm2 2h10v10h-10z" fill="#a5efac" transform="translate(0 1036.4)"/><g fill-rule="evenodd"><path d="m12 1048.4h-4.8l4.8-4.8z" fill="#70bfff"/><path d="m4 1040.4h4.8l-4.8 4.8z" fill="#ff7070"/><path d="m4 1048.4v-3.2l4.8-4.8h3.2v3.2l-4.8 4.8z" fill="#7aff70"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1v14h14v-14zm2 2h10v10h-10z" fill="#8eef97" transform="translate(0 1036.4)"/><g fill-rule="evenodd"><path d="m12 1048.4h-4.8l4.8-4.8z" fill="#70bfff"/><path d="m4 1040.4h4.8l-4.8 4.8z" fill="#ff4545"/><path d="m4 1048.4v-3.2l4.8-4.8h3.2v3.2l-4.8 4.8z" fill="#7aff70"/></g></g></svg> diff --git a/editor/icons/ConeTwistJoint3D.svg b/editor/icons/ConeTwistJoint3D.svg index 9eff38d0dc..300cc7ecc1 100644 --- a/editor/icons/ConeTwistJoint3D.svg +++ b/editor/icons/ConeTwistJoint3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9824 1a1.0001 1.0001 0 0 0 -.81445.44531l-4.7012 7.0527c-.80117.58197-1.3801 1.3563-1.4492 2.3145a1.0001 1.0001 0 0 0 -.017578.1875c0 .21449.033976.41628.082031.61328.0071983.028314.015306.055972.023438.083985.053631.19149.1274.37452.2207.54883.19678.36764.47105.69651.80273.98633.007988.007025.013442.016473.021484.023437.016953.014679.03747.026532.054688.041016.10299.086112.21259.16531.32422.24414.23883.16992.49083.33075.76953.4707.0025295.00127.0052799.002638.0078125.003906.001313.000658.0025928.001296.0039063.001953.0085785.00429.018732.007456.027344.011719.26499.13103.55174.24596.84961.35156.10487.037634.21202.071147.32031.10547.072945.022902.1402.050715.21484.072266.16777.04843.34161.086385.51367.12695.093562.021905.18185.048745.27734.068359.010733.002205.022447.003684.033203.00586.34623.071177.69974.12196 1.0566.16211.057889.006228.11544.01213.17383.017578.81052.079498 1.6348.079498 2.4453 0 .058387-.005448.11594-.01135.17383-.017578.3569-.040146.71041-.090932 1.0566-.16211.010948-.002251.022269-.003578.033203-.00586.095491-.019614.18378-.046454.27734-.068359.17206-.040568.3459-.078523.51367-.12695.074642-.021551.1419-.049364.21484-.072266.10829-.034322.21544-.067835.32031-.10547.29787-.1056.58462-.22053.84961-.35156.009951-.00492.021348-.008715.03125-.013672.002626-.001315.005189-.002588.007813-.003906.2787-.13995.5307-.30078.76953-.4707.11163-.07883.22123-.15803.32422-.24414.017218-.014484.037734-.026337.054687-.041016.008042-.006964.013497-.016412.021485-.023437.33169-.28982.60596-.61869.80273-.98633.093299-.17431.16707-.35733.2207-.54883.008132-.028013.016239-.055671.023438-.083985.048055-.197.082031-.39879.082031-.61328a1.0001 1.0001 0 0 0 -.017578-.18164 1.0001 1.0001 0 0 0 -.001953-.017578c-.073081-.95265-.64941-1.7232-1.4473-2.3027l-4.7012-7.0527a1.0001 1.0001 0 0 0 -.84961-.44531zm-.98242 4.3027v1.7461c-.43911.033461-.86366.087835-1.2734.16406l1.2734-1.9102zm2 0 1.2734 1.9102c-.40978-.076228-.83432-.1306-1.2734-.16406v-1.7461zm-2 3.748v1.9492a1.0001 1.0001 0 1 0 2 0v-1.9492c1.1126.10487 2.0951.37277 2.7949.72266.12146.060728.20622.12218.30664.18359l.80078 1.2012c-.032965.14677-.089654.30658-.30469.51758-.051464.049149-.10034.098137-.16406.14844-.045193.035312-.091373.070148-.14258.10547-.11245.07827-.24511.15838-.39062.23633-.075428.040204-.1553.078371-.23828.11719-.16195.075482-.33452.14662-.52148.21289-.070588.025324-.14454.048409-.21875.072265-.23425.074473-.48077.14392-.74414.20117-.021343.004579-.041038.011189-.0625.015625-.2559.05368-.53101.090517-.80859.125-.856.10229-1.7573.10229-2.6133 0-.27759-.034483-.5527-.07132-.80859-.125-.021462-.004436-.041156-.011046-.0625-.015625-.26337-.057254-.50989-.1267-.74414-.20117-.074211-.023856-.14816-.046941-.21875-.072265-.18697-.066266-.35954-.13741-.52148-.21289-.082979-.038816-.16285-.076983-.23828-.11719-.14552-.077951-.27818-.15806-.39062-.23633-.051205-.035321-.097386-.070157-.14258-.10547-.06372-.050301-.1126-.099289-.16406-.14844-.21503-.21099-.27173-.37081-.30469-.51758l.80078-1.2012c.10043-.061415.18518-.12287.30664-.18359.69978-.34989 1.6823-.61778 2.7949-.72266z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9824 1a1.0001 1.0001 0 0 0 -.81445.44531l-4.7012 7.0527c-.80117.58197-1.3801 1.3563-1.4492 2.3145a1.0001 1.0001 0 0 0 -.017578.1875c0 .21449.033976.41628.082031.61328.0071983.028314.015306.055972.023438.083985.053631.19149.1274.37452.2207.54883.19678.36764.47105.69651.80273.98633.007988.007025.013442.016473.021484.023437.016953.014679.03747.026532.054688.041016.10299.086112.21259.16531.32422.24414.23883.16992.49083.33075.76953.4707.0025295.00127.0052799.002638.0078125.003906.001313.000658.0025928.001296.0039063.001953.0085785.00429.018732.007456.027344.011719.26499.13103.55174.24596.84961.35156.10487.037634.21202.071147.32031.10547.072945.022902.1402.050715.21484.072266.16777.04843.34161.086385.51367.12695.093562.021905.18185.048745.27734.068359.010733.002205.022447.003684.033203.00586.34623.071177.69974.12196 1.0566.16211.057889.006228.11544.01213.17383.017578.81052.079498 1.6348.079498 2.4453 0 .058387-.005448.11594-.01135.17383-.017578.3569-.040146.71041-.090932 1.0566-.16211.010948-.002251.022269-.003578.033203-.00586.095491-.019614.18378-.046454.27734-.068359.17206-.040568.3459-.078523.51367-.12695.074642-.021551.1419-.049364.21484-.072266.10829-.034322.21544-.067835.32031-.10547.29787-.1056.58462-.22053.84961-.35156.009951-.00492.021348-.008715.03125-.013672.002626-.001315.005189-.002588.007813-.003906.2787-.13995.5307-.30078.76953-.4707.11163-.07883.22123-.15803.32422-.24414.017218-.014484.037734-.026337.054687-.041016.008042-.006964.013497-.016412.021485-.023437.33169-.28982.60596-.61869.80273-.98633.093299-.17431.16707-.35733.2207-.54883.008132-.028013.016239-.055671.023438-.083985.048055-.197.082031-.39879.082031-.61328a1.0001 1.0001 0 0 0 -.017578-.18164 1.0001 1.0001 0 0 0 -.001953-.017578c-.073081-.95265-.64941-1.7232-1.4473-2.3027l-4.7012-7.0527a1.0001 1.0001 0 0 0 -.84961-.44531zm-.98242 4.3027v1.7461c-.43911.033461-.86366.087835-1.2734.16406l1.2734-1.9102zm2 0 1.2734 1.9102c-.40978-.076228-.83432-.1306-1.2734-.16406v-1.7461zm-2 3.748v1.9492a1.0001 1.0001 0 1 0 2 0v-1.9492c1.1126.10487 2.0951.37277 2.7949.72266.12146.060728.20622.12218.30664.18359l.80078 1.2012c-.032965.14677-.089654.30658-.30469.51758-.051464.049149-.10034.098137-.16406.14844-.045193.035312-.091373.070148-.14258.10547-.11245.07827-.24511.15838-.39062.23633-.075428.040204-.1553.078371-.23828.11719-.16195.075482-.33452.14662-.52148.21289-.070588.025324-.14454.048409-.21875.072265-.23425.074473-.48077.14392-.74414.20117-.021343.004579-.041038.011189-.0625.015625-.2559.05368-.53101.090517-.80859.125-.856.10229-1.7573.10229-2.6133 0-.27759-.034483-.5527-.07132-.80859-.125-.021462-.004436-.041156-.011046-.0625-.015625-.26337-.057254-.50989-.1267-.74414-.20117-.074211-.023856-.14816-.046941-.21875-.072265-.18697-.066266-.35954-.13741-.52148-.21289-.082979-.038816-.16285-.076983-.23828-.11719-.14552-.077951-.27818-.15806-.39062-.23633-.051205-.035321-.097386-.070157-.14258-.10547-.06372-.050301-.1126-.099289-.16406-.14844-.21503-.21099-.27173-.37081-.30469-.51758l.80078-1.2012c.10043-.061415.18518-.12287.30664-.18359.69978-.34989 1.6823-.61778 2.7949-.72266z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Container.svg b/editor/icons/Container.svg index a7be880268..efe1966ad4 100644 --- a/editor/icons/Container.svg +++ b/editor/icons/Container.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2zm4 0v2h2v-2zm4 0v2c1.1046 0 2-.89543 2-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2zm4 0v2h2v-2zm4 0v2c1.1046 0 2-.89543 2-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/Control.svg b/editor/icons/Control.svg index 0ec9c4c6fe..3f3530de61 100644 --- a/editor/icons/Control.svg +++ b/editor/icons/Control.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#8eef97"/></svg> diff --git a/editor/icons/ControlLayout.svg b/editor/icons/ControlLayout.svg index c4aa64113d..11dd2554be 100644 --- a/editor/icons/ControlLayout.svg +++ b/editor/icons/ControlLayout.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm2 2h3v3h-3zm5 0h5v3h-5zm-5 5h3v5h-3zm5 0h5v5h-5z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm2 2h3v3h-3zm5 0h5v3h-5zm-5 5h3v5h-3zm5 0h5v5h-5z" fill="#8eef97"/></svg> diff --git a/editor/icons/CreateNewSceneFrom.svg b/editor/icons/CreateNewSceneFrom.svg index 094a0aae39..3ec6140515 100644 --- a/editor/icons/CreateNewSceneFrom.svg +++ b/editor/icons/CreateNewSceneFrom.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m14.564 2-2.2441.32812.81836 1.9004 1.7148-.25-.28906-1.9785zm-4.2227.61523-1.9785.28906.81836 1.9023 1.9785-.28906zm-3.959.57812-1.9785.28906.81836 1.9023 1.9785-.28906zm-3.957.57812-1.7148.25.28906 1.9785 2.2441-.32812-.81836-1.9004zm-1.4258 3.2285v6c0 1.1046.89543 2 2 2h7v-1h-2v-4h2v-2h4v2h1v-3z" fill="#e0e0e0" transform="translate(0 1036.4)"/><circle cx="-14" cy="1047.4" fill="#e0e0e0" r="0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#84ffb1" fill-rule="evenodd"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m14.564 2-2.2441.32812.81836 1.9004 1.7148-.25-.28906-1.9785zm-4.2227.61523-1.9785.28906.81836 1.9023 1.9785-.28906zm-3.959.57812-1.9785.28906.81836 1.9023 1.9785-.28906zm-3.957.57812-1.7148.25.28906 1.9785 2.2441-.32812-.81836-1.9004zm-1.4258 3.2285v6c0 1.1046.89543 2 2 2h7v-1h-2v-4h2v-2h4v2h1v-3z" fill="#e0e0e0" transform="translate(0 1036.4)"/><circle cx="-14" cy="1047.4" fill="#e0e0e0" r="0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#5fff97" fill-rule="evenodd"/></g></svg> diff --git a/editor/icons/Cubemap.svg b/editor/icons/Cubemap.svg index b3ec2bd3e7..81965f7a09 100644 --- a/editor/icons/Cubemap.svg +++ b/editor/icons/Cubemap.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 6v4h4v-4zm8 0v4h4v-4z" fill="#84ffb1"/><path d="m4 6v4h4v-4zm8 0v4h4v-4z" fill="#ff8484"/><path d="m4 2v4h4v-4zm0 8v4h4v-4z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 6v4h4v-4zm8 0v4h4v-4z" fill="#5fff97"/><path d="m4 6v4h4v-4zm8 0v4h4v-4z" fill="#ff5f5f"/><path d="m4 2v4h4v-4zm0 8v4h4v-4z" fill="#5fb2ff"/></svg> diff --git a/editor/icons/CubemapArray.svg b/editor/icons/CubemapArray.svg index c9d722dc52..847fc7f70a 100644 --- a/editor/icons/CubemapArray.svg +++ b/editor/icons/CubemapArray.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 6v4h2v-4zm6 0v4h4v-4z" fill="#84ffb1"/><path d="m4 6v4h4v-4zm8 0v4h2v-4z" fill="#ff8484"/><path d="m4 2v4h4v-4zm0 8v4h4v-4z" fill="#84c2ff"/><path d="m-.00000002 2v12h4.00000002v-2h-2v-8h2v-2h-2zm12.00000002 0v2h2.000001v8h-2.000001v2h4.000001v-12h-2z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 6v4h2v-4zm6 0v4h4v-4z" fill="#5fff97"/><path d="m4 6v4h4v-4zm8 0v4h2v-4z" fill="#ff5f5f"/><path d="m4 2v4h4v-4zm0 8v4h4v-4z" fill="#5fb2ff"/><path d="m-.00000002 2v12h4.00000002v-2h-2v-8h2v-2h-2zm12.00000002 0v2h2.000001v8h-2.000001v2h4.000001v-12h-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/CurveClose.svg b/editor/icons/CurveClose.svg index 26e30cdb1c..5cb8ab890e 100644 --- a/editor/icons/CurveClose.svg +++ b/editor/icons/CurveClose.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/><path d="m10 6v2h2v-2zm0 2h-2v2h2zm-2 2h-2v2h2z" fill="#84c2ff"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/><path d="m10 6v2h2v-2zm0 2h-2v2h2zm-2 2h-2v2h2z" fill="#5fb2ff"/></g></g></svg> diff --git a/editor/icons/CurveCreate.svg b/editor/icons/CurveCreate.svg index 962abd0b3f..1e80817a34 100644 --- a/editor/icons/CurveCreate.svg +++ b/editor/icons/CurveCreate.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm6 5v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#84ffb1"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm6 5v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#5fff97"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg> diff --git a/editor/icons/CurveCurve.svg b/editor/icons/CurveCurve.svg index 35770543af..e43e7ccd8a 100644 --- a/editor/icons/CurveCurve.svg +++ b/editor/icons/CurveCurve.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m8.4688.4707-2.6875 2.6875h-.0019531a2 2 0 0 0 -.7793-.1582 2 2 0 0 0 -2 2 2 2 0 0 0 .16016.7793l-2.6914 2.6914 1.0625 1.0605 2.6895-2.6895a2 2 0 0 0 .7793.1582 2 2 0 0 0 2-2 2 2 0 0 0 -.16016-.77734l2.6914-2.6914-1.0625-1.0605z" fill="#84c2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m8.4688.4707-2.6875 2.6875h-.0019531a2 2 0 0 0 -.7793-.1582 2 2 0 0 0 -2 2 2 2 0 0 0 .16016.7793l-2.6914 2.6914 1.0625 1.0605 2.6895-2.6895a2 2 0 0 0 .7793.1582 2 2 0 0 0 2-2 2 2 0 0 0 -.16016-.77734l2.6914-2.6914-1.0625-1.0605z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg> diff --git a/editor/icons/CurveDelete.svg b/editor/icons/CurveDelete.svg index 5bce6d0c1c..cf15d75bc1 100644 --- a/editor/icons/CurveDelete.svg +++ b/editor/icons/CurveDelete.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><path d="m5 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4.8789 5.4648-1.4141 1.4141 2.1211 2.1211-2.1211 2.1211 1.4141 1.4141 2.1211-2.1211 2.1211 2.1211 1.4141-1.4141-2.1211-2.1211 2.1211-2.1211-1.4141-1.4141-2.1211 2.1211z" fill="#ff8484"/><path d="m13 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><path d="m5 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4.8789 5.4648-1.4141 1.4141 2.1211 2.1211-2.1211 2.1211 1.4141 1.4141 2.1211-2.1211 2.1211 2.1211 1.4141-1.4141-2.1211-2.1211 2.1211-2.1211-1.4141-1.4141-2.1211 2.1211z" fill="#ff5f5f"/><path d="m13 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></svg> diff --git a/editor/icons/CurveEdit.svg b/editor/icons/CurveEdit.svg index 84b56fbccb..57e365f3cd 100644 --- a/editor/icons/CurveEdit.svg +++ b/editor/icons/CurveEdit.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm3 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#84c2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm3 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg> diff --git a/editor/icons/CylinderMesh.svg b/editor/icons/CylinderMesh.svg index 85483aeeca..f6315c253c 100644 --- a/editor/icons/CylinderMesh.svg +++ b/editor/icons/CylinderMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.5.9375c-1.6377 0-3.12.2123-4.2737.5969-.57682.1923-1.0754.4237-1.4905.7508-.41505.3271-.79834.8259-.79834 1.4648v7.5c0 .6389.38329 1.1396.79834 1.4667s.91366.5585 1.4905.7507c1.1536.3846 2.6359.5951 4.2737.5951s3.12-.2105 4.2737-.5951c.57682-.1922 1.0754-.4236 1.4905-.7507.41505-.3271.79834-.8278.79834-1.4667v-7.5c0-.6389-.38329-1.1377-.79834-1.4648s-.91366-.5585-1.4905-.7508c-1.1536-.3846-2.6359-.5969-4.2737-.5969zm0 1.875c1.4689 0 2.8.2076 3.6823.5017.4347.1449.7513.3163.9082.4376-.15705.1212-.47387.2911-.9082.4358-.88221.2941-2.2134.4999-3.6823.4999s-2.8-.2058-3.6823-.4999c-.43433-.1447-.75115-.3146-.9082-.4358.15691-.1213.47351-.2927.9082-.4376.88221-.2941 2.2134-.5017 3.6823-.5017zm-4.6875 2.9883c.13762.055.26578.1173.41382.1666 1.1536.3846 2.6359.5951 4.2737.5951s3.12-.2105 4.2737-.5951c.14804-.049.2762-.1112.41382-.1666v5.4492c-.15705.1212-.57092.2929-1.0052.4376-.88221.2941-2.2134.4999-3.6823.4999s-2.8-.2058-3.6823-.4999c-.43433-.1447-.8482-.3164-1.0052-.4376z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.5.9375c-1.6377 0-3.12.2123-4.2737.5969-.57682.1923-1.0754.4237-1.4905.7508-.41505.3271-.79834.8259-.79834 1.4648v7.5c0 .6389.38329 1.1396.79834 1.4667s.91366.5585 1.4905.7507c1.1536.3846 2.6359.5951 4.2737.5951s3.12-.2105 4.2737-.5951c.57682-.1922 1.0754-.4236 1.4905-.7507.41505-.3271.79834-.8278.79834-1.4667v-7.5c0-.6389-.38329-1.1377-.79834-1.4648s-.91366-.5585-1.4905-.7508c-1.1536-.3846-2.6359-.5969-4.2737-.5969zm0 1.875c1.4689 0 2.8.2076 3.6823.5017.4347.1449.7513.3163.9082.4376-.15705.1212-.47387.2911-.9082.4358-.88221.2941-2.2134.4999-3.6823.4999s-2.8-.2058-3.6823-.4999c-.43433-.1447-.75115-.3146-.9082-.4358.15691-.1213.47351-.2927.9082-.4376.88221-.2941 2.2134-.5017 3.6823-.5017zm-4.6875 2.9883c.13762.055.26578.1173.41382.1666 1.1536.3846 2.6359.5951 4.2737.5951s3.12-.2105 4.2737-.5951c.14804-.049.2762-.1112.41382-.1666v5.4492c-.15705.1212-.57092.2929-1.0052.4376-.88221.2941-2.2134.4999-3.6823.4999s-2.8-.2058-3.6823-.4999c-.43433-.1447-.8482-.3164-1.0052-.4376z" fill="#ffca5f"/></svg> diff --git a/editor/icons/DampedSpringJoint2D.svg b/editor/icons/DampedSpringJoint2D.svg index 02a7033106..99e1a1f1e1 100644 --- a/editor/icons/DampedSpringJoint2D.svg +++ b/editor/icons/DampedSpringJoint2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".98824"><path d="m4 3v2l8 3v-2zm0 5v2l8 3v-2z" fill="#708cea"/><path d="m4 3v2l8-2v-2zm0 5v2l8-2v-2zm0 5v2l8-2v-2z" fill="#a5b7f3"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".98824"><path d="m4 3v2l8 3v-2zm0 5v2l8 3v-2z" fill="#4b70ea"/><path d="m4 3v2l8-2v-2zm0 5v2l8-2v-2zm0 5v2l8-2v-2z" fill="#8da5f3"/></g></svg> diff --git a/editor/icons/DebugContinue.svg b/editor/icons/DebugContinue.svg index cf9e0724c2..8625626ab2 100644 --- a/editor/icons/DebugContinue.svg +++ b/editor/icons/DebugContinue.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m10 4v3h-5v2h5v3l2.5-2 2.5-2-2.5-2z" fill="#ff8484" transform="translate(0 1036.4)"/><circle cx="4" cy="1044.4" fill="#e0e0e0" r="3"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m10 4v3h-5v2h5v3l2.5-2 2.5-2-2.5-2z" fill="#ff5f5f" transform="translate(0 1036.4)"/><circle cx="4" cy="1044.4" fill="#e0e0e0" r="3"/></g></svg> diff --git a/editor/icons/DebugNext.svg b/editor/icons/DebugNext.svg index d510aff828..50532d6e77 100644 --- a/editor/icons/DebugNext.svg +++ b/editor/icons/DebugNext.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1v10h-2l1.5 2 1.5 2 1.5-2 1.5-2h-2v-10z" fill="#ff8484"/><path d="m7 1v2h8v-2zm2 4v2h6v-2zm0 4v2h6v-2zm-2 4v2h8v-2z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1v10h-2l1.5 2 1.5 2 1.5-2 1.5-2h-2v-10z" fill="#ff5f5f"/><path d="m7 1v2h8v-2zm2 4v2h6v-2zm0 4v2h6v-2zm-2 4v2h8v-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/DebugStep.svg b/editor/icons/DebugStep.svg index b26e9b7b25..f8d57ef693 100644 --- a/editor/icons/DebugStep.svg +++ b/editor/icons/DebugStep.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v8 2h2 1v2l2-1.5 2-1.5-2-1.5-2-1.5v2h-1v-8z" fill="#ff8484"/><path d="m7 1v2h8v-2zm2 4v2h6v-2zm0 4v2h6v-2zm-2 4v2h8v-2z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v8 2h2 1v2l2-1.5 2-1.5-2-1.5-2-1.5v2h-1v-8z" fill="#ff5f5f"/><path d="m7 1v2h8v-2zm2 4v2h6v-2zm0 4v2h6v-2zm-2 4v2h8v-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Decal.svg b/editor/icons/Decal.svg index 2a61ceb0a0..8c33f44360 100644 --- a/editor/icons/Decal.svg +++ b/editor/icons/Decal.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406l8.9082029-6.1894529c-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc9c9c"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5d5d"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc9c9c" fill-opacity=".392157"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406l8.9082029-6.1894529c-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc7f7f"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5d5d"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc7f7f" fill-opacity=".392157"/></svg> diff --git a/editor/icons/Dictionary.svg b/editor/icons/Dictionary.svg index c835398836..0284e847d9 100644 --- a/editor/icons/Dictionary.svg +++ b/editor/icons/Dictionary.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2v2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-8zm3 0v2h2v-2zm7 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-2 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2zm-3 3v-1h-2v4h2zm-5-1v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#77edb1"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2v2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-8zm3 0v2h2v-2zm7 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-2 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2zm-3 3v-1h-2v4h2zm-5-1v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#54ed9e"/></svg> diff --git a/editor/icons/DirectionalLight3D.svg b/editor/icons/DirectionalLight3D.svg index ff033636be..ef25fd473a 100644 --- a/editor/icons/DirectionalLight3D.svg +++ b/editor/icons/DirectionalLight3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/EditBezier.svg b/editor/icons/EditBezier.svg index 3feff790dc..82667d0bed 100644 --- a/editor/icons/EditBezier.svg +++ b/editor/icons/EditBezier.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1.4758015 1050.3064c11.6492855.7191 3.1098343-11.4976 12.2331255-11.3475" fill="none" stroke="#84c2ff" stroke-miterlimit="4.9" stroke-width="2.2"/><g fill="#e0e0e0"><circle cx="13.470984" cy="1038.7133" r="1.823002"/><circle cx="2.444912" cy="1050.1708" r="1.823002"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1.4758015 1050.3064c11.6492855.7191 3.1098343-11.4976 12.2331255-11.3475" fill="none" stroke="#5fb2ff" stroke-miterlimit="4.9" stroke-width="2.2"/><g fill="#e0e0e0"><circle cx="13.470984" cy="1038.7133" r="1.823002"/><circle cx="2.444912" cy="1050.1708" r="1.823002"/></g></g></svg> diff --git a/editor/icons/Editor3DHandle.svg b/editor/icons/Editor3DHandle.svg index f63234f410..00e0d865af 100644 --- a/editor/icons/Editor3DHandle.svg +++ b/editor/icons/Editor3DHandle.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill-opacity=".29412" r="8"/><circle cx="8" cy="8" fill="#fff" r="7"/><circle cx="8" cy="8" fill="#ff8484" r="5"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill-opacity=".29412" r="8"/><circle cx="8" cy="8" fill="#fff" r="7"/><circle cx="8" cy="8" fill="#ff5f5f" r="5"/></svg> diff --git a/editor/icons/EditorControlAnchor.svg b/editor/icons/EditorControlAnchor.svg index 4574f5d7be..3383ea121f 100644 --- a/editor/icons/EditorControlAnchor.svg +++ b/editor/icons/EditorControlAnchor.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 0a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 1.0566-.11914l9.9434 6.1191-6.1172-9.9395a5 5 0 0 0 .11719-1.0605 5 5 0 0 0 -5-5z" fill-opacity=".39216" transform="translate(0 1036.4)"/><path d="m5 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 1.1406-.16992l9.8594 7.1699-7.168-9.8555a4 4 0 0 0 .16797-1.1445 4 4 0 0 0 -4-4z" fill="#a5efac" fill-rule="evenodd" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><circle cx="5" cy="1041.4" fill="#a5efac" r="0"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 0a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 1.0566-.11914l9.9434 6.1191-6.1172-9.9395a5 5 0 0 0 .11719-1.0605 5 5 0 0 0 -5-5z" fill-opacity=".39216" transform="translate(0 1036.4)"/><path d="m5 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 1.1406-.16992l9.8594 7.1699-7.168-9.8555a4 4 0 0 0 .16797-1.1445 4 4 0 0 0 -4-4z" fill="#8eef97" fill-rule="evenodd" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><circle cx="5" cy="1041.4" fill="#8eef97" r="0"/></g></svg> diff --git a/editor/icons/EditorHandle.svg b/editor/icons/EditorHandle.svg index a56e64bde3..8f78189798 100644 --- a/editor/icons/EditorHandle.svg +++ b/editor/icons/EditorHandle.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill-opacity=".29412" r="5"/><circle cx="5" cy="5" fill="#fff" r="4"/><circle cx="5" cy="5" fill="#ff8484" r="3"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill-opacity=".29412" r="5"/><circle cx="5" cy="5" fill="#fff" r="4"/><circle cx="5" cy="5" fill="#ff5f5f" r="3"/></svg> diff --git a/editor/icons/EditorHandleAdd.svg b/editor/icons/EditorHandleAdd.svg index 82d3730d3c..aca6b61df1 100644 --- a/editor/icons/EditorHandleAdd.svg +++ b/editor/icons/EditorHandleAdd.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill-opacity=".29412" r="5"/><circle cx="5" cy="5" fill="#474747" r="4"/><path d="m4 2v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill-opacity=".29412" r="5"/><circle cx="5" cy="5" fill="#474747" r="4"/><path d="m4 2v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/></svg> diff --git a/editor/icons/EditorPivot.svg b/editor/icons/EditorPivot.svg index ecb5dd95b7..cd7f5779c5 100644 --- a/editor/icons/EditorPivot.svg +++ b/editor/icons/EditorPivot.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v6h-6v4h6v6h4v-6h6v-4h-6v-6zm1 7h2v2h-2z" fill="#fff" fill-opacity=".70588"/><path d="m7 1v5h2v-5zm-6 6v2h5v-2zm9 0v2h5v-2zm-3 3v5h2v-5z" fill="#ff8484"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v6h-6v4h6v6h4v-6h6v-4h-6v-6zm1 7h2v2h-2z" fill="#fff" fill-opacity=".70588"/><path d="m7 1v5h2v-5zm-6 6v2h5v-2zm9 0v2h5v-2zm-3 3v5h2v-5z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/EditorPosition.svg b/editor/icons/EditorPosition.svg index 09f09feffc..10d0f5629d 100644 --- a/editor/icons/EditorPosition.svg +++ b/editor/icons/EditorPosition.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v4.4199a4.2662 4.0576 0 0 0 -1.709 1.5801h-4.291v4h4.2949a4.2662 4.0576 0 0 0 1.7051 1.582v4.418h4v-4.4199a4.2662 4.0576 0 0 0 1.709-1.5801h4.291v-4h-4.2949a4.2662 4.0576 0 0 0 -1.7051-1.582v-4.418z" fill="#fff" fill-opacity=".70588"/><path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1-.11914 4.2662 4.0576 0 0 1 1 .11914v-3.0605zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199-2.9199 2.9201 2.9201 0 0 0 -2.9199-2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -.13477-1 4.2662 4.0576 0 0 1 .13672-1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 .13477 1 4.2662 4.0576 0 0 1 -.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 .11914 4.2662 4.0576 0 0 1 -1-.11914z" fill="#ff8484"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v4.4199a4.2662 4.0576 0 0 0 -1.709 1.5801h-4.291v4h4.2949a4.2662 4.0576 0 0 0 1.7051 1.582v4.418h4v-4.4199a4.2662 4.0576 0 0 0 1.709-1.5801h4.291v-4h-4.2949a4.2662 4.0576 0 0 0 -1.7051-1.582v-4.418z" fill="#fff" fill-opacity=".70588"/><path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1-.11914 4.2662 4.0576 0 0 1 1 .11914v-3.0605zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199-2.9199 2.9201 2.9201 0 0 0 -2.9199-2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -.13477-1 4.2662 4.0576 0 0 1 .13672-1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 .13477 1 4.2662 4.0576 0 0 1 -.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 .11914 4.2662 4.0576 0 0 1 -1-.11914z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/FixedSpatialMaterial.svg b/editor/icons/FixedSpatialMaterial.svg index 6701208560..322465a0c7 100644 --- a/editor/icons/FixedSpatialMaterial.svg +++ b/editor/icons/FixedSpatialMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -4.8887 2h2.8887 6.8965a7 7 0 0 0 -4.8965-2z" fill="#ff7070"/><path d="m3.1113 3a7 7 0 0 0 -1.4277 2h2.3164a2 2 0 0 1 2-2zm2.8887 0a2 2 0 0 1 2 2h6.3145a7 7 0 0 0 -1.418-2z" fill="#ffeb70"/><path d="m1.6836 5a7 7 0 0 0 -.60547 2h4.9219a2 2 0 0 1 -2-2h-2.3164zm4.3164 2h8.9199a7 7 0 0 0 -.60547-2h-6.3145a2 2 0 0 1 -2 2z" fill="#9dff70"/><path d="m1.0781 7a7 7 0 0 0 -.078125 1 7 7 0 0 0 .080078 1h13.842a7 7 0 0 0 .078125-1 7 7 0 0 0 -.080078-1h-8.9199-4.9219z" fill="#70ffb9"/><path d="m1.0801 9a7 7 0 0 0 .60547 2h12.631a7 7 0 0 0 .60547-2h-13.842z" fill="#70deff"/><path d="m3.1035 13a7 7 0 0 0 4.8965 2 7 7 0 0 0 4.8887-2z" fill="#ff70ac"/><path d="m1.6855 11a7 7 0 0 0 1.418 2h9.7852a7 7 0 0 0 1.4277-2h-12.631z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -4.8887 2h2.8887 6.8965a7 7 0 0 0 -4.8965-2z" fill="#ff4545"/><path d="m3.1113 3a7 7 0 0 0 -1.4277 2h2.3164a2 2 0 0 1 2-2zm2.8887 0a2 2 0 0 1 2 2h6.3145a7 7 0 0 0 -1.418-2z" fill="#ffe345"/><path d="m1.6836 5a7 7 0 0 0 -.60547 2h4.9219a2 2 0 0 1 -2-2h-2.3164zm4.3164 2h8.9199a7 7 0 0 0 -.60547-2h-6.3145a2 2 0 0 1 -2 2z" fill="#80ff45"/><path d="m1.0781 7a7 7 0 0 0 -.078125 1 7 7 0 0 0 .080078 1h13.842a7 7 0 0 0 .078125-1 7 7 0 0 0 -.080078-1h-8.9199-4.9219z" fill="#45ffa2"/><path d="m1.0801 9a7 7 0 0 0 .60547 2h12.631a7 7 0 0 0 .60547-2h-13.842z" fill="#45d7ff"/><path d="m3.1035 13a7 7 0 0 0 4.8965 2 7 7 0 0 0 4.8887-2z" fill="#ff4596"/><path d="m1.6855 11a7 7 0 0 0 1.418 2h9.7852a7 7 0 0 0 1.4277-2h-12.631z" fill="#8045ff"/></svg> diff --git a/editor/icons/FontData.svg b/editor/icons/FontData.svg index 7ee88582a5..4cb6412081 100644 --- a/editor/icons/FontData.svg +++ b/editor/icons/FontData.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2zm0 5v2h2v-2zm0 3v2h2v-2zm0 3v2h2v-2zm3 0v2h2v-2z" fill="#e0e0e0"/><path d="m4 5v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2z" fill="#ff8484"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2zm0 5v2h2v-2zm0 3v2h2v-2zm0 3v2h2v-2zm3 0v2h2v-2z" fill="#e0e0e0"/><path d="m4 5v2 1h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1 -1 1v1h1 2 1v-1a1 1 0 0 1 -1-1v-6h2a1 1 0 0 1 1 1h1v-1-2h-4-2z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/GIProbe.svg b/editor/icons/GIProbe.svg index b66c937317..f5e1025260 100644 --- a/editor/icons/GIProbe.svg +++ b/editor/icons/GIProbe.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4v-2h-3v-10h9v-2zm9 3a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.459v.54102c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1v-.54102a4 4 0 0 0 2-3.459 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-1 8v1h2v-1z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4v-2h-3v-10h9v-2zm9 3a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.459v.54102c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1v-.54102a4 4 0 0 0 2-3.459 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm-1 8v1h2v-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/GPUParticles2D.svg b/editor/icons/GPUParticles2D.svg index b291bcda95..a693e554b2 100644 --- a/editor/icons/GPUParticles2D.svg +++ b/editor/icons/GPUParticles2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.5898-2.9668 4.5 5 0 0 0 -4.4102-4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.5898-2.9668 4.5 5 0 0 0 -4.4102-4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#8da5f3"/></svg> diff --git a/editor/icons/GPUParticles3D.svg b/editor/icons/GPUParticles3D.svg index 25377f9f5f..bbc90ec35f 100644 --- a/editor/icons/GPUParticles3D.svg +++ b/editor/icons/GPUParticles3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.5898-2.9668 4.5 5 0 0 0 -4.4102-4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4141 4.0312 3 3 0 0 0 -2.5859 2.9688 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.5898-2.9668 4.5 5 0 0 0 -4.4102-4.0332zm-4 11a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/GPUParticlesAttractorBox.svg b/editor/icons/GPUParticlesAttractorBox.svg index 3c27b2d3cb..7a2ee7a6b9 100644 --- a/editor/icons/GPUParticlesAttractorBox.svg +++ b/editor/icons/GPUParticlesAttractorBox.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fc9c9c" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc9c9c" stroke-opacity=".996078"><ellipse cx="8" cy="-8" rx="2.339226" ry="4.949748" transform="rotate(90)"/><ellipse cx="8" cy="8" rx="2.339226" ry="4.949748"/><path d="m1.498906 1.498906h13.002189v13.002188h-13.002189z" stroke-width=".997813"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fc7f7f" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc7f7f" stroke-opacity=".996078"><ellipse cx="8" cy="-8" rx="2.339226" ry="4.949748" transform="rotate(90)"/><ellipse cx="8" cy="8" rx="2.339226" ry="4.949748"/><path d="m1.498906 1.498906h13.002189v13.002188h-13.002189z" stroke-width=".997813"/></g></svg> diff --git a/editor/icons/GPUParticlesAttractorSphere.svg b/editor/icons/GPUParticlesAttractorSphere.svg index 5473a23854..2215331a18 100644 --- a/editor/icons/GPUParticlesAttractorSphere.svg +++ b/editor/icons/GPUParticlesAttractorSphere.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-8" cy="-7.999999" fill="none" rx="6.499003" ry="6.499001" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.002" transform="scale(-1)"/><circle cx="8" cy="8" fill="#fc9c9c" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc9c9c" stroke-opacity=".996078"><ellipse cx="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 .70710678 -.70710678 .70710678 0 0)"/><ellipse cy="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 0)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-8" cy="-7.999999" fill="none" rx="6.499003" ry="6.499001" stroke="#fc7f7f" stroke-opacity=".996078" stroke-width="1.002" transform="scale(-1)"/><circle cx="8" cy="8" fill="#fc7f7f" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc7f7f" stroke-opacity=".996078"><ellipse cx="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 .70710678 -.70710678 .70710678 0 0)"/><ellipse cy="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 0)"/></g></svg> diff --git a/editor/icons/GPUParticlesAttractorVectorField.svg b/editor/icons/GPUParticlesAttractorVectorField.svg index 93a29789e3..87b2b21804 100644 --- a/editor/icons/GPUParticlesAttractorVectorField.svg +++ b/editor/icons/GPUParticlesAttractorVectorField.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="6.663637" cy="9.245457" fill="#fc9c9c" fill-opacity=".996078" rx="1.030661" ry=".998146"/><ellipse cx="-6.672815" cy="-9.387111" fill="none" rx="2.408711" ry="5.096776" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.99999945 .00104887 .00104887 -.99999945 0 0)"/><ellipse cx="9.387111" cy="-6.672815" fill="none" rx="2.408711" ry="5.096776" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.00104887 .99999945 -.99999945 .00104887 0 0)"/><g fill="#fc9c9c" fill-opacity=".996078"><path d="m11.8 15 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/><path d="m11 6 3-3 1 1v-3h-3l1 1-3 3z"/><path d="m1.8 5 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="6.663637" cy="9.245457" fill="#fc7f7f" fill-opacity=".996078" rx="1.030661" ry=".998146"/><ellipse cx="-6.672815" cy="-9.387111" fill="none" rx="2.408711" ry="5.096776" stroke="#fc7f7f" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.99999945 .00104887 .00104887 -.99999945 0 0)"/><ellipse cx="9.387111" cy="-6.672815" fill="none" rx="2.408711" ry="5.096776" stroke="#fc7f7f" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.00104887 .99999945 -.99999945 .00104887 0 0)"/><g fill="#fc7f7f" fill-opacity=".996078"><path d="m11.8 15 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/><path d="m11 6 3-3 1 1v-3h-3l1 1-3 3z"/><path d="m1.8 5 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionBox.svg b/editor/icons/GPUParticlesCollisionBox.svg index f7296b34c3..4f7325d086 100644 --- a/editor/icons/GPUParticlesCollisionBox.svg +++ b/editor/icons/GPUParticlesCollisionBox.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" fill-opacity=".996078"><path d="m7.5 2.8124998-5.5883107 2.7941554v5.7660988l5.5883107 2.794155 5.588311-2.794155v-5.7660988zm0 1.6886278 3.145021 1.5732692-3.145021 1.5717523-3.1450214-1.5717523zm-3.9916505 2.8362274 3.1933204 1.5966602v3.1465378l-3.1933204-1.598256zm7.9833015 0v3.145021l-3.1933209 1.598257v-3.146538z" stroke-width=".851579"/><circle cx="1.875" cy="3.75" r=".9375"/><circle cx="13.124999" cy="3.75" r=".9375"/><circle cx="9.374999" cy="1.875" r=".9375"/><circle cx="5.625" cy="1.875" r=".9375"/></g></svg> +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f" fill-opacity=".996078"><path d="m7.5 2.8124998-5.5883107 2.7941554v5.7660988l5.5883107 2.794155 5.588311-2.794155v-5.7660988zm0 1.6886278 3.145021 1.5732692-3.145021 1.5717523-3.1450214-1.5717523zm-3.9916505 2.8362274 3.1933204 1.5966602v3.1465378l-3.1933204-1.598256zm7.9833015 0v3.145021l-3.1933209 1.598257v-3.146538z" stroke-width=".851579"/><circle cx="1.875" cy="3.75" r=".9375"/><circle cx="13.124999" cy="3.75" r=".9375"/><circle cx="9.374999" cy="1.875" r=".9375"/><circle cx="5.625" cy="1.875" r=".9375"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionHeightField.svg b/editor/icons/GPUParticlesCollisionHeightField.svg index b483f299e9..8bdc98a84b 100644 --- a/editor/icons/GPUParticlesCollisionHeightField.svg +++ b/editor/icons/GPUParticlesCollisionHeightField.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c"><path d="m1 10c1-1 3-2 3-4s2-4 4-4 4 2 4 4 2 3 3 4l-7 5z"/><circle cx="2" cy="6" r="1"/><circle cx="14" cy="6" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="4" cy="2" r="1"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f"><path d="m1 10c1-1 3-2 3-4s2-4 4-4 4 2 4 4 2 3 3 4l-7 5z"/><circle cx="2" cy="6" r="1"/><circle cx="14" cy="6" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="4" cy="2" r="1"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionSDF.svg b/editor/icons/GPUParticlesCollisionSDF.svg index 6279990f3a..00eca8295d 100644 --- a/editor/icons/GPUParticlesCollisionSDF.svg +++ b/editor/icons/GPUParticlesCollisionSDF.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 14h-12v-9s3 4 5.9999999 3.9999999c3.0000001-.0000001 6.0000001-3.9999999 6.0000001-3.9999999z" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".996078" stroke-width="2"/><g fill="#fc9c9c" fill-opacity=".996078"><circle cx="2" cy="2" r="1"/><circle cx="14" cy="2" r="1"/><circle cx="10" cy="5" r="1"/><circle cx="6" cy="5" r="1"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 14h-12v-9s3 4 5.9999999 3.9999999c3.0000001-.0000001 6.0000001-3.9999999 6.0000001-3.9999999z" fill="none" stroke="#fc7f7f" stroke-linejoin="round" stroke-opacity=".996078" stroke-width="2"/><g fill="#fc7f7f" fill-opacity=".996078"><circle cx="2" cy="2" r="1"/><circle cx="14" cy="2" r="1"/><circle cx="10" cy="5" r="1"/><circle cx="6" cy="5" r="1"/></g></svg> diff --git a/editor/icons/GPUParticlesCollisionSphere.svg b/editor/icons/GPUParticlesCollisionSphere.svg index fc7715445c..cd188ddacc 100644 --- a/editor/icons/GPUParticlesCollisionSphere.svg +++ b/editor/icons/GPUParticlesCollisionSphere.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" fill-opacity=".996078"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f" fill-opacity=".996078"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg> diff --git a/editor/icons/Generic6DOFJoint3D.svg b/editor/icons/Generic6DOFJoint3D.svg index 63df5fc507..07918748e5 100644 --- a/editor/icons/Generic6DOFJoint3D.svg +++ b/editor/icons/Generic6DOFJoint3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v4.8828l-3.5527-1.7773a1 1 0 0 0 -.48438-.10352 1 1 0 0 0 -.85742.55078 1 1 0 0 0 .44727 1.3418l3.2109 1.6055-3.2109 1.6055a1 1 0 0 0 -.44727 1.3418 1 1 0 0 0 1.3418.44726l3.5527-1.7773v3.8828a1 1 0 0 0 1 1 1 1 0 0 0 1-1v-3.8828l3.5527 1.7773a1 1 0 0 0 1.3418-.44726 1 1 0 0 0 -.44726-1.3418l-3.2109-1.6055 3.2109-1.6055a1 1 0 0 0 .44726-1.3418 1 1 0 0 0 -.88672-.55273 1 1 0 0 0 -.45508.10547l-3.5527 1.7773v-4.8828a1 1 0 0 0 -1-1z" fill="#fc9c9c" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v4.8828l-3.5527-1.7773a1 1 0 0 0 -.48438-.10352 1 1 0 0 0 -.85742.55078 1 1 0 0 0 .44727 1.3418l3.2109 1.6055-3.2109 1.6055a1 1 0 0 0 -.44727 1.3418 1 1 0 0 0 1.3418.44726l3.5527-1.7773v3.8828a1 1 0 0 0 1 1 1 1 0 0 0 1-1v-3.8828l3.5527 1.7773a1 1 0 0 0 1.3418-.44726 1 1 0 0 0 -.44726-1.3418l-3.2109-1.6055 3.2109-1.6055a1 1 0 0 0 .44726-1.3418 1 1 0 0 0 -.88672-.55273 1 1 0 0 0 -.45508.10547l-3.5527 1.7773v-4.8828a1 1 0 0 0 -1-1z" fill="#fc7f7f" fill-rule="evenodd"/></svg> diff --git a/editor/icons/GraphEdit.svg b/editor/icons/GraphEdit.svg index b879259ffc..fbe7422f98 100644 --- a/editor/icons/GraphEdit.svg +++ b/editor/icons/GraphEdit.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.793 4.793 1.4141-1.4141-4.793-4.793h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm10.656 6.9297-.70703.70703 1.4141 1.4141.70703-.70703zm-1.4141 1.4141-3.8887 3.8887-.35352 1.7676 1.7676-.35352 3.8887-3.8887-1.4141-1.4141z" fill="#a5efac" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.793 4.793 1.4141-1.4141-4.793-4.793h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm10.656 6.9297-.70703.70703 1.4141 1.4141.70703-.70703zm-1.4141 1.4141-3.8887 3.8887-.35352 1.7676 1.7676-.35352 3.8887-3.8887-1.4141-1.4141z" fill="#8eef97" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg> diff --git a/editor/icons/GraphNode.svg b/editor/icons/GraphNode.svg index bcd7bfc1c1..061a81d951 100644 --- a/editor/icons/GraphNode.svg +++ b/editor/icons/GraphNode.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.0859 4.0859 1.4141-1.4141-4.0859-4.0859h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9.5 9a2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0 -2.5-2.5z" fill="#a5efac" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.0859 4.0859 1.4141-1.4141-4.0859-4.0859h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9.5 9a2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0 -2.5-2.5z" fill="#8eef97" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg> diff --git a/editor/icons/Grid.svg b/editor/icons/Grid.svg index 8353ad7d19..3b63bfb051 100644 --- a/editor/icons/Grid.svg +++ b/editor/icons/Grid.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 10 2h2 12v-2-12h-12zm2 2h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm1.9999999 2h2v2h-2zm4 0h2v2h-2zm4.0000001 0h2v2h-2zm-8.0000001 4.0000004h2v2h-2zm4 0h2v2h-2zm4.0000001 0h2v2h-2zm-8.0000001 3.9999996h2v2h-2zm4 0h2v2h-2zm4.0000001 0h2v2h-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/GridContainer.svg b/editor/icons/GridContainer.svg index fb6207d94b..94a312bc36 100644 --- a/editor/icons/GridContainer.svg +++ b/editor/icons/GridContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/GrooveJoint2D.svg b/editor/icons/GrooveJoint2D.svg index 41cf64ad66..0f7b84096c 100644 --- a/editor/icons/GrooveJoint2D.svg +++ b/editor/icons/GrooveJoint2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1037.4h-5v6h-5v2h5v6h5zm-7 0h-7v14h7v-4h-5v-6h5z" fill="#a5b7f3" fill-opacity=".98824" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1037.4h-5v6h-5v2h5v6h5zm-7 0h-7v14h7v-4h-5v-6h5z" fill="#8da5f3" fill-opacity=".98824" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/GuiChecked.svg b/editor/icons/GuiChecked.svg index 9bdf5dcb19..31b2995939 100644 --- a/editor/icons/GuiChecked.svg +++ b/editor/icons/GuiChecked.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3.3333333 1c-1.2887 0-2.3333333 1.0446683-2.3333333 2.3333333v9.3333337c0 1.2887 1.0446683 2.333333 2.3333333 2.333333h9.3333337c1.2887 0 2.333333-1.044668 2.333333-2.333333v-9.3333337c0-1.2887-1.044668-2.3333333-2.333333-2.3333333z" fill-opacity=".188235" stroke-width="1.166667"/><path d="m11.500773 3.7343508-5.6117507 5.6117502-1.7045017-1.6814543-1.4992276 1.4992276 3.2037293 3.1806817 7.1109777-7.1109775z" stroke-width="1.060227"/></g></svg> +<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.3333333 1c-1.2887 0-2.3333333 1.0446683-2.3333333 2.3333333v9.3333337c0 1.2887 1.0446683 2.333333 2.3333333 2.333333h9.3333337c1.2887 0 2.333333-1.044668 2.333333-2.333333v-9.3333337c0-1.2887-1.044668-2.3333333-2.333333-2.3333333z" fill="#699ce8" stroke-width="1.16667"/><path d="m11.500773 3.7343508-5.6117507 5.6117502-1.7045017-1.6814543-1.4992276 1.4992276 3.2037293 3.1806817 7.1109777-7.1109775z" fill="#fff" stroke-width="1.06023"/></svg> diff --git a/editor/icons/HBoxContainer.svg b/editor/icons/HBoxContainer.svg index 791fca0ebc..8fbeef525c 100644 --- a/editor/icons/HBoxContainer.svg +++ b/editor/icons/HBoxContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h2v10h-2zm4 0h2v10h-2zm4 0h2v10h-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h2v10h-2zm4 0h2v10h-2zm4 0h2v10h-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/HScrollBar.svg b/editor/icons/HScrollBar.svg index 5828ccb388..3b42eb94c9 100644 --- a/editor/icons/HScrollBar.svg +++ b/editor/icons/HScrollBar.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1041.4c0-1.108-.892-2-2-2h-10c-1.108 0-2 .892-2 2v6c0 1.108.892 2 2 2h10c1.108 0 2-.892 2-2zm-1 2.9883a1.0001 1.0001 0 0 1 -.168.5664l-2 3a1.0001 1.0001 0 1 1 -1.664-1.1094l1.6289-2.4453-1.6289-2.4453a1.0001 1.0001 0 1 1 1.664-1.1094l2 3a1.0001 1.0001 0 0 1 .168.543zm-7.9922-2.9981a1.0001 1.0001 0 0 1 -.1758.5645l-1.6308 2.4453 1.6308 2.4453a1.0001 1.0001 0 1 1 -1.664 1.1094l-2-3a1.0001 1.0001 0 0 1 0-1.1094l2-3a1.0001 1.0001 0 0 1 1.8398.5449z" fill="#a5efac" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1041.4c0-1.108-.892-2-2-2h-10c-1.108 0-2 .892-2 2v6c0 1.108.892 2 2 2h10c1.108 0 2-.892 2-2zm-1 2.9883a1.0001 1.0001 0 0 1 -.168.5664l-2 3a1.0001 1.0001 0 1 1 -1.664-1.1094l1.6289-2.4453-1.6289-2.4453a1.0001 1.0001 0 1 1 1.664-1.1094l2 3a1.0001 1.0001 0 0 1 .168.543zm-7.9922-2.9981a1.0001 1.0001 0 0 1 -.1758.5645l-1.6308 2.4453 1.6308 2.4453a1.0001 1.0001 0 1 1 -1.664 1.1094l-2-3a1.0001 1.0001 0 0 1 0-1.1094l2-3a1.0001 1.0001 0 0 1 1.8398.5449z" fill="#8eef97" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/HSeparator.svg b/editor/icons/HSeparator.svg index d786767be8..c47b126778 100644 --- a/editor/icons/HSeparator.svg +++ b/editor/icons/HSeparator.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2v3h6v-3zm-4 5v2h14v-2zm4 4v3h6v-3z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2v3h6v-3zm-4 5v2h14v-2zm4 4v3h6v-3z" fill="#8eef97"/></svg> diff --git a/editor/icons/HSlider.svg b/editor/icons/HSlider.svg index 0ab453bbce..c876afa843 100644 --- a/editor/icons/HSlider.svg +++ b/editor/icons/HSlider.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 3c-.55228 0-1 .44772-1 1v2c0 .55228.44772 1 1 1s1-.44772 1-1v-2c0-.55228-.44772-1-1-1zm12 0c-.55228 0-1 .44772-1 1v2c0 .55228.44772 1 1 1s1-.44772 1-1v-2c0-.55228-.44772-1-1-1zm-6 1c-.55228 0-1 .44772-1 1s.44772 1 1 1 1-.44772 1-1-.44772-1-1-1zm5 5c-1.1046 0-2 .89543-2 2 0 1.1046.89543 2 2 2 1.0099-.000337 1.8611-.75351 1.9844-1.7559.04003-.16104.03936-.32952-.002-.49024-.12404-1.0008-.97388-1.7527-1.9824-1.7539zm-11 1c-1.3523-.019125-1.3523 2.0191 0 2h7.1309c-.085635-.32648-.1296-.66248-.13086-1 .00189-.3376.046518-.67361.13281-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 3c-.55228 0-1 .44772-1 1v2c0 .55228.44772 1 1 1s1-.44772 1-1v-2c0-.55228-.44772-1-1-1zm12 0c-.55228 0-1 .44772-1 1v2c0 .55228.44772 1 1 1s1-.44772 1-1v-2c0-.55228-.44772-1-1-1zm-6 1c-.55228 0-1 .44772-1 1s.44772 1 1 1 1-.44772 1-1-.44772-1-1-1zm5 5c-1.1046 0-2 .89543-2 2 0 1.1046.89543 2 2 2 1.0099-.000337 1.8611-.75351 1.9844-1.7559.04003-.16104.03936-.32952-.002-.49024-.12404-1.0008-.97388-1.7527-1.9824-1.7539zm-11 1c-1.3523-.019125-1.3523 2.0191 0 2h7.1309c-.085635-.32648-.1296-.66248-.13086-1 .00189-.3376.046518-.67361.13281-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/HSplitContainer.svg b/editor/icons/HSplitContainer.svg index 796e331ef5..4cf32d00ff 100644 --- a/editor/icons/HSplitContainer.svg +++ b/editor/icons/HSplitContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h4v3l-2 2 2 2v3h-4zm6 0h4v10h-4v-3l2-2-2-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h4v3l-2 2 2 2v3h-4zm6 0h4v10h-4v-3l2-2-2-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/Heart.svg b/editor/icons/Heart.svg new file mode 100644 index 0000000000..4f46908760 --- /dev/null +++ b/editor/icons/Heart.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 14c-.1249999 0-.25-.046875-.34375-.140625l-4.875-4.703125c-.0625-.054687-1.7812496-1.6249999-1.7812496-3.5 0-2.2890626 1.3984372-3.6562499 3.7343748-3.6562499 1.3671873 0 2.6484373 1.390625 3.2656248 1.9999999.6171875-.6093749 1.8984375-1.9999999 3.265625-1.9999999 2.335938 0 3.734375 1.3671873 3.734375 3.6562499 0 1.8750001-1.71875 3.4453125-1.789062 3.5156251l-4.867188 4.6874999c-.09375.09375-.2187499.140625-.34375.140625z" fill="#ff7070"/></svg> diff --git a/editor/icons/HingeJoint3D.svg b/editor/icons/HingeJoint3D.svg index ca97169d82..a37377905d 100644 --- a/editor/icons/HingeJoint3D.svg +++ b/editor/icons/HingeJoint3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.2832 1.3281a1.0001 1.0001 0 0 0 -.88086.51172l-3.6895 6.3906c.40599-.13877.83411-.23047 1.2871-.23047.37043 0 .72206.067873 1.0625.16211l3.0723-5.3223a1.0001 1.0001 0 0 0 -.85156-1.5117zm-3.2832 7.6719a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h10a1 1 0 0 0 1-1 1 1 0 0 0 -1-1h-7.1738a3 3 0 0 0 .17383-1 3 3 0 0 0 -3-3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.2832 1.3281a1.0001 1.0001 0 0 0 -.88086.51172l-3.6895 6.3906c.40599-.13877.83411-.23047 1.2871-.23047.37043 0 .72206.067873 1.0625.16211l3.0723-5.3223a1.0001 1.0001 0 0 0 -.85156-1.5117zm-3.2832 7.6719a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h10a1 1 0 0 0 1-1 1 1 0 0 0 -1-1h-7.1738a3 3 0 0 0 .17383-1 3 3 0 0 0 -3-3zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/ImmediateGeometry3D.svg b/editor/icons/ImmediateGeometry3D.svg index 876d752ced..ec5a392a68 100644 --- a/editor/icons/ImmediateGeometry3D.svg +++ b/editor/icons/ImmediateGeometry3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9208 1046.4c-.26373.3-.4204.7296-.4204 1.2383 0 1.6277-3.1381-.1781-.33757 2.6703.88382.899 2.6544.6701 3.5382-.2288.88384-.899.88382-2.3565 0-3.2554-1.1002-1.1191-2.2001-1.0845-2.7803-.4244zm2.3802-1.6103 2.4005 2.4416 6.8014-6.9177c.66286-.6742.66286-1.7673 0-2.4415-.66288-.6741-1.7376-.6741-2.4005 0z" fill="#fc9c9c" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9208 1046.4c-.26373.3-.4204.7296-.4204 1.2383 0 1.6277-3.1381-.1781-.33757 2.6703.88382.899 2.6544.6701 3.5382-.2288.88384-.899.88382-2.3565 0-3.2554-1.1002-1.1191-2.2001-1.0845-2.7803-.4244zm2.3802-1.6103 2.4005 2.4416 6.8014-6.9177c.66286-.6742.66286-1.7673 0-2.4415-.66288-.6741-1.7376-.6741-2.4005 0z" fill="#fc7f7f" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/InsertAfter.svg b/editor/icons/InsertAfter.svg index b75df837bd..d7fc9c67c0 100644 --- a/editor/icons/InsertAfter.svg +++ b/editor/icons/InsertAfter.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="12" fill="none" r="2"/><path d="m11.99.99023a1.0001 1.0001 0 0 0 -.69726 1.7168l.29297.29297h-2.5859v2h2.5859l-.29297.29297a1.0001 1.0001 0 1 0 1.4141 1.4141l2-2a1.0001 1.0001 0 0 0 0-1.4141l-2-2a1.0001 1.0001 0 0 0 -.7168-.30273zm-8.9902.0097656c-1.108 0-2 .892-2 2v2c0 1.108.892 2 2 2h2c1.108 0 2-.892 2-2v-2c0-1.108-.892-2-2-2z" fill="#e0e0e0"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="12" fill="none" r="2"/><path d="m11.99.99023a1.0001 1.0001 0 0 0 -.69726 1.7168l.29297.29297h-2.5859v2h2.5859l-.29297.29297a1.0001 1.0001 0 1 0 1.4141 1.4141l2-2a1.0001 1.0001 0 0 0 0-1.4141l-2-2a1.0001 1.0001 0 0 0 -.7168-.30273zm-8.9902.0097656c-1.108 0-2 .892-2 2v2c0 1.108.892 2 2 2h2c1.108 0 2-.892 2-2v-2c0-1.108-.892-2-2-2z" fill="#e0e0e0"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/></svg> diff --git a/editor/icons/InsertBefore.svg b/editor/icons/InsertBefore.svg index 44c876fc76..ee62b28380 100644 --- a/editor/icons/InsertBefore.svg +++ b/editor/icons/InsertBefore.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="12" fill="none" r="2"/><path d="m4.0096.99023a1.0001 1.0001 0 0 1 .69726 1.7168l-.29297.29297h2.5859v2h-2.5859l.29297.29297a1.0001 1.0001 0 1 1 -1.4141 1.4141l-2-2a1.0001 1.0001 0 0 1 0-1.4141l2-2a1.0001 1.0001 0 0 1 .7168-.30273zm8.9902.0097656c1.108 0 2 .892 2 2v2c0 1.108-.892 2-2 2h-2c-1.108 0-2-.892-2-2v-2c0-1.108.892-2 2-2z" fill="#e0e0e0"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="12" fill="none" r="2"/><path d="m4.0096.99023a1.0001 1.0001 0 0 1 .69726 1.7168l-.29297.29297h2.5859v2h-2.5859l.29297.29297a1.0001 1.0001 0 1 1 -1.4141 1.4141l-2-2a1.0001 1.0001 0 0 1 0-1.4141l2-2a1.0001 1.0001 0 0 1 .7168-.30273zm8.9902.0097656c1.108 0 2 .892 2 2v2c0 1.108-.892 2-2 2h-2c-1.108 0-2-.892-2-2v-2c0-1.108.892-2 2-2z" fill="#e0e0e0"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/></svg> diff --git a/editor/icons/InverseKinematics.svg b/editor/icons/InverseKinematics.svg index e4a076fbbd..4c6dbd4546 100644 --- a/editor/icons/InverseKinematics.svg +++ b/editor/icons/InverseKinematics.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v10.27h2v-10.271a2 2 0 0 0 .73047-.72852h4.541a2 2 0 0 0 .72852.73047v3.2695h-2v2l-1 2 3 2v-4h2v4l3-2-1-2v-2h-2v-3.2715a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-4.541a2 2 0 0 0 -1.7285-1z" fill="#fc9c9c" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v10.27h2v-10.271a2 2 0 0 0 .73047-.72852h4.541a2 2 0 0 0 .72852.73047v3.2695h-2v2l-1 2 3 2v-4h2v4l3-2-1-2v-2h-2v-3.2715a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-4.541a2 2 0 0 0 -1.7285-1z" fill="#fc7f7f" fill-rule="evenodd"/></svg> diff --git a/editor/icons/ItemList.svg b/editor/icons/ItemList.svg index fb98a706a9..efa753fdb6 100644 --- a/editor/icons/ItemList.svg +++ b/editor/icons/ItemList.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-6 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-6 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-6 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-6 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/KeyAnimation.svg b/editor/icons/KeyAnimation.svg index 5afd5bdb70..24a1e84da2 100644 --- a/editor/icons/KeyAnimation.svg +++ b/editor/icons/KeyAnimation.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#b76ef0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#a448f0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> diff --git a/editor/icons/KeyAudio.svg b/editor/icons/KeyAudio.svg index e1a93529a6..18caa7afe2 100644 --- a/editor/icons/KeyAudio.svg +++ b/editor/icons/KeyAudio.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eae668" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eae440" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> diff --git a/editor/icons/KeyBezier.svg b/editor/icons/KeyBezier.svg index cd41f953b1..7bbdd8dbab 100644 --- a/editor/icons/KeyBezier.svg +++ b/editor/icons/KeyBezier.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5792f6" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#2877f6" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> diff --git a/editor/icons/KeyBezierSelected.svg b/editor/icons/KeyBezierSelected.svg index e8536e97b4..741f9bea60 100644 --- a/editor/icons/KeyBezierSelected.svg +++ b/editor/icons/KeyBezierSelected.svg @@ -1 +1 @@ -<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#84c2ff" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1044.4)" width="6.1027" x="-741.53" y="741.08"/></svg> +<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1044.4)" width="6.1027" x="-741.53" y="741.08"/></svg> diff --git a/editor/icons/KeyCall.svg b/editor/icons/KeyCall.svg index dd47272d4f..5ffbceeb09 100644 --- a/editor/icons/KeyCall.svg +++ b/editor/icons/KeyCall.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#66f376" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#3cf34e" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> diff --git a/editor/icons/KeyNext.svg b/editor/icons/KeyNext.svg index a2b616072b..83a8329494 100644 --- a/editor/icons/KeyNext.svg +++ b/editor/icons/KeyNext.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/><path d="m11 1a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 2.8672 2.8691v-.86914h3.6387a4 4 0 0 0 1.3613-3 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/><path d="m11 1a4 4 0 0 0 -3.8691 3h-6.1309v2h1v2h3v-2h2.1328a4 4 0 0 0 2.8672 2.8691v-.86914h3.6387a4 4 0 0 0 1.3613-3 4 4 0 0 0 -4-4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0" fill-opacity=".99608"/></svg> diff --git a/editor/icons/KeySelected.svg b/editor/icons/KeySelected.svg index 32f900bdd6..aff66b9a27 100644 --- a/editor/icons/KeySelected.svg +++ b/editor/icons/KeySelected.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#84c2ff" height="6.1027" ry=".76286" transform="matrix(.87871827 -.87871827 .87871827 .87871827 .03288 -1297.7965)" width="6.1027" x="-741.53003" y="741.08002"/><rect fill="#003e7a" height="3.434683" ry=".429348" stroke-width=".562814" transform="matrix(.89137101 -.86588067 .89137101 .86588067 -.038545 -1297.8361)" width="3.434683" x="-751.20953" y="753.42743"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5fb2ff" height="6.1027" ry=".76286" transform="matrix(.87871827 -.87871827 .87871827 .87871827 .03288 -1297.7965)" width="6.1027" x="-741.53003" y="741.08002"/><rect fill="#003e7a" height="3.434683" ry=".429348" stroke-width=".562814" transform="matrix(.89137101 -.86588067 .89137101 .86588067 -.038545 -1297.8361)" width="3.434683" x="-751.20953" y="753.42743"/></svg> diff --git a/editor/icons/KeyXform.svg b/editor/icons/KeyXform.svg index 12f27d32a9..59c14cd820 100644 --- a/editor/icons/KeyXform.svg +++ b/editor/icons/KeyXform.svg @@ -1 +1 @@ -<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea9568" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea7940" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> diff --git a/editor/icons/KinematicBody2D.svg b/editor/icons/KinematicBody2D.svg index 70faad6a49..b71fda9650 100644 --- a/editor/icons/KinematicBody2D.svg +++ b/editor/icons/KinematicBody2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6.4921 1c-.55401 0-1 .446-1 1v3c0 .554.44599 1 1 1h1v.9902a1.0001 1.0001 0 0 0 -.31641.062l-2.0508.6836-.68359-2.0508a1.0001 1.0001 0 0 0 -.99023-.6972 1.0001 1.0001 0 0 0 -.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656.6328l1.6836-.5605v.6113c0 .041.018715.076.023437.1152l-4.5781 3.0528a1.0001 1.0001 0 1 0 1.1094 1.664l5.0566-3.3711 1.4941 2.9864a1.0001 1.0001 0 0 0 1.2109.5019l3-1a1.0001 1.0001 0 1 0 -.63281-1.8965l-2.1777.7246-.97461-1.9511c.2759-.1777.46875-.4723.46875-.8262v-1h1.3828l.72266 1.4473a1.0001 1.0001 0 1 0 1.7891-.8946l-1-2a1.0001 1.0001 0 0 0 -.89453-.5527h-3v-1h1c.55401 0 1-.446 1-1v-3c0-.554-.44599-1-1-1zm0 2h1v2h-1z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6.4921 1c-.55401 0-1 .446-1 1v3c0 .554.44599 1 1 1h1v.9902a1.0001 1.0001 0 0 0 -.31641.062l-2.0508.6836-.68359-2.0508a1.0001 1.0001 0 0 0 -.99023-.6972 1.0001 1.0001 0 0 0 -.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656.6328l1.6836-.5605v.6113c0 .041.018715.076.023437.1152l-4.5781 3.0528a1.0001 1.0001 0 1 0 1.1094 1.664l5.0566-3.3711 1.4941 2.9864a1.0001 1.0001 0 0 0 1.2109.5019l3-1a1.0001 1.0001 0 1 0 -.63281-1.8965l-2.1777.7246-.97461-1.9511c.2759-.1777.46875-.4723.46875-.8262v-1h1.3828l.72266 1.4473a1.0001 1.0001 0 1 0 1.7891-.8946l-1-2a1.0001 1.0001 0 0 0 -.89453-.5527h-3v-1h1c.55401 0 1-.446 1-1v-3c0-.554-.44599-1-1-1zm0 2h1v2h-1z" fill="#8da5f3"/></svg> diff --git a/editor/icons/KinematicBody3D.svg b/editor/icons/KinematicBody3D.svg index 06e9275ec1..d0def4f14a 100644 --- a/editor/icons/KinematicBody3D.svg +++ b/editor/icons/KinematicBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1c-.55401 0-1 .44599-1 1v3c0 .55401.44599 1 1 1h1v.99023a1.0001 1.0001 0 0 0 -.31641.0625l-2.0508.68359-.68359-2.0508a1.0001 1.0001 0 0 0 -.99023-.69727 1.0001 1.0001 0 0 0 -.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656.63281l1.6836-.56055v.61133c0 .04088.018715.07566.023437.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109.50195l3-1a1.0001 1.0001 0 1 0 -.63281-1.8965l-2.1777.72461-.97461-1.9512c.2759-.17764.46875-.47227.46875-.82617v-1h1.3828l.72266 1.4473a1.0001 1.0001 0 1 0 1.7891-.89453l-1-2a1.0001 1.0001 0 0 0 -.89453-.55273h-3v-1h1c.55401 0 1-.44599 1-1v-3c0-.55401-.44599-1-1-1zm0 2h1v2h-1z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1c-.55401 0-1 .44599-1 1v3c0 .55401.44599 1 1 1h1v.99023a1.0001 1.0001 0 0 0 -.31641.0625l-2.0508.68359-.68359-2.0508a1.0001 1.0001 0 0 0 -.99023-.69727 1.0001 1.0001 0 0 0 -.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656.63281l1.6836-.56055v.61133c0 .04088.018715.07566.023437.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109.50195l3-1a1.0001 1.0001 0 1 0 -.63281-1.8965l-2.1777.72461-.97461-1.9512c.2759-.17764.46875-.47227.46875-.82617v-1h1.3828l.72266 1.4473a1.0001 1.0001 0 1 0 1.7891-.89453l-1-2a1.0001 1.0001 0 0 0 -.89453-.55273h-3v-1h1c.55401 0 1-.44599 1-1v-3c0-.55401-.44599-1-1-1zm0 2h1v2h-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/Label.svg b/editor/icons/Label.svg index bfb1c903f3..f7a6fb3a9e 100644 --- a/editor/icons/Label.svg +++ b/editor/icons/Label.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 3a1.0001 1.0001 0 0 0 -.70703.29297l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1.0001 1.0001 0 0 0 .70703.29297h8a1.0001 1.0001 0 0 0 1-1v-8a1.0001 1.0001 0 0 0 -1-1h-8zm-1 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#a5efac" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 3a1.0001 1.0001 0 0 0 -.70703.29297l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1.0001 1.0001 0 0 0 .70703.29297h8a1.0001 1.0001 0 0 0 1-1v-8a1.0001 1.0001 0 0 0 -1-1h-8zm-1 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#8eef97" fill-rule="evenodd"/></svg> diff --git a/editor/icons/LightOccluder2D.svg b/editor/icons/LightOccluder2D.svg index 8c5bb89218..ff2c4d4561 100644 --- a/editor/icons/LightOccluder2D.svg +++ b/editor/icons/LightOccluder2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1037.4c-2.7614 0-5 2.2386-5 5 .00253 1.9858 1.18 3.7819 3 4.5762v2.4238h4v-2.4199c1.8213-.7949 2.999-2.5929 3-4.5801 0-2.7614-2.2386-5-5-5zm0 2v6c-1.6569 0-3-1.3431-3-3s1.3431-3 3-3zm-1 11v1h2v-1z" fill="#a5b7f3" fill-opacity=".98824" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1037.4c-2.7614 0-5 2.2386-5 5 .00253 1.9858 1.18 3.7819 3 4.5762v2.4238h4v-2.4199c1.8213-.7949 2.999-2.5929 3-4.5801 0-2.7614-2.2386-5-5-5zm0 2v6c-1.6569 0-3-1.3431-3-3s1.3431-3 3-3zm-1 11v1h2v-1z" fill="#8da5f3" fill-opacity=".98824" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/LightmapProbe.svg b/editor/icons/LightmapProbe.svg index bc790d50c1..07f2b41a7c 100644 --- a/editor/icons/LightmapProbe.svg +++ b/editor/icons/LightmapProbe.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9h3v-2h-3zm2.050781 2.535156 1.414063 1.414063 1.414062-1.414063-1.414062-1.414062zm0-7.070312 1.414063 1.414062 1.414062-1.414062-1.414062-1.414063zm1.949219 3.535156c0 1.6569 1.3432 3 3 3s3-1.3431 3-3-1.3432-3-3-3-3 1.3431-3 3zm3 7c3.865993 0 7-3.134007 7-7s-3.134007-7-7-7v2.333984c2.577329 0 4.666016 2.088687 4.666016 4.666016s-2.088687 4.666016-4.666016 4.666016z" fill="#fc9c9c" fill-opacity=".996078" stroke-width="1.16667"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9h3v-2h-3zm2.050781 2.535156 1.414063 1.414063 1.414062-1.414063-1.414062-1.414062zm0-7.070312 1.414063 1.414062 1.414062-1.414062-1.414062-1.414063zm1.949219 3.535156c0 1.6569 1.3432 3 3 3s3-1.3431 3-3-1.3432-3-3-3-3 1.3431-3 3zm3 7c3.865993 0 7-3.134007 7-7s-3.134007-7-7-7v2.333984c2.577329 0 4.666016 2.088687 4.666016 4.666016s-2.088687 4.666016-4.666016 4.666016z" fill="#fc7f7f" fill-opacity=".996078" stroke-width="1.16667"/></svg> diff --git a/editor/icons/Line2D.svg b/editor/icons/Line2D.svg index a0f9d1e33c..e9e70af5c7 100644 --- a/editor/icons/Line2D.svg +++ b/editor/icons/Line2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1045.4 3 4 3-10 3 6 3-2" fill="none" stroke="#a5b7f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1045.4 3 4 3-10 3 6 3-2" fill="none" stroke="#8da5f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/LineEdit.svg b/editor/icons/LineEdit.svg index 54e3190259..168836a432 100644 --- a/editor/icons/LineEdit.svg +++ b/editor/icons/LineEdit.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 4v5h2v-5zm-1 7c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2h-2-10z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 4v5h2v-5zm-1 7c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2h-2-10z" fill="#8eef97"/></svg> diff --git a/editor/icons/LinkButton.svg b/editor/icons/LinkButton.svg index 3a99d241c3..a3d29e82e8 100644 --- a/editor/icons/LinkButton.svg +++ b/editor/icons/LinkButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 3a5 5 0 0 0 -4.3301 2.5 5 5 0 0 0 0 5 5 5 0 0 0 4.3301 2.5h1v-2h-1a3 3 0 0 1 -3-3 3 3 0 0 1 3-3h1v-2zm3 0v2h1a3 3 0 0 1 3 3 3 3 0 0 1 -3 3h-1v2h1a5 5 0 0 0 4.3301-2.5 5 5 0 0 0 0-5 5 5 0 0 0 -4.3301-2.5zm-3 4a.99998.99998 0 0 0 -1 1 .99998.99998 0 0 0 1 1h4a.99998.99998 0 0 0 1-1 .99998.99998 0 0 0 -1-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 3a5 5 0 0 0 -4.3301 2.5 5 5 0 0 0 0 5 5 5 0 0 0 4.3301 2.5h1v-2h-1a3 3 0 0 1 -3-3 3 3 0 0 1 3-3h1v-2zm3 0v2h1a3 3 0 0 1 3 3 3 3 0 0 1 -3 3h-1v2h1a5 5 0 0 0 4.3301-2.5 5 5 0 0 0 0-5 5 5 0 0 0 -4.3301-2.5zm-3 4a.99998.99998 0 0 0 -1 1 .99998.99998 0 0 0 1 1h4a.99998.99998 0 0 0 1-1 .99998.99998 0 0 0 -1-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/Listener3D.svg b/editor/icons/Listener3D.svg index 7afbdccd43..c068474d17 100644 --- a/editor/icons/Listener3D.svg +++ b/editor/icons/Listener3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.75-.54175 2.3583-1.1406 2.8574-.29944.2495-.62954.44071-.97656.69141-.17351.1253-.35729.26529-.53711.49219-.17982.227-.3457.58398-.3457.95898 0 1.2778-.31632 1.5742-.63867 1.7676-.32236.1934-.86133.23242-1.3613.23242h-1v2h1c.5 0 1.461.038922 2.3887-.51758.87316-.5239 1.4826-1.6633 1.5566-3.2266.011365-.0098.027247-.024684.10938-.083984.21547-.1556.63537-.40194 1.0859-.77734.90112-.751 1.8594-2.1445 1.8594-4.3945a5 5 0 0 0 -5-5zm7.9277 1-1.7383 1.0039a6 6 0 0 1 .81055 2.9961 6 6 0 0 1 -.80859 2.998l1.7363 1.002a8 8 0 0 0 0-8z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.75-.54175 2.3583-1.1406 2.8574-.29944.2495-.62954.44071-.97656.69141-.17351.1253-.35729.26529-.53711.49219-.17982.227-.3457.58398-.3457.95898 0 1.2778-.31632 1.5742-.63867 1.7676-.32236.1934-.86133.23242-1.3613.23242h-1v2h1c.5 0 1.461.038922 2.3887-.51758.87316-.5239 1.4826-1.6633 1.5566-3.2266.011365-.0098.027247-.024684.10938-.083984.21547-.1556.63537-.40194 1.0859-.77734.90112-.751 1.8594-2.1445 1.8594-4.3945a5 5 0 0 0 -5-5zm7.9277 1-1.7383 1.0039a6 6 0 0 1 .81055 2.9961 6 6 0 0 1 -.80859 2.998l1.7363 1.002a8 8 0 0 0 0-8z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/MarginContainer.svg b/editor/icons/MarginContainer.svg index 82e72c0da9..6c6f1271d1 100644 --- a/editor/icons/MarginContainer.svg +++ b/editor/icons/MarginContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#a5efac" transform="translate(0 -1036.4)"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10z" transform="translate(0 1036.4)"/><path d="m4 1042.4v4l2-2z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#8eef97" transform="translate(0 -1036.4)"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10z" transform="translate(0 1036.4)"/><path d="m4 1042.4v4l2-2z"/></g></svg> diff --git a/editor/icons/MenuButton.svg b/editor/icons/MenuButton.svg index ca129baced..cb1d9e8382 100644 --- a/editor/icons/MenuButton.svg +++ b/editor/icons/MenuButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h14v-4zm5 1h4l-2 2zm-4 4a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7a1 1 0 0 0 -1-1zm1 2h10v2h-10zm0 3h10v2h-10z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h14v-4zm5 1h4l-2 2zm-4 4a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7a1 1 0 0 0 -1-1zm1 2h10v2h-10zm0 3h10v2h-10z" fill="#8eef97"/></svg> diff --git a/editor/icons/Mesh.svg b/editor/icons/Mesh.svg index c02d5d0613..a1743e4c58 100644 --- a/editor/icons/Mesh.svg +++ b/editor/icons/Mesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#ffca5f"/></svg> diff --git a/editor/icons/MeshInstance2D.svg b/editor/icons/MeshInstance2D.svg index b8df0768d2..8f6de06252 100644 --- a/editor/icons/MeshInstance2D.svg +++ b/editor/icons/MeshInstance2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#8da5f3"/></svg> diff --git a/editor/icons/MeshInstance3D.svg b/editor/icons/MeshInstance3D.svg index aa0cf7740b..a9258505f8 100644 --- a/editor/icons/MeshInstance3D.svg +++ b/editor/icons/MeshInstance3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -1.0312-1.75h.03125v-6.5215a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm2.4141 3h5.8574a2 2 0 0 0 .72852.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141 6.5859 6.5859h-5.8574a2 2 0 0 0 -.72852-.73047v-5.8555z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/MeshLibrary.svg b/editor/icons/MeshLibrary.svg index 6e824af177..5d64acd97e 100644 --- a/editor/icons/MeshLibrary.svg +++ b/editor/icons/MeshLibrary.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h2.2695v-2h-2.2715a2 2 0 0 0 -.72852-.73047v-5.8555l3 3v-.41406a2.0002 2.0002 0 0 1 .80859-1.6055l-2.3945-2.3945h5.8574a2 2 0 0 0 .72852.73047v1.2695a2.0002 2.0002 0 0 1 .99805.27148 2.0002 2.0002 0 0 1 1.002-.27148v-1.2715a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm6 7v1 5 1h5c.55228 0 1-.4477 1-1v-5c0-.5523-.44772-1-1-1v4l-1-1-1 1v-4z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h2.2695v-2h-2.2715a2 2 0 0 0 -.72852-.73047v-5.8555l3 3v-.41406a2.0002 2.0002 0 0 1 .80859-1.6055l-2.3945-2.3945h5.8574a2 2 0 0 0 .72852.73047v1.2695a2.0002 2.0002 0 0 1 .99805.27148 2.0002 2.0002 0 0 1 1.002-.27148v-1.2715a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm6 7v1 5 1h5c.55228 0 1-.4477 1-1v-5c0-.5523-.44772-1-1-1v4l-1-1-1 1v-4z" fill="#ffca5f"/></svg> diff --git a/editor/icons/MiniObject.svg b/editor/icons/MiniObject.svg index b4a336923d..7fe3b773d6 100644 --- a/editor/icons/MiniObject.svg +++ b/editor/icons/MiniObject.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm0 5a3 3 0 0 0 -3-3 3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3zm7-3v5a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-5zm-10 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#79f3e8"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2v8h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3v-2zm0 5a3 3 0 0 0 -3-3 3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3zm7-3v5a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-5zm-10 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#55f3e3"/></svg> diff --git a/editor/icons/MovePoint.svg b/editor/icons/MovePoint.svg index 03b15e47b5..a5d728e6dd 100644 --- a/editor/icons/MovePoint.svg +++ b/editor/icons/MovePoint.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 1.2129-.10742l-2.5996-6.3203a1.5002 1.5002 0 0 1 1.3711-2.0703v-.0019531a1.5002 1.5002 0 0 1 .58594.11133l6.3184 2.5996a7 7 0 0 0 .11133-1.2109 7 7 0 0 0 -7-7zm2.7559 9.7559.52344 1.2734a1.5002 1.5002 0 0 1 .48047-.26953 1.5002 1.5002 0 0 1 .26953-.47852l-1.2734-.52539z" fill="#fff" transform="translate(0 1036.4)"/><path d="m8 3a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 .42578-.021484l-1.8125-4.4063a1.5002 1.5002 0 0 1 1.3711-2.0703v-.0019531a1.5002 1.5002 0 0 1 .58594.11133l4.4082 1.8125a5 5 0 0 0 .021484-.42383 5 5 0 0 0 -5-5zm2.7559 7.7559.44336 1.0801a5 5 0 0 0 .63867-.63281l-1.082-.44727z" fill="#ff8484" transform="translate(0 1036.4)"/><path d="m16 1047.7-8-3.291 3.291 8 .9471-2.8201 1.8836 1.8835.9418-.9418-1.8836-1.8835z" fill="#e0e0e0"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 1.2129-.10742l-2.5996-6.3203a1.5002 1.5002 0 0 1 1.3711-2.0703v-.0019531a1.5002 1.5002 0 0 1 .58594.11133l6.3184 2.5996a7 7 0 0 0 .11133-1.2109 7 7 0 0 0 -7-7zm2.7559 9.7559.52344 1.2734a1.5002 1.5002 0 0 1 .48047-.26953 1.5002 1.5002 0 0 1 .26953-.47852l-1.2734-.52539z" fill="#fff" transform="translate(0 1036.4)"/><path d="m8 3a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 .42578-.021484l-1.8125-4.4063a1.5002 1.5002 0 0 1 1.3711-2.0703v-.0019531a1.5002 1.5002 0 0 1 .58594.11133l4.4082 1.8125a5 5 0 0 0 .021484-.42383 5 5 0 0 0 -5-5zm2.7559 7.7559.44336 1.0801a5 5 0 0 0 .63867-.63281l-1.082-.44727z" fill="#ff5f5f" transform="translate(0 1036.4)"/><path d="m16 1047.7-8-3.291 3.291 8 .9471-2.8201 1.8836 1.8835.9418-.9418-1.8836-1.8835z" fill="#e0e0e0"/></g></svg> diff --git a/editor/icons/MultiMesh.svg b/editor/icons/MultiMesh.svg index 6ee638db4c..5b4900841f 100644 --- a/editor/icons/MultiMesh.svg +++ b/editor/icons/MultiMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#ffca5f"/></svg> diff --git a/editor/icons/MultiMeshInstance2D.svg b/editor/icons/MultiMeshInstance2D.svg index 07c72aeed1..253a43bf55 100644 --- a/editor/icons/MultiMeshInstance2D.svg +++ b/editor/icons/MultiMeshInstance2D.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m-1-1h582v402h-582z" fill="none"/><path d="m3 1c-1.1046 0-2 .89543-2 2 .00056.71397.38169 1.3735 1 1.7305v6.541c-.61771.35664-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.00056 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.00056-1.3735.38169-1.7305 1h-6.541c-.35664-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#a5b7f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m-1-1h582v402h-582z" fill="none"/><path d="m3 1c-1.1046 0-2 .89543-2 2 .00056.71397.38169 1.3735 1 1.7305v6.541c-.61771.35664-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.00056 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.00056-1.3735.38169-1.7305 1h-6.541c-.35664-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#8da5f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg> diff --git a/editor/icons/MultiMeshInstance3D.svg b/editor/icons/MultiMeshInstance3D.svg index 61d728c4be..3ccd2c9cbe 100644 --- a/editor/icons/MultiMeshInstance3D.svg +++ b/editor/icons/MultiMeshInstance3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h1.2695v-2h-1.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c.17532.30158.42647.55205.72852.72656v1.2734h2v-1.2695c.61831-.35698.99944-1.0165 1-1.7305 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/Navigation2D.svg b/editor/icons/Navigation2D.svg index 6725400e92..aa3e258eae 100644 --- a/editor/icons/Navigation2D.svg +++ b/editor/icons/Navigation2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/Navigation3D.svg b/editor/icons/Navigation3D.svg index 74c8e204a3..646500d9ed 100644 --- a/editor/icons/Navigation3D.svg +++ b/editor/icons/Navigation3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1050.4 5-2 5 2-5-12z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/NavigationMesh.svg b/editor/icons/NavigationMesh.svg index 45bc51ac31..c5f16596a6 100644 --- a/editor/icons/NavigationMesh.svg +++ b/editor/icons/NavigationMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h2.5078l.75-2h-3.2598a2 2 0 0 0 -.72852-.73047v-5.8555l4.6973 4.6973.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 .72852.73047v.27148a2.0002 2.0002 0 0 1 .023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l.12695.33789v-1.9082a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9 6-3 8 3-2 3 2z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h2.5078l.75-2h-3.2598a2 2 0 0 0 -.72852-.73047v-5.8555l4.6973 4.6973.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 .72852.73047v.27148a2.0002 2.0002 0 0 1 .023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l.12695.33789v-1.9082a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9 6-3 8 3-2 3 2z" fill="#ffca5f"/></svg> diff --git a/editor/icons/NavigationRegion2D.svg b/editor/icons/NavigationRegion2D.svg index 3ec0938417..8efd836075 100644 --- a/editor/icons/NavigationRegion2D.svg +++ b/editor/icons/NavigationRegion2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.1339223.0000569-.2535666.0306675-.3652344.0742188-.022275.0088111-.0410424.0209185-.0625.03125-.0889622.0424668-.1681009.0954994-.2382812.1601562-.0215322.0195204-.0427394.0372854-.0625.0585938-.0741112.0810923-.13722.1698052-.1816406.2695312-.0034324.0076504-.0084746.0137334-.0117188.0214844l-.0019531.0019531c-.0452252.1091882-.0629923.2268973-.0683594.3457031-.0005086.0130821-.0078112.023903-.0078125.0371094v12c.0000552.552262.4477381.999945 1 1h4.8847656a2.1184381 2.1184381 0 0 1 .1328125-.744141l2.9999999-7.9999996a2.1184381 2.1184381 0 0 1 2.007813-1.3730469 2.1184381 2.1184381 0 0 1 1.957031 1.3730469l1.017578 2.7128906v-6.96875c-.000001-.0132064-.007305-.0240273-.007812-.0371094-.005369-.1188058-.023135-.2365149-.06836-.3457031l-.001953-.0019531c-.003155-.0075626-.008384-.0139987-.011719-.0214844-.044421-.099726-.107529-.188439-.18164-.2695312-.019761-.0213083-.040968-.0390734-.0625-.0585938-.070181-.0646568-.149319-.1176895-.238282-.1601562-.021457-.0103315-.040225-.022439-.0625-.03125-.111667-.0435511-.231312-.0741619-.365234-.0742188zm10 6-3 8 3-2 3 2z" fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.1339223.0000569-.2535666.0306675-.3652344.0742188-.022275.0088111-.0410424.0209185-.0625.03125-.0889622.0424668-.1681009.0954994-.2382812.1601562-.0215322.0195204-.0427394.0372854-.0625.0585938-.0741112.0810923-.13722.1698052-.1816406.2695312-.0034324.0076504-.0084746.0137334-.0117188.0214844l-.0019531.0019531c-.0452252.1091882-.0629923.2268973-.0683594.3457031-.0005086.0130821-.0078112.023903-.0078125.0371094v12c.0000552.552262.4477381.999945 1 1h4.8847656a2.1184381 2.1184381 0 0 1 .1328125-.744141l2.9999999-7.9999996a2.1184381 2.1184381 0 0 1 2.007813-1.3730469 2.1184381 2.1184381 0 0 1 1.957031 1.3730469l1.017578 2.7128906v-6.96875c-.000001-.0132064-.007305-.0240273-.007812-.0371094-.005369-.1188058-.023135-.2365149-.06836-.3457031l-.001953-.0019531c-.003155-.0075626-.008384-.0139987-.011719-.0214844-.044421-.099726-.107529-.188439-.18164-.2695312-.019761-.0213083-.040968-.0390734-.0625-.0585938-.070181-.0646568-.149319-.1176895-.238282-.1601562-.021457-.0103315-.040225-.022439-.0625-.03125-.111667-.0435511-.231312-.0741619-.365234-.0742188zm10 6-3 8 3-2 3 2z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd"/></svg> diff --git a/editor/icons/NavigationRegion3D.svg b/editor/icons/NavigationRegion3D.svg index 7a899dbc80..39b6d0ca13 100644 --- a/editor/icons/NavigationRegion3D.svg +++ b/editor/icons/NavigationRegion3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.1339223.0000569-.2535666.030668-.3652344.074219-.022275.00881-.041042.020919-.0625.03125-.088962.042467-.1681009.095499-.2382812.1601562-.021532.01952-.042739.037285-.0625.058594-.074111.081092-.13722.1698052-.1816406.2695312-.00343.00765-.00847.013733-.011719.021484l-.00195.00195c-.0452281.1091913-.0629952.2269004-.0683623.3457062-.0005086.0130821-.0078112.023903-.0078125.0371094v12c.0000552.552262.4477381.999945 1 1h4.8847656a2.1184381 2.1184381 0 0 1 .1328125-.744141l2.9999999-7.9999996a2.1184381 2.1184381 0 0 1 2.007813-1.3730469 2.1184381 2.1184381 0 0 1 1.957031 1.3730469l1.017578 2.7128906v-6.96875c-.000001-.013206-.0073-.024027-.0078-.037109-.0054-.1188058-.02313-.2365149-.06836-.3457031l-.002-.00195c-.0032-.00756-.0084-.013999-.01172-.021484-.04442-.099726-.107529-.188439-.18164-.2695312-.01976-.021308-.04097-.039073-.0625-.058594-.07018-.064657-.149319-.1176895-.238282-.1601562-.02146-.010331-.04022-.022439-.0625-.03125-.111631-.0435548-.231276-.0741656-.365198-.0742225zm10 6-3 8 3-2 3 2z" fill="#fc9c9c" fill-opacity=".996078" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.1339223.0000569-.2535666.030668-.3652344.074219-.022275.00881-.041042.020919-.0625.03125-.088962.042467-.1681009.095499-.2382812.1601562-.021532.01952-.042739.037285-.0625.058594-.074111.081092-.13722.1698052-.1816406.2695312-.00343.00765-.00847.013733-.011719.021484l-.00195.00195c-.0452281.1091913-.0629952.2269004-.0683623.3457062-.0005086.0130821-.0078112.023903-.0078125.0371094v12c.0000552.552262.4477381.999945 1 1h4.8847656a2.1184381 2.1184381 0 0 1 .1328125-.744141l2.9999999-7.9999996a2.1184381 2.1184381 0 0 1 2.007813-1.3730469 2.1184381 2.1184381 0 0 1 1.957031 1.3730469l1.017578 2.7128906v-6.96875c-.000001-.013206-.0073-.024027-.0078-.037109-.0054-.1188058-.02313-.2365149-.06836-.3457031l-.002-.00195c-.0032-.00756-.0084-.013999-.01172-.021484-.04442-.099726-.107529-.188439-.18164-.2695312-.01976-.021308-.04097-.039073-.0625-.058594-.07018-.064657-.149319-.1176895-.238282-.1601562-.02146-.010331-.04022-.022439-.0625-.03125-.111631-.0435548-.231276-.0741656-.365198-.0742225zm10 6-3 8 3-2 3 2z" fill="#fc7f7f" fill-opacity=".996078" fill-rule="evenodd"/></svg> diff --git a/editor/icons/New.svg b/editor/icons/New.svg index efc897cb4f..1667f46075 100644 --- a/editor/icons/New.svg +++ b/editor/icons/New.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.400017)"><path d="m2 1v14h8v-1h-2v-4h2v-2h4v-2h-5v-5zm8 0v4h4z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m11 1045.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.400017)"><path d="m2 1v14h8v-1h-2v-4h2v-2h4v-2h-5v-5zm8 0v4h4z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m11 1045.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97"/></g></svg> diff --git a/editor/icons/NewRoot.svg b/editor/icons/NewRoot.svg index 061ff6043a..df3d590d01 100644 --- a/editor/icons/NewRoot.svg +++ b/editor/icons/NewRoot.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 4.7813475v2.0494746c-.6177049.3566305-.998733 1.0152377-1 1.7285 0 1.1045694.8954305 1.9999999 2 1.9999999.7139771-.000554 1.3735116-.381678 1.7305-.9999995h1.3545593c.3566306.6177035 1.0152377.9987325 1.7285.9999995 1.1045696 0 1.9999996-.8954305 1.9999996-1.9999999 0-1.1045695-.89543-2-1.9999996-2-.7139771.0005537-1.3735116.3816774-1.7305 1h-1.3545593c-.1747809-.3030102-.4259781-.5548798-.72852-.73047v-2.0494746c-.5384713.0290292-1.2982621.0368063-1.99998.00197z" fill="#e0e0e0"/><path d="m6.8474576 9.6288045v1.2020165c-.617705.35663-.998733 1.015237-1 1.7285 0 1.104569.89543 2 2 2 .713977-.000554 1.373512-.381678 1.7305-1h1.2867634c.35663.617704 1.015237.998733 1.7285 1 1.104569 0 1.999999-.895431 1.999999-2 0-1.10457-.89543-2-1.999999-2-.713977.000553-1.373512.381677-1.7305 1h-1.2867634c-.174781-.303011-.425978-.55488-.72852-.73047v-1.2020165s-1.264363.03681-1.99998.002z" fill="#e0e0e0"/><path d="m2.7966098 1.3559322c-1.104569 0-2.00000003.8954305-2.00000003 2 .000554.7139771.38167803 1.3735116 1.00000003 1.7305.757716.266212.949133.2840609 1.99998-.00197.617705-.3566306.998733-1.0152377 1-1.7285 0-1.1045695-.89543-2-2-2z" fill="#84ffb1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 4.7813475v2.0494746c-.6177049.3566305-.998733 1.0152377-1 1.7285 0 1.1045694.8954305 1.9999999 2 1.9999999.7139771-.000554 1.3735116-.381678 1.7305-.9999995h1.3545593c.3566306.6177035 1.0152377.9987325 1.7285.9999995 1.1045696 0 1.9999996-.8954305 1.9999996-1.9999999 0-1.1045695-.89543-2-1.9999996-2-.7139771.0005537-1.3735116.3816774-1.7305 1h-1.3545593c-.1747809-.3030102-.4259781-.5548798-.72852-.73047v-2.0494746c-.5384713.0290292-1.2982621.0368063-1.99998.00197z" fill="#e0e0e0"/><path d="m6.8474576 9.6288045v1.2020165c-.617705.35663-.998733 1.015237-1 1.7285 0 1.104569.89543 2 2 2 .713977-.000554 1.373512-.381678 1.7305-1h1.2867634c.35663.617704 1.015237.998733 1.7285 1 1.104569 0 1.999999-.895431 1.999999-2 0-1.10457-.89543-2-1.999999-2-.713977.000553-1.373512.381677-1.7305 1h-1.2867634c-.174781-.303011-.425978-.55488-.72852-.73047v-1.2020165s-1.264363.03681-1.99998.002z" fill="#e0e0e0"/><path d="m2.7966098 1.3559322c-1.104569 0-2.00000003.8954305-2.00000003 2 .000554.7139771.38167803 1.3735116 1.00000003 1.7305.757716.266212.949133.2840609 1.99998-.00197.617705-.3566306.998733-1.0152377 1-1.7285 0-1.1045695-.89543-2-2-2z" fill="#5fff97"/></svg> diff --git a/editor/icons/NinePatchRect.svg b/editor/icons/NinePatchRect.svg index d857b71a46..56ed224f98 100644 --- a/editor/icons/NinePatchRect.svg +++ b/editor/icons/NinePatchRect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#a5efac" transform="translate(0 -1036.4)"><path d="m1 1037.4h2v14h-2z"/><path d="m1 1049.4h14v2h-14z"/><path d="m1 1037.4h14v2h-14z"/><path d="m13 1037.4h2v14h-2z"/><path d="m1 1041.4h14v.99998h-14z"/><path d="m1 1046.4h14v.99998h-14z"/><g transform="rotate(90)"><path d="m1037.4-6h14v.99998h-14z"/><path d="m1037.4-11h14v.99998h-14z"/></g></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#8eef97" transform="translate(0 -1036.4)"><path d="m1 1037.4h2v14h-2z"/><path d="m1 1049.4h14v2h-14z"/><path d="m1 1037.4h14v2h-14z"/><path d="m13 1037.4h2v14h-2z"/><path d="m1 1041.4h14v.99998h-14z"/><path d="m1 1046.4h14v.99998h-14z"/><g transform="rotate(90)"><path d="m1037.4-6h14v.99998h-14z"/><path d="m1037.4-11h14v.99998h-14z"/></g></g></svg> diff --git a/editor/icons/Node2D.svg b/editor/icons/Node2D.svg index 7f27e0695f..a47399df92 100644 --- a/editor/icons/Node2D.svg +++ b/editor/icons/Node2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#8da5f3"/></svg> diff --git a/editor/icons/Node3D.svg b/editor/icons/Node3D.svg index 56f6ed5542..c8a3163e51 100644 --- a/editor/icons/Node3D.svg +++ b/editor/icons/Node3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/NodePath.svg b/editor/icons/NodePath.svg index 3ecb830bec..14c753a136 100644 --- a/editor/icons/NodePath.svg +++ b/editor/icons/NodePath.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2v-2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm5 0v8h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3v-2zm-9 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#6993ec"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2v-2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm5 0v8h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3v-2zm-9 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1z" fill="#417aec"/></svg> diff --git a/editor/icons/OccluderPolygon2D.svg b/editor/icons/OccluderPolygon2D.svg index cdceb16441..ae5d2f4a1d 100644 --- a/editor/icons/OccluderPolygon2D.svg +++ b/editor/icons/OccluderPolygon2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m1 1045.4 6 6h8v-8l-6-6h-8z" fill="#3552b1"/><path d="m1 1037.4h8l-3 4 3 4h-8z" fill="#a5b7f3" fill-opacity=".98824"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m1 1045.4 6 6h8v-8l-6-6h-8z" fill="#3552b1"/><path d="m1 1037.4h8l-3 4 3 4h-8z" fill="#8da5f3" fill-opacity=".98824"/></g></svg> diff --git a/editor/icons/OmniLight3D.svg b/editor/icons/OmniLight3D.svg index 06b3786ebe..391e9104a1 100644 --- a/editor/icons/OmniLight3D.svg +++ b/editor/icons/OmniLight3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/OptionButton.svg b/editor/icons/OptionButton.svg index 50e6fae218..0a07470618 100644 --- a/editor/icons/OptionButton.svg +++ b/editor/icons/OptionButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h5 1 1 2 1c1.1046 0 2-.89543 2-2v-6c0-1.1046-.89543-2-2-2h-1-2-1-1zm8 2.9863a1.0001 1.0001 0 0 1 .7168 1.7207l-3 3a1.0001 1.0001 0 0 1 -1.4141 0l-3-3a1.0001 1.0001 0 0 1 .69727-1.7168 1.0001 1.0001 0 0 1 .7168.30273l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 .69727-.30664z" fill="#a5efac" transform="translate(0 1036.4)"/><path d="m4 1042.4h4v4h-4z" fill="none"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h5 1 1 2 1c1.1046 0 2-.89543 2-2v-6c0-1.1046-.89543-2-2-2h-1-2-1-1zm8 2.9863a1.0001 1.0001 0 0 1 .7168 1.7207l-3 3a1.0001 1.0001 0 0 1 -1.4141 0l-3-3a1.0001 1.0001 0 0 1 .69727-1.7168 1.0001 1.0001 0 0 1 .7168.30273l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 .69727-.30664z" fill="#8eef97" transform="translate(0 1036.4)"/><path d="m4 1042.4h4v4h-4z" fill="none"/></g></svg> diff --git a/editor/icons/PackedColorArray.svg b/editor/icons/PackedColorArray.svg index 206819ffb6..588002f188 100644 --- a/editor/icons/PackedColorArray.svg +++ b/editor/icons/PackedColorArray.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 3.5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff7070"/><path d="m13 3.5a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1z" fill="#70bfff"/><path d="m7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#7aff70"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 3.5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff4545"/><path d="m13 3.5a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1z" fill="#70bfff"/><path d="m7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#7aff70"/></svg> diff --git a/editor/icons/PackedFloat32Array.svg b/editor/icons/PackedFloat32Array.svg index 503b0e7b6f..ccfbb748b7 100644 --- a/editor/icons/PackedFloat32Array.svg +++ b/editor/icons/PackedFloat32Array.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm3 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#61daf4"/><path d="m7 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm3 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#35d4f4"/><path d="m7 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/PackedFloat64Array.svg b/editor/icons/PackedFloat64Array.svg index 503b0e7b6f..ccfbb748b7 100644 --- a/editor/icons/PackedFloat64Array.svg +++ b/editor/icons/PackedFloat64Array.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm3 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#61daf4"/><path d="m7 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1zm1 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm3 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#35d4f4"/><path d="m7 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/PackedInt32Array.svg b/editor/icons/PackedInt32Array.svg index a1dc417c11..973e4b9ab2 100644 --- a/editor/icons/PackedInt32Array.svg +++ b/editor/icons/PackedInt32Array.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m3 2v2h2v-2zm2 2v2h-2v4h4v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#7dc6ef"/><path d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m3 2v2h2v-2zm2 2v2h-2v4h4v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#5abbef"/><path d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/PackedInt64Array.svg b/editor/icons/PackedInt64Array.svg index a1dc417c11..973e4b9ab2 100644 --- a/editor/icons/PackedInt64Array.svg +++ b/editor/icons/PackedInt64Array.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m3 2v2h2v-2zm2 2v2h-2v4h4v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#7dc6ef"/><path d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m3 2v2h2v-2zm2 2v2h-2v4h4v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#5abbef"/><path d="m5 4v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/PackedStringArray.svg b/editor/icons/PackedStringArray.svg index e9285e2192..5273d6bc56 100644 --- a/editor/icons/PackedStringArray.svg +++ b/editor/icons/PackedStringArray.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m7 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-2a1 1 0 0 1 1-1h1v3a3 3 0 0 0 3 3h2v-3a1 1 0 0 1 1-1v-2a3 3 0 0 0 -3 3v1a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#6ba7ec"/><path d="m8 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m7 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-2a1 1 0 0 1 1-1h1v3a3 3 0 0 0 3 3h2v-3a1 1 0 0 1 1-1v-2a3 3 0 0 0 -3 3v1a1 1 0 0 1 -1-1v-1h1v-2h-1v-2h-2z" fill="#4593ec"/><path d="m8 2v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/PackedVector2Array.svg b/editor/icons/PackedVector2Array.svg index a5c8921045..f7e23b800f 100644 --- a/editor/icons/PackedVector2Array.svg +++ b/editor/icons/PackedVector2Array.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m9 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.0019531v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm-6 1v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#bd91f1"/><path d="m9 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.00195v2.0001h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5001z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m9 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.0019531v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm-6 1v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#ac73f1"/><path d="m9 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.00195v2.0001h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5001z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/PackedVector3Array.svg b/editor/icons/PackedVector3Array.svg index e1de83908d..e78be63df2 100644 --- a/editor/icons/PackedVector3Array.svg +++ b/editor/icons/PackedVector3Array.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m8 1v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44772 1-1 1h-1v2h1c1.0716-.0001501 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34772-.36523-.50195.13856-.15301.26095-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.003906v-2zm0 2h-2v3c-.0000096.55228-.44772.99999-1 1v-4h-2v6h2c1.6569 0 3-1.3431 3-3z" fill="#e286f0"/><path d="m8 1v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44772 1-1 1h-1v2h1c1.0716-.0001501 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34772-.36523-.50195.13856-.15301.26095-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.003906v-2z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m8 1v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44772 1-1 1h-1v2h1c1.0716-.0001501 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34772-.36523-.50195.13856-.15301.26095-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.003906v-2zm0 2h-2v3c-.0000096.55228-.44772.99999-1 1v-4h-2v6h2c1.6569 0 3-1.3431 3-3z" fill="#de66f0"/><path d="m8 1v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44772 1-1 1h-1v2h1c1.0716-.0001501 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34772-.36523-.50195.13856-.15301.26095-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.003906v-2z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/Panel.svg b/editor/icons/Panel.svg index f82822c5a1..7a36a35048 100644 --- a/editor/icons/Panel.svg +++ b/editor/icons/Panel.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/PanelContainer.svg b/editor/icons/PanelContainer.svg index 017941ba36..2f783d6e49 100644 --- a/editor/icons/PanelContainer.svg +++ b/editor/icons/PanelContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10z" fill="#8eef97"/></svg> diff --git a/editor/icons/PanoramaSkyMaterial.svg b/editor/icons/PanoramaSkyMaterial.svg index 33ffc20351..eddcbfd871 100644 --- a/editor/icons/PanoramaSkyMaterial.svg +++ b/editor/icons/PanoramaSkyMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v2h8 1c0-.554.446-1 1-1h2c.554 0 1 .446 1 1h1v-2z" fill="#9dff70"/><path d="m1 3v2h14v-2h-1.589844c-2.86436 1.357608-6.9481434 1.30996-10.347656 0z" fill="#ffeb70"/><path d="m1 2v1h2.0625c-.7241713-.2790504-1.419865-.6077805-2.0625-1zm14 0c-.465784.3952185-1.005424.7230054-1.589844 1h1.589844z" fill="#ff7070"/><path d="m1 7v2h2 1 5c-.554 0-1-.446-1-1s.446-1 1-1zm13 0c0 .554-.446 1-1 1h-1c0 .554-.446 1-1 1h4v-2z" fill="#70ffb9"/><path d="m1 9v2h2c-.554 0-1-.446-1-1s.446-1 1-1zm3 0c.554 0 1 .446 1 1s-.446 1-1 1h11v-2h-4-2z" fill="#70deff"/><path d="m1 13v-2h14v2h-1.589844c-2.86436-1.357608-6.9481434-1.30996-10.347656 0z" fill="#9f70ff"/><path d="m1 14v-1h2.0625c-.7241713.27905-1.419865.60778-2.0625 1zm14 0c-.465784-.395219-1.005424-.723005-1.589844-1h1.589844z" fill="#ff70ac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v2h8 1c0-.554.446-1 1-1h2c.554 0 1 .446 1 1h1v-2z" fill="#80ff45"/><path d="m1 3v2h14v-2h-1.589844c-2.86436 1.357608-6.9481434 1.30996-10.347656 0z" fill="#ffe345"/><path d="m1 2v1h2.0625c-.7241713-.2790504-1.419865-.6077805-2.0625-1zm14 0c-.465784.3952185-1.005424.7230054-1.589844 1h1.589844z" fill="#ff4545"/><path d="m1 7v2h2 1 5c-.554 0-1-.446-1-1s.446-1 1-1zm13 0c0 .554-.446 1-1 1h-1c0 .554-.446 1-1 1h4v-2z" fill="#45ffa2"/><path d="m1 9v2h2c-.554 0-1-.446-1-1s.446-1 1-1zm3 0c.554 0 1 .446 1 1s-.446 1-1 1h11v-2h-4-2z" fill="#45d7ff"/><path d="m1 13v-2h14v2h-1.589844c-2.86436-1.357608-6.9481434-1.30996-10.347656 0z" fill="#8045ff"/><path d="m1 14v-1h2.0625c-.7241713.27905-1.419865.60778-2.0625 1zm14 0c-.465784-.395219-1.005424-.723005-1.589844-1h1.589844z" fill="#ff4596"/></svg> diff --git a/editor/icons/ParallaxLayer.svg b/editor/icons/ParallaxLayer.svg index 64bf68f604..0768e941ad 100644 --- a/editor/icons/ParallaxLayer.svg +++ b/editor/icons/ParallaxLayer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v10c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-10c.0000096-.55228.44772-.99999 1-1zm4 3-3 3 3 3zm2 0v6l3-3z" fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v10c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-10c.0000096-.55228.44772-.99999 1-1zm4 3-3 3 3 3zm2 0v6l3-3z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/ParticlesMaterial.svg b/editor/icons/ParticlesMaterial.svg index f9a25530ef..33598980a5 100644 --- a/editor/icons/ParticlesMaterial.svg +++ b/editor/icons/ParticlesMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -3.5938 2h7.1816a4.5 5 0 0 0 -3.5879-2z" fill="#ff7070"/><path d="m4.4062 3a4.5 5 0 0 0 -.81445 2h8.8105a4.5 5 0 0 0 -.81445-2z" fill="#ffeb70"/><path d="m3.5918 5a4.5 5 0 0 0 -.0058594.03125 3 3 0 0 0 -2.4121 1.9688h13.65a3 3 0 0 0 -2.4141-1.9668 4.5 5 0 0 0 -.007812-.033203h-8.8105z" fill="#9dff70"/><path d="m1.1738 7a3 3 0 0 0 -.17383 1 3 3 0 0 0 .17578 1h13.65a3 3 0 0 0 .17383-1 3 3 0 0 0 -.17578-1z" fill="#70ffb9"/><path d="m1.1758 9a3 3 0 0 0 2.8242 2h8a3 3 0 0 0 2.8262-2h-13.65z" fill="#70deff"/><path d="m3 13a1 1 0 0 0 1 1 1 1 0 0 0 1-1zm5 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm3 0a1 1 0 0 0 1 1 1 1 0 0 0 1-1z" fill="#ff70ac"/><path d="m4 12a1 1 0 0 0 -1 1h2a1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1h2a1 1 0 0 0 -1-1z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -3.5938 2h7.1816a4.5 5 0 0 0 -3.5879-2z" fill="#ff4545"/><path d="m4.4062 3a4.5 5 0 0 0 -.81445 2h8.8105a4.5 5 0 0 0 -.81445-2z" fill="#ffe345"/><path d="m3.5918 5a4.5 5 0 0 0 -.0058594.03125 3 3 0 0 0 -2.4121 1.9688h13.65a3 3 0 0 0 -2.4141-1.9668 4.5 5 0 0 0 -.007812-.033203h-8.8105z" fill="#80ff45"/><path d="m1.1738 7a3 3 0 0 0 -.17383 1 3 3 0 0 0 .17578 1h13.65a3 3 0 0 0 .17383-1 3 3 0 0 0 -.17578-1z" fill="#45ffa2"/><path d="m1.1758 9a3 3 0 0 0 2.8242 2h8a3 3 0 0 0 2.8262-2h-13.65z" fill="#45d7ff"/><path d="m3 13a1 1 0 0 0 1 1 1 1 0 0 0 1-1zm5 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm3 0a1 1 0 0 0 1 1 1 1 0 0 0 1-1z" fill="#ff4596"/><path d="m4 12a1 1 0 0 0 -1 1h2a1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1h2a1 1 0 0 0 -1-1z" fill="#8045ff"/></svg> diff --git a/editor/icons/Path2D.svg b/editor/icons/Path2D.svg index 5633dcf923..494ca344be 100644 --- a/editor/icons/Path2D.svg +++ b/editor/icons/Path2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 .84961 1.6328c-.19239.88508-.55317 1.3394-.98633 1.6426-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c.8927-.62488 1.5321-1.6538 1.8184-3.0977a2 2 0 0 0 1.1699-1.8164 2 2 0 0 0 -2-2z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 .84961 1.6328c-.19239.88508-.55317 1.3394-.98633 1.6426-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c.8927-.62488 1.5321-1.6538 1.8184-3.0977a2 2 0 0 0 1.1699-1.8164 2 2 0 0 0 -2-2z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/Path3D.svg b/editor/icons/Path3D.svg index 913fe8abf6..076ce9acd2 100644 --- a/editor/icons/Path3D.svg +++ b/editor/icons/Path3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 .84961 1.6328c-.19239.88508-.55317 1.3394-.98633 1.6426-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c.8927-.62488 1.5321-1.6538 1.8184-3.0977a2 2 0 0 0 1.1699-1.8164 2 2 0 0 0 -2-2z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 1a2 2 0 0 0 -2 2 2 2 0 0 0 .84961 1.6328c-.19239.88508-.55317 1.3394-.98633 1.6426-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c.8927-.62488 1.5321-1.6538 1.8184-3.0977a2 2 0 0 0 1.1699-1.8164 2 2 0 0 0 -2-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/PathFollow2D.svg b/editor/icons/PathFollow2D.svg index ac0f17240e..a1fb97cf34 100644 --- a/editor/icons/PathFollow2D.svg +++ b/editor/icons/PathFollow2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 0-3 4h1.9473c-.1385 1.3203-.5583 1.9074-1.084 2.2754-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c1.0528-.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 0-3 4h1.9473c-.1385 1.3203-.5583 1.9074-1.084 2.2754-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c1.0528-.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/PathFollow3D.svg b/editor/icons/PathFollow3D.svg index c9bd7009dc..f9bb38939e 100644 --- a/editor/icons/PathFollow3D.svg +++ b/editor/icons/PathFollow3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 0-3 4h1.9473c-.1385 1.3203-.5583 1.9074-1.084 2.2754-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c1.0528-.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 0-3 4h1.9473c-.1385 1.3203-.5583 1.9074-1.084 2.2754-.64426.451-1.7129.60547-2.9629.73047s-2.6814.22053-3.9121 1.082c-.89278.62493-1.5321 1.6522-1.8184 3.0957a2 2 0 0 0 -1.1699 1.8164 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -.84961-1.6328c.19235-.88496.55306-1.3373.98633-1.6406.64426-.451 1.7129-.60547 2.9629-.73047s2.6814-.22053 3.9121-1.082c1.0528-.73697 1.7552-2.032 1.9375-3.9141h2.0508l-3-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/PhysicalBone3D.svg b/editor/icons/PhysicalBone3D.svg index 55df1f1e19..29f0611b9e 100644 --- a/editor/icons/PhysicalBone3D.svg +++ b/editor/icons/PhysicalBone3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" transform="translate(-2.5625 -18.4375)"><path d="m13.107422 19.382812a2.4664 2.4663 0 0 0 -1.78125.720704 2.4664 2.4663 0 0 0 -.185547.21289l1.332031 2.433594-1.605469.603516-3.414062 3.414062a2.4664 2.4663 0 0 0 -3.1015625.3125 2.4664 2.4663 0 0 0 0 3.488281 2.4664 2.4663 0 0 0 1.3964844.695313 2.4664 2.4663 0 0 0 .6953125 1.396484 2.4664 2.4663 0 0 0 3.4882812 0 2.4664 2.4663 0 0 0 .3144534-3.103515l3.560547-3.560547a2.4664 2.4663 0 0 0 3.099609-.310547 2.4664 2.4663 0 0 0 0-3.488281 2.4664 2.4663 0 0 0 -1.396484-.697266 2.4664 2.4663 0 0 0 -.695313-1.396484 2.4664 2.4663 0 0 0 -1.707031-.720704z"/><path d="m3.7211033 21.208326.9608286 4.82644 1.3962404-.524494z"/><path d="m6.4843278 19.465234.9608285 4.82644 1.3962404-.524494z"/><path d="m9.6964655 19.33678.7108285 3.51394 1.39624-.524494z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc7f7f" transform="translate(-2.5625 -18.4375)"><path d="m13.107422 19.382812a2.4664 2.4663 0 0 0 -1.78125.720704 2.4664 2.4663 0 0 0 -.185547.21289l1.332031 2.433594-1.605469.603516-3.414062 3.414062a2.4664 2.4663 0 0 0 -3.1015625.3125 2.4664 2.4663 0 0 0 0 3.488281 2.4664 2.4663 0 0 0 1.3964844.695313 2.4664 2.4663 0 0 0 .6953125 1.396484 2.4664 2.4663 0 0 0 3.4882812 0 2.4664 2.4663 0 0 0 .3144534-3.103515l3.560547-3.560547a2.4664 2.4663 0 0 0 3.099609-.310547 2.4664 2.4663 0 0 0 0-3.488281 2.4664 2.4663 0 0 0 -1.396484-.697266 2.4664 2.4663 0 0 0 -.695313-1.396484 2.4664 2.4663 0 0 0 -1.707031-.720704z"/><path d="m3.7211033 21.208326.9608286 4.82644 1.3962404-.524494z"/><path d="m6.4843278 19.465234.9608285 4.82644 1.3962404-.524494z"/><path d="m9.6964655 19.33678.7108285 3.51394 1.39624-.524494z"/></g></svg> diff --git a/editor/icons/PhysicalSkyMaterial.svg b/editor/icons/PhysicalSkyMaterial.svg index 68bf2785a4..a32b451c53 100644 --- a/editor/icons/PhysicalSkyMaterial.svg +++ b/editor/icons/PhysicalSkyMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v2h8 1c0-.554.446-1 1-1h2c.554 0 1 .446 1 1h1v-2z" fill="#9dff70"/><path d="m1 7v2h2 1 5c-.554 0-1-.446-1-1s.446-1 1-1zm13 0c0 .554-.446 1-1 1h-1c0 .554-.446 1-1 1h4v-2z" fill="#70ffb9"/><path d="m1 9v2h2c-.554 0-1-.446-1-1s.446-1 1-1zm3 0c.554 0 1 .446 1 1s-.446 1-1 1h11v-2h-4-2z" fill="#70deff"/><path d="m1 3v2h14v-2z" fill="#ffeb70"/><path d="m1 11v2h14v-2z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v2h8 1c0-.554.446-1 1-1h2c.554 0 1 .446 1 1h1v-2z" fill="#80ff45"/><path d="m1 7v2h2 1 5c-.554 0-1-.446-1-1s.446-1 1-1zm13 0c0 .554-.446 1-1 1h-1c0 .554-.446 1-1 1h4v-2z" fill="#45ffa2"/><path d="m1 9v2h2c-.554 0-1-.446-1-1s.446-1 1-1zm3 0c.554 0 1 .446 1 1s-.446 1-1 1h11v-2h-4-2z" fill="#45d7ff"/><path d="m1 3v2h14v-2z" fill="#ffe345"/><path d="m1 11v2h14v-2z" fill="#8045ff"/></svg> diff --git a/editor/icons/PinJoint2D.svg b/editor/icons/PinJoint2D.svg index 4e701df7fb..fc7329e4f3 100644 --- a/editor/icons/PinJoint2D.svg +++ b/editor/icons/PinJoint2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1.2715-.70703.70703v1.4141l-2.1211 2.123 4.2422 4.2422 2.1211-2.1211h1.4141l.70703-.70703-5.6562-5.6582zm-3.5352 4.9512-3.5352.70703 7.0703 7.0703.70703-3.5352-4.2422-4.2422zm-1.4141 4.2422-1.4141 1.4141-.70703 2.1211 2.1211-.70703 1.4141-1.4141-1.4141-1.4141z" fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1.2715-.70703.70703v1.4141l-2.1211 2.123 4.2422 4.2422 2.1211-2.1211h1.4141l.70703-.70703-5.6562-5.6582zm-3.5352 4.9512-3.5352.70703 7.0703 7.0703.70703-3.5352-4.2422-4.2422zm-1.4141 4.2422-1.4141 1.4141-.70703 2.1211 2.1211-.70703 1.4141-1.4141-1.4141-1.4141z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd"/></svg> diff --git a/editor/icons/PinJoint3D.svg b/editor/icons/PinJoint3D.svg index 12f388b2f7..8cba452163 100644 --- a/editor/icons/PinJoint3D.svg +++ b/editor/icons/PinJoint3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1.2715-.70703.70703v1.4141l-2.1211 2.123 4.2422 4.2422 2.1211-2.1211h1.4141l.70703-.70703-5.6562-5.6582zm-3.5352 4.9512-3.5352.70703 7.0703 7.0703.70703-3.5352-4.2422-4.2422zm-1.4141 4.2422-1.4141 1.4141-.70703 2.1211 2.1211-.70703 1.4141-1.4141-1.4141-1.4141z" fill="#fc9c9c" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 1.2715-.70703.70703v1.4141l-2.1211 2.123 4.2422 4.2422 2.1211-2.1211h1.4141l.70703-.70703-5.6562-5.6582zm-3.5352 4.9512-3.5352.70703 7.0703 7.0703.70703-3.5352-4.2422-4.2422zm-1.4141 4.2422-1.4141 1.4141-.70703 2.1211 2.1211-.70703 1.4141-1.4141-1.4141-1.4141z" fill="#fc7f7f" fill-rule="evenodd"/></svg> diff --git a/editor/icons/Plane.svg b/editor/icons/Plane.svg index edaa86e772..5857ac56f7 100644 --- a/editor/icons/Plane.svg +++ b/editor/icons/Plane.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 2v8h2v-2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm6 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm-4 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm8 0v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#f77070"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 2v8h2v-2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm6 0v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5zm-4 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm8 0v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3z" fill="#f74949"/></svg> diff --git a/editor/icons/PlaneMesh.svg b/editor/icons/PlaneMesh.svg index 3514c1e3e3..54b33616ba 100644 --- a/editor/icons/PlaneMesh.svg +++ b/editor/icons/PlaneMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 4-7 4 7 4 7-4zm0 2 3.5 2-3.5 2-3.5-2z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 4-7 4 7 4 7-4zm0 2 3.5 2-3.5 2-3.5-2z" fill="#ffca5f"/></svg> diff --git a/editor/icons/PointLight2D.svg b/editor/icons/PointLight2D.svg index d660b82c34..1a3222c79e 100644 --- a/editor/icons/PointLight2D.svg +++ b/editor/icons/PointLight2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/PointMesh.svg b/editor/icons/PointMesh.svg index 184200c528..ec04989e02 100644 --- a/editor/icons/PointMesh.svg +++ b/editor/icons/PointMesh.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffd684"><ellipse cx="3.7237" cy="3.0268" rx="2.0114" ry="1.9956"/><ellipse cx="11.717" cy="6.1734" rx="2.0114" ry="1.9956"/><ellipse cx="6.5219" cy="12.477" rx="2.0114" ry="1.9956"/></g></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><ellipse cx="3.7237" cy="3.0268" rx="2.0114" ry="1.9956"/><ellipse cx="11.717" cy="6.1734" rx="2.0114" ry="1.9956"/><ellipse cx="6.5219" cy="12.477" rx="2.0114" ry="1.9956"/></g></svg> diff --git a/editor/icons/Polygon2D.svg b/editor/icons/Polygon2D.svg index b74ba3e342..9d7ad5d1cf 100644 --- a/editor/icons/Polygon2D.svg +++ b/editor/icons/Polygon2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="#a5b7f3" stroke="#a5b7f3" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12h12l-6 6z" fill="#8da5f3" stroke="#8da5f3" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/Portal.svg b/editor/icons/Portal.svg index e52e0473a6..9365c450da 100644 --- a/editor/icons/Portal.svg +++ b/editor/icons/Portal.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 7 0 0 0 -5 7 5 7 0 0 0 5 7 5 7 0 0 0 5-7 5 7 0 0 0 -5-7zm0 2a3 5 0 0 1 3 5 3 5 0 0 1 -3 5 3 5 0 0 1 -3-5 3 5 0 0 1 3-5z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 7 0 0 0 -5 7 5 7 0 0 0 5 7 5 7 0 0 0 5-7 5 7 0 0 0 -5-7zm0 2a3 5 0 0 1 3 5 3 5 0 0 1 -3 5 3 5 0 0 1 -3-5 3 5 0 0 1 3-5z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/Position2D.svg b/editor/icons/Position2D.svg index d5e7ff9621..191f0b2a03 100644 --- a/editor/icons/Position2D.svg +++ b/editor/icons/Position2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v4h2v-4zm-6 6v2h4v-2zm10 0v2h4v-2zm-4 4v4h2v-4z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v4h2v-4zm-6 6v2h4v-2zm10 0v2h4v-2zm-4 4v4h2v-4z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/Position3D.svg b/editor/icons/Position3D.svg index da7dfb010a..894b195589 100644 --- a/editor/icons/Position3D.svg +++ b/editor/icons/Position3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v4h2v-4zm-6 6v2h4v-2zm10 0v2h4v-2zm-4 4v4h2v-4z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v4h2v-4zm-6 6v2h4v-2zm10 0v2h4v-2zm-4 4v4h2v-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/PrismMesh.svg b/editor/icons/PrismMesh.svg index bc5f4fb0b1..cca52bb7b0 100644 --- a/editor/icons/PrismMesh.svg +++ b/editor/icons/PrismMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9824 1.002a1.0001 1.0001 0 0 0 -.81445.44336l-5.9727 8.9609-.027344.03906a1 1 0 0 0 -.0625.10742 1 1 0 0 0 .44727 1.3418l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1 1 0 0 0 .44726-1.3418 1 1 0 0 0 -.0625-.10742l-6-9a1.0001 1.0001 0 0 0 -.84961-.44336zm-.98242 4.3008v7.0801l-3.5391-1.7715zm2 0 3.5391 5.3086-3.5391 1.7715z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9824 1.002a1.0001 1.0001 0 0 0 -.81445.44336l-5.9727 8.9609-.027344.03906a1 1 0 0 0 -.0625.10742 1 1 0 0 0 .44727 1.3418l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1 1 0 0 0 .44726-1.3418 1 1 0 0 0 -.0625-.10742l-6-9a1.0001 1.0001 0 0 0 -.84961-.44336zm-.98242 4.3008v7.0801l-3.5391-1.7715zm2 0 3.5391 5.3086-3.5391 1.7715z" fill="#ffca5f"/></svg> diff --git a/editor/icons/ProceduralSkyMaterial.svg b/editor/icons/ProceduralSkyMaterial.svg index 9aa362d8da..ceaf56dbce 100644 --- a/editor/icons/ProceduralSkyMaterial.svg +++ b/editor/icons/ProceduralSkyMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.0761719 11a7 7 0 0 0 .609375 2h12.6308591a7 7 0 0 0 .609375-2h-9.925781c0 .554-.446 1-1 1h-1c-.554 0-1-.446-1-1z" fill="#9f70ff"/><path d="m1.0722656 9a7 7 0 0 0 -.0722656 1 7 7 0 0 0 .0761719 1h.9238281c0-.554.446-1 1-1h1c.554 0 1 .446 1 1h9.925781a7 7 0 0 0 .074219-1 7 7 0 0 0 -.072266-1h-2.927734-1c0 .554-.446 1-1 1h-2c-.554 0-1-.446-1-1z" fill="#70deff"/><path d="m1.6757812 7a7 7 0 0 0 -.6035156 2h5.9277344c0-.554.446-1 1-1h1c0-.554.446-1 1-1zm10.3242188 0c.554 0 1 .446 1 1s-.446 1-1 1h2.927734a7 7 0 0 0 -.603515-2z" fill="#70ffb9"/><path d="m3.1035156 5a7 7 0 0 0 -1.4277344 2h12.6484378a7 7 0 0 0 -1.425781-2z" fill="#9dff70"/><path d="m8 3a7 7 0 0 0 -4.8964844 2h9.7949224a7 7 0 0 0 -4.898438-2z" fill="#ffeb70"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.0761719 11a7 7 0 0 0 .609375 2h12.6308591a7 7 0 0 0 .609375-2h-9.925781c0 .554-.446 1-1 1h-1c-.554 0-1-.446-1-1z" fill="#8045ff"/><path d="m1.0722656 9a7 7 0 0 0 -.0722656 1 7 7 0 0 0 .0761719 1h.9238281c0-.554.446-1 1-1h1c.554 0 1 .446 1 1h9.925781a7 7 0 0 0 .074219-1 7 7 0 0 0 -.072266-1h-2.927734-1c0 .554-.446 1-1 1h-2c-.554 0-1-.446-1-1z" fill="#45d7ff"/><path d="m1.6757812 7a7 7 0 0 0 -.6035156 2h5.9277344c0-.554.446-1 1-1h1c0-.554.446-1 1-1zm10.3242188 0c.554 0 1 .446 1 1s-.446 1-1 1h2.927734a7 7 0 0 0 -.603515-2z" fill="#45ffa2"/><path d="m3.1035156 5a7 7 0 0 0 -1.4277344 2h12.6484378a7 7 0 0 0 -1.425781-2z" fill="#80ff45"/><path d="m8 3a7 7 0 0 0 -4.8964844 2h9.7949224a7 7 0 0 0 -4.898438-2z" fill="#ffe345"/></svg> diff --git a/editor/icons/ProgressBar.svg b/editor/icons/ProgressBar.svg index 2200cb8ea7..5c49563f23 100644 --- a/editor/icons/ProgressBar.svg +++ b/editor/icons/ProgressBar.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-6c0-1.1046-.89543-2-2-2zm0 2h10v6h-10zm1 1v4h1v-4zm2 0v4h1v-4zm2 0v4h1v-4z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-6c0-1.1046-.89543-2-2-2zm0 2h10v6h-10zm1 1v4h1v-4zm2 0v4h1v-4zm2 0v4h1v-4z" fill="#8eef97"/></svg> diff --git a/editor/icons/ProximityGroup3D.svg b/editor/icons/ProximityGroup3D.svg index 703abc6486..5cbf8add7b 100644 --- a/editor/icons/ProximityGroup3D.svg +++ b/editor/icons/ProximityGroup3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm2 2h10v10h-10zm7.5 1c-.82843.0000048-1.5.67157-1.5 1.5.0000048.82843.67157 1.5 1.5 1.5.82842-.0000048 1.5-.67157 1.5-1.5-.000005-.82843-.67158-1.5-1.5-1.5zm-5 5c-.82843-.0000048-1.5.67157-1.5 1.5-.0000048.82843.67157 1.5 1.5 1.5.82843.000005 1.5-.67157 1.5-1.5.0000048-.82843-.67157-1.5-1.5-1.5zm5 0c-.82843.0000048-1.5.67157-1.5 1.5.0000048.82842.67157 1.5 1.5 1.5.82842-.000005 1.5-.67158 1.5-1.5-.000005-.82843-.67158-1.5-1.5-1.5z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm2 2h10v10h-10zm7.5 1c-.82843.0000048-1.5.67157-1.5 1.5.0000048.82843.67157 1.5 1.5 1.5.82842-.0000048 1.5-.67157 1.5-1.5-.000005-.82843-.67158-1.5-1.5-1.5zm-5 5c-.82843-.0000048-1.5.67157-1.5 1.5-.0000048.82843.67157 1.5 1.5 1.5.82843.000005 1.5-.67157 1.5-1.5.0000048-.82843-.67157-1.5-1.5-1.5zm5 0c-.82843.0000048-1.5.67157-1.5 1.5.0000048.82842.67157 1.5 1.5 1.5.82842-.000005 1.5-.67158 1.5-1.5-.000005-.82843-.67158-1.5-1.5-1.5z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/Quad.svg b/editor/icons/Quad.svg index cf07be1d2f..70ef6b7227 100644 --- a/editor/icons/Quad.svg +++ b/editor/icons/Quad.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 10 2h2 12v-2-12h-12zm3.4141 2h8.5859v8.5859zm-1.4141 1.4141 8.5859 8.5859h-8.5859z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 10 2h2 12v-2-12h-12zm3.4141 2h8.5859v8.5859zm-1.4141 1.4141 8.5859 8.5859h-8.5859z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/QuadMesh.svg b/editor/icons/QuadMesh.svg index bee0b2853f..86cc1bc233 100644 --- a/editor/icons/QuadMesh.svg +++ b/editor/icons/QuadMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1v14h-14v-14zm-2 2h-8.5859l8.5859 8.5859zm-10 1.4141v8.5859h8.5859z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1v14h-14v-14zm-2 2h-8.5859l8.5859 8.5859zm-10 1.4141v8.5859h8.5859z" fill="#ffca5f"/></svg> diff --git a/editor/icons/Quat.svg b/editor/icons/Quat.svg index 66020e5243..cf29160ff4 100644 --- a/editor/icons/Quat.svg +++ b/editor/icons/Quat.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3a3 3 0 0 0 -3 3 3 3 0 0 0 3 3v2h2v-2.7695a3 3 0 0 0 2 .76953h2v-6h-2v4a1 1 0 0 1 -1-1v-3h-2zm0 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#ec69a3"/><path d="m4 3v3a3 3 0 0 0 3 3h2v-6h-2v4a1 1 0 0 1 -1-1v-3z" fill="#fff" fill-opacity=".39216"/><path d="m13 1v2h-2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-2 4v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#ec69a3"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3a3 3 0 0 0 -3 3 3 3 0 0 0 3 3v2h2v-2.7695a3 3 0 0 0 2 .76953h2v-6h-2v4a1 1 0 0 1 -1-1v-3h-2zm0 2v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#ec418e"/><path d="m4 3v3a3 3 0 0 0 3 3h2v-6h-2v4a1 1 0 0 1 -1-1v-3z" fill="#fff" fill-opacity=".39216"/><path d="m13 1v2h-2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-3a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-2 4v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#ec418e"/></svg> diff --git a/editor/icons/RID.svg b/editor/icons/RID.svg index 9198e421b1..40764867ba 100644 --- a/editor/icons/RID.svg +++ b/editor/icons/RID.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 2v2h2v-2zm7 0v2h-1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1 2v-8zm-10 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2zm3 2v4h2v-4zm6 0h1v2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#69ec9a"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 2v2h2v-2zm7 0v2h-1a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1 2v-8zm-10 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2zm3 2v4h2v-4zm6 0h1v2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#41ec80"/></svg> diff --git a/editor/icons/RayCast2D.svg b/editor/icons/RayCast2D.svg index 645da1e2da..07c8d45239 100644 --- a/editor/icons/RayCast2D.svg +++ b/editor/icons/RayCast2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v9h-3l4 5 4-5h-3v-9z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v9h-3l4 5 4-5h-3v-9z" fill="#8da5f3"/></svg> diff --git a/editor/icons/RayCast3D.svg b/editor/icons/RayCast3D.svg index 4500551463..9670e63022 100644 --- a/editor/icons/RayCast3D.svg +++ b/editor/icons/RayCast3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v9h-3l4 5 4-5h-3v-9z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v9h-3l4 5 4-5h-3v-9z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/Rayito.svg b/editor/icons/Rayito.svg index 1db71c2231..1d4f9ca458 100644 --- a/editor/icons/Rayito.svg +++ b/editor/icons/Rayito.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1-1 7h2.875l-.875 7 9-8h-3.8574l.85742-6h-7z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1-1 7h2.875l-.875 7 9-8h-3.8574l.85742-6h-7z" fill="#ffca5f"/></svg> diff --git a/editor/icons/Rect2.svg b/editor/icons/Rect2.svg index 18dbdf3a12..5b069bd3c1 100644 --- a/editor/icons/Rect2.svg +++ b/editor/icons/Rect2.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 2v2h-1a3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5-1.3457 3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1h3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v1a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-10 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#f191a5"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13 2v2h-1a3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5-1.3457 3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1h3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v1a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-1h1v-2h-1v-2zm-10 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#f1738f"/></svg> diff --git a/editor/icons/Rect2i.svg b/editor/icons/Rect2i.svg index 142ad88515..76f4fededf 100644 --- a/editor/icons/Rect2i.svg +++ b/editor/icons/Rect2i.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 2v2h-1c-1.7267 0-3 1.3359-3 3 0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228 0-1-.44772-1-1s.44772-1 1-1h1v1c0 1.6569 1.3431 3 3 3v-2c-.55228 0-.93526-.45152-1-1v-1h1v-2h-1v-2zm-5 2c-1.6569 0-2.9547 1.3438-3 3v3h2v-3c0-.55228.44772-1 1-1h1v-2z" fill="#f191a5"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 2v2h-1c-1.7267 0-3 1.3359-3 3 0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228 0-1-.44772-1-1s.44772-1 1-1h1v1c0 1.6569 1.3431 3 3 3v-2c-.55228 0-.93526-.45152-1-1v-1h1v-2h-1v-2zm-5 2c-1.6569 0-2.9547 1.3438-3 3v3h2v-3c0-.55228.44772-1 1-1h1v-2z" fill="#f1738f"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg> diff --git a/editor/icons/ReferenceRect.svg b/editor/icons/ReferenceRect.svg index 449ca250e3..4ba50b2af2 100644 --- a/editor/icons/ReferenceRect.svg +++ b/editor/icons/ReferenceRect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h2v-2zm3 0v2h8v-2zm9 0v2h2v-2zm-12 3v8h2v-8zm12 0v8h2v-8zm-12 9v2h2v-2zm3 0v2h8v-2zm9 0v2h2v-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h2v-2zm3 0v2h8v-2zm9 0v2h2v-2zm-12 3v8h2v-8zm12 0v8h2v-8zm-12 9v2h2v-2zm3 0v2h8v-2zm9 0v2h2v-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/ReflectionProbe.svg b/editor/icons/ReflectionProbe.svg index ff9263d798..a88a3524be 100644 --- a/editor/icons/ReflectionProbe.svg +++ b/editor/icons/ReflectionProbe.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10 2a1.0001 1.0001 0 1 0 0 2h1.5859l-4.5195 4.5195-4.2988-5.1582-1.5352 1.2793 5 6a1.0001 1.0001 0 0 0 1.4746.064453l5.293-5.293v1.5879a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 0 0 -1-1h-4zm-9 7v5a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1-1v-4h-2v3h-10v-4z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m10 2a1.0001 1.0001 0 1 0 0 2h1.5859l-4.5195 4.5195-4.2988-5.1582-1.5352 1.2793 5 6a1.0001 1.0001 0 0 0 1.4746.064453l5.293-5.293v1.5879a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 0 0 -1-1h-4zm-9 7v5a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1-1v-4h-2v3h-10v-4z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/RemoteTransform2D.svg b/editor/icons/RemoteTransform2D.svg index 81a3946d9f..9d03db5c3b 100644 --- a/editor/icons/RemoteTransform2D.svg +++ b/editor/icons/RemoteTransform2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.8565 0-5.4995 1.5262-6.9277 4a1 1 0 0 0 .36523 1.3672 1 1 0 0 0 1.3672-.36719c1.0726-1.8578 3.0501-3 5.1953-3s4.1227 1.1422 5.1953 3a1 1 0 0 0 1.3672.36719 1 1 0 0 0 .36523-1.3672c-1.4283-2.4738-4.0712-4-6.9277-4zm0 4c-1.8056 0-3.396 1.2207-3.8633 2.9648a1 1 0 0 0 .70703 1.2246 1 1 0 0 0 1.2246-.70703c.23553-.8791 1.0216-1.4824 1.9316-1.4824s1.6961.60332 1.9316 1.4824a1 1 0 0 0 1.2246.70703 1 1 0 0 0 .70703-1.2246c-.46732-1.7441-2.0577-2.9648-3.8633-2.9648zm0 4c-.554 0-1 .446-1 1v1h-3a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h-3v-1c0-.554-.446-1-1-1z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.8565 0-5.4995 1.5262-6.9277 4a1 1 0 0 0 .36523 1.3672 1 1 0 0 0 1.3672-.36719c1.0726-1.8578 3.0501-3 5.1953-3s4.1227 1.1422 5.1953 3a1 1 0 0 0 1.3672.36719 1 1 0 0 0 .36523-1.3672c-1.4283-2.4738-4.0712-4-6.9277-4zm0 4c-1.8056 0-3.396 1.2207-3.8633 2.9648a1 1 0 0 0 .70703 1.2246 1 1 0 0 0 1.2246-.70703c.23553-.8791 1.0216-1.4824 1.9316-1.4824s1.6961.60332 1.9316 1.4824a1 1 0 0 0 1.2246.70703 1 1 0 0 0 .70703-1.2246c-.46732-1.7441-2.0577-2.9648-3.8633-2.9648zm0 4c-.554 0-1 .446-1 1v1h-3a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h-3v-1c0-.554-.446-1-1-1z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/RemoteTransform3D.svg b/editor/icons/RemoteTransform3D.svg index d55e4e4224..96cd31a2df 100644 --- a/editor/icons/RemoteTransform3D.svg +++ b/editor/icons/RemoteTransform3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.8565 0-5.4995 1.5262-6.9277 4a1 1 0 0 0 .36523 1.3672 1 1 0 0 0 1.3672-.36719c1.0726-1.8578 3.0501-3 5.1953-3s4.1227 1.1422 5.1953 3a1 1 0 0 0 1.3672.36719 1 1 0 0 0 .36523-1.3672c-1.4283-2.4738-4.0712-4-6.9277-4zm0 4c-1.8056 0-3.396 1.2207-3.8633 2.9648a1 1 0 0 0 .70703 1.2246 1 1 0 0 0 1.2246-.70703c.23553-.8791 1.0216-1.4824 1.9316-1.4824s1.6961.60332 1.9316 1.4824a1 1 0 0 0 1.2246.70703 1 1 0 0 0 .70703-1.2246c-.46732-1.7441-2.0577-2.9648-3.8633-2.9648zm0 4c-.554 0-1 .446-1 1v1h-3a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h-3v-1c0-.554-.446-1-1-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.8565 0-5.4995 1.5262-6.9277 4a1 1 0 0 0 .36523 1.3672 1 1 0 0 0 1.3672-.36719c1.0726-1.8578 3.0501-3 5.1953-3s4.1227 1.1422 5.1953 3a1 1 0 0 0 1.3672.36719 1 1 0 0 0 .36523-1.3672c-1.4283-2.4738-4.0712-4-6.9277-4zm0 4c-1.8056 0-3.396 1.2207-3.8633 2.9648a1 1 0 0 0 .70703 1.2246 1 1 0 0 0 1.2246-.70703c.23553-.8791 1.0216-1.4824 1.9316-1.4824s1.6961.60332 1.9316 1.4824a1 1 0 0 0 1.2246.70703 1 1 0 0 0 .70703-1.2246c-.46732-1.7441-2.0577-2.9648-3.8633-2.9648zm0 4c-.554 0-1 .446-1 1v1h-3a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h-3v-1c0-.554-.446-1-1-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Reparent.svg b/editor/icons/Reparent.svg index 04efb08b99..e95eb742db 100644 --- a/editor/icons/Reparent.svg +++ b/editor/icons/Reparent.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v5.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -.72852-.73047v-5.541a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2z" fill="#e0e0e0"/><path d="m9 1-4 3 4 3v-2a3 3 0 0 1 3 3v2h2v-2a5 5 0 0 0 -5-5z" fill="#84ffb1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v5.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -.72852-.73047v-5.541a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2z" fill="#e0e0e0"/><path d="m9 1-4 3 4 3v-2a3 3 0 0 1 3 3v2h2v-2a5 5 0 0 0 -5-5z" fill="#5fff97"/></svg> diff --git a/editor/icons/ReparentToNewNode.svg b/editor/icons/ReparentToNewNode.svg index cca610d2b1..f28a04a19e 100644 --- a/editor/icons/ReparentToNewNode.svg +++ b/editor/icons/ReparentToNewNode.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1.4915254 13c0 1.104569.8954305 2 2 2 .7139771-.000554 1.3735116-.381677 1.7305-1h6.0494746c.356631.617705 1.015238.998733 1.7285 1 1.104569 0 2-.895431 2-2s-.895431-2-2-2c-.713977.000554-1.373512.381677-1.7305 1h-6.0494746c-.1747809-.30301-.8483719-1-1.7285-1-.9027301 0-2 .891221-2 2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m10.421845 1038.2814-2.7947264 2.096 2.7947264 2.0961v-1.3974c2.716918 0 2.180792 1.4469 2.180792 3.9265v1.3974h1.397363v-1.3974c0-3.863.13086-5.3239-3.578155-5.3239z" fill="#84ffb1" stroke-width=".698682"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#84ffb1" transform="translate(-8.5 1028.4)"/><path d="m4.5 1047.7968v-3.1171h-2.0000005v3.1171z" fill="#e0e0e0" stroke-width=".717839"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1.4915254 13c0 1.104569.8954305 2 2 2 .7139771-.000554 1.3735116-.381677 1.7305-1h6.0494746c.356631.617705 1.015238.998733 1.7285 1 1.104569 0 2-.895431 2-2s-.895431-2-2-2c-.713977.000554-1.373512.381677-1.7305 1h-6.0494746c-.1747809-.30301-.8483719-1-1.7285-1-.9027301 0-2 .891221-2 2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m10.421845 1038.2814-2.7947264 2.096 2.7947264 2.0961v-1.3974c2.716918 0 2.180792 1.4469 2.180792 3.9265v1.3974h1.397363v-1.3974c0-3.863.13086-5.3239-3.578155-5.3239z" fill="#5fff97" stroke-width=".698682"/><path d="m11 9v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#5fff97" transform="translate(-8.5 1028.4)"/><path d="m4.5 1047.7968v-3.1171h-2.0000005v3.1171z" fill="#e0e0e0" stroke-width=".717839"/></g></svg> diff --git a/editor/icons/RibbonTrailMesh.svg b/editor/icons/RibbonTrailMesh.svg new file mode 100644 index 0000000000..3f6cf0bfef --- /dev/null +++ b/editor/icons/RibbonTrailMesh.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f" stroke-width=".25" transform="rotate(90)"><path d="m6.5625-14.062499h1.875v13.124999h-1.875z"/><path d="m.9375-11.249999h1.875v7.499999h-1.875z"/><path d="m12.187499-11.249999h1.875v7.5h-1.875z"/></g></svg> diff --git a/editor/icons/RichTextEffect.svg b/editor/icons/RichTextEffect.svg index f1d3f168ff..3745219934 100644 --- a/editor/icons/RichTextEffect.svg +++ b/editor/icons/RichTextEffect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h7v-2zm9 0v2h5v-2zm-9 4v2h11v-2zm0 4v2h4v-2zm6 0v2h1c-.044949-.094701-.088906-.20229-.125-.3418-.077717-.30039-.10439-.81722.16406-1.293.081489-.1441.18202-.26127.28906-.36523zm-6 4v2h8.2812c-.066517-.011548-.1231-.014758-.20117-.037109-.30195-.08645-.76491-.33245-1.0352-.80664-.23366-.4121-.24101-.84933-.18945-1.1562z" fill="#e0e0e0"/><path d="m12.216 8.598a.53334 3.2001 0 0 0 -.50976 2.2754 3.2001.53334 30 0 0 -2.2656-.71484 3.2001.53334 30 0 0 1.75 1.6016.53334 3.2001 60 0 0 -1.7461 1.5996.53334 3.2001 60 0 0 2.2578-.71094.53334 3.2001 0 0 0 .51367 2.3496.53334 3.2001 0 0 0 .51367-2.3516 3.2001.53334 30 0 0 2.2539.71094 3.2001.53334 30 0 0 -1.7441-1.5977.53334 3.2001 60 0 0 1.748-1.5996.53334 3.2001 60 0 0 -2.2617.71484.53334 3.2001 0 0 0 -.50977-2.2773z" fill="#cea4f1" stroke-width="1.0667"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h7v-2zm9 0v2h5v-2zm-9 4v2h11v-2zm0 4v2h4v-2zm6 0v2h1c-.044949-.094701-.088906-.20229-.125-.3418-.077717-.30039-.10439-.81722.16406-1.293.081489-.1441.18202-.26127.28906-.36523zm-6 4v2h8.2812c-.066517-.011548-.1231-.014758-.20117-.037109-.30195-.08645-.76491-.33245-1.0352-.80664-.23366-.4121-.24101-.84933-.18945-1.1562z" fill="#e0e0e0"/><path d="m12.216 8.598a.53334 3.2001 0 0 0 -.50976 2.2754 3.2001.53334 30 0 0 -2.2656-.71484 3.2001.53334 30 0 0 1.75 1.6016.53334 3.2001 60 0 0 -1.7461 1.5996.53334 3.2001 60 0 0 2.2578-.71094.53334 3.2001 0 0 0 .51367 2.3496.53334 3.2001 0 0 0 .51367-2.3516 3.2001.53334 30 0 0 2.2539.71094 3.2001.53334 30 0 0 -1.7441-1.5977.53334 3.2001 60 0 0 1.748-1.5996.53334 3.2001 60 0 0 -2.2617.71484.53334 3.2001 0 0 0 -.50977-2.2773z" fill="#c38ef1" stroke-width="1.0667"/></svg> diff --git a/editor/icons/RichTextLabel.svg b/editor/icons/RichTextLabel.svg index 7283d3dd62..14c1af3ea3 100644 --- a/editor/icons/RichTextLabel.svg +++ b/editor/icons/RichTextLabel.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h8v-2zm12 0-3 3h2v8h-2l3 3 3-3h-2v-8h2zm-12 4v2h2v-2zm4 0v2h4v-2zm-4 4v2h8v-2zm0 4v2h4v-2zm6 0v2h2v-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h8v-2zm12 0-3 3h2v8h-2l3 3 3-3h-2v-8h2zm-12 4v2h2v-2zm4 0v2h4v-2zm-4 4v2h8v-2zm0 4v2h4v-2zm6 0v2h2v-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/RigidBody2D.svg b/editor/icons/RigidBody2D.svg index 9dc626b94e..5d08e991ae 100644 --- a/editor/icons/RigidBody2D.svg +++ b/editor/icons/RigidBody2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 1.2227 3.9531 7 7 0 0 0 .30273.4082c.000785-.00256.0011667-.005252.0019532-.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422-.80273c.001375.000393.002531.00156.003906.001953a7 7 0 0 0 .035156-.021485 7 7 0 0 0 .42578-.25 7 7 0 0 0 .16992-.10352 7 7 0 0 0 .36914-.26953 7 7 0 0 0 .20508-.15625 7 7 0 0 0 .3418-.30859 7 7 0 0 0 .16406-.1543 7 7 0 0 0 .33008-.36133 7 7 0 0 0 .14062-.16016 7 7 0 0 0 .27734-.37305 7 7 0 0 0 .13867-.19531 7 7 0 0 0 .21875-.36133 7 7 0 0 0 .14258-.25 7 7 0 0 0 .15625-.33398 7 7 0 0 0 .13867-.31055 7 7 0 0 0 .10742-.30859 7 7 0 0 0 .11914-.35352 7 7 0 0 0 .087891-.36914 7 7 0 0 0 .066406-.29297 7 7 0 0 0 .056641-.40039 7 7 0 0 0 .037109-.3125 7 7 0 0 0 .025391-.55273 7 7 0 0 0 -4.3926-6.4922 7 7 0 0 0 -.001953 0 7 7 0 0 0 -.66016-.22852 7 7 0 0 0 -.0058594-.0019531 7 7 0 0 0 -.55078-.13086 7 7 0 0 0 -.14062-.03125 7 7 0 0 0 -.55078-.072266 7 7 0 0 0 -.14258-.017578 7 7 0 0 0 -.55469-.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 0 -.94922-1.6992c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668zm-6.8281 2.1797c.14632.65093.35776 1.2833.68359 1.8848a2 2 0 0 0 -.80664 1.6016h-1a6 6 0 0 1 1.123-3.4863zm1.877 1.4863a2 2 0 0 0 -.10938.0039062 2 2 0 0 1 .10938-.0039062zm-.18945.011719a2 2 0 0 0 -.12109.013672 2 2 0 0 1 .12109-.013672zm-.44141.09375a2 2 0 0 0 -.056641.019531 2 2 0 0 1 .056641-.019531zm-1.3594 2.0605a2 2 0 0 0 .013672.11914 2 2 0 0 1 -.013672-.11914zm.027344.20898a2 2 0 0 0 .017578.080078 2 2 0 0 1 -.017578-.080078zm.73438 1.1992a2 2 0 0 0 1.2285.42578 2 2 0 0 0 1.0508-.30078c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473.33203 6 6 0 0 1 -5.0547-2.7695c.23771-.5785.50336-1.1403.82617-1.6563z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 1.2227 3.9531 7 7 0 0 0 .30273.4082c.000785-.00256.0011667-.005252.0019532-.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422-.80273c.001375.000393.002531.00156.003906.001953a7 7 0 0 0 .035156-.021485 7 7 0 0 0 .42578-.25 7 7 0 0 0 .16992-.10352 7 7 0 0 0 .36914-.26953 7 7 0 0 0 .20508-.15625 7 7 0 0 0 .3418-.30859 7 7 0 0 0 .16406-.1543 7 7 0 0 0 .33008-.36133 7 7 0 0 0 .14062-.16016 7 7 0 0 0 .27734-.37305 7 7 0 0 0 .13867-.19531 7 7 0 0 0 .21875-.36133 7 7 0 0 0 .14258-.25 7 7 0 0 0 .15625-.33398 7 7 0 0 0 .13867-.31055 7 7 0 0 0 .10742-.30859 7 7 0 0 0 .11914-.35352 7 7 0 0 0 .087891-.36914 7 7 0 0 0 .066406-.29297 7 7 0 0 0 .056641-.40039 7 7 0 0 0 .037109-.3125 7 7 0 0 0 .025391-.55273 7 7 0 0 0 -4.3926-6.4922 7 7 0 0 0 -.001953 0 7 7 0 0 0 -.66016-.22852 7 7 0 0 0 -.0058594-.0019531 7 7 0 0 0 -.55078-.13086 7 7 0 0 0 -.14062-.03125 7 7 0 0 0 -.55078-.072266 7 7 0 0 0 -.14258-.017578 7 7 0 0 0 -.55469-.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 0 -.94922-1.6992c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668zm-6.8281 2.1797c.14632.65093.35776 1.2833.68359 1.8848a2 2 0 0 0 -.80664 1.6016h-1a6 6 0 0 1 1.123-3.4863zm1.877 1.4863a2 2 0 0 0 -.10938.0039062 2 2 0 0 1 .10938-.0039062zm-.18945.011719a2 2 0 0 0 -.12109.013672 2 2 0 0 1 .12109-.013672zm-.44141.09375a2 2 0 0 0 -.056641.019531 2 2 0 0 1 .056641-.019531zm-1.3594 2.0605a2 2 0 0 0 .013672.11914 2 2 0 0 1 -.013672-.11914zm.027344.20898a2 2 0 0 0 .017578.080078 2 2 0 0 1 -.017578-.080078zm.73438 1.1992a2 2 0 0 0 1.2285.42578 2 2 0 0 0 1.0508-.30078c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473.33203 6 6 0 0 1 -5.0547-2.7695c.23771-.5785.50336-1.1403.82617-1.6563z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/RigidBody3D.svg b/editor/icons/RigidBody3D.svg index 476bf3966a..7f5db4ce88 100644 --- a/editor/icons/RigidBody3D.svg +++ b/editor/icons/RigidBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 .035156.69922 7 7 0 0 0 .27734 1.3691 7 7 0 0 0 .91016 1.8848 7 7 0 0 0 .30273.4082c.000785-.00256.0011667-.005252.0019532-.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422-.80273c.001374.000393.002531.00156.003906.001953a7 7 0 0 0 .035156-.021485 7 7 0 0 0 .42578-.25 7 7 0 0 0 .16992-.10352 7 7 0 0 0 .36914-.26953 7 7 0 0 0 .20508-.15625 7 7 0 0 0 .3418-.30859 7 7 0 0 0 .16406-.1543 7 7 0 0 0 .33008-.36133 7 7 0 0 0 .14062-.16016 7 7 0 0 0 .27734-.37305 7 7 0 0 0 .13867-.19531 7 7 0 0 0 .21875-.36133 7 7 0 0 0 .14258-.25 7 7 0 0 0 .15625-.33398 7 7 0 0 0 .13867-.31055 7 7 0 0 0 .10742-.30859 7 7 0 0 0 .11914-.35352 7 7 0 0 0 .087891-.36914 7 7 0 0 0 .066406-.29297 7 7 0 0 0 .056641-.40039 7 7 0 0 0 .037109-.3125 7 7 0 0 0 .025391-.55273 7 7 0 0 0 -4.3848-6.4883 7 7 0 0 0 -.007812-.0039063 7 7 0 0 0 -.001953 0 7 7 0 0 0 -.61523-.21289 7 7 0 0 0 -.044922-.015625 7 7 0 0 0 -.0058594-.0019531 7 7 0 0 0 -.55078-.13086 7 7 0 0 0 -.14062-.03125 7 7 0 0 0 -.55078-.072266 7 7 0 0 0 -.14258-.017578 7 7 0 0 0 -.55469-.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 0 -.94922-1.6992c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668zm-6.8281 2.1797c.14632.65093.35776 1.2833.68359 1.8848a2 2 0 0 0 -.80664 1.6016h-1a6 6 0 0 1 1.123-3.4863zm1.877 1.4863a2 2 0 0 0 -.10938.0039062 2 2 0 0 1 .10938-.0039062zm-.18945.011719a2 2 0 0 0 -.12109.013672 2 2 0 0 1 .12109-.013672zm-.44141.09375a2 2 0 0 0 -.056641.019531 2 2 0 0 1 .056641-.019531zm-1.3594 2.0605a2 2 0 0 0 .013672.11914 2 2 0 0 1 -.013672-.11914zm.027344.20898a2 2 0 0 0 .017578.080078 2 2 0 0 1 -.017578-.080078zm.73438 1.1992a2 2 0 0 0 1.2285.42578 2 2 0 0 0 1.0508-.30078c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473.33203 6 6 0 0 1 -5.0547-2.7695c.23771-.5785.50336-1.1403.82617-1.6563z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 .035156.69922 7 7 0 0 0 .27734 1.3691 7 7 0 0 0 .91016 1.8848 7 7 0 0 0 .30273.4082c.000785-.00256.0011667-.005252.0019532-.007812a7 7 0 0 0 5.4727 2.6465 7 7 0 0 0 3.2422-.80273c.001374.000393.002531.00156.003906.001953a7 7 0 0 0 .035156-.021485 7 7 0 0 0 .42578-.25 7 7 0 0 0 .16992-.10352 7 7 0 0 0 .36914-.26953 7 7 0 0 0 .20508-.15625 7 7 0 0 0 .3418-.30859 7 7 0 0 0 .16406-.1543 7 7 0 0 0 .33008-.36133 7 7 0 0 0 .14062-.16016 7 7 0 0 0 .27734-.37305 7 7 0 0 0 .13867-.19531 7 7 0 0 0 .21875-.36133 7 7 0 0 0 .14258-.25 7 7 0 0 0 .15625-.33398 7 7 0 0 0 .13867-.31055 7 7 0 0 0 .10742-.30859 7 7 0 0 0 .11914-.35352 7 7 0 0 0 .087891-.36914 7 7 0 0 0 .066406-.29297 7 7 0 0 0 .056641-.40039 7 7 0 0 0 .037109-.3125 7 7 0 0 0 .025391-.55273 7 7 0 0 0 -4.3848-6.4883 7 7 0 0 0 -.007812-.0039063 7 7 0 0 0 -.001953 0 7 7 0 0 0 -.61523-.21289 7 7 0 0 0 -.044922-.015625 7 7 0 0 0 -.0058594-.0019531 7 7 0 0 0 -.55078-.13086 7 7 0 0 0 -.14062-.03125 7 7 0 0 0 -.55078-.072266 7 7 0 0 0 -.14258-.017578 7 7 0 0 0 -.55469-.025391zm1.9512 1.334a6 6 0 0 1 4.0488 5.666h-7a2 2 0 0 0 -.94922-1.6992c1.3464-2.0289 2.6038-3.2631 3.9004-3.9668zm-6.8281 2.1797c.14632.65093.35776 1.2833.68359 1.8848a2 2 0 0 0 -.80664 1.6016h-1a6 6 0 0 1 1.123-3.4863zm1.877 1.4863a2 2 0 0 0 -.10938.0039062 2 2 0 0 1 .10938-.0039062zm-.18945.011719a2 2 0 0 0 -.12109.013672 2 2 0 0 1 .12109-.013672zm-.44141.09375a2 2 0 0 0 -.056641.019531 2 2 0 0 1 .056641-.019531zm-1.3594 2.0605a2 2 0 0 0 .013672.11914 2 2 0 0 1 -.013672-.11914zm.027344.20898a2 2 0 0 0 .017578.080078 2 2 0 0 1 -.017578-.080078zm.73438 1.1992a2 2 0 0 0 1.2285.42578 2 2 0 0 0 1.0508-.30078c1.345 2.0268 2.6013 3.2645 3.8965 3.9688a6 6 0 0 1 -1.9473.33203 6 6 0 0 1 -5.0547-2.7695c.23771-.5785.50336-1.1403.82617-1.6563z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/Room.svg b/editor/icons/Room.svg index 6491d0409c..2bc165e736 100644 --- a/editor/icons/Room.svg +++ b/editor/icons/Room.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-6 3a1.0001 1.0001 0 0 0 -.55273.89453v6a1.0001 1.0001 0 0 0 .55273.89453l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1.0001 1.0001 0 0 0 .55273-.89453v-6a1.0001 1.0001 0 0 0 -.55273-.89453l-6-3a1.0001 1.0001 0 0 0 -.48438-.10352zm1.0371 2.6172 4 2v3.7637l-4-2zm-1 5.5 3.7637 1.8809-3.7637 1.8828-3.7637-1.8828z" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-6 3a1.0001 1.0001 0 0 0 -.55273.89453v6a1.0001 1.0001 0 0 0 .55273.89453l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1.0001 1.0001 0 0 0 .55273-.89453v-6a1.0001 1.0001 0 0 0 -.55273-.89453l-6-3a1.0001 1.0001 0 0 0 -.48438-.10352zm1.0371 2.6172 4 2v3.7637l-4-2zm-1 5.5 3.7637 1.8809-3.7637 1.8828-3.7637-1.8828z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd"/></svg> diff --git a/editor/icons/RootMotionView.svg b/editor/icons/RootMotionView.svg index f2d23e5b9f..051b95543c 100644 --- a/editor/icons/RootMotionView.svg +++ b/editor/icons/RootMotionView.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="8" cy="8" gradientTransform="matrix(.85714281 -.00000007 .00000004 .85714284 1.142858 1.142858)" gradientUnits="userSpaceOnUse" r="7"><stop offset="0" stop-color="#fc9c9c"/><stop offset=".83333331" stop-color="#fc9c9c" stop-opacity=".701961"/><stop offset="1" stop-color="#fc9c9c" stop-opacity="0"/></radialGradient><path d="m5 2v3h-3v2h3v2h-3v2h3v3h2v-3h2v3h2v-3h3v-2h-3v-2h3v-2h-3v-3h-2v3h-2v-3zm2 5h2v2h-2z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="8" cy="8" gradientTransform="matrix(.85714281 -.00000007 .00000004 .85714284 1.142858 1.142858)" gradientUnits="userSpaceOnUse" r="7"><stop offset="0" stop-color="#fc7f7f"/><stop offset=".83333331" stop-color="#fc7f7f" stop-opacity=".701961"/><stop offset="1" stop-color="#fc7f7f" stop-opacity="0"/></radialGradient><path d="m5 2v3h-3v2h3v2h-3v2h3v3h2v-3h2v3h2v-3h3v-2h-3v-2h3v-2h-3v-3h-2v3h-2v-3zm2 5h2v2h-2z" fill="url(#a)"/></svg> diff --git a/editor/icons/SampleLibrary.svg b/editor/icons/SampleLibrary.svg index 962f7b9413..a5f86d7f3c 100644 --- a/editor/icons/SampleLibrary.svg +++ b/editor/icons/SampleLibrary.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.0215 1.002a1.0001 1.0001 0 0 0 -1 .875l-.58984 4.7227-.52344-1.0469a1.0001 1.0001 0 0 0 -.89453-.55273h-2a1.0001 1.0001 0 1 0 0 2h1.3828l1.7227 3.4473a1.0001 1.0001 0 0 0 1.8867-.32227l.58984-4.7227.52344 1.0449a1.0001 1.0001 0 0 0 .89453.55273h3a1.0001 1.0001 0 1 0 0-2h-2.3809l-1.7246-3.4473a1.0001 1.0001 0 0 0 -.88672-.55078zm1.9785 6.998v1 5 1h5c.55228 0 1-.44772 1-1v-5c0-.55228-.44772-1-1-1v4l-1-1-1 1v-4z" fill="#ff8484"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.0215 1.002a1.0001 1.0001 0 0 0 -1 .875l-.58984 4.7227-.52344-1.0469a1.0001 1.0001 0 0 0 -.89453-.55273h-2a1.0001 1.0001 0 1 0 0 2h1.3828l1.7227 3.4473a1.0001 1.0001 0 0 0 1.8867-.32227l.58984-4.7227.52344 1.0449a1.0001 1.0001 0 0 0 .89453.55273h3a1.0001 1.0001 0 1 0 0-2h-2.3809l-1.7246-3.4473a1.0001 1.0001 0 0 0 -.88672-.55078zm1.9785 6.998v1 5 1h5c.55228 0 1-.44772 1-1v-5c0-.55228-.44772-1-1-1v4l-1-1-1 1v-4z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/ScriptCreate.svg b/editor/icons/ScriptCreate.svg index 91e95eb8c7..564dcddc2e 100644 --- a/editor/icons/ScriptCreate.svg +++ b/editor/icons/ScriptCreate.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5 1v-1h-1v-4h2v-2h2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#84ffb1" fill-rule="evenodd"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5 1v-1h-1v-4h2v-2h2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#5fff97" fill-rule="evenodd"/></g></svg> diff --git a/editor/icons/ScriptRemove.svg b/editor/icons/ScriptRemove.svg index b455583a6c..9af184c946 100644 --- a/editor/icons/ScriptRemove.svg +++ b/editor/icons/ScriptRemove.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5.6348l-1.584-1.584 1.4141-1.4141-1.4141-1.416 3.5352-3.5352 1.4141 1.4141v-.46484-3h3v-2c0-1.1046-.89543-2-2-2h-7z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13.414 1048.4 1.4142-1.4142-1.4142-1.4142-1.4142 1.4142-1.4142-1.4142-1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142-1.4142z" fill="#ff8484" fill-rule="evenodd"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5.6348l-1.584-1.584 1.4141-1.4141-1.4141-1.416 3.5352-3.5352 1.4141 1.4141v-.46484-3h3v-2c0-1.1046-.89543-2-2-2h-7z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13.414 1048.4 1.4142-1.4142-1.4142-1.4142-1.4142 1.4142-1.4142-1.4142-1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142-1.4142z" fill="#ff5f5f" fill-rule="evenodd"/></g></svg> diff --git a/editor/icons/ScrollContainer.svg b/editor/icons/ScrollContainer.svg index 600590684d..de631a525e 100644 --- a/editor/icons/ScrollContainer.svg +++ b/editor/icons/ScrollContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm5 1-2 2h4zm2 2v4l2-2zm0 4h-4l2 2zm-4 0v-4l-2 2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm5 1-2 2h4zm2 2v4l2-2zm0 4h-4l2 2zm-4 0v-4l-2 2z" fill="#8eef97"/></svg> diff --git a/editor/icons/Shader.svg b/editor/icons/Shader.svg index 33479326d4..5a7e51191f 100644 --- a/editor/icons/Shader.svg +++ b/editor/icons/Shader.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v12c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-8l-5-5zm1 2h6v3c0 .554.44599 1 1 1h3v6h-10z" fill="#e0e0e0"/><path d="m10 11h2v1h-2z" fill="#9f70ff"/><path d="m4 6h2v1h-2z" fill="#ffeb70"/><path d="m8 8h4v1h-4z" fill="#9dff70"/><path d="m7 6h1v1h-1z" fill="#70deff"/><path d="m4 11h5v1h-5z" fill="#ff70ac"/><path d="m4 4h3v1h-3z" fill="#ff7070"/><path d="m4 8h3v1h-3z" fill="#70ffb9"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v12c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-8l-5-5zm1 2h6v3c0 .554.44599 1 1 1h3v6h-10z" fill="#e0e0e0"/><path d="m10 11h2v1h-2z" fill="#8045ff"/><path d="m4 6h2v1h-2z" fill="#ffe345"/><path d="m8 8h4v1h-4z" fill="#80ff45"/><path d="m7 6h1v1h-1z" fill="#45d7ff"/><path d="m4 11h5v1h-5z" fill="#ff4596"/><path d="m4 4h3v1h-3z" fill="#ff4545"/><path d="m4 8h3v1h-3z" fill="#45ffa2"/></svg> diff --git a/editor/icons/ShaderMaterial.svg b/editor/icons/ShaderMaterial.svg index ff92f0c376..80a1d0a24d 100644 --- a/editor/icons/ShaderMaterial.svg +++ b/editor/icons/ShaderMaterial.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v1h2 6 3l-2-2z" fill="#ff7070"/><path d="m1 3v2h2v-2zm8 0v2h5l-2-2z" fill="#ffeb70"/><path d="m1 5v2h2v-2zm8 0v1c0 .554.44599 1 1 1h3 2v-1l-1-1z" fill="#9dff70"/><path d="m1 7v2h2v-2zm12 0v2h2v-2z" fill="#70ffb9"/><path d="m1 9v2h2v-2zm12 0v2h2v-2z" fill="#70deff"/><path d="m1 13v1c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-1h-2-10z" fill="#ff70ac"/><path d="m1 11v2h2v-2zm12 0v2h2v-2z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v1h2 6 3l-2-2z" fill="#ff4545"/><path d="m1 3v2h2v-2zm8 0v2h5l-2-2z" fill="#ffe345"/><path d="m1 5v2h2v-2zm8 0v1c0 .554.44599 1 1 1h3 2v-1l-1-1z" fill="#80ff45"/><path d="m1 7v2h2v-2zm12 0v2h2v-2z" fill="#45ffa2"/><path d="m1 9v2h2v-2zm12 0v2h2v-2z" fill="#45d7ff"/><path d="m1 13v1c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-1h-2-10z" fill="#ff4596"/><path d="m1 11v2h2v-2zm12 0v2h2v-2z" fill="#8045ff"/></svg> diff --git a/editor/icons/Signal.svg b/editor/icons/Signal.svg index 91599ffd65..ad5b5e5b06 100644 --- a/editor/icons/Signal.svg +++ b/editor/icons/Signal.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 3v10h2 4v-2h-4v-6h4v-2h-4zm9 1v3h-5v2h5v3l2.5-2 2.5-2-2.5-2z" fill="#ff8484"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 3v10h2 4v-2h-4v-6h4v-2h-4zm9 1v3h-5v2h5v3l2.5-2 2.5-2-2.5-2z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/Skeleton2D.svg b/editor/icons/Skeleton2D.svg index b34a2a9dca..fc2555fb8a 100644 --- a/editor/icons/Skeleton2D.svg +++ b/editor/icons/Skeleton2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#8da5f3"/></svg> diff --git a/editor/icons/Skeleton3D.svg b/editor/icons/Skeleton3D.svg index e0780dedd6..f1a1db86a9 100644 --- a/editor/icons/Skeleton3D.svg +++ b/editor/icons/Skeleton3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 .26562v.001953h4v-.001953a2 2 0 0 0 1-.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0 -4-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2zm-2 2h1v1h1v-1h1 1v1h1v-1h1v.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-.86914z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/SliderJoint3D.svg b/editor/icons/SliderJoint3D.svg index 57d22dff6a..20b265b766 100644 --- a/editor/icons/SliderJoint3D.svg +++ b/editor/icons/SliderJoint3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-.55228 0-1 .44772-1 1s.44772 1 1 1h3l-7 7v3l12-12zm10 2-12 12h8c.55228 0 1-.44772 1-1s-.44772-1-1-1h-3l7-7z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-.55228 0-1 .44772-1 1s.44772 1 1 1h3l-7 7v3l12-12zm10 2-12 12h8c.55228 0 1-.44772 1-1s-.44772-1-1-1h-3l7-7z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/Slot.svg b/editor/icons/Slot.svg index ec35be6b51..93c125a801 100644 --- a/editor/icons/Slot.svg +++ b/editor/icons/Slot.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 3v2h4v6h-4v2h4 2v-10h-2zm-3 1v3h-5v2h5v3l2.5-2 2.5-2-2.5-2z" fill="#84ffb1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 3v2h4v6h-4v2h4 2v-10h-2zm-3 1v3h-5v2h5v3l2.5-2 2.5-2-2.5-2z" fill="#5fff97"/></svg> diff --git a/editor/icons/SoftBody3D.svg b/editor/icons/SoftBody3D.svg index e46691d6a2..7bc9a22c22 100644 --- a/editor/icons/SoftBody3D.svg +++ b/editor/icons/SoftBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1s-3 5 0 7-1 7-1 7h13s3-6 0-8 1-6 1-6zm2 2h7s-2 3 1 5 0 5 0 5h-7s2-4-1-6 0-4 0-4z" fill="#fc9c9c" fill-opacity=".996078"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1s-3 5 0 7-1 7-1 7h13s3-6 0-8 1-6 1-6zm2 2h7s-2 3 1 5 0 5 0 5h-7s2-4-1-6 0-4 0-4z" fill="#fc7f7f" fill-opacity=".996078"/></svg> diff --git a/editor/icons/SphereMesh.svg b/editor/icons/SphereMesh.svg index 66cc8e3cc4..be2dd44a34 100644 --- a/editor/icons/SphereMesh.svg +++ b/editor/icons/SphereMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7s7-3.1458 7-7c0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-.071342-2.6061-.29819-3.9434-.69141.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549.41253 3.637 2.0767 3.9414 4.1699-1.3046.36677-2.6158.60259-3.9414.6875zm3.7852 6.2812c-.50864 1.7788-1.9499 3.1531-3.7852 3.5215v-2.9512c1.2792-.072301 2.5419-.26704 3.7852-.57031zm-9.5645.017578c1.2733.31892 2.5337.50215 3.7793.5625v2.9414c-1.8291-.36719-3.266-1.7339-3.7793-3.5039z" fill="#ffd684"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7s7-3.1458 7-7c0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-.071342-2.6061-.29819-3.9434-.69141.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549.41253 3.637 2.0767 3.9414 4.1699-1.3046.36677-2.6158.60259-3.9414.6875zm3.7852 6.2812c-.50864 1.7788-1.9499 3.1531-3.7852 3.5215v-2.9512c1.2792-.072301 2.5419-.26704 3.7852-.57031zm-9.5645.017578c1.2733.31892 2.5337.50215 3.7793.5625v2.9414c-1.8291-.36719-3.266-1.7339-3.7793-3.5039z" fill="#ffca5f"/></svg> diff --git a/editor/icons/SpinBox.svg b/editor/icons/SpinBox.svg index a8dc55d8db..1206ada6bd 100644 --- a/editor/icons/SpinBox.svg +++ b/editor/icons/SpinBox.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h7v-2-6-2zm10 1-2 3h4zm-10 1h5v6h-5zm8 4 2 3 2-3z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h7v-2-6-2zm10 1-2 3h4zm-10 1h5v6h-5zm8 4 2 3 2-3z" fill="#8eef97"/></svg> diff --git a/editor/icons/SpotLight3D.svg b/editor/icons/SpotLight3D.svg index a1dea938a3..73b738efcf 100644 --- a/editor/icons/SpotLight3D.svg +++ b/editor/icons/SpotLight3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1 1 0 0 0 -1 1v3.6934c-1.7861.86608-3 2.4605-3 4.3066h4a2 2 0 0 0 2 2 2 2 0 0 0 2-2h4c0-1.8462-1.2139-3.4406-3-4.3066v-3.6934a1 1 0 0 0 -1-1zm-1.0977 9.6348-1.7324 1 1 1.7305 1.7324-1zm6.1953 0-1 1.7305 1.7324 1 1-1.7305zm-4.0977 2.3652v2h2v-2z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1 1 0 0 0 -1 1v3.6934c-1.7861.86608-3 2.4605-3 4.3066h4a2 2 0 0 0 2 2 2 2 0 0 0 2-2h4c0-1.8462-1.2139-3.4406-3-4.3066v-3.6934a1 1 0 0 0 -1-1zm-1.0977 9.6348-1.7324 1 1 1.7305 1.7324-1zm6.1953 0-1 1.7305 1.7324 1 1-1.7305zm-4.0977 2.3652v2h2v-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/SpringArm3D.svg b/editor/icons/SpringArm3D.svg index 707e408dd9..e2c607c7bd 100644 --- a/editor/icons/SpringArm3D.svg +++ b/editor/icons/SpringArm3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#fc9c9c" stroke-width="2"><path d="m8 14 6-6"/><path d="m2 2 7 7"/><path d="m10 9h-6"/><path d="m9 9v-5"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#fc7f7f" stroke-width="2"><path d="m8 14 6-6"/><path d="m2 2 7 7"/><path d="m10 9h-6"/><path d="m9 9v-5"/></g></svg> diff --git a/editor/icons/Sprite2D.svg b/editor/icons/Sprite2D.svg index faae0e444f..0d3ec05a30 100644 --- a/editor/icons/Sprite2D.svg +++ b/editor/icons/Sprite2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4zm-1 5c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm8 0c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 .7168 1.7207c-.74987.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-.422-2.8281-1.1719a1.0001 1.0001 0 0 1 .69727-1.7168 1.0001 1.0001 0 0 1 .7168.30273c.37534.37535.88325.58594 1.4141.58594s1.0387-.21059 1.4141-.58594a1.0001 1.0001 0 0 1 .69727-.30664z" fill="#a5b7f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4zm-1 5c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm8 0c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 .7168 1.7207c-.74987.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-.422-2.8281-1.1719a1.0001 1.0001 0 0 1 .69727-1.7168 1.0001 1.0001 0 0 1 .7168.30273c.37534.37535.88325.58594 1.4141.58594s1.0387-.21059 1.4141-.58594a1.0001 1.0001 0 0 1 .69727-.30664z" fill="#8da5f3"/></svg> diff --git a/editor/icons/Sprite3D.svg b/editor/icons/Sprite3D.svg index 4ccd8f9c48..b002249ed7 100644 --- a/editor/icons/Sprite3D.svg +++ b/editor/icons/Sprite3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4zm-1 5c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm8 0c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 .7168 1.7207c-.74987.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-.422-2.8281-1.1719a1.0001 1.0001 0 0 1 .69727-1.7168 1.0001 1.0001 0 0 1 .7168.30273c.37534.37535.88325.58594 1.4141.58594s1.0387-.21059 1.4141-.58594a1.0001 1.0001 0 0 1 .69727-.30664z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4zm-1 5c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm8 0c.554 0 1 .446 1 1v2c0 .554-.446 1-1 1s-1-.446-1-1v-2c0-.554.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 .7168 1.7207c-.74987.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-.422-2.8281-1.1719a1.0001 1.0001 0 0 1 .69727-1.7168 1.0001 1.0001 0 0 1 .7168.30273c.37534.37535.88325.58594 1.4141.58594s1.0387-.21059 1.4141-.58594a1.0001 1.0001 0 0 1 .69727-.30664z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/StandardMaterial3D.svg b/editor/icons/StandardMaterial3D.svg index 7c52665a89..717ba5d239 100644 --- a/editor/icons/StandardMaterial3D.svg +++ b/editor/icons/StandardMaterial3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-3.7891 1.8945h8.4727l-3.7891-1.8945a1.0001 1.0001 0 0 0 -.48438-.10352z" fill="#ff7070"/><path d="m3.7637 3-2.2109 1.1055a1.0001 1.0001 0 0 0 -.55273.89453h3.2363l3.7637-1.8809 3.7637 1.8809h3.2363a1.0001 1.0001 0 0 0 -.55273-.89453l-2.2109-1.1055h-8.4727z" fill="#ffeb70"/><path d="m1 5v2h2v-.38086l.76172.38086h8.4766l.76172-.38086v.38086h2v-2h-3.2363l-3.7637 1.8828-3.7637-1.8828h-3.2363z" fill="#9dff70"/><path d="m1 7v2h2v-2zm2.7617 0 3.2383 1.6191v.38086h2v-.38086l3.2383-1.6191zm9.2383 0v2h2v-2z" fill="#70ffb9"/><path d="m1 9v2h3.2344l-1.2344-.61719v-1.3828h-2zm6 0v2h2v-2zm6 0v1.3828l-1.2344.61719h3.2344v-2h-2z" fill="#70deff"/><path d="m3.7637 13 3.7891 1.8945a1.0001 1.0001 0 0 0 .48438.10547 1.0001 1.0001 0 0 0 .41016-.10547l3.7891-1.8945h-8.4727z" fill="#ff70ac"/><path d="m1 11a1.0001 1.0001 0 0 0 .55273.89453l2.2109 1.1055h8.4727l2.2109-1.1055a1.0001 1.0001 0 0 0 .55273-.89453h-3.2344l-2.7656 1.3828v-1.3828h-2v1.3828l-2.7656-1.3828h-3.2344z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-3.7891 1.8945h8.4727l-3.7891-1.8945a1.0001 1.0001 0 0 0 -.48438-.10352z" fill="#ff4545"/><path d="m3.7637 3-2.2109 1.1055a1.0001 1.0001 0 0 0 -.55273.89453h3.2363l3.7637-1.8809 3.7637 1.8809h3.2363a1.0001 1.0001 0 0 0 -.55273-.89453l-2.2109-1.1055h-8.4727z" fill="#ffe345"/><path d="m1 5v2h2v-.38086l.76172.38086h8.4766l.76172-.38086v.38086h2v-2h-3.2363l-3.7637 1.8828-3.7637-1.8828h-3.2363z" fill="#80ff45"/><path d="m1 7v2h2v-2zm2.7617 0 3.2383 1.6191v.38086h2v-.38086l3.2383-1.6191zm9.2383 0v2h2v-2z" fill="#45ffa2"/><path d="m1 9v2h3.2344l-1.2344-.61719v-1.3828h-2zm6 0v2h2v-2zm6 0v1.3828l-1.2344.61719h3.2344v-2h-2z" fill="#45d7ff"/><path d="m3.7637 13 3.7891 1.8945a1.0001 1.0001 0 0 0 .48438.10547 1.0001 1.0001 0 0 0 .41016-.10547l3.7891-1.8945h-8.4727z" fill="#ff4596"/><path d="m1 11a1.0001 1.0001 0 0 0 .55273.89453l2.2109 1.1055h8.4727l2.2109-1.1055a1.0001 1.0001 0 0 0 .55273-.89453h-3.2344l-2.7656 1.3828v-1.3828h-2v1.3828l-2.7656-1.3828h-3.2344z" fill="#8045ff"/></svg> diff --git a/editor/icons/StaticBody2D.svg b/editor/icons/StaticBody2D.svg index 66940ad415..ba61605522 100644 --- a/editor/icons/StaticBody2D.svg +++ b/editor/icons/StaticBody2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#a5b7f3" fill-opacity=".98824" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#8da5f3" fill-opacity=".98824" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/StaticBody3D.svg b/editor/icons/StaticBody3D.svg index a4a641f28c..55b061571f 100644 --- a/editor/icons/StaticBody3D.svg +++ b/editor/icons/StaticBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/String.svg b/editor/icons/String.svg index 5b7ade8b1e..abcb92d4b2 100644 --- a/editor/icons/String.svg +++ b/editor/icons/String.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-2a1 1 0 0 1 1-1h1v-2zm2 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm8 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#6ba7ec"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2a3 3 0 0 0 -3 3v2a1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 3-3v-2a1 1 0 0 1 1-1h1v-2zm2 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm8 2a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v-2z" fill="#4593ec"/></svg> diff --git a/editor/icons/StringName.svg b/editor/icons/StringName.svg index 8f2ef13a37..3b67f2accd 100644 --- a/editor/icons/StringName.svg +++ b/editor/icons/StringName.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2c-1.6569 0-3 1.3431-3 3v2c0 .55228-.44772 1-1 1h-1v2h1c1.6569 0 3-1.3431 3-3v-2c0-.55228.44772-1 1-1h1v3c0 1.6569 1.3431 3 3 3h3v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-5v-2zm3 4h2v2h-1c-.55228 0-1-.44772-1-1z" fill="#6ba7ec"/><path d="m10 4v6h2v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-1z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2c-1.6569 0-3 1.3431-3 3v2c0 .55228-.44772 1-1 1h-1v2h1c1.6569 0 3-1.3431 3-3v-2c0-.55228.44772-1 1-1h1v3c0 1.6569 1.3431 3 3 3h3v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-5v-2zm3 4h2v2h-1c-.55228 0-1-.44772-1-1z" fill="#4593ec"/><path d="m10 4v6h2v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-1z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/StyleBoxEmpty.svg b/editor/icons/StyleBoxEmpty.svg index e1a2bc6888..3c4546dff5 100644 --- a/editor/icons/StyleBoxEmpty.svg +++ b/editor/icons/StyleBoxEmpty.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v1h2v-2zm3 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2v-1c-.000055-.5523-.44774-.9999-1-1z" fill="#ff7070"/><path d="m1 5v2h2v-2zm12 0v.23242c.31584.1783.57817.43795.75977.75195.19142.33153.43699.67036.69922 1.0156h.54102v-2h-2z" fill="#9dff70"/><path d="m12 7c-.43047.7456-.94451 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2zm2.459 0c.17438.2296.352.46082.54102.69922v-.69922z" fill="#70ffb9"/><path d="m1 9v2h2v-2zm9.5645 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78151-1.31-1.334-2z" fill="#70deff"/><path d="m1 13v1c.0000552.5523.44774.9999 1 1h1v-2zm4 0v2h2v-2zm4.1836 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff70ac"/><path d="m9.2305 11c-.13656.32585-.23047.65576-.23047 1 0 .35235.07201.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v1h2v-2zm3 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2v-1c-.000055-.5523-.44774-.9999-1-1z" fill="#ff4545"/><path d="m1 5v2h2v-2zm12 0v.23242c.31584.1783.57817.43795.75977.75195.19142.33153.43699.67036.69922 1.0156h.54102v-2h-2z" fill="#80ff45"/><path d="m12 7c-.43047.7456-.94451 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2zm2.459 0c.17438.2296.352.46082.54102.69922v-.69922z" fill="#45ffa2"/><path d="m1 9v2h2v-2zm9.5645 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78151-1.31-1.334-2z" fill="#45d7ff"/><path d="m1 13v1c.0000552.5523.44774.9999 1 1h1v-2zm4 0v2h2v-2zm4.1836 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff4596"/><path d="m9.2305 11c-.13656.32585-.23047.65576-.23047 1 0 .35235.07201.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#8045ff"/></svg> diff --git a/editor/icons/StyleBoxFlat.svg b/editor/icons/StyleBoxFlat.svg index b24c453f6b..5bf01f5e66 100644 --- a/editor/icons/StyleBoxFlat.svg +++ b/editor/icons/StyleBoxFlat.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v1h14v-1c-.000055-.5523-.44774-.9999-1-1z" fill="#ff7070"/><path d="m1 3v2h14v-2z" fill="#ffeb70"/><path d="m1 5v2h8.582c.25686-.33847.49465-.66934.68555-1 .33885-.5859.95103-.96109 1.627-.99609.7512-.04 1.4613.34489 1.8379.99609.18899.32737.42831.66049.68555 1h.58203v-2h-14z" fill="#9dff70"/><path d="m1 7v2h7.0547c.14116-.20345.28508-.40233.42383-.58398.38601-.5053.76348-.96794 1.1035-1.416h-8.582zm11 0c-.43047.7456-.94451 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2zm2.418 0c.18626.24583.37928.49419.58203.75v-.75z" fill="#70ffb9"/><path d="m1 9v2h6.1172c.17955-.78395.54577-1.4354.9375-2zm9.5645 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78151-1.31-1.334-2z" fill="#70deff"/><path d="m1 13v1c.0000552.5523.44774.9999 1 1h6.0371c-.44511-.58388-.76161-1.2639-.91992-2h-6.1172zm8.1836 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff70ac"/><path d="m1 11v2h6.1172c-.06966-.3239-.11719-.65596-.11719-1 0-.35655.045474-.68688.11719-1zm8.2305 0c-.13656.32585-.23047.65576-.23047 1 0 .35235.07201.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v1h14v-1c-.000055-.5523-.44774-.9999-1-1z" fill="#ff4545"/><path d="m1 3v2h14v-2z" fill="#ffe345"/><path d="m1 5v2h8.582c.25686-.33847.49465-.66934.68555-1 .33885-.5859.95103-.96109 1.627-.99609.7512-.04 1.4613.34489 1.8379.99609.18899.32737.42831.66049.68555 1h.58203v-2h-14z" fill="#80ff45"/><path d="m1 7v2h7.0547c.14116-.20345.28508-.40233.42383-.58398.38601-.5053.76348-.96794 1.1035-1.416h-8.582zm11 0c-.43047.7456-.94451 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2zm2.418 0c.18626.24583.37928.49419.58203.75v-.75z" fill="#45ffa2"/><path d="m1 9v2h6.1172c.17955-.78395.54577-1.4354.9375-2zm9.5645 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78151-1.31-1.334-2z" fill="#45d7ff"/><path d="m1 13v1c.0000552.5523.44774.9999 1 1h6.0371c-.44511-.58388-.76161-1.2639-.91992-2h-6.1172zm8.1836 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff4596"/><path d="m1 11v2h6.1172c-.06966-.3239-.11719-.65596-.11719-1 0-.35655.045474-.68688.11719-1zm8.2305 0c-.13656.32585-.23047.65576-.23047 1 0 .35235.07201.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#8045ff"/></svg> diff --git a/editor/icons/StyleBoxLine.svg b/editor/icons/StyleBoxLine.svg index e92f33b7b0..995f56f726 100644 --- a/editor/icons/StyleBoxLine.svg +++ b/editor/icons/StyleBoxLine.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.303 1c-.4344 0-.86973.16881-1.2012.50586l-1.4688 1.4941h4.3418c.082839-.52789-.072596-1.0872-.47266-1.4941-.33144-.33705-.76482-.50586-1.1992-.50586z" fill="#ff7070"/><path d="m10.633 3-1.9668 2h4.8008l1.0352-1.0527c.2628-.2673.41824-.60049.47266-.94727h-4.3418z" fill="#ffeb70"/><path d="m8.666 5-1.9648 2h2.8809c.25686-.33847.49465-.66934.68555-1 .33885-.5859.95098-.96109 1.627-.99609.44399-.023642.86385.115 1.2188.35547l.35352-.35938h-4.8008z" fill="#9dff70"/><path d="m1.2617 13c-.08284.52789.072596 1.0872.47266 1.4941.33144.33705.76484.50586 1.1992.50586.4344 0 .8697-.16881 1.2012-.50586l1.4688-1.4941h-4.3418zm7.9219 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff70ac"/><path d="m2.7695 11-1.0352 1.0527c-.2628.2673-.41824.60049-.47266.94727h4.3418l1.4238-1.4473c.020288-.18998.04923-.37542.089844-.55273h-4.3477zm6.4609 0c-.13656.32585-.23047.65576-.23047 1 0 .35235.072014.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#9f70ff"/><path d="m4.7363 9-1.9668 2h4.3477c.17955-.78395.54577-1.4354.9375-2zm5.8281 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78149-1.31-1.334-2z" fill="#70deff"/><path d="m6.7012 7-1.9648 2h3.3184c.14116-.20345.28508-.40233.42383-.58398.38601-.5053.7635-.96796 1.1035-1.416h-2.8809zm5.2988 0c-.43047.7456-.94456 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2z" fill="#70ffb9"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.303 1c-.4344 0-.86973.16881-1.2012.50586l-1.4688 1.4941h4.3418c.082839-.52789-.072596-1.0872-.47266-1.4941-.33144-.33705-.76482-.50586-1.1992-.50586z" fill="#ff4545"/><path d="m10.633 3-1.9668 2h4.8008l1.0352-1.0527c.2628-.2673.41824-.60049.47266-.94727h-4.3418z" fill="#ffe345"/><path d="m8.666 5-1.9648 2h2.8809c.25686-.33847.49465-.66934.68555-1 .33885-.5859.95098-.96109 1.627-.99609.44399-.023642.86385.115 1.2188.35547l.35352-.35938h-4.8008z" fill="#80ff45"/><path d="m1.2617 13c-.08284.52789.072596 1.0872.47266 1.4941.33144.33705.76484.50586 1.1992.50586.4344 0 .8697-.16881 1.2012-.50586l1.4688-1.4941h-4.3418zm7.9219 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff4596"/><path d="m2.7695 11-1.0352 1.0527c-.2628.2673-.41824.60049-.47266.94727h4.3418l1.4238-1.4473c.020288-.18998.04923-.37542.089844-.55273h-4.3477zm6.4609 0c-.13656.32585-.23047.65576-.23047 1 0 .35235.072014.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#8045ff"/><path d="m4.7363 9-1.9668 2h4.3477c.17955-.78395.54577-1.4354.9375-2zm5.8281 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78149-1.31-1.334-2z" fill="#45d7ff"/><path d="m6.7012 7-1.9648 2h3.3184c.14116-.20345.28508-.40233.42383-.58398.38601-.5053.7635-.96796 1.1035-1.416h-2.8809zm5.2988 0c-.43047.7456-.94456 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2z" fill="#45ffa2"/></svg> diff --git a/editor/icons/StyleBoxTexture.svg b/editor/icons/StyleBoxTexture.svg index 89bbc41ef8..a356d11885 100644 --- a/editor/icons/StyleBoxTexture.svg +++ b/editor/icons/StyleBoxTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v1h2 10 2v-1a1.0001 1.0001 0 0 0 -1-1z" fill="#ff7070"/><path d="m1 3v2h2v-2zm12 0v2h2v-2zm-4 1v1h1v-1z" fill="#ffeb70"/><path d="m1 5v2h2v-2zm7 0v1h-2v1h3.543c.26215-.34438.50373-.68039.69727-1.0156a2.0315 2.0315 0 0 1 .75977-.75195v-.23242h-1-1-1zm5 0v.23242a2.0315 2.0315 0 0 1 .75977.75195c.19142.33153.43699.67033.69922 1.0156h.54102v-2h-2z" fill="#9dff70"/><path d="m1 7v2h2v-2zm4 0v1h-1v1h4.0156c.14585-.2113.29419-.41592.4375-.60352.38121-.49904.75394-.95521 1.0898-1.3965h-3.543-1zm7 0c-.43047.7456-.94451 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2zm2.459 0c.17438.22962.352.46082.54102.69922v-.69922z" fill="#70ffb9"/><path d="m1 9v2h2v-2zm9.5645 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78151-1.31-1.334-2z" fill="#70deff"/><path d="m1 13v1a1.0001 1.0001 0 0 0 1 1h5.998c-.4429-.5864-.77294-1.2592-.92578-2h-4.0723-2zm8.1836 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff70ac"/><path d="m1 11v2h2v-2zm8.2305 0c-.13656.32585-.23047.65576-.23047 1 0 .35235.07201.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#9f70ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v1h2 10 2v-1a1.0001 1.0001 0 0 0 -1-1z" fill="#ff4545"/><path d="m1 3v2h2v-2zm12 0v2h2v-2zm-4 1v1h1v-1z" fill="#ffe345"/><path d="m1 5v2h2v-2zm7 0v1h-2v1h3.543c.26215-.34438.50373-.68039.69727-1.0156a2.0315 2.0315 0 0 1 .75977-.75195v-.23242h-1-1-1zm5 0v.23242a2.0315 2.0315 0 0 1 .75977.75195c.19142.33153.43699.67033.69922 1.0156h.54102v-2h-2z" fill="#80ff45"/><path d="m1 7v2h2v-2zm4 0v1h-1v1h4.0156c.14585-.2113.29419-.41592.4375-.60352.38121-.49904.75394-.95521 1.0898-1.3965h-3.543-1zm7 0c-.43047.7456-.94451 1.3867-1.4355 2h2.8711c-.49104-.6133-1.0051-1.2544-1.4355-2zm2.459 0c.17438.22962.352.46082.54102.69922v-.69922z" fill="#45ffa2"/><path d="m1 9v2h2v-2zm9.5645 0c-.55248.69003-1.0583 1.3421-1.334 2h5.5391c-.2757-.65786-.78151-1.31-1.334-2z" fill="#45d7ff"/><path d="m1 13v1a1.0001 1.0001 0 0 0 1 1h5.998c-.4429-.5864-.77294-1.2592-.92578-2h-4.0723-2zm8.1836 0c.41312 1.1628 1.5119 2 2.8164 2s2.4033-.83718 2.8164-2z" fill="#ff4596"/><path d="m1 11v2h2v-2zm8.2305 0c-.13656.32585-.23047.65576-.23047 1 0 .35235.07201.68593.18359 1h5.6328c.11158-.31407.18359-.64765.18359-1 0-.34424-.093909-.67415-.23047-1h-5.5391z" fill="#8045ff"/></svg> diff --git a/editor/icons/SubViewportContainer.svg b/editor/icons/SubViewportContainer.svg index baf80e5086..e4584c3b9a 100644 --- a/editor/icons/SubViewportContainer.svg +++ b/editor/icons/SubViewportContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm3 1c-.5304.0001-1.0391.21084-1.4141.58594-.37509.375-.58586.88366-.58594 1.4141v4c.00008.5304.21085 1.0391.58594 1.4141.37501.3751.88366.58584 1.4141.58594h4c1.1046 0 2-.8954 2-2v-4c0-1.1046-.89543-2-2-2zm0 1h4c.55228 0 .99999.4477 1 1v4c-.00001.5523-.44772 1-1 1h-4c-.55228 0-.99999-.4477-1-1v-4c.00001-.5523.44772-1 1-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm3 1c-.5304.0001-1.0391.21084-1.4141.58594-.37509.375-.58586.88366-.58594 1.4141v4c.00008.5304.21085 1.0391.58594 1.4141.37501.3751.88366.58584 1.4141.58594h4c1.1046 0 2-.8954 2-2v-4c0-1.1046-.89543-2-2-2zm0 1h4c.55228 0 .99999.4477 1 1v4c-.00001.5523-.44772 1-1 1h-4c-.55228 0-.99999-.4477-1-1v-4c.00001-.5523.44772-1 1-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/TabContainer.svg b/editor/icons/TabContainer.svg index aeb5507279..92ca60911a 100644 --- a/editor/icons/TabContainer.svg +++ b/editor/icons/TabContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h5v2 2h5v6h-10zm7 0h3v2h-3z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h5v2 2h5v6h-10zm7 0h3v2h-3z" fill="#8eef97"/></svg> diff --git a/editor/icons/Tabs.svg b/editor/icons/Tabs.svg index 4fd4a5cd80..e20a1a0131 100644 --- a/editor/icons/Tabs.svg +++ b/editor/icons/Tabs.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 4c-1.108 0-1.8178.9071-2 2l-1 6h-1v2h4 6 4v-2h-2l-1-6c-.18216-1.0929-.89199-2-2-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 4c-1.108 0-1.8178.9071-2 2l-1 6h-1v2h4 6 4v-2h-2l-1-6c-.18216-1.0929-.89199-2-2-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/TestCube.svg b/editor/icons/TestCube.svg index bdfb3c893b..9995f5b5f4 100644 --- a/editor/icons/TestCube.svg +++ b/editor/icons/TestCube.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-6 3a1.0001 1.0001 0 0 0 -.55273.89453v6a1.0001 1.0001 0 0 0 .55273.89453l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1.0001 1.0001 0 0 0 .55273-.89453v-6a1.0001 1.0001 0 0 0 -.55273-.89453l-6-3a1.0001 1.0001 0 0 0 -.48438-.10352zm.037109 2.1172 3.7637 1.8809-3.7637 1.8828-3.7637-1.8828zm-5 3.5 4 2v3.7637l-4-2zm10 0v3.7637l-4 2v-3.7637z" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd" transform="translate(0 .000012)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-6 3a1.0001 1.0001 0 0 0 -.55273.89453v6a1.0001 1.0001 0 0 0 .55273.89453l6 3a1.0001 1.0001 0 0 0 .89453 0l6-3a1.0001 1.0001 0 0 0 .55273-.89453v-6a1.0001 1.0001 0 0 0 -.55273-.89453l-6-3a1.0001 1.0001 0 0 0 -.48438-.10352zm.037109 2.1172 3.7637 1.8809-3.7637 1.8828-3.7637-1.8828zm-5 3.5 4 2v3.7637l-4-2zm10 0v3.7637l-4 2v-3.7637z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd" transform="translate(0 .000012)"/></svg> diff --git a/editor/icons/TextEdit.svg b/editor/icons/TextEdit.svg index 366cf6596d..67a5145373 100644 --- a/editor/icons/TextEdit.svg +++ b/editor/icons/TextEdit.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v4h1v-4z" fill="#a5efac" transform="translate(0 1036.4)"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v4h1v-4z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg> diff --git a/editor/icons/TextureButton.svg b/editor/icons/TextureButton.svg index 497386945e..8d3d1c52ce 100644 --- a/editor/icons/TextureButton.svg +++ b/editor/icons/TextureButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1v2h6v10h-4v2h6v-14zm-5 1v3.1328l-1.4453-.96484-1.1094 1.6641 3 2c.3359.2239.77347.2239 1.1094 0l3-2-1.1094-1.6641-1.4453.96484v-3.1328zm7 4v1h-1v1h-1v1h1v2h2 2v-2h-1v-2h-1v-1zm-7.5 4c-.831 0-1.5.669-1.5 1.5v.5 1h-1v2h8v-2h-1v-1-.5c0-.831-.669-1.5-1.5-1.5z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1v2h6v10h-4v2h6v-14zm-5 1v3.1328l-1.4453-.96484-1.1094 1.6641 3 2c.3359.2239.77347.2239 1.1094 0l3-2-1.1094-1.6641-1.4453.96484v-3.1328zm7 4v1h-1v1h-1v1h1v2h2 2v-2h-1v-2h-1v-1zm-7.5 4c-.831 0-1.5.669-1.5 1.5v.5 1h-1v2h8v-2h-1v-1-.5c0-.831-.669-1.5-1.5-1.5z" fill="#8eef97"/></svg> diff --git a/editor/icons/TextureProgressBar.svg b/editor/icons/TextureProgressBar.svg index 30d76e33b8..a72f0e5754 100644 --- a/editor/icons/TextureProgressBar.svg +++ b/editor/icons/TextureProgressBar.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#a5efac" transform="translate(0 -1036.4)"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-6c0-1.1046-.89543-2-2-2zm0 2h10v6h-10z" transform="translate(0 1036.4)"/><path d="m4 1042.4h1v2h-1z"/><path d="m6 1043.4h1v3h-1z"/><path d="m8 1042.4h1v4h-1z"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#8eef97" transform="translate(0 -1036.4)"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-6c0-1.1046-.89543-2-2-2zm0 2h10v6h-10z" transform="translate(0 1036.4)"/><path d="m4 1042.4h1v2h-1z"/><path d="m6 1043.4h1v3h-1z"/><path d="m8 1042.4h1v4h-1z"/></g></svg> diff --git a/editor/icons/TextureRect.svg b/editor/icons/TextureRect.svg index 605afbb7ca..5f55c06bce 100644 --- a/editor/icons/TextureRect.svg +++ b/editor/icons/TextureRect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm2 2h10v10h-10zm6 3v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm2 2h10v10h-10zm6 3v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/Theme.svg b/editor/icons/Theme.svg index 00e1716dad..401d884022 100644 --- a/editor/icons/Theme.svg +++ b/editor/icons/Theme.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="0"><path d="m6.7246 3c-.52985.78935-.96267 1.4021-1.3945 2h5.3398c-.43187-.59786-.86468-1.2107-1.3945-2z" fill="#ffeb70"/><path d="m5.3301 5c-.52617.72841-1.0198 1.4208-1.375 2h8.0898c-.35516-.57924-.84883-1.2716-1.375-2z" fill="#9dff70"/><path d="m3.9551 7c-.41451.67603-.71534 1.3082-.85547 2h9.8008c-.14013-.69181-.44096-1.324-.85547-2h-8.0898z" fill="#70ffb9"/><path d="m3.0996 9c-.063989.3159-.099609.64498-.099609 1 0 .34242.034776.67693.10156 1h9.7969c.066786-.32307.10156-.65758.10156-1 0-.35502-.03562-.6841-.099609-1h-9.8008z" fill="#70deff"/><path d="m3.1016 11c.15381.74405.48967 1.4159.93555 2h7.9258c.44588-.5841.78173-1.2559.93555-2h-9.7969z" fill="#9f70ff"/><path d="m4.0371 13c.9218 1.2076 2.3612 2 3.9629 2s3.0411-.79243 3.9629-2z" fill="#ff70ac"/><path d="m8 1c-.45196.75327-.87224 1.3994-1.2754 2h2.5508c-.40315-.6006-.82343-1.2467-1.2754-2z" fill="#ff7070"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="0"><path d="m6.7246 3c-.52985.78935-.96267 1.4021-1.3945 2h5.3398c-.43187-.59786-.86468-1.2107-1.3945-2z" fill="#ffe345"/><path d="m5.3301 5c-.52617.72841-1.0198 1.4208-1.375 2h8.0898c-.35516-.57924-.84883-1.2716-1.375-2z" fill="#80ff45"/><path d="m3.9551 7c-.41451.67603-.71534 1.3082-.85547 2h9.8008c-.14013-.69181-.44096-1.324-.85547-2h-8.0898z" fill="#45ffa2"/><path d="m3.0996 9c-.063989.3159-.099609.64498-.099609 1 0 .34242.034776.67693.10156 1h9.7969c.066786-.32307.10156-.65758.10156-1 0-.35502-.03562-.6841-.099609-1h-9.8008z" fill="#45d7ff"/><path d="m3.1016 11c.15381.74405.48967 1.4159.93555 2h7.9258c.44588-.5841.78173-1.2559.93555-2h-9.7969z" fill="#8045ff"/><path d="m4.0371 13c.9218 1.2076 2.3612 2 3.9629 2s3.0411-.79243 3.9629-2z" fill="#ff4596"/><path d="m8 1c-.45196.75327-.87224 1.3994-1.2754 2h2.5508c-.40315-.6006-.82343-1.2467-1.2754-2z" fill="#ff4545"/></g></svg> diff --git a/editor/icons/ThemeRemoveAllItems.svg b/editor/icons/ThemeRemoveAllItems.svg index 652274a0e7..c04254ea8d 100644 --- a/editor/icons/ThemeRemoveAllItems.svg +++ b/editor/icons/ThemeRemoveAllItems.svg @@ -1 +1 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1.745c-.595 0-1.084.489-1.084 1.084v3.699l-3.851-1.927c-.163-.08-.343-.119-.525-.112-.395.015-.752.244-.929.597-.076.151-.115.317-.115.485 0 .41.233.786.599.97l3.481 1.74-3.481 1.74c-.366.184-.599.56-.599.97 0 .168.039.334.115.485.183.367.559.599.969.599.168 0 .334-.039.485-.114l3.851-1.927v3.111c0 .594.489 1.084 1.084 1.084s1.084-.49 1.084-1.084v-3.111l3.851 1.927c.151.075.317.114.485.114.41 0 .786-.232.969-.599.076-.151.115-.317.115-.485 0-.41-.233-.786-.599-.97l-3.481-1.74 3.481-1.74c.366-.184.599-.56.599-.97 0-.168-.039-.334-.115-.485-.182-.364-.554-.596-.961-.599-.171-.001-.34.038-.493.114l-3.851 1.927v-3.699c0-.595-.489-1.084-1.084-1.084z" fill="#a5efac"/><g fill-rule="nonzero"><path d="m8 1.745v1.783h-1.084v-.699c0-.595.489-1.084 1.084-1.084z" fill="#ff7070"/><path d="m1.528 5.312h2.957l-1.42-.711c-.163-.08-.343-.119-.525-.112-.395.015-.752.244-.929.597-.036.072-.064.148-.083.226zm5.388-1.784h1.084v1.784h-1.084z" fill="#ffeb70"/><path d="m6.916 5.312h1.084v1.783h-4.796l-1.109-.554c-.366-.184-.599-.56-.599-.97 0-.088.011-.175.032-.259h2.957l2.431 1.216z" fill="#9dff70"/><path d="m3.204 7.095h4.796v1.783h-3.619l1.195-.597z" fill="#70ffb9"/><path d="m4.381 8.878h3.619v1.784h-1.084v-.628l-1.255.628h-4.114c.088-.274.283-.508.548-.641z" fill="#70deff"/><path d="m6.916 12.445h1.084v1.784c-.595-.001-1.084-.49-1.084-1.084z" fill="#ff70ac"/><path d="m6.916 10.662h1.084v1.783h-1.084zm-1.255 0h-4.114c-.033.105-.051.216-.051.329 0 .168.039.334.115.485.183.367.559.599.969.599.168 0 .334-.039.485-.114z" fill="#9f70ff"/></g></svg> +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1.745c-.595 0-1.084.489-1.084 1.084v3.699l-3.851-1.927c-.163-.08-.343-.119-.525-.112-.395.015-.752.244-.929.597-.076.151-.115.317-.115.485 0 .41.233.786.599.97l3.481 1.74-3.481 1.74c-.366.184-.599.56-.599.97 0 .168.039.334.115.485.183.367.559.599.969.599.168 0 .334-.039.485-.114l3.851-1.927v3.111c0 .594.489 1.084 1.084 1.084s1.084-.49 1.084-1.084v-3.111l3.851 1.927c.151.075.317.114.485.114.41 0 .786-.232.969-.599.076-.151.115-.317.115-.485 0-.41-.233-.786-.599-.97l-3.481-1.74 3.481-1.74c.366-.184.599-.56.599-.97 0-.168-.039-.334-.115-.485-.182-.364-.554-.596-.961-.599-.171-.001-.34.038-.493.114l-3.851 1.927v-3.699c0-.595-.489-1.084-1.084-1.084z" fill="#8eef97"/><g fill-rule="nonzero"><path d="m8 1.745v1.783h-1.084v-.699c0-.595.489-1.084 1.084-1.084z" fill="#ff4545"/><path d="m1.528 5.312h2.957l-1.42-.711c-.163-.08-.343-.119-.525-.112-.395.015-.752.244-.929.597-.036.072-.064.148-.083.226zm5.388-1.784h1.084v1.784h-1.084z" fill="#ffe345"/><path d="m6.916 5.312h1.084v1.783h-4.796l-1.109-.554c-.366-.184-.599-.56-.599-.97 0-.088.011-.175.032-.259h2.957l2.431 1.216z" fill="#80ff45"/><path d="m3.204 7.095h4.796v1.783h-3.619l1.195-.597z" fill="#45ffa2"/><path d="m4.381 8.878h3.619v1.784h-1.084v-.628l-1.255.628h-4.114c.088-.274.283-.508.548-.641z" fill="#45d7ff"/><path d="m6.916 12.445h1.084v1.784c-.595-.001-1.084-.49-1.084-1.084z" fill="#ff4596"/><path d="m6.916 10.662h1.084v1.783h-1.084zm-1.255 0h-4.114c-.033.105-.051.216-.051.329 0 .168.039.334.115.485.183.367.559.599.969.599.168 0 .334-.039.485-.114z" fill="#8045ff"/></g></svg> diff --git a/editor/icons/ThemeRemoveCustomItems.svg b/editor/icons/ThemeRemoveCustomItems.svg index 839f584fce..5ecde9ff55 100644 --- a/editor/icons/ThemeRemoveCustomItems.svg +++ b/editor/icons/ThemeRemoveCustomItems.svg @@ -1 +1 @@ -<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m11.299 3c.772.513 1.42 1.199 1.888 2h-2.553c-.706-.621-1.629-1-2.634-1s-1.928.379-2.634 1h-2.553c.468-.801 1.116-1.487 1.888-2z" fill="#ffeb70"/><path d="m5.366 5c-.593.522-1.033 1.216-1.238 2h-2.043c.122-.717.373-1.392.728-2zm7.821 0c.355.608.606 1.283.728 2h-2.043c-.205-.784-.645-1.478-1.238-2z" fill="#9dff70"/><path d="m13.915 7c.056.326.085.66.085 1s-.029.674-.085 1h-2.043c.083-.32.128-.655.128-1s-.045-.68-.128-1zm-9.787 0c-.083.32-.128.655-.128 1s.045.68.128 1h-2.043c-.056-.326-.085-.66-.085-1s.029-.674.085-1z" fill="#70ffb9"/><path d="m4.128 9c.205.784.645 1.478 1.238 2h-2.553c-.355-.608-.606-1.283-.728-2zm9.787 0c-.122.717-.373 1.392-.728 2h-2.553c.593-.522 1.033-1.216 1.238-2z" fill="#70deff"/><path d="m11.299 13h-6.598c.949.631 2.084 1 3.299 1s2.35-.369 3.299-1z" fill="#ff70ac"/><path d="m13.187 11c-.468.801-1.116 1.487-1.888 2h-6.598c-.772-.513-1.42-1.199-1.888-2h2.553c.706.621 1.629 1 2.634 1s1.928-.379 2.634-1z" fill="#9f70ff"/><path d="m4.701 3h6.598c-.949-.631-2.084-1-3.299-1s-2.35.369-3.299 1z" fill="#ff7070"/></g></svg> +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m11.299 3c.772.513 1.42 1.199 1.888 2h-2.553c-.706-.621-1.629-1-2.634-1s-1.928.379-2.634 1h-2.553c.468-.801 1.116-1.487 1.888-2z" fill="#ffe345"/><path d="m5.366 5c-.593.522-1.033 1.216-1.238 2h-2.043c.122-.717.373-1.392.728-2zm7.821 0c.355.608.606 1.283.728 2h-2.043c-.205-.784-.645-1.478-1.238-2z" fill="#80ff45"/><path d="m13.915 7c.056.326.085.66.085 1s-.029.674-.085 1h-2.043c.083-.32.128-.655.128-1s-.045-.68-.128-1zm-9.787 0c-.083.32-.128.655-.128 1s.045.68.128 1h-2.043c-.056-.326-.085-.66-.085-1s.029-.674.085-1z" fill="#45ffa2"/><path d="m4.128 9c.205.784.645 1.478 1.238 2h-2.553c-.355-.608-.606-1.283-.728-2zm9.787 0c-.122.717-.373 1.392-.728 2h-2.553c.593-.522 1.033-1.216 1.238-2z" fill="#45d7ff"/><path d="m11.299 13h-6.598c.949.631 2.084 1 3.299 1s2.35-.369 3.299-1z" fill="#ff4596"/><path d="m13.187 11c-.468.801-1.116 1.487-1.888 2h-6.598c-.772-.513-1.42-1.199-1.888-2h2.553c.706.621 1.629 1 2.634 1s1.928-.379 2.634-1z" fill="#8045ff"/><path d="m4.701 3h6.598c-.949-.631-2.084-1-3.299-1s-2.35.369-3.299 1z" fill="#ff4545"/></g></svg> diff --git a/editor/icons/TileMap.svg b/editor/icons/TileMap.svg index d1904338a8..291d02b858 100644 --- a/editor/icons/TileMap.svg +++ b/editor/icons/TileMap.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm-12 3v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/TouchScreenButton.svg b/editor/icons/TouchScreenButton.svg index aec0951d59..7e3e232867 100644 --- a/editor/icons/TouchScreenButton.svg +++ b/editor/icons/TouchScreenButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a1 1 0 0 0 -1 1v2a1 1 0 0 0 1 1h2v-1h-1-1v-2h8v2h-2v1h2a1 1 0 0 0 1-1v-2a1 1 0 0 0 -1-1zm4 2a1 1 0 0 0 -1 1v7 .033203l-2.4746-1.8086c-.52015-.3803-1.1948-.4556-1.6504 0-.45566.4556-.45561 1.1948 0 1.6504l4.125 4.125h6c1.1046 0 2-.8954 2-2v-5h-6v-4a1 1 0 0 0 -1-1z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a1 1 0 0 0 -1 1v2a1 1 0 0 0 1 1h2v-1h-1-1v-2h8v2h-2v1h2a1 1 0 0 0 1-1v-2a1 1 0 0 0 -1-1zm4 2a1 1 0 0 0 -1 1v7 .033203l-2.4746-1.8086c-.52015-.3803-1.1948-.4556-1.6504 0-.45566.4556-.45561 1.1948 0 1.6504l4.125 4.125h6c1.1046 0 2-.8954 2-2v-5h-6v-4a1 1 0 0 0 -1-1z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/TrackAddKey.svg b/editor/icons/TrackAddKey.svg index 5d2b4ebaf9..82eff5d2bf 100644 --- a/editor/icons/TrackAddKey.svg +++ b/editor/icons/TrackAddKey.svg @@ -1 +1 @@ -<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#84ffb1"/></svg> +<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#5fff97"/></svg> diff --git a/editor/icons/TrackAddKeyHl.svg b/editor/icons/TrackAddKeyHl.svg index 0a0cdea48c..03fb90f1e9 100644 --- a/editor/icons/TrackAddKeyHl.svg +++ b/editor/icons/TrackAddKeyHl.svg @@ -1 +1 @@ -<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#84ffb1"/><path d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fff" fill-opacity=".42424"/></svg> +<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#5fff97"/><path d="m3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fff" fill-opacity=".42424"/></svg> diff --git a/editor/icons/Transform.svg b/editor/icons/Transform.svg index 4d9bb829cd..a940120702 100644 --- a/editor/icons/Transform.svg +++ b/editor/icons/Transform.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2 2 4-2 4h2l.9082-2.1816 1.0918 2.1816h2l-2-4 2-4h-2l-.9082 2.1816-1.0918-2.1816zm6 8h2v-2h1v-2h-1v-1c.0000096-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm4-6v6h2v-2l1 1 1-1v2h2v-6h-2l-1 2-1-2z" fill="#f6a86e"/><path d="m9 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1h1v-2z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2 2 4-2 4h2l.9082-2.1816 1.0918 2.1816h2l-2-4 2-4h-2l-.9082 2.1816-1.0918-2.1816zm6 8h2v-2h1v-2h-1v-1c.0000096-.55228.44772-.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm4-6v6h2v-2l1 1 1-1v2h2v-6h-2l-1 2-1-2z" fill="#f68f45"/><path d="m9 2a3 3 0 0 0 -3 3v5h2v-2h1v-2h-1v-1a1 1 0 0 1 1-1h1v-2z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/Transform2D.svg b/editor/icons/Transform2D.svg index a0b5430298..75be0b73e1 100644 --- a/editor/icons/Transform2D.svg +++ b/editor/icons/Transform2D.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v2h2v6h2v-6h2v-2zm7 0v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.0019531v2h7a4 4 0 0 0 3.4648-2 4 4 0 0 0 0-4 4 4 0 0 0 -3.4648-2h-2v6h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm5 2a2 2 0 0 1 1.7324 1 2 2 0 0 1 0 2 2 2 0 0 1 -1.7324 1z" fill="#c4ec69"/><path d="m7 2v2c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001326-1.3751.38108-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.0019531v2h5v-2h-3c1.0716-.00015 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53582-.92807-1.526-1.4998-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v2h2v6h2v-6h2v-2zm7 0v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.0019531v2h7a4 4 0 0 0 3.4648-2 4 4 0 0 0 0-4 4 4 0 0 0 -3.4648-2h-2v6h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm5 2a2 2 0 0 1 1.7324 1 2 2 0 0 1 0 2 2 2 0 0 1 -1.7324 1z" fill="#b9ec41"/><path d="m7 2v2c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001326-1.3751.38108-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.0019531v2h5v-2h-3c1.0716-.00015 2.0618-.57193 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53582-.92807-1.526-1.4998-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/Tree.svg b/editor/icons/Tree.svg index 9476f40db3..a6c8ace55f 100644 --- a/editor/icons/Tree.svg +++ b/editor/icons/Tree.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v13c.0000552.55226.44774.99994 1 1h13v-2h-12v-6h2v3c.0000552.55226.44774.99994 1 1h9v-2h-8v-2h8v-2h-12v-2h12v-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v13c.0000552.55226.44774.99994 1 1h13v-2h-12v-6h2v3c.0000552.55226.44774.99994 1 1h9v-2h-8v-2h8v-2h-12v-2h12v-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/TubeTrailMesh.svg b/editor/icons/TubeTrailMesh.svg new file mode 100644 index 0000000000..3ca524226f --- /dev/null +++ b/editor/icons/TubeTrailMesh.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><path d="m14.0625 7.5c0-1.6377-.2123-3.12-.5969-4.2737-.1923-.57682-.4237-1.0754-.7508-1.4905-.3271-.41505-.8259-.79834-1.4648-.79834h-7.5c-.6389 0-1.1396.38329-1.4667.79834s-.5585.91366-.7507 1.4905c-.3846 1.1536-.5951 2.6359-.5951 4.2737s.2105 3.12.5951 4.2737c.1922.57682.4236 1.0754.7507 1.4905.3271.41505.8278.79834 1.4667.79834h7.5c.6389 0 1.1377-.38329 1.4648-.79834s.5585-.91366.7508-1.4905c.3846-1.1536.5969-2.6359.5969-4.2737zm-2.8125-4.6875002c.4358 1.0052002 0 0 .4358 1.0052002.2941.88221.5017 2.2134.5017 3.6823s-.2076 2.8-.5017 3.6823c-.1449.4347 0 0-.4358 1.005199l-7.5.000041c-.1212-.15705-.2929-.57092-.4376-1.0052-.2941-.88221-.4999-2.2134-.4999-3.6823s.2058-2.8.4999-3.6823c.1447-.43433.3164-.8482.4376-1.0052"/><path d="m6.5625-11.25h1.875v7.5h-1.875z" stroke-width=".25" transform="rotate(90)"/></g></svg> diff --git a/editor/icons/Tween.svg b/editor/icons/Tween.svg index d5cfbbcd88..388aaaf66a 100644 --- a/editor/icons/Tween.svg +++ b/editor/icons/Tween.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v2h6v6h2v-8zm-1 4 1.793 1.793-4.793 4.793v-4.5859h-2v8h8v-2h-4.5859l4.793-4.793 1.793 1.793v-5h-5z" fill="#cea4f1" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v2h6v6h2v-8zm-1 4 1.793 1.793-4.793 4.793v-4.5859h-2v8h8v-2h-4.5859l4.793-4.793 1.793 1.793v-5h-5z" fill="#c38ef1" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VBoxContainer.svg b/editor/icons/VBoxContainer.svg index 9a68df4f6a..c515d61d83 100644 --- a/editor/icons/VBoxContainer.svg +++ b/editor/icons/VBoxContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1039.4c0-1.1046-.89543-2-2-2h-10c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2zm-2 0v2h-10v-2zm0 4v2h-10v-2zm0 4v2h-10v-2z" fill="#a5efac" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 1039.4c0-1.1046-.89543-2-2-2h-10c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2zm-2 0v2h-10v-2zm0 4v2h-10v-2zm0 4v2h-10v-2z" fill="#8eef97" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/VScrollBar.svg b/editor/icons/VScrollBar.svg index e0fc575860..65f068f8da 100644 --- a/editor/icons/VScrollBar.svg +++ b/editor/icons/VScrollBar.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h6c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm2.9883 1a1.0001 1.0001 0 0 1 .56641.16797l3 2a1.0001 1.0001 0 1 1 -1.1094 1.6641l-2.4453-1.6289-2.4453 1.6289a1.0001 1.0001 0 1 1 -1.1094-1.6641l3-2a1.0001 1.0001 0 0 1 .54297-.16797zm-2.998 7.9922a1.0001 1.0001 0 0 1 .56445.17578l2.4453 1.6309 2.4453-1.6309a1.0001 1.0001 0 1 1 1.1094 1.6641l-3 2a1.0001 1.0001 0 0 1 -1.1094 0l-3-2a1.0001 1.0001 0 0 1 .54492-1.8398z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h6c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm2.9883 1a1.0001 1.0001 0 0 1 .56641.16797l3 2a1.0001 1.0001 0 1 1 -1.1094 1.6641l-2.4453-1.6289-2.4453 1.6289a1.0001 1.0001 0 1 1 -1.1094-1.6641l3-2a1.0001 1.0001 0 0 1 .54297-.16797zm-2.998 7.9922a1.0001 1.0001 0 0 1 .56445.17578l2.4453 1.6309 2.4453-1.6309a1.0001 1.0001 0 1 1 1.1094 1.6641l-3 2a1.0001 1.0001 0 0 1 -1.1094 0l-3-2a1.0001 1.0001 0 0 1 .54492-1.8398z" fill="#8eef97"/></svg> diff --git a/editor/icons/VSeparator.svg b/editor/icons/VSeparator.svg index 11038b7542..1fd31d89d1 100644 --- a/editor/icons/VSeparator.svg +++ b/editor/icons/VSeparator.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1047.4h3v-6h-3zm5 4h2v-14h-2zm4-4h3v-6h-3z" fill="#a5efac" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1047.4h3v-6h-3zm5 4h2v-14h-2zm4-4h3v-6h-3z" fill="#8eef97" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/icons/VSlider.svg b/editor/icons/VSlider.svg index 0ecb1e9aa3..16fafe1162 100644 --- a/editor/icons/VSlider.svg +++ b/editor/icons/VSlider.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm5 0c-.55228 0-1 .44772-1 1s.44772 1 1 1h2c.55228 0 1-.44772 1-1s-.44772-1-1-1zm-4 5.8672c-.32639.086294-.6624.13092-1 .13281-.33752-.0012549-.67352-.045224-1-.13086v5 1.1309 1c-.019125 1.3523 2.0191 1.3523 2 0v-1-1.1328-5zm5 .13281c-.55228 0-1 .44772-1 1s.44772 1 1 1 1-.44772 1-1-.44772-1-1-1zm-1 6c-.55228 0-1 .44772-1 1s.44772 1 1 1h2c.55228 0 1-.44772 1-1s-.44772-1-1-1z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm5 0c-.55228 0-1 .44772-1 1s.44772 1 1 1h2c.55228 0 1-.44772 1-1s-.44772-1-1-1zm-4 5.8672c-.32639.086294-.6624.13092-1 .13281-.33752-.0012549-.67352-.045224-1-.13086v5 1.1309 1c-.019125 1.3523 2.0191 1.3523 2 0v-1-1.1328-5zm5 .13281c-.55228 0-1 .44772-1 1s.44772 1 1 1 1-.44772 1-1-.44772-1-1-1zm-1 6c-.55228 0-1 .44772-1 1s.44772 1 1 1h2c.55228 0 1-.44772 1-1s-.44772-1-1-1z" fill="#8eef97"/></svg> diff --git a/editor/icons/VSplitContainer.svg b/editor/icons/VSplitContainer.svg index 21d45bd5e7..785b1b1880 100644 --- a/editor/icons/VSplitContainer.svg +++ b/editor/icons/VSplitContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v4h-3l-2-2-2 2h-3zm0 6h3l2 2 2-2h3v4h-10z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v4h-3l-2-2-2 2h-3zm0 6h3l2 2 2-2h3v4h-10z" fill="#8eef97"/></svg> diff --git a/editor/icons/Variant.svg b/editor/icons/Variant.svg index 71ebd060ae..dff2c67ebc 100644 --- a/editor/icons/Variant.svg +++ b/editor/icons/Variant.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm3 0v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v2h2v-8h-2v4a1 1 0 0 1 -1-1v-3h-2zm-8-1v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#69ecbd"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h2v-6zm3 0v6h2v-4a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3v2h2v-8h-2v4a1 1 0 0 1 -1-1v-3h-2zm-8-1v2a1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#41ecad"/></svg> diff --git a/editor/icons/Vector2.svg b/editor/icons/Vector2.svg index 43a93df83f..2bab922ca9 100644 --- a/editor/icons/Vector2.svg +++ b/editor/icons/Vector2.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.001953v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm-11 2v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm5 3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3z" fill="#bd91f1"/><path d="m12 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.001953v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.001953v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5zm-11 2v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm5 3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3z" fill="#ac73f1"/><path d="m12 2v2h1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 2 2 0 0 0 -1.7324 1 2 2 0 0 0 -.26562 1h-.001953v2h5v-2h-3a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -2.5977-1.5z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/Vector2i.svg b/editor/icons/Vector2i.svg index 39803fd6a4..f2923542e8 100644 --- a/editor/icons/Vector2i.svg +++ b/editor/icons/Vector2i.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.002v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53578-.92809-1.526-1.4999-2.5977-1.5zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#bd91f1"/><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.001953v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53583-.92809-1.526-1.4999-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.002v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53578-.92809-1.526-1.4999-2.5977-1.5zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#ac73f1"/><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.001953v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53583-.92809-1.526-1.4999-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg> diff --git a/editor/icons/Vector3.svg b/editor/icons/Vector3.svg index 2606f6e22b..85cac571cf 100644 --- a/editor/icons/Vector3.svg +++ b/editor/icons/Vector3.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 2v2h2a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -.36523-.50195 3 3 0 0 0 .36523-.49805 3 3 0 0 0 .39844-1.5h.003906v-2zm-11 2v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm5 3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3z" fill="#e286f0"/><path d="m12 2v2h2a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -.36523-.50195 3 3 0 0 0 .36523-.49805 3 3 0 0 0 .39844-1.5h.003906v-2z" fill="#fff" fill-opacity=".39216"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 2v2h2a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -.36523-.50195 3 3 0 0 0 .36523-.49805 3 3 0 0 0 .39844-1.5h.003906v-2zm-11 2v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm5 3a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3z" fill="#de66f0"/><path d="m12 2v2h2a1 1 0 0 1 -1 1v2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1h-1v2h1a3 3 0 0 0 2.5977-1.5 3 3 0 0 0 0-3 3 3 0 0 0 -.36523-.50195 3 3 0 0 0 .36523-.49805 3 3 0 0 0 .39844-1.5h.003906v-2z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/Vector3i.svg b/editor/icons/Vector3i.svg index 09651193a5..26e9c1b3ef 100644 --- a/editor/icons/Vector3i.svg +++ b/editor/icons/Vector3i.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.45296.92408-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#e286f0"/><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44948.95585-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.45296.92408-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#de66f0"/><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44948.95585-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#5abbef"/></svg> diff --git a/editor/icons/VehicleBody3D.svg b/editor/icons/VehicleBody3D.svg index 0cfbad371c..00e4696a17 100644 --- a/editor/icons/VehicleBody3D.svg +++ b/editor/icons/VehicleBody3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h2.1016c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h1.0508v-4h-4v-4zm1 1h4v3h-4zm-1.5 6a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5zm7 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 3a1 1 0 0 0 -1 1l-1 3h-2v4h1.0508c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h2.1016c.23167-1.1411 1.2398-2 2.4492-2s2.2175.85893 2.4492 2h1.0508v-4h-4v-4zm1 1h4v3h-4zm-1.5 6a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5zm7 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5-1.5 1.5 1.5 0 0 0 -1.5-1.5z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/VehicleWheel3D.svg b/editor/icons/VehicleWheel3D.svg index 0391eac4cf..4c825d6e34 100644 --- a/editor/icons/VehicleWheel3D.svg +++ b/editor/icons/VehicleWheel3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5zm0 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm0 2a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5zm0 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm-2 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/editor/icons/VideoPlayer.svg b/editor/icons/VideoPlayer.svg index c5433e0131..092a26b955 100644 --- a/editor/icons/VideoPlayer.svg +++ b/editor/icons/VideoPlayer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.0907 0-2 .9093-2 2v10c0 1.0907.90929 2 2 2h10c1.0907 0 2-.9093 2-2v-10c0-1.0907-.90929-2-2-2zm0 2h10v8h-10zm3 2v4l4-2z" fill="#a5efac"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.0907 0-2 .9093-2 2v10c0 1.0907.90929 2 2 2h10c1.0907 0 2-.9093 2-2v-10c0-1.0907-.90929-2-2-2zm0 2h10v8h-10zm3 2v4l4-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/VisibilityEnabler2D.svg b/editor/icons/VisibilityEnabler2D.svg index e603936d83..989675f44f 100644 --- a/editor/icons/VisibilityEnabler2D.svg +++ b/editor/icons/VisibilityEnabler2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v3h1v-2h2v-1zm11 0v1h2v2h1v-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-7 6v3h3v-1h-2v-2zm13 0v2h-2v1h3v-3z" fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v3h1v-2h2v-1zm11 0v1h2v2h1v-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-7 6v3h3v-1h-2v-2zm13 0v2h-2v1h3v-3z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VisibilityEnabler3D.svg b/editor/icons/VisibilityEnabler3D.svg index 07ba8b88df..6923bcb46b 100644 --- a/editor/icons/VisibilityEnabler3D.svg +++ b/editor/icons/VisibilityEnabler3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v3h1v-2h2v-1zm11 0v1h2v2h1v-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-7 6v3h3v-1h-2v-2zm13 0v2h-2v1h3v-3z" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v3h1v-2h2v-1zm11 0v1h2v2h1v-3zm-4 1c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246s5.8365-1.7892 6.9609-5.7246a1.0001 1.0001 0 0 0 0-.55273c-1.1003-3.7876-4.4066-5.7227-6.9609-5.7227zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4zm0 2a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-7 6v3h3v-1h-2v-2zm13 0v2h-2v1h3v-3z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VisibilityNotifier2D.svg b/editor/icons/VisibilityNotifier2D.svg index 8eaf8334ac..13df19be56 100644 --- a/editor/icons/VisibilityNotifier2D.svg +++ b/editor/icons/VisibilityNotifier2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1v6h2v-6zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-.65207 4.7109-2h-.71094-2v-.54102a4 4 0 0 1 -2 .54102 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 2 .54102v-2.1816c-.68312-.23834-1.3644-.35938-2-.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4 2v2h2v-2z" fill="#a5b7f3" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1v6h2v-6zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-.65207 4.7109-2h-.71094-2v-.54102a4 4 0 0 1 -2 .54102 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 2 .54102v-2.1816c-.68312-.23834-1.3644-.35938-2-.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4 2v2h2v-2z" fill="#8da5f3" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VisibilityNotifier3D.svg b/editor/icons/VisibilityNotifier3D.svg index afb433c9ed..2fdf784701 100644 --- a/editor/icons/VisibilityNotifier3D.svg +++ b/editor/icons/VisibilityNotifier3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1v6h2v-6zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-.65207 4.7109-2h-.71094-2v-.54102a4 4 0 0 1 -2 .54102 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 2 .54102v-2.1816c-.68312-.23834-1.3644-.35938-2-.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4 2v2h2v-2z" fill="#fc9c9c" fill-opacity=".99608" fill-rule="evenodd"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1v6h2v-6zm-4 2c-2.5567 0-5.7907 1.9477-6.9551 5.7051a1.0001 1.0001 0 0 0 -.0058594.57031c1.1244 3.9354 4.4609 5.7246 6.9609 5.7246 1.4907 0 3.2717-.65207 4.7109-2h-.71094-2v-.54102a4 4 0 0 1 -2 .54102 4 4 0 0 1 -4-4 4 4 0 0 1 4-4 4 4 0 0 1 2 .54102v-2.1816c-.68312-.23834-1.3644-.35938-2-.35938zm0 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4 2v2h2v-2z" fill="#fc7f7f" fill-opacity=".99608" fill-rule="evenodd"/></svg> diff --git a/editor/icons/VisualShader.svg b/editor/icons/VisualShader.svg index 7006066592..92b4737cbe 100644 --- a/editor/icons/VisualShader.svg +++ b/editor/icons/VisualShader.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m2.8642 9.9954v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z"/><path d="m10.864 9.9954a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z"/><path d="m2 1c-.55226.0001-.99994.4477-1 1v7h2v-6h6v3c0 .554.44599 1 1 1h3v2h2v-3l-5-5z"/></g><path d="m4 6h2v1h-2z" fill="#ffeb70"/><path d="m8 8h4v1h-4z" fill="#9dff70"/><path d="m7 6h1v1h-1z" fill="#70deff"/><path d="m4 4h3v1h-3z" fill="#ff7070"/><path d="m4 8h3v1h-3z" fill="#70ffb9"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m2.8642 9.9954v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z"/><path d="m10.864 9.9954a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z"/><path d="m2 1c-.55226.0001-.99994.4477-1 1v7h2v-6h6v3c0 .554.44599 1 1 1h3v2h2v-3l-5-5z"/></g><path d="m4 6h2v1h-2z" fill="#ffe345"/><path d="m8 8h4v1h-4z" fill="#80ff45"/><path d="m7 6h1v1h-1z" fill="#45d7ff"/><path d="m4 4h3v1h-3z" fill="#ff4545"/><path d="m4 8h3v1h-3z" fill="#45ffa2"/></svg> diff --git a/editor/icons/WorldEnvironment.svg b/editor/icons/WorldEnvironment.svg index 314639a576..d26ec52034 100644 --- a/editor/icons/WorldEnvironment.svg +++ b/editor/icons/WorldEnvironment.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-1.7305 2.3125c-.83125 1.5372-1.2685 3.1037-1.2695 4.6816-.64057-.11251-1.3005-.27158-1.9766-.47266a5 5 0 0 1 3.2461-4.209zm3.4629.0039062a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm-1.7324.0078126c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.96392.096801-1.9566.1103-2.9844.027344-.0016335-.063192-.0078125-.12632-.0078125-.18945 0-1.5333.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039zm-9.7461.033203c.68377.18153 1.3555.33345 2.0098.43164.18781 1.0551.56647 2.1026 1.125 3.1367a5 5 0 0 1 -3.1348-3.5684zm6.168.55469c-.22615.98866-.65424 1.9884-1.3008 3.0059-.63811-1.0042-1.0645-1.9908-1.293-2.9668.89027.054126 1.7517.029377 2.5938-.039062z" fill="#fc9c9c" fill-opacity=".99608"/><path d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.4894.049148-.98713.077552-1.4922.082031v1.4922c.43915-.0075968.87287-.031628 1.3008-.066406-.22615.98866-.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039z" fill="#a5b7f3"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-1.7305 2.3125c-.83125 1.5372-1.2685 3.1037-1.2695 4.6816-.64057-.11251-1.3005-.27158-1.9766-.47266a5 5 0 0 1 3.2461-4.209zm3.4629.0039062a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm-1.7324.0078126c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.96392.096801-1.9566.1103-2.9844.027344-.0016335-.063192-.0078125-.12632-.0078125-.18945 0-1.5333.48744-3.0828 1.5-4.6758zm4.8789 5.7578a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039zm-9.7461.033203c.68377.18153 1.3555.33345 2.0098.43164.18781 1.0551.56647 2.1026 1.125 3.1367a5 5 0 0 1 -3.1348-3.5684zm6.168.55469c-.22615.98866-.65424 1.9884-1.3008 3.0059-.63811-1.0042-1.0645-1.9908-1.293-2.9668.89027.054126 1.7517.029377 2.5938-.039062z" fill="#fc7f7f" fill-opacity=".99608"/><path d="m8 1v2.3242c1.0126 1.593 1.5 3.1425 1.5 4.6758 0 .054042-.0066161.10803-.0078125.16211-.4894.049148-.98713.077552-1.4922.082031v1.4922c.43915-.0075968.87287-.031628 1.3008-.066406-.22615.98866-.65424 1.9884-1.3008 3.0059v2.3242a7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm1.7324 2.3164a5 5 0 0 1 3.2383 4.1875c-.65187.17448-1.3077.32867-1.9727.44922-.00845-1.5627-.44294-3.1141-1.2656-4.6367zm3.1465 5.7656a5 5 0 0 1 -3.1484 3.6055c.57106-1.0564.95277-2.1268 1.1367-3.2051.68204-.10905 1.3556-.23789 2.0117-.40039z" fill="#8da5f3"/></g></svg> diff --git a/editor/icons/X509Certificate.svg b/editor/icons/X509Certificate.svg index b56268f281..718b0ee6a1 100644 --- a/editor/icons/X509Certificate.svg +++ b/editor/icons/X509Certificate.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 4.233 4.233" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.967.263-3.704.001v2.646h1.427a.993.993 0 0 1 -.022-.096.993.993 0 0 1 -.012-.099.993.993 0 0 1 -.002-.07.993.993 0 0 1 .005-.1.993.993 0 0 1 .014-.097.993.993 0 0 1 .025-.096.993.993 0 0 1 .034-.093.993.993 0 0 1 .043-.09.993.993 0 0 1 .052-.085.993.993 0 0 1 .06-.079.993.993 0 0 1 .068-.072.993.993 0 0 1 .074-.066.993.993 0 0 1 .08-.057.993.993 0 0 1 .087-.05.993.993 0 0 1 .09-.04.993.993 0 0 1 .095-.031.993.993 0 0 1 .096-.022.993.993 0 0 1 .099-.012.993.993 0 0 1 .07-.003.993.993 0 0 1 .099.006.993.993 0 0 1 .098.014.993.993 0 0 1 .096.025.993.993 0 0 1 .094.034.993.993 0 0 1 .089.043.993.993 0 0 1 .084.052.993.993 0 0 1 .08.06.993.993 0 0 1 .072.068.993.993 0 0 1 .065.074.993.993 0 0 1 .058.08.993.993 0 0 1 .05.087.993.993 0 0 1 .04.09.993.993 0 0 1 .031.095.993.993 0 0 1 .022.096.993.993 0 0 1 .012.099.993.993 0 0 1 .002.07.993.993 0 0 1 -.004.1.993.993 0 0 1 -.015.097.993.993 0 0 1 -.017.068h.365z" fill="#e0e0e0"/><g fill="#ff8484"><path d="m2.116 3.175v.793l.53-.253.529.253v-.793z"/><circle cx="2.646" cy="2.645" r=".794"/></g></svg> +<svg height="16" viewBox="0 0 4.233 4.233" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.967.263-3.704.001v2.646h1.427a.993.993 0 0 1 -.022-.096.993.993 0 0 1 -.012-.099.993.993 0 0 1 -.002-.07.993.993 0 0 1 .005-.1.993.993 0 0 1 .014-.097.993.993 0 0 1 .025-.096.993.993 0 0 1 .034-.093.993.993 0 0 1 .043-.09.993.993 0 0 1 .052-.085.993.993 0 0 1 .06-.079.993.993 0 0 1 .068-.072.993.993 0 0 1 .074-.066.993.993 0 0 1 .08-.057.993.993 0 0 1 .087-.05.993.993 0 0 1 .09-.04.993.993 0 0 1 .095-.031.993.993 0 0 1 .096-.022.993.993 0 0 1 .099-.012.993.993 0 0 1 .07-.003.993.993 0 0 1 .099.006.993.993 0 0 1 .098.014.993.993 0 0 1 .096.025.993.993 0 0 1 .094.034.993.993 0 0 1 .089.043.993.993 0 0 1 .084.052.993.993 0 0 1 .08.06.993.993 0 0 1 .072.068.993.993 0 0 1 .065.074.993.993 0 0 1 .058.08.993.993 0 0 1 .05.087.993.993 0 0 1 .04.09.993.993 0 0 1 .031.095.993.993 0 0 1 .022.096.993.993 0 0 1 .012.099.993.993 0 0 1 .002.07.993.993 0 0 1 -.004.1.993.993 0 0 1 -.015.097.993.993 0 0 1 -.017.068h.365z" fill="#e0e0e0"/><g fill="#ff5f5f"><path d="m2.116 3.175v.793l.53-.253.529.253v-.793z"/><circle cx="2.646" cy="2.645" r=".794"/></g></svg> diff --git a/editor/icons/XRAnchor3D.svg b/editor/icons/XRAnchor3D.svg index 0f6282a085..2d8e543f85 100644 --- a/editor/icons/XRAnchor3D.svg +++ b/editor/icons/XRAnchor3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v2h-2v2h2v3.2656l-2.5527-1.2773c-.15005-.075253-.31662-.11152-.48438-.10547-.36536.013648-.69415.2256-.85742.55273-.24709.49403-.046823 1.0948.44727 1.3418l4.4473 2.2227 4.4473-2.2227c.49409-.24697.69435-.84777.44726-1.3418-.24697-.49409-.84777-.69435-1.3418-.44727l-2.5527 1.2773v-3.2656h2v-2h-2v-2zm-3 11v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v4h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v2h-2v2h2v3.2656l-2.5527-1.2773c-.15005-.075253-.31662-.11152-.48438-.10547-.36536.013648-.69415.2256-.85742.55273-.24709.49403-.046823 1.0948.44727 1.3418l4.4473 2.2227 4.4473-2.2227c.49409-.24697.69435-.84777.44726-1.3418-.24697-.49409-.84777-.69435-1.3418-.44727l-2.5527 1.2773v-3.2656h2v-2h-2v-2zm-3 11v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v4h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/XRCamera3D.svg b/editor/icons/XRCamera3D.svg index 9f9072fc1e..b4657c9f2c 100644 --- a/editor/icons/XRCamera3D.svg +++ b/editor/icons/XRCamera3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9.5 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117-.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3zm-5.5 12v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9.5 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117-.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 .554.44599 1 1 1h6c.55401 0 1-.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1-2.2305 3 3 0 0 0 -3-3zm-5.5 12v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/XRController3D.svg b/editor/icons/XRController3D.svg index 9296b11c8e..cfde6691df 100644 --- a/editor/icons/XRController3D.svg +++ b/editor/icons/XRController3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.554 0-1 .446-1 1v6c0 .554.446 1 1 1h12c.554 0 1-.446 1-1v-6c0-.554-.446-1-1-1zm2 1h2v2h2v2h-2v2h-2v-2h-2v-2h2zm9 1c.55228 0 1 .44772 1 1s-.44772 1-1 1-1-.44772-1-1 .44772-1 1-1zm-2 2c.55228 0 1 .44772 1 1s-.44772 1-1 1-1-.44772-1-1 .44772-1 1-1zm-7 7v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.554 0-1 .446-1 1v6c0 .554.446 1 1 1h12c.554 0 1-.446 1-1v-6c0-.554-.446-1-1-1zm2 1h2v2h2v2h-2v2h-2v-2h-2v-2h2zm9 1c.55228 0 1 .44772 1 1s-.44772 1-1 1-1-.44772-1-1 .44772-1 1-1zm-2 2c.55228 0 1 .44772 1 1s-.44772 1-1 1-1-.44772-1-1 .44772-1 1-1zm-7 7v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/XROrigin3D.svg b/editor/icons/XROrigin3D.svg index dda24e7530..03d6e67500 100644 --- a/editor/icons/XROrigin3D.svg +++ b/editor/icons/XROrigin3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-4 4v2h3v-2zm5 0c-.55228 0-1 .44772-1 1s.44772 1 1 1 1-.44772 1-1-.44772-1-1-1zm2 0v2h3v-2zm-3 3v3h2v-3zm-3 4v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-4 4v2h3v-2zm5 0c-.55228 0-1 .44772-1 1s.44772 1 1 1 1-.44772 1-1-.44772-1-1-1zm2 0v2h3v-2zm-3 3v3h2v-3zm-3 4v1c0 .55228.44772 1 1 1-.55228 0-1 .44772-1 1v1h1v-1h1v1h1v-1c0-.55228-.44772-1-1-1 .55228 0 1-.44772 1-1v-1h-1v1h-1v-1zm5 0v1 3h1v-1h1v1h1v-1c-.000834-.17579-.047991-.34825-.13672-.5.088728-.15175.13588-.32421.13672-.5v-1c0-.55228-.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/YSort.svg b/editor/icons/YSort.svg index 40367bd2b2..31e5d9a67e 100644 --- a/editor/icons/YSort.svg +++ b/editor/icons/YSort.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1-3 3h2v8h-2l3 3 3-3h-2v-8h2zm5 1v2h6v-2zm0 5v2h4v-2zm0 5v2h2v-2z" fill="#a5b7f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1-3 3h2v8h-2l3 3 3-3h-2v-8h2zm5 1v2h6v-2zm0 5v2h4v-2zm0 5v2h2v-2z" fill="#8da5f3" fill-opacity=".98824"/></svg> diff --git a/editor/icons/bool.svg b/editor/icons/bool.svg index e6e32001ef..674cbc9e6c 100644 --- a/editor/icons/bool.svg +++ b/editor/icons/bool.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2a3 3 0 0 0 2.5-1.3457 3 3 0 0 0 2.5 1.3457 3 3 0 0 0 2-.76758 3 3 0 0 0 2 .76758 3 3 0 0 0 2.5-1.3457 3 3 0 0 0 2.5 1.3457v-2a1 1 0 0 1 -1-1v-5h-2v2.7695a3 3 0 0 0 -2-.76953 3 3 0 0 0 -2 .76758 3 3 0 0 0 -2-.76758 3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5-1.3457v-2zm2 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#8da6f0"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 2v8h2a3 3 0 0 0 2.5-1.3457 3 3 0 0 0 2.5 1.3457 3 3 0 0 0 2-.76758 3 3 0 0 0 2 .76758 3 3 0 0 0 2.5-1.3457 3 3 0 0 0 2.5 1.3457v-2a1 1 0 0 1 -1-1v-5h-2v2.7695a3 3 0 0 0 -2-.76953 3 3 0 0 0 -2 .76758 3 3 0 0 0 -2-.76758 3 3 0 0 0 -2.5 1.3457 3 3 0 0 0 -2.5-1.3457v-2zm2 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" fill="#6f91f0"/></svg> diff --git a/editor/icons/float.svg b/editor/icons/float.svg index 1e931ad930..b941332e6c 100644 --- a/editor/icons/float.svg +++ b/editor/icons/float.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2a3 3 0 0 0 -3 3v5h2v-2h2v-2h-2v-1a1 1 0 0 1 1-1h1v-2zm3 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-5zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2z" fill="#61daf4"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 2a3 3 0 0 0 -3 3v5h2v-2h2v-2h-2v-1a1 1 0 0 1 1-1h1v-2zm3 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-5zm6 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2z" fill="#35d4f4"/></svg> diff --git a/editor/icons/int.svg b/editor/icons/int.svg index f8c88300f7..b943822c23 100644 --- a/editor/icons/int.svg +++ b/editor/icons/int.svg @@ -1 +1 @@ -<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 2v2h2v-2zm11 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm-8 2v6h2v-4h1a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3h-1zm-3 2v4h2v-4z" fill="#7dc6ef"/></svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 2v2h2v-2zm11 0v5a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1v-1h2v-2h-2v-2zm-8 2v6h2v-4h1a1 1 0 0 1 1 1v3h2v-3a3 3 0 0 0 -3-3h-1zm-3 2v4h2v-4z" fill="#5abbef"/></svg> diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp index 26c6a8462b..c5b2a8dc3a 100644 --- a/editor/import/resource_importer_image.cpp +++ b/editor/import/resource_importer_image.cpp @@ -75,7 +75,7 @@ Error ResourceImporterImage::import(const String &p_source_file, const String &p ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open file from path '" + p_source_file + "'."); - size_t len = f->get_len(); + uint64_t len = f->get_length(); Vector<uint8_t> data; data.resize(len); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 48340ac242..488c124c28 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -339,7 +339,7 @@ void SceneImportSettings::_update_scene() { material_tree->clear(); mesh_tree->clear(); - //hiden roots + //hidden roots material_tree->create_item(); mesh_tree->create_item(); diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index bc7e8a1626..fa1a027a8d 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -30,6 +30,7 @@ #include "scene_importer_mesh.h" +#include "core/math/math_defs.h" #include "scene/resources/surface_tool.h" void EditorSceneImporterMesh::add_blend_shape(const String &p_name) { @@ -141,6 +142,18 @@ void EditorSceneImporterMesh::set_surface_material(int p_surface, const Ref<Mate surfaces.write[p_surface].material = p_material; } +Basis EditorSceneImporterMesh::compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 p_y_raw) { + Vector3 x = p_x_raw.normalized(); + Vector3 z = x.cross(p_y_raw); + z = z.normalized(); + Vector3 y = z.cross(x); + Basis basis; + basis.set_axis(Vector3::AXIS_X, x); + basis.set_axis(Vector3::AXIS_Y, y); + basis.set_axis(Vector3::AXIS_Z, z); + return basis; +} + void EditorSceneImporterMesh::generate_lods() { if (!SurfaceTool::simplify_func) { return; @@ -151,6 +164,9 @@ void EditorSceneImporterMesh::generate_lods() { if (!SurfaceTool::simplify_sloppy_func) { return; } + if (!SurfaceTool::simplify_with_attrib_func) { + return; + } for (int i = 0; i < surfaces.size(); i++) { if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) { @@ -163,59 +179,62 @@ void EditorSceneImporterMesh::generate_lods() { if (indices.size() == 0) { continue; //no lods if no indices } + Vector<Vector3> normals = surfaces[i].arrays[RS::ARRAY_NORMAL]; uint32_t vertex_count = vertices.size(); const Vector3 *vertices_ptr = vertices.ptr(); - - int min_indices = 10; - int index_target = indices.size() / 2; - print_line("Total indices: " + itos(indices.size())); - float mesh_scale = SurfaceTool::simplify_scale_func((const float *)vertices_ptr, vertex_count, sizeof(Vector3)); - const float target_error = 1e-3f; - float abs_target_error = target_error / mesh_scale; + Vector<float> attributes; + Vector<float> normal_weights; + int32_t attribute_count = 6; + if (normals.size()) { + attributes.resize(normals.size() * attribute_count); + for (int32_t normal_i = 0; normal_i < normals.size(); normal_i++) { + Basis basis; + basis.set_euler(normals[normal_i]); + Vector3 basis_x = basis.get_axis(0); + Vector3 basis_y = basis.get_axis(1); + basis = compute_rotation_matrix_from_ortho_6d(basis_x, basis_y); + basis_x = basis.get_axis(0); + basis_y = basis.get_axis(1); + attributes.write[normal_i * attribute_count + 0] = basis_x.x; + attributes.write[normal_i * attribute_count + 1] = basis_x.y; + attributes.write[normal_i * attribute_count + 2] = basis_x.z; + attributes.write[normal_i * attribute_count + 3] = basis_y.x; + attributes.write[normal_i * attribute_count + 4] = basis_y.y; + attributes.write[normal_i * attribute_count + 5] = basis_y.z; + } + normal_weights.resize(vertex_count); + for (int32_t weight_i = 0; weight_i < normal_weights.size(); weight_i++) { + normal_weights.write[weight_i] = 1.0; + } + } else { + attribute_count = 0; + } + const int min_indices = 10; + const float error_tolerance = 1.44224'95703; // Cube root of 3 + const float threshold = 1.0 / error_tolerance; + int index_target = indices.size() * threshold; + float max_mesh_error_percentage = 1e0f; + float mesh_error = 0.0f; while (index_target > min_indices) { - float error; Vector<int> new_indices; new_indices.resize(indices.size()); - size_t new_len = SurfaceTool::simplify_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, abs_target_error, &error); - if ((int)new_len > (index_target * 120 / 100)) { - // Attribute discontinuities break normals. - bool is_sloppy = false; - if (is_sloppy) { - abs_target_error = target_error / mesh_scale; - index_target = new_len; - while (index_target > min_indices) { - Vector<int> sloppy_new_indices; - sloppy_new_indices.resize(indices.size()); - new_len = SurfaceTool::simplify_sloppy_func((unsigned int *)sloppy_new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, abs_target_error, &error); - if ((int)new_len > (index_target * 120 / 100)) { - break; // 20 percent tolerance - } - sloppy_new_indices.resize(new_len); - Surface::LOD lod; - lod.distance = error * mesh_scale; - abs_target_error = lod.distance; - if (Math::is_equal_approx(abs_target_error, 0.0f)) { - return; - } - lod.indices = sloppy_new_indices; - print_line("Lod " + itos(surfaces.write[i].lods.size()) + " shoot for " + itos(index_target / 3) + " triangles, got " + itos(new_len / 3) + " triangles. Distance " + rtos(lod.distance) + ". Use simplify sloppy."); - surfaces.write[i].lods.push_back(lod); - index_target /= 2; - } - } - break; // 20 percent tolerance + size_t new_len = SurfaceTool::simplify_with_attrib_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, max_mesh_error_percentage, &mesh_error, (float *)attributes.ptrw(), normal_weights.ptrw(), attribute_count); + if ((int)new_len > (index_target * error_tolerance)) { + break; } - new_indices.resize(new_len); Surface::LOD lod; - lod.distance = error * mesh_scale; - abs_target_error = lod.distance; - if (Math::is_equal_approx(abs_target_error, 0.0f)) { - return; + lod.distance = mesh_error; + if (Math::is_equal_approx(mesh_error, 0.0f)) { + break; + } + if (new_len <= 0) { + break; } + new_indices.resize(new_len); lod.indices = new_indices; - print_line("Lod " + itos(surfaces.write[i].lods.size()) + " shoot for " + itos(index_target / 3) + " triangles, got " + itos(new_len / 3) + " triangles. Distance " + rtos(lod.distance)); + print_line("Lod " + itos(surfaces.write[i].lods.size()) + " begin with " + itos(indices.size() / 3) + " triangles and shoot for " + itos(index_target / 3) + " triangles. Got " + itos(new_len / 3) + " triangles. Lod screen ratio " + rtos(lod.distance)); surfaces.write[i].lods.push_back(lod); - index_target /= 2; + index_target *= threshold; } } } diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h index b3e8137e0a..c00339a620 100644 --- a/editor/import/scene_importer_mesh.h +++ b/editor/import/scene_importer_mesh.h @@ -67,6 +67,7 @@ class EditorSceneImporterMesh : public Resource { Ref<EditorSceneImporterMesh> shadow_mesh; Size2i lightmap_size_hint; + Basis compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 y_raw); protected: void _set_data(const Dictionary &p_data); diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index afafd7d195..cc261ea868 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -30,9 +30,9 @@ #include "node_3d_editor_gizmos.h" +#include "core/math/convex_hull.h" #include "core/math/geometry_2d.h" #include "core/math/geometry_3d.h" -#include "core/math/quick_hull.h" #include "scene/3d/audio_stream_player_3d.h" #include "scene/3d/baked_lightmap.h" #include "scene/3d/collision_polygon_3d.h" @@ -4161,7 +4161,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (points.size() > 3) { Vector<Vector3> varr = Variant(points); Geometry3D::MeshData md; - Error err = QuickHull::build(varr, md); + Error err = ConvexHullComputer::convex_hull(varr, md); if (err == OK) { Vector<Vector3> points2; points2.resize(md.edges.size() * 2); diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp index f496811e0a..7dda61f0bf 100644 --- a/editor/plugin_config_dialog.cpp +++ b/editor/plugin_config_dialog.cpp @@ -214,6 +214,7 @@ PluginConfigDialog::PluginConfigDialog() { desc_edit = memnew(TextEdit); desc_edit->set_custom_minimum_size(Size2(400, 80) * EDSCALE); + desc_edit->set_wrap_enabled(true); grid->add_child(desc_edit); Label *author_lb = memnew(Label); diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 80d0a7db60..e6f7ec1fbf 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -266,7 +266,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) { if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { - if (mb->get_control() || mb->get_shift() || mb->get_alt()) { + if (mb->is_ctrl_pressed() || mb->is_shift_pressed() || mb->is_alt_pressed()) { return false; } @@ -399,7 +399,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint))); //Move the point in a single axis. Should only work when editing a polygon and while holding shift. - if (mode == MODE_EDIT && mm->get_shift()) { + if (mode == MODE_EDIT && mm->is_shift_pressed()) { Vector2 old_point = pre_move_edit.get(selected_point.vertex); if (ABS(cpoint.x - old_point.x) > ABS(cpoint.y - old_point.y)) { cpoint.y = old_point.y; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 612a8f30a4..bd88d96a66 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -994,7 +994,7 @@ void AnimationPlayerEditor::_animation_duplicate() { } } -void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) { +void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set, bool p_timeline_only) { if (updating || !player || player->is_playing()) { return; }; @@ -1015,18 +1015,18 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) { pos = Math::snapped(pos, _get_editor_step()); } - if (player->is_valid() && !p_set) { - float cpos = player->get_current_animation_position(); + if (!p_timeline_only) { + if (player->is_valid() && !p_set) { + float cpos = player->get_current_animation_position(); - player->seek_delta(pos, pos - cpos); - } else { - player->stop(true); - player->seek(pos, true); + player->seek_delta(pos, pos - cpos); + } else { + player->stop(true); + player->seek(pos, true); + } } track_editor->set_anim_pos(pos); - - updating = true; }; void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { @@ -1048,7 +1048,7 @@ void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) frame->set_max(p_len); } -void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) { +void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag, bool p_timeline_only) { timeline_position = p_pos; if (!is_visible_in_tree()) { @@ -1070,7 +1070,7 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) updating = true; frame->set_value(Math::snapped(p_pos, _get_editor_step())); updating = false; - _seek_value_changed(p_pos, !p_drag); + _seek_value_changed(p_pos, !p_drag, p_timeline_only); } void AnimationPlayerEditor::_animation_tool_menu(int p_option) { @@ -1222,10 +1222,10 @@ void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { ERR_FAIL_COND(p_ev.is_null()); Ref<InputEventKey> k = p_ev; - if (is_visible_in_tree() && k.is_valid() && k->is_pressed() && !k->is_echo() && !k->get_alt() && !k->get_control() && !k->get_metakey()) { + if (is_visible_in_tree() && k.is_valid() && k->is_pressed() && !k->is_echo() && !k->is_alt_pressed() && !k->is_ctrl_pressed() && !k->is_meta_pressed()) { switch (k->get_keycode()) { case KEY_A: { - if (!k->get_shift()) { + if (!k->is_shift_pressed()) { _play_bw_from_pressed(); } else { _play_bw_pressed(); @@ -1237,7 +1237,7 @@ void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { accept_event(); } break; case KEY_D: { - if (!k->get_shift()) { + if (!k->is_shift_pressed()) { _play_from_pressed(); } else { _play_pressed(); @@ -1693,7 +1693,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay animation->connect("item_selected", callable_mp(this, &AnimationPlayerEditor::_animation_selected)); file->connect("file_selected", callable_mp(this, &AnimationPlayerEditor::_dialog_action)); - frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true)); + frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true, false)); scale->connect("text_entered", callable_mp(this, &AnimationPlayerEditor::_scale_changed)); renaming = false; diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index 2f6bf55e4c..5c2348f86b 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -187,7 +187,7 @@ class AnimationPlayerEditor : public VBoxContainer { void _scale_changed(const String &p_scale); void _dialog_action(String p_file); void _seek_frame_changed(const String &p_frame); - void _seek_value_changed(float p_value, bool p_set = false); + void _seek_value_changed(float p_value, bool p_set = false, bool p_timeline_only = false); void _blend_editor_next_changed(const int p_idx); void _list_changed(); @@ -197,7 +197,7 @@ class AnimationPlayerEditor : public VBoxContainer { void _animation_player_changed(Object *p_pl); - void _animation_key_editor_seek(float p_pos, bool p_drag); + void _animation_key_editor_seek(float p_pos, bool p_drag, bool p_timeline_only = false); void _animation_key_editor_anim_len_changed(float p_len); void _unhandled_key_input(const Ref<InputEvent> &p_ev); diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index a9709bbb16..c915276d3a 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -124,7 +124,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } // select node or push a field inside - if (mb.is_valid() && !mb->get_shift() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (mb.is_valid() && !mb->is_shift_pressed() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { selected_transition_from = StringName(); selected_transition_to = StringName(); selected_node = StringName(); @@ -237,7 +237,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv } //connect nodes - if (mb.is_valid() && ((tool_select->is_pressed() && mb->get_shift()) || tool_connect->is_pressed()) && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) { + if (mb.is_valid() && ((tool_select->is_pressed() && mb->is_shift_pressed()) || tool_connect->is_pressed()) && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) { for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected connecting = true; diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index a0d9afee74..93bb170128 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -464,7 +464,7 @@ void EditorAssetLibraryItemDownload::_make_request() { retry->hide(); download->cancel_request(); - download->set_download_file(EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); + download->set_download_file(EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); Error err = download->request(host); if (err != OK) { @@ -702,7 +702,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PackedB PackedByteArray image_data = p_data; if (use_cache) { - String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); + String cache_filename_base = EditorPaths::get_singleton()->get_cache_dir().plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); FileAccess *file = FileAccess::open(cache_filename_base + ".data", FileAccess::READ); @@ -781,7 +781,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons if (p_code != HTTPClient::RESPONSE_NOT_MODIFIED) { for (int i = 0; i < headers.size(); i++) { if (headers[i].findn("ETag:") == 0) { // Save etag - String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); + String cache_filename_base = EditorPaths::get_singleton()->get_cache_dir().plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); String new_etag = headers[i].substr(headers[i].find(":") + 1, headers[i].length()).strip_edges(); FileAccess *file; @@ -829,7 +829,7 @@ void EditorAssetLibrary::_update_image_queue() { List<int> to_delete; for (Map<int, ImageQueue>::Element *E = image_queue.front(); E; E = E->next()) { if (!E->get().active && current_images < max_images) { - String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + E->get().image_url.md5_text()); + String cache_filename_base = EditorPaths::get_singleton()->get_cache_dir().plus_file("assetimage_" + E->get().image_url.md5_text()); Vector<String> headers; if (FileAccess::exists(cache_filename_base + ".etag") && FileAccess::exists(cache_filename_base + ".data")) { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 91022ccb2c..2be586733b 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -332,7 +332,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; - bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CTRL); // Smart snap using the canvas position Vector2 output = p_target; @@ -460,7 +460,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig } float CanvasItemEditor::snap_angle(float p_target, float p_start) const { - if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) { + if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CTRL)) && snap_rotation_step != 0) { if (snap_relative) { return Math::snapped(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step); } else { @@ -481,11 +481,11 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { } if (k.is_valid()) { - if (k->get_keycode() == KEY_CONTROL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT) { + if (k->get_keycode() == KEY_CTRL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT) { viewport->update(); } - if (k->is_pressed() && !k->get_control() && !k->is_echo()) { + if (k->is_pressed() && !k->is_ctrl_pressed() && !k->is_echo()) { if ((grid_snap_active || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) { // Multiply the grid size grid_step_multiplier = MIN(grid_step_multiplier + 1, 12); @@ -1269,12 +1269,12 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bool p_already_accepted) { Ref<InputEventMouseButton> b = p_event; if (b.is_valid() && !p_already_accepted) { - const bool pan_on_scroll = bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan")) && !b->get_control(); + const bool pan_on_scroll = bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan")) && !b->is_ctrl_pressed(); if (pan_on_scroll) { // Perform horizontal scrolling first so we can check for Shift being held. if (b->is_pressed() && - (b->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT || (b->get_shift() && b->get_button_index() == MOUSE_BUTTON_WHEEL_UP))) { + (b->get_button_index() == MOUSE_BUTTON_WHEEL_LEFT || (b->is_shift_pressed() && b->get_button_index() == MOUSE_BUTTON_WHEEL_UP))) { // Pan left view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); update_viewport(); @@ -1282,7 +1282,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo } if (b->is_pressed() && - (b->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT || (b->get_shift() && b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN))) { + (b->get_button_index() == MOUSE_BUTTON_WHEEL_RIGHT || (b->is_shift_pressed() && b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN))) { // Pan right view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); update_viewport(); @@ -1389,7 +1389,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid() && !p_already_accepted) { // If control key pressed, then zoom instead of pan - if (pan_gesture->get_control()) { + if (pan_gesture->is_ctrl_pressed()) { const float factor = pan_gesture->get_delta().y; zoom_widget->set_zoom_by_increments(1); @@ -1574,7 +1574,7 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { // Start rotation if (drag_type == DRAG_NONE) { if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed()) { - if ((b->get_command() && !b->get_alt() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) { + if ((b->is_command_pressed() && !b->is_alt_pressed() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) { List<CanvasItem *> selection = _get_edited_canvas_items(); // Remove not movable nodes @@ -1740,7 +1740,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER, control)); new_anchor = _position_to_anchor(control, new_anchor).snapped(Vector2(0.001, 0.001)); - bool use_single_axis = m->get_shift(); + bool use_single_axis = m->is_shift_pressed(); Vector2 drag_vector = xform.xform(drag_to) - xform.xform(drag_from); bool use_y = Math::abs(drag_vector.y) > Math::abs(drag_vector.x); @@ -1888,8 +1888,8 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { //Reset state canvas_item->_edit_set_state(se->undo_state); - bool uniform = m->get_shift(); - bool symmetric = m->get_alt(); + bool uniform = m->is_shift_pressed(); + bool symmetric = m->is_alt_pressed(); Rect2 local_rect = canvas_item->_edit_get_rect(); float aspect = local_rect.get_size().y / local_rect.get_size().x; @@ -2028,7 +2028,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { // Drag resize handles if (drag_type == DRAG_NONE) { - if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && ((b->get_alt() && b->get_control()) || tool == TOOL_SCALE)) { + if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed() && ((b->is_alt_pressed() && b->is_ctrl_pressed()) || tool == TOOL_SCALE)) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { CanvasItem *canvas_item = selection[0]; @@ -2074,8 +2074,8 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { Transform2D unscaled_transform = (transform * parent_xform * canvas_item->_edit_get_transform()).orthonormalized(); Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform; - bool uniform = m->get_shift(); - bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool uniform = m->is_shift_pressed(); + bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CTRL); Point2 drag_from_local = simple_xform.xform(drag_from); Point2 drag_to_local = simple_xform.xform(drag_to); @@ -2167,7 +2167,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_NONE) { //Start moving the nodes if (b.is_valid() && b->get_button_index() == MOUSE_BUTTON_LEFT && b->is_pressed()) { - if ((b->get_alt() && !b->get_control()) || tool == TOOL_MOVE) { + if ((b->is_alt_pressed() && !b->is_ctrl_pressed()) || tool == TOOL_MOVE) { List<CanvasItem *> selection = _get_edited_canvas_items(); drag_selection.clear(); @@ -2235,7 +2235,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { new_pos.x = previous_pos.x; } - bool single_axis = m->get_shift(); + bool single_axis = m->is_shift_pressed(); if (single_axis) { if (ABS(new_pos.x - previous_pos.x) > ABS(new_pos.y - previous_pos.y)) { new_pos.y = previous_pos.y; @@ -2244,7 +2244,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } } - bool force_no_IK = m->get_alt(); + bool force_no_IK = m->is_alt_pressed(); int index = 0; for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); @@ -2335,8 +2335,8 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { _restore_canvas_item_state(drag_selection, true); - bool move_local_base = k->get_alt(); - bool move_local_base_rotated = k->get_control() || k->get_metakey(); + bool move_local_base = k->is_alt_pressed(); + bool move_local_base_rotated = k->is_ctrl_pressed() || k->is_meta_pressed(); Vector2 dir; if (k->get_keycode() == KEY_UP) { @@ -2348,12 +2348,12 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } else if (k->get_keycode() == KEY_RIGHT) { dir += Vector2(1, 0); } - if (k->get_shift()) { + if (k->is_shift_pressed()) { dir *= grid_step * Math::pow(2.0, grid_step_multiplier); } drag_to += dir; - if (k->get_shift()) { + if (k->is_shift_pressed()) { drag_to = drag_to.snapped(grid_step * Math::pow(2.0, grid_step_multiplier)); } @@ -2442,18 +2442,18 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_NONE) { if (b.is_valid() && - ((b->get_button_index() == MOUSE_BUTTON_RIGHT && b->get_alt() && tool == TOOL_SELECT) || + ((b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_alt_pressed() && tool == TOOL_SELECT) || (b->get_button_index() == MOUSE_BUTTON_LEFT && tool == TOOL_LIST_SELECT))) { // Popup the selection menu list Point2 click = transform.affine_inverse().xform(b->get_position()); - _get_canvas_items_at_pos(click, selection_results, b->get_alt() && tool != TOOL_LIST_SELECT); + _get_canvas_items_at_pos(click, selection_results, b->is_alt_pressed() && tool != TOOL_LIST_SELECT); if (selection_results.size() == 1) { CanvasItem *item = selection_results[0].item; selection_results.clear(); - _select_click_on_item(item, click, b->get_shift()); + _select_click_on_item(item, click, b->is_shift_pressed()); return true; } else if (!selection_results.is_empty()) { @@ -2497,14 +2497,14 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { selection_menu->set_item_tooltip(i, String(item->get_name()) + "\nType: " + item->get_class() + "\nPath: " + node_path); } - selection_menu_additive_selection = b->get_shift(); + selection_menu_additive_selection = b->is_shift_pressed(); selection_menu->set_position(get_screen_transform().xform(b->get_position())); selection_menu->popup(); return true; } } - if (b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->get_control()) { + if (b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT && b->is_ctrl_pressed()) { add_node_menu->set_position(get_global_transform().xform(get_local_mouse_position())); add_node_menu->set_size(Vector2(1, 1)); add_node_menu->popup(); @@ -2540,7 +2540,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (!canvas_item) { // Start a box selection - if (!b->get_shift()) { + if (!b->is_shift_pressed()) { // Clear the selection if not additive editor_selection->clear(); viewport->update(); @@ -2552,7 +2552,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { box_selecting_to = drag_from; return true; } else { - bool still_selected = _select_click_on_item(canvas_item, click, b->get_shift()); + bool still_selected = _select_click_on_item(canvas_item, click, b->is_shift_pressed()); // Start dragging if (still_selected) { // Drag the node(s) if requested @@ -3574,7 +3574,7 @@ void CanvasItemEditor::_draw_selection() { } // Draw the move handles - bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CTRL); bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT); if (tool == TOOL_MOVE && show_transformation_gizmos) { if (_is_node_movable(canvas_item)) { @@ -4380,7 +4380,7 @@ void CanvasItemEditor::_update_scrollbars() { // Calculate scrollable area. Rect2 canvas_item_rect = Rect2(Point2(), screen_rect); - if (editor->get_edited_scene()) { + if (editor->is_inside_tree() && editor->get_edited_scene()) { Rect2 content_rect = _get_encompassing_rect(editor->get_edited_scene()); canvas_item_rect.expand_to(content_rect.position); canvas_item_rect.expand_to(content_rect.position + content_rect.size); @@ -5361,8 +5361,10 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_queue_update_bone_list", &CanvasItemEditor::_update_bone_list); ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list); ClassDB::bind_method("_reset_create_position", &CanvasItemEditor::_reset_create_position); + ClassDB::bind_method(D_METHOD("get_state"), &CanvasItemEditor::get_state); ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state); ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport); + ClassDB::bind_method(D_METHOD("_zoom_on_position"), &CanvasItemEditor::_zoom_on_position); ADD_SIGNAL(MethodInfo("item_lock_status_changed")); ADD_SIGNAL(MethodInfo("item_group_status_changed")); diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp index b50a497ccf..252e5c68a0 100644 --- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp @@ -175,7 +175,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con case MODE_EDIT: { if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { - if (mb->get_control()) { + if (mb->is_ctrl_pressed()) { if (poly.size() < 3) { undo_redo->create_action(TTR("Edit Poly")); undo_redo->add_undo_method(node, "set_polygon", poly); @@ -317,7 +317,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con Vector2 cpoint(spoint.x, spoint.y); - if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CTRL)) { snap_ignore = false; } diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index db999f50ab..7a38fd2bd5 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -168,8 +168,8 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { // Snap to "round" coordinates when holding Ctrl. // Be more precise when holding Shift as well. float snap_threshold; - if (mm.get_control()) { - snap_threshold = mm.get_shift() ? 0.025 : 0.1; + if (mm.is_ctrl_pressed()) { + snap_threshold = mm.is_shift_pressed() ? 0.025 : 0.1; } else { snap_threshold = 0.0; } diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 18cc5d43fb..2d79e4f3e3 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -265,7 +265,7 @@ Ref<Texture2D> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const } Ref<Texture2D> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { - String temp_path = EditorSettings::get_singleton()->get_cache_dir(); + String temp_path = EditorPaths::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 81f1852fba..ba39ce3aed 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -85,10 +85,10 @@ void ViewportRotationControl::_notification(int p_what) { axis_menu_options.clear(); axis_menu_options.push_back(Node3DEditorViewport::VIEW_RIGHT); axis_menu_options.push_back(Node3DEditorViewport::VIEW_TOP); - axis_menu_options.push_back(Node3DEditorViewport::VIEW_FRONT); + axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR); axis_menu_options.push_back(Node3DEditorViewport::VIEW_LEFT); axis_menu_options.push_back(Node3DEditorViewport::VIEW_BOTTOM); - axis_menu_options.push_back(Node3DEditorViewport::VIEW_REAR); + axis_menu_options.push_back(Node3DEditorViewport::VIEW_FRONT); axis_colors.clear(); axis_colors.push_back(get_theme_color("axis_x_color", "Editor")); @@ -309,7 +309,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) { bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4); manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT); manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT); - manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_CTRL); float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia); float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia); @@ -794,22 +794,22 @@ static int _get_key_modifier_setting(const String &p_property) { case 3: return KEY_META; case 4: - return KEY_CONTROL; + return KEY_CTRL; } return 0; } static int _get_key_modifier(Ref<InputEventWithModifiers> e) { - if (e->get_shift()) { + if (e->is_shift_pressed()) { return KEY_SHIFT; } - if (e->get_alt()) { + if (e->is_alt_pressed()) { return KEY_ALT; } - if (e->get_control()) { - return KEY_CONTROL; + if (e->is_ctrl_pressed()) { + return KEY_CTRL; } - if (e->get_metakey()) { + if (e->is_meta_pressed()) { return KEY_META; } return 0; @@ -1024,7 +1024,7 @@ bool Node3DEditorViewport ::_is_node_locked(const Node *p_node) { } void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { - _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift()); + _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->is_shift_pressed()); Node *scene = editor->get_edited_scene(); @@ -1037,7 +1037,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { } } - clicked_wants_append = b->get_shift(); + clicked_wants_append = b->is_shift_pressed(); if (selection_results.size() == 1) { clicked = selection_results[0].item->get_instance_id(); @@ -1149,7 +1149,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } if (_edit.mode == TRANSFORM_NONE && b->is_pressed()) { - if (b->get_alt()) { + if (b->is_alt_pressed()) { if (nav_scheme == NAVIGATION_MAYA) { break; } @@ -1234,7 +1234,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { case MOUSE_BUTTON_LEFT: { if (b->is_pressed()) { NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); - if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) { + if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->is_alt_pressed()) { break; } @@ -1262,7 +1262,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { int handle = -1; Vector3 point; Vector3 normal; - bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, b->get_shift()); + bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, b->is_shift_pressed()); if (inters && handle != -1) { _edit.gizmo = seg; _edit.gizmo_handle = handle; @@ -1279,7 +1279,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { clicked = ObjectID(); clicked_includes_current = false; - if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->get_command()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) { + if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->is_command_pressed()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) { /* HANDLE ROTATION */ if (get_selected_count() == 0) { break; //bye @@ -1314,11 +1314,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { int gizmo_handle = -1; - clicked = _select_ray(b->get_position(), b->get_shift(), clicked_includes_current, &gizmo_handle, b->get_shift()); + clicked = _select_ray(b->get_position(), b->is_shift_pressed(), clicked_includes_current, &gizmo_handle, b->is_shift_pressed()); //clicking is always deferred to either move or release - clicked_wants_append = b->get_shift(); + clicked_wants_append = b->is_shift_pressed(); if (clicked.is_null()) { if (!clicked_wants_append) { @@ -1441,13 +1441,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { set_message(n + ": " + String(v)); } else if (m->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { - if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) { + if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) { nav_mode = NAVIGATION_ORBIT; - } else if (nav_scheme == NAVIGATION_MODO && m->get_alt() && m->get_shift()) { + } else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed() && m->is_shift_pressed()) { nav_mode = NAVIGATION_PAN; - } else if (nav_scheme == NAVIGATION_MODO && m->get_alt() && m->get_control()) { + } else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed() && m->is_ctrl_pressed()) { nav_mode = NAVIGATION_ZOOM; - } else if (nav_scheme == NAVIGATION_MODO && m->get_alt()) { + } else if (nav_scheme == NAVIGATION_MODO && m->is_alt_pressed()) { nav_mode = NAVIGATION_ORBIT; } else { if (clicked.is_valid()) { @@ -1831,7 +1831,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } } else if ((m->get_button_mask() & MOUSE_BUTTON_MASK_RIGHT) || freelook_active) { - if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) { + if (nav_scheme == NAVIGATION_MAYA && m->is_alt_pressed()) { nav_mode = NAVIGATION_ZOOM; } else if (freelook_active) { nav_mode = NAVIGATION_LOOK; @@ -1924,7 +1924,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } else if (nav_scheme == NAVIGATION_MAYA) { - if (pan_gesture->get_alt()) { + if (pan_gesture->is_alt_pressed()) { nav_mode = NAVIGATION_PAN; } } @@ -2053,7 +2053,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const real_t pan_speed = 1 / 150.0; int pan_speed_modifier = 10; - if (nav_scheme == NAVIGATION_MAYA && p_event->get_shift()) { + if (nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) { pan_speed *= pan_speed_modifier; } @@ -2078,7 +2078,7 @@ void Node3DEditorViewport::_nav_zoom(Ref<InputEventWithModifiers> p_event, const real_t zoom_speed = 1 / 80.0; int zoom_speed_modifier = 10; - if (nav_scheme == NAVIGATION_MAYA && p_event->get_shift()) { + if (nav_scheme == NAVIGATION_MAYA && p_event->is_shift_pressed()) { zoom_speed *= zoom_speed_modifier; } @@ -6204,7 +6204,7 @@ void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) { return; } - snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CTRL); } void Node3DEditor::_sun_environ_settings_pressed() { diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index 84b4516452..208abeb87f 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -89,7 +89,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { // Check for point movement start (for point + in/out controls). if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { - if (mode == MODE_EDIT && !mb->get_shift() && dist_to_p < grab_threshold) { + if (mode == MODE_EDIT && !mb->is_shift_pressed() && dist_to_p < grab_threshold) { // Points can only be moved in edit mode. action = ACTION_MOVING_POINT; @@ -149,7 +149,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } // Check for point creation. - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && ((mb->is_command_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) { Ref<Curve2D> curve = node->get_curve(); undo_redo->create_action(TTR("Add Point to Curve")); diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 47bd1114d2..8c73294723 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -316,7 +316,7 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref set_handle_clicked(false); } - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->get_control()))) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->is_ctrl_pressed()))) { //click into curve, break it down Vector<Vector3> v3a = c->tessellate(); int idx = 0; diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 470d897dcc..6d82685c05 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -613,11 +613,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } if (uv_move_current == UV_MODE_EDIT_POINT) { - if (mb->get_shift() && mb->get_command()) { + if (mb->is_shift_pressed() && mb->is_command_pressed()) { uv_move_current = UV_MODE_SCALE; - } else if (mb->get_shift()) { + } else if (mb->is_shift_pressed()) { uv_move_current = UV_MODE_MOVE; - } else if (mb->get_command()) { + } else if (mb->is_command_pressed()) { uv_move_current = UV_MODE_ROTATE; } } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 8c4c5a3461..623e4ea66e 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -218,6 +218,8 @@ Ref<EditorSyntaxHighlighter> EditorPlainTextSyntaxHighlighter::_create() const { /*** SCRIPT EDITOR ****/ void ScriptEditorBase::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_base_editor"), &ScriptEditorBase::get_base_editor); + ADD_SIGNAL(MethodInfo("name_changed")); ADD_SIGNAL(MethodInfo("edited_script_changed")); ADD_SIGNAL(MethodInfo("request_help", PropertyInfo(Variant::STRING, "topic"))); @@ -337,13 +339,13 @@ void ScriptEditorQuickOpen::_update_search() { if ((search_box->get_text() == "" || file.findn(search_box->get_text()) != -1)) { TreeItem *ti = search_options->create_item(root); ti->set_text(0, file); - if (root->get_children() == ti) { + if (root->get_first_child() == ti) { ti->select(0); } } } - get_ok_button()->set_disabled(root->get_children() == nullptr); + get_ok_button()->set_disabled(root->get_first_child() == nullptr); } void ScriptEditorQuickOpen::_confirmed() { @@ -1501,6 +1503,11 @@ void ScriptEditor::_notification(int p_what) { filename->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("normal", "LineEdit")); recent_scripts->set_as_minsize(); + + if (is_inside_tree()) { + _update_script_colors(); + _update_script_names(); + } } break; case NOTIFICATION_READY: { @@ -1675,7 +1682,7 @@ struct _ScriptEditorItemData { if (sort_key == id.sort_key) { return index < id.index; } else { - return sort_key < id.sort_key; + return sort_key.naturalnocasecmp_to(id.sort_key) < 0; } } else { return category < id.category; @@ -2279,8 +2286,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra void ScriptEditor::save_current_script() { ScriptEditorBase *current = _get_current_editor(); - - if (_test_script_times_on_disk()) { + if (!current || _test_script_times_on_disk()) { return; } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 570ebfba4e..9ae63b7c4f 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -163,6 +163,8 @@ public: virtual Control *get_edit_menu() = 0; virtual void clear_edit_menu() = 0; + virtual Control *get_base_editor() const = 0; + virtual void validate() = 0; ScriptEditorBase() {} diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index c982207224..fe5d830239 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -170,66 +170,25 @@ void ScriptTextEditor::_load_theme_settings() { CodeEdit *text_edit = code_editor->get_text_editor(); text_edit->clear_keywords(); + Color updated_marked_line_color = EDITOR_GET("text_editor/highlighting/mark_color"); Color updated_safe_line_number_color = EDITOR_GET("text_editor/highlighting/safe_line_number_color"); - if (updated_safe_line_number_color != safe_line_number_color) { + + bool safe_line_number_color_updated = updated_safe_line_number_color != safe_line_number_color; + bool marked_line_color_updated = updated_marked_line_color != marked_line_color; + if (safe_line_number_color_updated || marked_line_color_updated) { safe_line_number_color = updated_safe_line_number_color; for (int i = 0; i < text_edit->get_line_count(); i++) { - if (text_edit->get_line_gutter_item_color(i, line_number_gutter) != default_line_number_color) { + if (marked_line_color_updated && text_edit->get_line_background_color(i) == marked_line_color) { + text_edit->set_line_background_color(i, updated_marked_line_color); + } + + if (safe_line_number_color_updated && text_edit->get_line_gutter_item_color(i, line_number_gutter) != default_line_number_color) { text_edit->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); } } + marked_line_color = updated_marked_line_color; } - Color background_color = EDITOR_GET("text_editor/highlighting/background_color"); - Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color"); - Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color"); - Color completion_existing_color = EDITOR_GET("text_editor/highlighting/completion_existing_color"); - Color completion_scroll_color = EDITOR_GET("text_editor/highlighting/completion_scroll_color"); - Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color"); - Color text_color = EDITOR_GET("text_editor/highlighting/text_color"); - Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color"); - Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color"); - Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color"); - Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color"); - Color selection_color = EDITOR_GET("text_editor/highlighting/selection_color"); - Color brace_mismatch_color = EDITOR_GET("text_editor/highlighting/brace_mismatch_color"); - Color current_line_color = EDITOR_GET("text_editor/highlighting/current_line_color"); - Color line_length_guideline_color = EDITOR_GET("text_editor/highlighting/line_length_guideline_color"); - Color word_highlighted_color = EDITOR_GET("text_editor/highlighting/word_highlighted_color"); - Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); - Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); - Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); - Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); - Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); - Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color"); - Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color"); - - text_edit->add_theme_color_override("background_color", background_color); - text_edit->add_theme_color_override("completion_background_color", completion_background_color); - text_edit->add_theme_color_override("completion_selected_color", completion_selected_color); - text_edit->add_theme_color_override("completion_existing_color", completion_existing_color); - text_edit->add_theme_color_override("completion_scroll_color", completion_scroll_color); - text_edit->add_theme_color_override("completion_font_color", completion_font_color); - text_edit->add_theme_color_override("font_color", text_color); - text_edit->add_theme_color_override("line_number_color", line_number_color); - text_edit->add_theme_color_override("caret_color", caret_color); - text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_selected_color", text_selected_color); - text_edit->add_theme_color_override("selection_color", selection_color); - text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); - text_edit->add_theme_color_override("current_line_color", current_line_color); - text_edit->add_theme_color_override("line_length_guideline_color", line_length_guideline_color); - text_edit->add_theme_color_override("word_highlighted_color", word_highlighted_color); - text_edit->add_theme_color_override("bookmark_color", bookmark_color); - text_edit->add_theme_color_override("breakpoint_color", breakpoint_color); - text_edit->add_theme_color_override("executing_line_color", executing_line_color); - text_edit->add_theme_color_override("mark_color", mark_color); - text_edit->add_theme_color_override("code_folding_color", code_folding_color); - text_edit->add_theme_color_override("search_result_color", search_result_color); - text_edit->add_theme_color_override("search_result_border_color", search_result_border_color); - - text_edit->add_theme_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6)); - theme_loaded = true; if (!script.is_null()) { _set_theme_for_script(); @@ -292,7 +251,7 @@ void ScriptTextEditor::_show_warnings_panel(bool p_show) { void ScriptTextEditor::_warning_clicked(Variant p_line) { if (p_line.get_type() == Variant::INT) { - code_editor->get_text_editor()->cursor_set_line(p_line.operator int64_t()); + goto_line_centered(p_line.operator int64_t()); } else if (p_line.get_type() == Variant::DICTIONARY) { Dictionary meta = p_line.operator Dictionary(); code_editor->get_text_editor()->insert_at("# warning-ignore:" + meta["code"].operator String(), meta["line"].operator int64_t() - 1); @@ -546,7 +505,7 @@ void ScriptTextEditor::_validate_script() { bool highlight_safe = EDITOR_DEF("text_editor/highlighting/highlight_type_safe_lines", true); bool last_is_safe = false; for (int i = 0; i < te->get_line_count(); i++) { - te->set_line_as_marked(i, line == i); + te->set_line_background_color(i, (line == i) ? marked_line_color : Color(0, 0, 0, 0)); if (highlight_safe) { if (safe_lines.has(i + 1)) { te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); @@ -1402,6 +1361,10 @@ void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) void ScriptTextEditor::set_debugger_active(bool p_active) { } +Control *ScriptTextEditor::get_base_editor() const { + return code_editor->get_text_editor(); +} + Variant ScriptTextEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { return Variant(); } @@ -1466,11 +1429,17 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data Array files = d["files"]; String text_to_drop; + bool preload = Input::get_singleton()->is_key_pressed(KEY_CTRL); for (int i = 0; i < files.size(); i++) { if (i > 0) { - text_to_drop += ","; + text_to_drop += ", "; + } + + if (preload) { + text_to_drop += "preload(\"" + String(files[i]).c_escape() + "\")"; + } else { + text_to_drop += "\"" + String(files[i]).c_escape() + "\""; } - text_to_drop += "\"" + String(files[i]).c_escape() + "\""; } te->cursor_set_line(row); @@ -1933,7 +1902,7 @@ void ScriptTextEditor::register_editor() { #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); #else - ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D); + ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_D); #endif ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E); ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 17abfcf4cc..f784bbe1f8 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -89,6 +89,8 @@ class ScriptTextEditor : public ScriptEditorBase { Color default_line_number_color = Color(1, 1, 1); Color safe_line_number_color = Color(1, 1, 1); + Color marked_line_color = Color(1, 1, 1); + PopupPanel *color_panel = nullptr; ColorPicker *color_picker = nullptr; Vector2 color_position; @@ -233,6 +235,8 @@ public: virtual void clear_edit_menu() override; static void register_editor(); + virtual Control *get_base_editor() const override; + virtual void validate() override; ScriptTextEditor(); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 3cdba9cf16..a210a46127 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -37,12 +37,18 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/project_settings_editor.h" #include "editor/property_editor.h" #include "servers/display_server.h" #include "servers/rendering/shader_types.h" /*** SHADER SCRIPT EDITOR ****/ +static bool saved_warnings_enabled = false; +static bool saved_treat_warning_as_errors = false; +static Map<ShaderWarning::Code, bool> saved_warnings; +static uint32_t saved_warning_flags = 0U; + Ref<Shader> ShaderTextEditor::get_edited_shader() const { return shader; } @@ -57,6 +63,8 @@ void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) { get_text_editor()->set_text(p_shader->get_code()); get_text_editor()->clear_undo_history(); + get_text_editor()->call_deferred("set_h_scroll", 0); + get_text_editor()->call_deferred("set_v_scroll", 0); _validate_script(); _line_col_changed(); @@ -82,54 +90,21 @@ void ShaderTextEditor::reload_text() { update_line_and_column(); } +void ShaderTextEditor::set_warnings_panel(RichTextLabel *p_warnings_panel) { + warnings_panel = p_warnings_panel; +} + void ShaderTextEditor::_load_theme_settings() { - Color background_color = EDITOR_GET("text_editor/highlighting/background_color"); - Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color"); - Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color"); - Color completion_existing_color = EDITOR_GET("text_editor/highlighting/completion_existing_color"); - Color completion_scroll_color = EDITOR_GET("text_editor/highlighting/completion_scroll_color"); - Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color"); - Color text_color = EDITOR_GET("text_editor/highlighting/text_color"); - Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color"); - Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color"); - Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color"); - Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color"); - Color selection_color = EDITOR_GET("text_editor/highlighting/selection_color"); - Color brace_mismatch_color = EDITOR_GET("text_editor/highlighting/brace_mismatch_color"); - Color current_line_color = EDITOR_GET("text_editor/highlighting/current_line_color"); - Color line_length_guideline_color = EDITOR_GET("text_editor/highlighting/line_length_guideline_color"); - Color word_highlighted_color = EDITOR_GET("text_editor/highlighting/word_highlighted_color"); - Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); - Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); - Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); - Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); - Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); - Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color"); - Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color"); - - get_text_editor()->add_theme_color_override("background_color", background_color); - get_text_editor()->add_theme_color_override("completion_background_color", completion_background_color); - get_text_editor()->add_theme_color_override("completion_selected_color", completion_selected_color); - get_text_editor()->add_theme_color_override("completion_existing_color", completion_existing_color); - get_text_editor()->add_theme_color_override("completion_scroll_color", completion_scroll_color); - get_text_editor()->add_theme_color_override("completion_font_color", completion_font_color); - get_text_editor()->add_theme_color_override("font_color", text_color); - get_text_editor()->add_theme_color_override("line_number_color", line_number_color); - get_text_editor()->add_theme_color_override("caret_color", caret_color); - get_text_editor()->add_theme_color_override("caret_background_color", caret_background_color); - get_text_editor()->add_theme_color_override("font_selected_color", text_selected_color); - get_text_editor()->add_theme_color_override("selection_color", selection_color); - get_text_editor()->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); - get_text_editor()->add_theme_color_override("current_line_color", current_line_color); - get_text_editor()->add_theme_color_override("line_length_guideline_color", line_length_guideline_color); - get_text_editor()->add_theme_color_override("word_highlighted_color", word_highlighted_color); - get_text_editor()->add_theme_color_override("mark_color", mark_color); - get_text_editor()->add_theme_color_override("bookmark_color", bookmark_color); - get_text_editor()->add_theme_color_override("breakpoint_color", breakpoint_color); - get_text_editor()->add_theme_color_override("executing_line_color", executing_line_color); - get_text_editor()->add_theme_color_override("code_folding_color", code_folding_color); - get_text_editor()->add_theme_color_override("search_result_color", search_result_color); - get_text_editor()->add_theme_color_override("search_result_border_color", search_result_border_color); + CodeEdit *text_editor = get_text_editor(); + Color updated_marked_line_color = EDITOR_GET("text_editor/highlighting/mark_color"); + if (updated_marked_line_color != marked_line_color) { + for (int i = 0; i < text_editor->get_line_count(); i++) { + if (text_editor->get_line_background_color(i) == marked_line_color) { + text_editor->set_line_background_color(i, updated_marked_line_color); + } + } + marked_line_color = updated_marked_line_color; + } syntax_highlighter->set_number_color(EDITOR_GET("text_editor/highlighting/number_color")); syntax_highlighter->set_symbol_color(EDITOR_GET("text_editor/highlighting/symbol_color")); @@ -178,6 +153,12 @@ void ShaderTextEditor::_load_theme_settings() { syntax_highlighter->clear_color_regions(); syntax_highlighter->add_color_region("/*", "*/", comment_color, false); syntax_highlighter->add_color_region("//", "", comment_color, true); + + if (warnings_panel) { + // Warnings panel + warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts")); + warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts")); + } } void ShaderTextEditor::_check_shader_mode() { @@ -224,6 +205,9 @@ void ShaderTextEditor::_validate_script() { ShaderLanguage sl; + sl.enable_warning_checking(saved_warnings_enabled); + sl.set_warning_flags(saved_warning_flags); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); if (err != OK) { @@ -231,20 +215,70 @@ void ShaderTextEditor::_validate_script() { set_error(error_text); set_error_pos(sl.get_error_line() - 1, 0); for (int i = 0; i < get_text_editor()->get_line_count(); i++) { - get_text_editor()->set_line_as_marked(i, false); + get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); } - get_text_editor()->set_line_as_marked(sl.get_error_line() - 1, true); - + get_text_editor()->set_line_background_color(sl.get_error_line() - 1, marked_line_color); } else { for (int i = 0; i < get_text_editor()->get_line_count(); i++) { - get_text_editor()->set_line_as_marked(i, false); + get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); } set_error(""); } + if (warnings.size() > 0 || err != OK) { + warnings_panel->clear(); + } + warnings.clear(); + for (List<ShaderWarning>::Element *E = sl.get_warnings_ptr(); E; E = E->next()) { + warnings.push_back(E->get()); + } + if (warnings.size() > 0 && err == OK) { + warnings.sort_custom<WarningsComparator>(); + _update_warning_panel(); + } else { + set_warning_nb(0); + } emit_signal("script_changed"); } +void ShaderTextEditor::_update_warning_panel() { + int warning_count = 0; + + warnings_panel->push_table(2); + for (int i = 0; i < warnings.size(); i++) { + ShaderWarning &w = warnings[i]; + + if (warning_count == 0) { + if (saved_treat_warning_as_errors) { + String error_text = "error(" + itos(w.get_line()) + "): " + w.get_message() + " " + TTR("Warnings should be fixed to prevent errors."); + set_error_pos(w.get_line() - 1, 0); + set_error(error_text); + get_text_editor()->set_line_background_color(w.get_line() - 1, marked_line_color); + } + } + + warning_count++; + + // First cell. + warnings_panel->push_cell(); + warnings_panel->push_meta(w.get_line() - 1); + warnings_panel->push_color(warnings_panel->get_theme_color("warning_color", "Editor")); + warnings_panel->add_text(TTR("Line") + " " + itos(w.get_line())); + warnings_panel->add_text(" (" + w.get_name() + "):"); + warnings_panel->pop(); // Color. + warnings_panel->pop(); // Meta goto. + warnings_panel->pop(); // Cell. + + // Second cell. + warnings_panel->push_cell(); + warnings_panel->add_text(w.get_message()); + warnings_panel->pop(); // Cell. + } + warnings_panel->pop(); // Table. + + set_warning_nb(warning_count); +} + void ShaderTextEditor::_bind_methods() { } @@ -358,10 +392,6 @@ void ShaderEditor::_notification(int p_what) { } } -void ShaderEditor::_params_changed() { - shader_editor->_validate_script(); -} - void ShaderEditor::_editor_settings_changed() { shader_editor->update_editor_settings(); @@ -370,8 +400,19 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_editor()->set_draw_executing_lines_gutter(false); } +void ShaderEditor::_show_warnings_panel(bool p_show) { + warnings_panel->set_visible(p_show); +} + +void ShaderEditor::_warning_clicked(Variant p_line) { + if (p_line.get_type() == Variant::INT) { + shader_editor->get_text_editor()->cursor_set_line(p_line.operator int64_t()); + } +} + void ShaderEditor::_bind_methods() { - ClassDB::bind_method("_params_changed", &ShaderEditor::_params_changed); + ClassDB::bind_method("_show_warnings_panel", &ShaderEditor::_show_warnings_panel); + ClassDB::bind_method("_warning_clicked", &ShaderEditor::_warning_clicked); } void ShaderEditor::ensure_select_current() { @@ -389,6 +430,47 @@ void ShaderEditor::goto_line_selection(int p_line, int p_begin, int p_end) { shader_editor->goto_line_selection(p_line, p_begin, p_end); } +void ShaderEditor::_project_settings_changed() { + _update_warnings(true); +} + +void ShaderEditor::_update_warnings(bool p_validate) { + bool changed = false; + + bool warnings_enabled = GLOBAL_GET("debug/shader_language/warnings/enable").booleanize(); + if (warnings_enabled != saved_warnings_enabled) { + saved_warnings_enabled = warnings_enabled; + changed = true; + } + + bool treat_warning_as_errors = GLOBAL_GET("debug/shader_language/warnings/treat_warnings_as_errors").booleanize(); + if (treat_warning_as_errors != saved_treat_warning_as_errors) { + saved_treat_warning_as_errors = treat_warning_as_errors; + changed = true; + } + + bool update_flags = false; + + for (int i = 0; i < ShaderWarning::WARNING_MAX; i++) { + ShaderWarning::Code code = (ShaderWarning::Code)i; + bool value = GLOBAL_GET("debug/shader_language/warnings/" + ShaderWarning::get_name_from_code(code).to_lower()); + + if (saved_warnings[code] != value) { + saved_warnings[code] = value; + update_flags = true; + changed = true; + } + } + + if (update_flags) { + saved_warning_flags = (uint32_t)ShaderWarning::get_flags_from_codemap(saved_warnings); + } + + if (p_validate && changed && shader_editor && shader_editor->get_edited_shader().is_valid()) { + shader_editor->validate_script(); + } +} + void ShaderEditor::_check_for_external_edit() { if (shader.is_null() || !shader.is_valid()) { return; @@ -560,13 +642,22 @@ void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) { } ShaderEditor::ShaderEditor(EditorNode *p_node) { + GLOBAL_DEF("debug/shader_language/warnings/enable", true); + GLOBAL_DEF("debug/shader_language/warnings/treat_warnings_as_errors", false); + for (int i = 0; i < (int)ShaderWarning::WARNING_MAX; i++) { + GLOBAL_DEF("debug/shader_language/warnings/" + ShaderWarning::get_name_from_code((ShaderWarning::Code)i).to_lower(), true); + } + _update_warnings(false); + shader_editor = memnew(ShaderTextEditor); shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); shader_editor->add_theme_constant_override("separation", 0); shader_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE); + shader_editor->connect("show_warnings_panel", callable_mp(this, &ShaderEditor::_show_warnings_panel)); shader_editor->connect("script_changed", callable_mp(this, &ShaderEditor::apply_shaders)); EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ShaderEditor::_editor_settings_changed)); + ProjectSettingsEditor::get_singleton()->connect("confirmed", callable_mp(this, &ShaderEditor::_project_settings_changed)); shader_editor->get_text_editor()->set_callhint_settings( EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"), @@ -651,7 +742,23 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) { hbc->add_child(goto_menu); hbc->add_child(help_menu); hbc->add_theme_style_override("panel", p_node->get_gui_base()->get_theme_stylebox("ScriptEditorPanel", "EditorStyles")); - main_container->add_child(shader_editor); + + VSplitContainer *editor_box = memnew(VSplitContainer); + main_container->add_child(editor_box); + editor_box->set_anchors_and_offsets_preset(Control::PRESET_WIDE); + editor_box->set_v_size_flags(SIZE_EXPAND_FILL); + editor_box->add_child(shader_editor); + + warnings_panel = memnew(RichTextLabel); + warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); + warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL); + warnings_panel->set_meta_underline(true); + warnings_panel->set_selection_enabled(true); + warnings_panel->set_focus_mode(FOCUS_CLICK); + warnings_panel->hide(); + warnings_panel->connect("meta_clicked", callable_mp(this, &ShaderEditor::_warning_clicked)); + editor_box->add_child(warnings_panel); + shader_editor->set_warnings_panel(warnings_panel); goto_line_dialog = memnew(GotoLineDialog); add_child(goto_line_dialog); diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 731c0a5b7e..d7da73f2ae 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -35,6 +35,7 @@ #include "editor/editor_plugin.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel_container.h" +#include "scene/gui/rich_text_label.h" #include "scene/gui/tab_container.h" #include "scene/gui/text_edit.h" #include "scene/main/timer.h" @@ -44,10 +45,19 @@ class ShaderTextEditor : public CodeTextEditor { GDCLASS(ShaderTextEditor, CodeTextEditor); + Color marked_line_color = Color(1, 1, 1); + + struct WarningsComparator { + _ALWAYS_INLINE_ bool operator()(const ShaderWarning &p_a, const ShaderWarning &p_b) const { return (p_a.get_line() < p_b.get_line()); } + }; + Ref<CodeHighlighter> syntax_highlighter; + RichTextLabel *warnings_panel = nullptr; Ref<Shader> shader; + List<ShaderWarning> warnings; void _check_shader_mode(); + void _update_warning_panel(); protected: static void _bind_methods(); @@ -59,6 +69,7 @@ public: virtual void _validate_script() override; void reload_text(); + void set_warnings_panel(RichTextLabel *p_warnings_panel); Ref<Shader> get_edited_shader() const; void set_edited_shader(const Ref<Shader> &p_shader); @@ -100,6 +111,7 @@ class ShaderEditor : public PanelContainer { PopupMenu *bookmarks_menu; MenuButton *help_menu; PopupMenu *context_menu; + RichTextLabel *warnings_panel = nullptr; uint64_t idle; GotoLineDialog *goto_line_dialog; @@ -109,13 +121,16 @@ class ShaderEditor : public PanelContainer { ShaderTextEditor *shader_editor; void _menu_option(int p_option); - void _params_changed(); mutable Ref<Shader> shader; void _editor_settings_changed(); + void _project_settings_changed(); void _check_for_external_edit(); void _reload_shader_from_disk(); + void _show_warnings_panel(bool p_show); + void _warning_clicked(Variant p_line); + void _update_warnings(bool p_validate); protected: void _notification(int p_what); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index bd6dac7490..59bc8f9e55 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -115,7 +115,7 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { int idx = h * y + x; - if (mb->get_shift() && last_frame_selected >= 0) { + if (mb->is_shift_pressed() && last_frame_selected >= 0) { //select multiple int from = idx; int to = last_frame_selected; @@ -124,7 +124,7 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { } for (int i = from; i <= to; i++) { - if (mb->get_control()) { + if (mb->is_ctrl_pressed()) { frames_selected.erase(i); } else { frames_selected.insert(i); @@ -150,11 +150,11 @@ void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) { // Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer // to allow performing this action anywhere, even if the cursor isn't // hovering the texture in the workspace. - if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->is_ctrl_pressed()) { _sheet_zoom_in(); // Don't scroll up after zooming in. accept_event(); - } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->is_ctrl_pressed()) { _sheet_zoom_out(); // Don't scroll down after zooming out. accept_event(); @@ -220,7 +220,7 @@ void SpriteFramesEditor::_sheet_zoom_out() { void SpriteFramesEditor::_sheet_zoom_reset() { // Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad. - sheet_zoom = MAX(1.0, EDSCALE); + sheet_zoom = MAX(1.0f, EDSCALE); Size2 texture_size = split_sheet_preview->get_texture()->get_size(); split_sheet_preview->set_custom_minimum_size(texture_size * sheet_zoom); } @@ -252,10 +252,10 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) { EditorNode::get_singleton()->show_warning(TTR("Unable to load images")); ERR_FAIL_COND(!texture.is_valid()); } - bool new_texture = texture != split_sheet_preview->get_texture(); frames_selected.clear(); last_frame_selected = -1; + bool new_texture = texture != split_sheet_preview->get_texture(); split_sheet_preview->set_texture(texture); if (new_texture) { //different texture, reset to 4x4 @@ -280,17 +280,17 @@ void SpriteFramesEditor::_notification(int p_what) { move_down->set_icon(get_theme_icon("MoveRight", "EditorIcons")); _delete->set_icon(get_theme_icon("Remove", "EditorIcons")); zoom_out->set_icon(get_theme_icon("ZoomLess", "EditorIcons")); - zoom_1->set_icon(get_theme_icon("ZoomReset", "EditorIcons")); + zoom_reset->set_icon(get_theme_icon("ZoomReset", "EditorIcons")); zoom_in->set_icon(get_theme_icon("ZoomMore", "EditorIcons")); new_anim->set_icon(get_theme_icon("New", "EditorIcons")); remove_anim->set_icon(get_theme_icon("Remove", "EditorIcons")); split_sheet_zoom_out->set_icon(get_theme_icon("ZoomLess", "EditorIcons")); - split_sheet_zoom_1->set_icon(get_theme_icon("ZoomReset", "EditorIcons")); + split_sheet_zoom_reset->set_icon(get_theme_icon("ZoomReset", "EditorIcons")); split_sheet_zoom_in->set_icon(get_theme_icon("ZoomMore", "EditorIcons")); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { - splite_sheet_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); + split_sheet_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree")); } break; case NOTIFICATION_READY: { add_theme_constant_override("autohide", 1); // Fixes the dragger always showing up. @@ -513,7 +513,7 @@ void SpriteFramesEditor::_animation_select() { if (frames->has_animation(edited_anim)) { double value = anim_speed->get_line_edit()->get_text().to_float(); - if (!Math::is_equal_approx(value, frames->get_animation_speed(edited_anim))) { + if (!Math::is_equal_approx(value, (double)frames->get_animation_speed(edited_anim))) { _animation_fps_changed(value); } } @@ -694,11 +694,11 @@ void SpriteFramesEditor::_tree_input(const Ref<InputEvent> &p_event) { const Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed() && mb->is_ctrl_pressed()) { _zoom_in(); // Don't scroll up after zooming in. accept_event(); - } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->is_ctrl_pressed()) { _zoom_out(); // Don't scroll down after zooming out. accept_event(); @@ -733,7 +733,7 @@ void SpriteFramesEditor::_zoom_out() { } void SpriteFramesEditor::_zoom_reset() { - thumbnail_zoom = MAX(1.0, EDSCALE); + thumbnail_zoom = MAX(1.0f, EDSCALE); tree->set_fixed_column_width(thumbnail_default_size * 3 / 2); tree->set_fixed_icon_size(Size2(thumbnail_default_size, thumbnail_default_size)); } @@ -954,7 +954,7 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da if (String(d["type"]) == "files") { Vector<String> files = d["files"]; - if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CTRL)) { _prepare_sprite_sheet(files[0]); } else { _file_load_request(files, at_pos); @@ -1086,11 +1086,13 @@ SpriteFramesEditor::SpriteFramesEditor() { zoom_out->set_flat(true); zoom_out->set_tooltip(TTR("Zoom Out")); hbc->add_child(zoom_out); - zoom_1 = memnew(Button); - zoom_1->connect("pressed", callable_mp(this, &SpriteFramesEditor::_zoom_reset)); - zoom_1->set_flat(true); - zoom_1->set_tooltip(TTR("Zoom Reset")); - hbc->add_child(zoom_1); + + zoom_reset = memnew(Button); + zoom_reset->connect("pressed", callable_mp(this, &SpriteFramesEditor::_zoom_reset)); + zoom_reset->set_flat(true); + zoom_reset->set_tooltip(TTR("Zoom Reset")); + hbc->add_child(zoom_reset); + zoom_in = memnew(Button); zoom_in->connect("pressed", callable_mp(this, &SpriteFramesEditor::_zoom_in)); zoom_in->set_flat(true); @@ -1183,16 +1185,16 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_preview->connect("draw", callable_mp(this, &SpriteFramesEditor::_sheet_preview_draw)); split_sheet_preview->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_preview_input)); - splite_sheet_scroll = memnew(ScrollContainer); - splite_sheet_scroll->set_enable_h_scroll(true); - splite_sheet_scroll->set_enable_v_scroll(true); - splite_sheet_scroll->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_scroll_input)); - split_sheet_panel->add_child(splite_sheet_scroll); + split_sheet_scroll = memnew(ScrollContainer); + split_sheet_scroll->set_enable_h_scroll(true); + split_sheet_scroll->set_enable_v_scroll(true); + split_sheet_scroll->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_scroll_input)); + split_sheet_panel->add_child(split_sheet_scroll); CenterContainer *cc = memnew(CenterContainer); cc->add_child(split_sheet_preview); cc->set_h_size_flags(SIZE_EXPAND_FILL); cc->set_v_size_flags(SIZE_EXPAND_FILL); - splite_sheet_scroll->add_child(cc); + split_sheet_scroll->add_child(cc); MarginContainer *split_sheet_zoom_margin = memnew(MarginContainer); split_sheet_panel->add_child(split_sheet_zoom_margin); @@ -1209,12 +1211,14 @@ SpriteFramesEditor::SpriteFramesEditor() { split_sheet_zoom_out->set_tooltip(TTR("Zoom Out")); split_sheet_zoom_out->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_out)); split_sheet_zoom_hb->add_child(split_sheet_zoom_out); - split_sheet_zoom_1 = memnew(Button); - split_sheet_zoom_1->set_flat(true); - split_sheet_zoom_1->set_focus_mode(FOCUS_NONE); - split_sheet_zoom_1->set_tooltip(TTR("Zoom Reset")); - split_sheet_zoom_1->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_reset)); - split_sheet_zoom_hb->add_child(split_sheet_zoom_1); + + split_sheet_zoom_reset = memnew(Button); + split_sheet_zoom_reset->set_flat(true); + split_sheet_zoom_reset->set_focus_mode(FOCUS_NONE); + split_sheet_zoom_reset->set_tooltip(TTR("Zoom Reset")); + split_sheet_zoom_reset->connect("pressed", callable_mp(this, &SpriteFramesEditor::_sheet_zoom_reset)); + split_sheet_zoom_hb->add_child(split_sheet_zoom_reset); + split_sheet_zoom_in = memnew(Button); split_sheet_zoom_in->set_flat(true); split_sheet_zoom_in->set_focus_mode(FOCUS_NONE); @@ -1230,14 +1234,14 @@ SpriteFramesEditor::SpriteFramesEditor() { // Config scale. scale_ratio = 1.2f; - thumbnail_default_size = 96 * MAX(1.0, EDSCALE); - thumbnail_zoom = MAX(1.0, EDSCALE); - max_thumbnail_zoom = 8.0f * MAX(1.0, EDSCALE); - min_thumbnail_zoom = 0.1f * MAX(1.0, EDSCALE); + thumbnail_default_size = 96 * MAX(1, EDSCALE); + thumbnail_zoom = MAX(1.0f, EDSCALE); + max_thumbnail_zoom = 8.0f * MAX(1.0f, EDSCALE); + min_thumbnail_zoom = 0.1f * MAX(1.0f, EDSCALE); // Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad. - sheet_zoom = MAX(1.0, EDSCALE); - max_sheet_zoom = 16.0f * MAX(1.0, EDSCALE); - min_sheet_zoom = 0.01f * MAX(1.0, EDSCALE); + sheet_zoom = MAX(1.0f, EDSCALE); + max_sheet_zoom = 16.0f * MAX(1.0f, EDSCALE); + min_sheet_zoom = 0.01f * MAX(1.0f, EDSCALE); _zoom_reset(); } diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index bbc26ca726..77cdbb4af6 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -54,13 +54,12 @@ class SpriteFramesEditor : public HSplitContainer { Button *move_up; Button *move_down; Button *zoom_out; - Button *zoom_1; + Button *zoom_reset; Button *zoom_in; ItemList *tree; bool loading_scene; int sel; - HSplitContainer *split; Button *new_anim; Button *remove_anim; @@ -79,12 +78,12 @@ class SpriteFramesEditor : public HSplitContainer { ConfirmationDialog *delete_dialog; ConfirmationDialog *split_sheet_dialog; - ScrollContainer *splite_sheet_scroll; + ScrollContainer *split_sheet_scroll; TextureRect *split_sheet_preview; SpinBox *split_sheet_h; SpinBox *split_sheet_v; Button *split_sheet_zoom_out; - Button *split_sheet_zoom_1; + Button *split_sheet_zoom_reset; Button *split_sheet_zoom_in; EditorFileDialog *file_split_sheet; Set<int> frames_selected; diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 2b8bfe067d..1edcbd2cc9 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -59,58 +59,7 @@ void TextEditor::_change_syntax_highlighter(int p_idx) { } void TextEditor::_load_theme_settings() { - CodeEdit *text_edit = code_editor->get_text_editor(); - text_edit->get_syntax_highlighter()->update_cache(); - - Color background_color = EDITOR_GET("text_editor/highlighting/background_color"); - Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color"); - Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color"); - Color completion_existing_color = EDITOR_GET("text_editor/highlighting/completion_existing_color"); - Color completion_scroll_color = EDITOR_GET("text_editor/highlighting/completion_scroll_color"); - Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color"); - Color text_color = EDITOR_GET("text_editor/highlighting/text_color"); - Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color"); - Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color"); - Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color"); - Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color"); - Color selection_color = EDITOR_GET("text_editor/highlighting/selection_color"); - Color brace_mismatch_color = EDITOR_GET("text_editor/highlighting/brace_mismatch_color"); - Color current_line_color = EDITOR_GET("text_editor/highlighting/current_line_color"); - Color line_length_guideline_color = EDITOR_GET("text_editor/highlighting/line_length_guideline_color"); - Color word_highlighted_color = EDITOR_GET("text_editor/highlighting/word_highlighted_color"); - Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); - Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); - Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); - Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); - Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); - Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color"); - Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color"); - - text_edit->add_theme_color_override("background_color", background_color); - text_edit->add_theme_color_override("completion_background_color", completion_background_color); - text_edit->add_theme_color_override("completion_selected_color", completion_selected_color); - text_edit->add_theme_color_override("completion_existing_color", completion_existing_color); - text_edit->add_theme_color_override("completion_scroll_color", completion_scroll_color); - text_edit->add_theme_color_override("completion_font_color", completion_font_color); - text_edit->add_theme_color_override("font_color", text_color); - text_edit->add_theme_color_override("line_number_color", line_number_color); - text_edit->add_theme_color_override("caret_color", caret_color); - text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_selected_color", text_selected_color); - text_edit->add_theme_color_override("selection_color", selection_color); - text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); - text_edit->add_theme_color_override("current_line_color", current_line_color); - text_edit->add_theme_color_override("line_length_guideline_color", line_length_guideline_color); - text_edit->add_theme_color_override("word_highlighted_color", word_highlighted_color); - text_edit->add_theme_color_override("breakpoint_color", breakpoint_color); - text_edit->add_theme_color_override("executing_line_color", executing_line_color); - text_edit->add_theme_color_override("mark_color", mark_color); - text_edit->add_theme_color_override("bookmark_color", bookmark_color); - text_edit->add_theme_color_override("code_folding_color", code_folding_color); - text_edit->add_theme_color_override("search_result_color", search_result_color); - text_edit->add_theme_color_override("search_result_border_color", search_result_border_color); - - text_edit->add_theme_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6)); + code_editor->get_text_editor()->get_syntax_highlighter()->update_cache(); } String TextEditor::get_name() { @@ -171,6 +120,10 @@ void TextEditor::add_callback(const String &p_function, PackedStringArray p_args void TextEditor::set_debugger_active(bool p_active) { } +Control *TextEditor::get_base_editor() const { + return code_editor->get_text_editor(); +} + Array TextEditor::get_breakpoints() { return Array(); } diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index c066d51b18..abb75cc9d8 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -142,6 +142,8 @@ public: virtual void validate() override; + virtual Control *get_base_editor() const override; + static void register_editor(); TextEditor(); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 7b927ad98b..62ecdb8c32 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -331,7 +331,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) { if (E->get().has_point(point)) { rect = E->get(); - if (Input::get_singleton()->is_key_pressed(KEY_CONTROL) && !(Input::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) { + if (Input::get_singleton()->is_key_pressed(KEY_CTRL) && !(Input::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) { Rect2 r; if (node_sprite) { r = node_sprite->get_region_rect(); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 36c1bf3a09..f1c73f99dc 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -321,7 +321,7 @@ void ThemeItemImportTree::_toggle_type_items(bool p_collapse) { return; } - TreeItem *type_node = root->get_children(); + TreeItem *type_node = root->get_first_child(); while (type_node) { type_node->set_collapsed(p_collapse); type_node = type_node->get_next(); @@ -491,7 +491,7 @@ void ThemeItemImportTree::_tree_item_edited() { } void ThemeItemImportTree::_select_all_subitems(TreeItem *p_root_item, bool p_select_with_data) { - TreeItem *child_item = p_root_item->get_children(); + TreeItem *child_item = p_root_item->get_first_child(); while (child_item) { child_item->set_checked(IMPORT_ITEM, true); if (p_select_with_data) { @@ -505,7 +505,7 @@ void ThemeItemImportTree::_select_all_subitems(TreeItem *p_root_item, bool p_sel } void ThemeItemImportTree::_deselect_all_subitems(TreeItem *p_root_item, bool p_deselect_completely) { - TreeItem *child_item = p_root_item->get_children(); + TreeItem *child_item = p_root_item->get_first_child(); while (child_item) { child_item->set_checked(IMPORT_ITEM_DATA, false); if (p_deselect_completely) { @@ -527,7 +527,7 @@ void ThemeItemImportTree::_update_parent_items(TreeItem *p_root_item) { bool any_checked = false; bool any_checked_with_data = false; - TreeItem *child_item = parent_item->get_children(); + TreeItem *child_item = parent_item->get_first_child(); while (child_item) { if (child_item->is_checked(IMPORT_ITEM)) { any_checked = true; @@ -1694,6 +1694,9 @@ void ThemeItemEditorDialog::_notification(int p_what) { edit_items_remove_all->set_icon(get_theme_icon("ThemeRemoveAllItems", "EditorIcons")); import_another_theme_button->set_icon(get_theme_icon("Folder", "EditorIcons")); + + tc->add_theme_style_override("tab_selected", get_theme_stylebox("tab_selected_odd", "TabContainer")); + tc->add_theme_style_override("panel", get_theme_stylebox("panel_odd", "TabContainer")); } break; } } @@ -1707,7 +1710,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() { get_ok_button()->set_text(TTR("Close")); set_hide_on_ok(false); // Closing may require a confirmation in some cases. - TabContainer *tc = memnew(TabContainer); + tc = memnew(TabContainer); tc->set_tab_align(TabContainer::TabAlign::ALIGN_LEFT); add_child(tc); diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 5f4de68f45..c42ebf1a19 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -181,6 +181,8 @@ class ThemeItemEditorDialog : public AcceptDialog { Ref<Theme> edited_theme; + TabContainer *tc; + ItemList *edit_type_list; LineEdit *edit_add_type_value; String edited_item_type; diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 4de2f962bc..78f181e321 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -39,9 +39,10 @@ #include "scene/gui/texture_rect.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" void TileAtlasView::_gui_input(const Ref<InputEvent> &p_event) { - bool ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool ctrl = Input::get_singleton()->is_key_pressed(KEY_CTRL); Ref<InputEventMouseButton> b = p_event; if (b.is_valid()) { @@ -195,9 +196,9 @@ void TileAtlasView::_base_tiles_root_control_gui_input(const Ref<InputEvent> &p_ if (mm.is_valid()) { Transform2D xform = base_tiles_drawing_root->get_transform().affine_inverse(); Vector2i coords = get_atlas_tile_coords_at_pos(xform.xform(mm->get_position())); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { coords = tile_set_atlas_source->get_tile_at_coords(coords); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { base_tiles_root_control->set_tooltip(vformat(TTR("Source: %d\nAtlas coordinates: %s\nAlternative: 0"), source_id, coords)); } } @@ -215,7 +216,7 @@ void TileAtlasView::_draw_base_tiles() { for (int x = 0; x < grid_size.x; x++) { for (int y = 0; y < grid_size.y; y++) { Vector2i coords = Vector2i(x, y); - if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { Rect2i rect = Rect2i(texture_region_size * coords + margins, texture_region_size); base_tiles_draw->draw_texture_rect_region(texture, rect, rect); } @@ -229,17 +230,23 @@ void TileAtlasView::_draw_base_tiles() { rect.set_end(Vector2i(texture->get_size().x, margins.y)); base_tiles_draw->draw_texture_rect_region(texture, rect, rect); // Bottom - rect.position = Vector2i(0, margins.y + (grid_size.y * texture_region_size.y)); - rect.set_end(texture->get_size()); - base_tiles_draw->draw_texture_rect_region(texture, rect, rect); + int bottom_border = margins.y + (grid_size.y * texture_region_size.y); + if (bottom_border < texture->get_size().y) { + rect.position = Vector2i(0, bottom_border); + rect.set_end(texture->get_size()); + base_tiles_draw->draw_texture_rect_region(texture, rect, rect); + } // Left rect.position = Vector2i(0, margins.y); rect.set_end(Vector2i(margins.x, margins.y + (grid_size.y * texture_region_size.y))); base_tiles_draw->draw_texture_rect_region(texture, rect, rect); // Right. - rect.position = Vector2i(margins.x + (grid_size.x * texture_region_size.x), margins.y); - rect.set_end(Vector2i(texture->get_size().x, margins.y + (grid_size.y * texture_region_size.y))); - base_tiles_draw->draw_texture_rect_region(texture, rect, rect); + int right_border = margins.x + (grid_size.x * texture_region_size.x); + if (right_border < texture->get_size().x) { + rect.position = Vector2i(right_border, margins.y); + rect.set_end(Vector2i(texture->get_size().x, margins.y + (grid_size.y * texture_region_size.y))); + base_tiles_draw->draw_texture_rect_region(texture, rect, rect); + } // Draw actual tiles, using their properties (modulation, etc...) for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { @@ -249,7 +256,7 @@ void TileAtlasView::_draw_base_tiles() { Vector2i offset_pos = (margins + (atlas_coords * texture_region_size) + tile_set_atlas_source->get_tile_texture_region(atlas_coords).size / 2 + tile_set_atlas_source->get_tile_effective_texture_offset(atlas_coords, 0)); // Draw the tile. - TileSetAtlasPluginRendering::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0); + TileSetPluginAtlasRendering::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0); } } } @@ -268,7 +275,7 @@ void TileAtlasView::_draw_base_tiles_texture_grid() { for (int y = 0; y < grid_size.y; y++) { Vector2i origin = margins + (Vector2i(x, y) * (texture_region_size + separation)); Vector2i base_tile_coords = tile_set_atlas_source->get_tile_at_coords(Vector2i(x, y)); - if (base_tile_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (base_tile_coords != TileSetSource::INVALID_ATLAS_COORDS) { if (base_tile_coords == Vector2i(x, y)) { // Draw existing tile. Vector2i size_in_atlas = tile_set_atlas_source->get_tile_size_in_atlas(base_tile_coords); @@ -299,7 +306,7 @@ void TileAtlasView::_draw_base_tiles_dark() { Vector2i origin = margins + (Vector2i(x, y) * (texture_region_size + separation)); Vector2i base_tile_coords = tile_set_atlas_source->get_tile_at_coords(Vector2i(x, y)); - if (base_tile_coords == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (base_tile_coords == TileSetSource::INVALID_ATLAS_COORDS) { // Draw the grid. base_tiles_dark->draw_rect(Rect2i(origin, texture_region_size), Color(0.0, 0.0, 0.0, 0.5), true); } @@ -310,6 +317,7 @@ void TileAtlasView::_draw_base_tiles_dark() { void TileAtlasView::_draw_base_tiles_shape_grid() { // Draw the shapes. + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); Vector2i tile_shape_size = tile_set->get_tile_size(); for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { Vector2i tile_id = tile_set_atlas_source->get_tile_id(i); @@ -318,7 +326,7 @@ void TileAtlasView::_draw_base_tiles_shape_grid() { Vector2 origin = texture_region.position + (texture_region.size - tile_shape_size) / 2 + in_tile_base_offset; // Draw only if the tile shape fits in the texture region - tile_set->draw_tile_shape(base_tiles_shape_grid, Rect2(origin, tile_shape_size), Color(1.0, 0.5, 0.2, 0.8)); + tile_set->draw_tile_shape(base_tiles_shape_grid, Rect2(origin, tile_shape_size), grid_color); } } @@ -331,7 +339,7 @@ void TileAtlasView::_alternative_tiles_root_control_gui_input(const Ref<InputEve Vector3i coords3 = get_alternative_tile_at_pos(xform.xform(mm->get_position())); Vector2i coords = Vector2i(coords3.x, coords3.y); int alternative_id = coords3.z; - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && alternative_id != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS && alternative_id != TileSetSource::INVALID_TILE_ALTERNATIVE) { alternative_tiles_root_control->set_tooltip(vformat(TTR("Source: %d\nAtlas coordinates: %s\nAlternative: %d"), source_id, coords, alternative_id)); } } @@ -364,7 +372,7 @@ void TileAtlasView::_draw_alternatives() { } // Draw the tile. - TileSetAtlasPluginRendering::draw_tile(alternatives_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, alternative_id); + TileSetPluginAtlasRendering::draw_tile(alternatives_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, alternative_id); // Increment the x position. current_pos.x += transposed ? texture_region.size.y : texture_region.size.x; @@ -464,7 +472,7 @@ Vector2i TileAtlasView::get_atlas_tile_coords_at_pos(const Vector2 p_pos) const return ret; } - return TileSetAtlasSource::INVALID_ATLAS_COORDS; + return TileSetSource::INVALID_ATLAS_COORDS; } void TileAtlasView::_update_alternative_tiles_rect_cache() { @@ -506,7 +514,7 @@ Vector3i TileAtlasView::get_alternative_tile_at_pos(const Vector2 p_pos) const { } } - return Vector3i(TileSetAtlasSource::INVALID_ATLAS_COORDS.x, TileSetAtlasSource::INVALID_ATLAS_COORDS.y, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + return Vector3i(TileSetSource::INVALID_ATLAS_COORDS.x, TileSetSource::INVALID_ATLAS_COORDS.y, TileSetSource::INVALID_TILE_ALTERNATIVE); } Rect2i TileAtlasView::get_alternative_tile_rect(const Vector2i p_coords, int p_alternative_tile) { @@ -575,7 +583,7 @@ TileAtlasView::TileAtlasView() { // Base tiles. Label *base_tile_label = memnew(Label); - base_tile_label->set_text(TTR("Base tiles")); + base_tile_label->set_text(TTR("Base Tiles")); base_tile_label->set_align(Label::ALIGN_CENTER); left_vbox->add_child(base_tile_label); @@ -623,7 +631,7 @@ TileAtlasView::TileAtlasView() { // Alternative tiles. Label *alternative_tiles_label = memnew(Label); - alternative_tiles_label->set_text(TTR("Alternative tiles")); + alternative_tiles_label->set_text(TTR("Alternative Tiles")); alternative_tiles_label->set_align(Label::ALIGN_CENTER); right_vbox->add_child(alternative_tiles_label); diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 0b674bec39..61457e3e59 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -113,7 +113,22 @@ void TileDataPositionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform ERR_FAIL_COND(value.get_type() != Variant::VECTOR2I && value.get_type() != Variant::VECTOR2); Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_theme_icon("EditorPosition", "EditorIcons"); - p_canvas_item->draw_texture(position_icon, p_transform.get_origin() + Vector2(value) - position_icon->get_size() / 2); + p_canvas_item->draw_texture(position_icon, p_transform.xform(Vector2(value)) - position_icon->get_size() / 2); +} + +void TileDataYSortEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, String p_property) { + TileData *tile_data = _get_tile_data(p_tile_set, p_atlas_source_id, p_atlas_coords, p_alternative_tile); + ERR_FAIL_COND(!tile_data); + + bool valid; + Variant value = tile_data->get(p_property, &valid); + if (!valid) { + return; + } + ERR_FAIL_COND(value.get_type() != Variant::INT); + + Ref<Texture2D> position_icon = TileSetEditor::get_singleton()->get_theme_icon("EditorPosition", "EditorIcons"); + p_canvas_item->draw_texture(position_icon, p_transform.xform(Vector2(0, value)) - position_icon->get_size() / 2); } void TileDataOcclusionShapeEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, String p_property) { @@ -166,7 +181,7 @@ void TileDataTerrainsEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform Vector<String> components = String(p_property).split("/", true); if (components[0] == "terrain_mode" || components[0] == "terrain" || components[0] == "terrains_peering_bit") { - TileSetAtlasPluginTerrain::draw_terrains(p_canvas_item, p_transform, p_tile_set, tile_data); + TileSetPluginAtlasTerrain::draw_terrains(p_canvas_item, p_transform, p_tile_set, tile_data); } } diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h index f4f9c25157..b82189e1ee 100644 --- a/editor/plugins/tiles/tile_data_editors.h +++ b/editor/plugins/tiles/tile_data_editors.h @@ -79,6 +79,13 @@ public: virtual void draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, String p_property) override; }; +class TileDataYSortEditor : public TileDataEditor { + GDCLASS(TileDataYSortEditor, TileDataEditor); + +public: + virtual void draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, String p_property) override; +}; + class TileDataOcclusionShapeEditor : public TileDataEditor { GDCLASS(TileDataOcclusionShapeEditor, TileDataEditor); diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index cfc4dff329..ef13d8ea12 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -32,6 +32,7 @@ #include "tiles_editor_plugin.h" +#include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/plugins/canvas_item_editor_plugin.h" @@ -55,18 +56,25 @@ void TileMapEditorTilesPlugin::_notification(int p_what) { picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons")); erase_button->set_icon(get_theme_icon("Eraser", "EditorIcons")); - missing_texture_texture = get_theme_icon("TileSet", "EditorIcons"); + toggle_grid_button->set_icon(get_theme_icon("Grid", "EditorIcons")); + + missing_atlas_texture_icon = get_theme_icon("TileSet", "EditorIcons"); + + toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); break; case NOTIFICATION_VISIBILITY_CHANGED: _stop_dragging(); + break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: + toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); + break; } } void TileMapEditorTilesPlugin::tile_set_changed() { _update_fix_selected_and_hovered(); - _update_bottom_panel(); _update_tile_set_sources_list(); - _update_atlas_view(); + _update_bottom_panel(); } void TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled(bool p_pressed) { @@ -77,6 +85,10 @@ void TileMapEditorTilesPlugin::_on_scattering_spinbox_changed(double p_value) { scattering = p_value; } +void TileMapEditorTilesPlugin::_on_grid_toggled(bool p_pressed) { + EditorSettings::get_singleton()->set("editors/tiles_editor/display_grid", p_pressed); +} + void TileMapEditorTilesPlugin::_update_toolbar() { // Stop draggig if needed. _stop_dragging(); @@ -146,19 +158,38 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { for (int i = 0; i < tile_set->get_source_count(); i++) { int source_id = tile_set->get_source_id(i); - // TODO: handle with virtual functions TileSetSource *source = *tile_set->get_source(source_id); + + Ref<Texture2D> texture; + String item_text; + + // Atlas source. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { - Ref<Texture2D> texture = atlas_source->get_texture(); + texture = atlas_source->get_texture(); if (texture.is_valid()) { - sources_list->add_item(vformat("%s - (id:%d)", texture->get_path().get_file(), source_id), texture); + item_text = vformat("%s (id:%d)", texture->get_path().get_file(), source_id); } else { - sources_list->add_item(vformat("No texture atlas source - (id:%d)", source_id), missing_texture_texture); + item_text = vformat("No Texture Atlas Source (id:%d)", source_id); } - } else { - sources_list->add_item(vformat("Unknown type source - (id:%d)", source_id), missing_texture_texture); } + + // Scene collection source. + TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + if (scene_collection_source) { + texture = get_theme_icon("PackedScene", "EditorIcons"); + item_text = vformat(TTR("Scene Collection Source (id:%d)"), source_id); + } + + // Use default if not valid. + if (item_text.is_empty()) { + item_text = vformat(TTR("Unknown Type Source (id:%d)"), source_id); + } + if (!texture.is_valid()) { + texture = missing_atlas_texture_icon; + } + + sources_list->add_item(item_text, texture); sources_list->set_item_metadata(i, source_id); } @@ -176,7 +207,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() { TilesEditor::get_singleton()->set_atlas_sources_lists_current(sources_list->get_current()); } -void TileMapEditorTilesPlugin::_update_atlas_view() { +void TileMapEditorTilesPlugin::_update_bottom_panel() { // Update the atlas display. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); if (!tile_map) { @@ -185,39 +216,161 @@ void TileMapEditorTilesPlugin::_update_atlas_view() { Ref<TileSet> tile_set = tile_map->get_tileset(); if (!tile_set.is_valid()) { - tile_atlas_view->hide(); return; } int source_index = sources_list->get_current(); if (source_index >= 0 && source_index < sources_list->get_item_count()) { + atlas_sources_split_container->show(); + missing_source_label->hide(); + int source_id = sources_list->get_item_metadata(source_index); TileSetSource *source = *tile_set->get_source(source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); + TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + if (atlas_source) { - tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id); tile_atlas_view->show(); + scene_tiles_list->hide(); + invalid_source_label->hide(); + _update_atlas_view(); + } else if (scenes_collection_source) { + tile_atlas_view->hide(); + scene_tiles_list->show(); + invalid_source_label->hide(); + _update_scenes_collection_view(); + } else { + tile_atlas_view->hide(); + scene_tiles_list->hide(); + invalid_source_label->show(); } } else { + atlas_sources_split_container->hide(); + missing_source_label->show(); + tile_atlas_view->hide(); + scene_tiles_list->hide(); + invalid_source_label->hide(); } +} - // Synchronize atlas view. - TilesEditor::get_singleton()->synchronize_atlas_view(tile_atlas_view); +void TileMapEditorTilesPlugin::_update_atlas_view() { + TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); + if (!tile_map) { + return; + } + Ref<TileSet> tile_set = tile_map->get_tileset(); + if (!tile_set.is_valid()) { + return; + } + + int source_id = sources_list->get_item_metadata(sources_list->get_current()); + TileSetSource *source = *tile_set->get_source(source_id); + TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); + ERR_FAIL_COND(!atlas_source); + + tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id); + TilesEditor::get_singleton()->synchronize_atlas_view(tile_atlas_view); tile_atlas_control->update(); } -void TileMapEditorTilesPlugin::_update_bottom_panel() { +void TileMapEditorTilesPlugin::_update_scenes_collection_view() { TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); if (!tile_map) { return; } + Ref<TileSet> tile_set = tile_map->get_tileset(); + if (!tile_set.is_valid()) { + return; + } + + int source_id = sources_list->get_item_metadata(sources_list->get_current()); + TileSetSource *source = *tile_set->get_source(source_id); + TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + ERR_FAIL_COND(!scenes_collection_source); + + // Clear the list. + scene_tiles_list->clear(); - // Update the tabs. - missing_source_label->set_visible(tile_set.is_valid() && tile_set->get_source_count() == 0); - atlas_sources_split_container->set_visible(tile_set.is_valid() && tile_set->get_source_count() > 0); + // Rebuild the list. + for (int i = 0; i < scenes_collection_source->get_scene_tiles_count(); i++) { + int scene_id = scenes_collection_source->get_scene_tile_id(i); + + Ref<PackedScene> scene = scenes_collection_source->get_scene_tile_scene(scene_id); + + int item_index = 0; + if (scene.is_valid()) { + item_index = scene_tiles_list->add_item(vformat("%s (path:%s id:%d)", scene->get_path().get_file().get_basename(), scene->get_path(), scene_id)); + Variant udata = i; + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(scene, this, "_scene_thumbnail_done", udata); + } else { + item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), get_theme_icon("PackedScene", "EditorIcons")); + } + scene_tiles_list->set_item_metadata(item_index, scene_id); + + // Check if in selection. + if (tile_set_selection.has(TileMapCell(source_id, Vector2i(), scene_id))) { + scene_tiles_list->select(item_index, false); + } + } + + // Icon size update. + int int_size = int(EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size")) * EDSCALE; + scene_tiles_list->set_fixed_icon_size(Vector2(int_size, int_size)); +} + +void TileMapEditorTilesPlugin::_scene_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) { + int index = p_ud; + + if (index >= 0 && index < scene_tiles_list->get_item_count()) { + scene_tiles_list->set_item_icon(index, p_preview); + } +} + +void TileMapEditorTilesPlugin::_scenes_list_multi_selected(int p_index, bool p_selected) { + TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); + if (!tile_map) { + return; + } + + Ref<TileSet> tile_set = tile_map->get_tileset(); + if (!tile_set.is_valid()) { + return; + } + + // Add or remove the Tile form the selection. + int scene_id = scene_tiles_list->get_item_metadata(p_index); + int source_id = sources_list->get_item_metadata(sources_list->get_current()); + TileSetSource *source = *tile_set->get_source(source_id); + TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + ERR_FAIL_COND(!scenes_collection_source); + + TileMapCell selected = TileMapCell(source_id, Vector2i(), scene_id); + + // Clear the selection if shift is not pressed. + if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + tile_set_selection.clear(); + } + + if (p_selected) { + tile_set_selection.insert(selected); + } else { + if (tile_set_selection.has(selected)) { + tile_set_selection.erase(selected); + } + } + + _update_selection_pattern_from_tileset_selection(); +} + +void TileMapEditorTilesPlugin::_scenes_list_nothing_selected() { + scene_tiles_list->deselect_all(); + tile_set_selection.clear(); + tile_map_selection.clear(); + selection_pattern->clear(); + _update_selection_pattern_from_tileset_selection(); } bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { @@ -257,7 +410,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p if (!tile_map_selection.is_empty()) { undo_redo->create_action(TTR("Delete tiles")); for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) { - undo_redo->add_do_method(tile_map, "set_cell", E->get(), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + undo_redo->add_do_method(tile_map, "set_cell", E->get(), -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); undo_redo->add_undo_method(tile_map, "set_cell", E->get(), tile_map->get_cell_source_id(E->get()), tile_map->get_cell_atlas_coords(E->get()), tile_map->get_cell_alternative_tile(E->get())); } undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection()); @@ -288,7 +441,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p if (!tile_map_selection.is_empty()) { undo_redo->create_action(TTR("Delete tiles")); for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) { - undo_redo->add_do_method(tile_map, "set_cell", E->get(), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + undo_redo->add_do_method(tile_map, "set_cell", E->get(), -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); undo_redo->add_undo_method(tile_map, "set_cell", E->get(), tile_map->get_cell_source_id(E->get()), tile_map->get_cell_atlas_coords(E->get()), tile_map->get_cell_alternative_tile(E->get())); } undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection()); @@ -357,14 +510,14 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p // Pressed if (tool_buttons_group->get_pressed_button() == select_tool_button) { drag_start_mouse_pos = mpos; - if (tile_map_selection.has(tile_map->world_to_map(drag_start_mouse_pos)) && !mb->get_shift()) { + if (tile_map_selection.has(tile_map->world_to_map(drag_start_mouse_pos)) && !mb->is_shift_pressed()) { // Move the selection drag_type = DRAG_TYPE_MOVE; drag_modified.clear(); for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) { Vector2i coords = E->get(); drag_modified.insert(coords, TileMapCell(tile_map->get_cell_source_id(coords), tile_map->get_cell_atlas_coords(coords), tile_map->get_cell_alternative_tile(coords))); - tile_map->set_cell(coords, -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + tile_map->set_cell(coords, -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); } } else { // Select tiles @@ -460,14 +613,16 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over // Draw the selection. if (is_visible_in_tree() && tool_buttons_group->get_pressed_button() == select_tool_button) { // In select mode, we only draw the current selection if we are modifying it (pressing control or shift). - if (drag_type == DRAG_TYPE_MOVE || (drag_type == DRAG_TYPE_SELECT && !Input::get_singleton()->is_key_pressed(KEY_CONTROL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { + if (drag_type == DRAG_TYPE_MOVE || (drag_type == DRAG_TYPE_SELECT && !Input::get_singleton()->is_key_pressed(KEY_CTRL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { // Do nothing } else { - tile_map->draw_cells_outline(p_overlay, tile_map_selection, Color(0.0, 0.0, 1.0), xform); + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); + tile_map->draw_cells_outline(p_overlay, tile_map_selection, selection_color, xform); } } - // handle the preview of the tiles to be placed. + // Handle the preview of the tiles to be placed. if (is_visible_in_tree() && has_mouse) { // Only if the tilemap editor is opened and the viewport is hovered. Map<Vector2i, TileMapCell> preview; Rect2i drawn_grid_rect; @@ -562,32 +717,37 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over const int fading = 5; // Draw the lines of the grid behind the preview. - if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) { - drawn_grid_rect = drawn_grid_rect.grow(fading); - for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) { - for (int y = drawn_grid_rect.position.y; y < (drawn_grid_rect.position.y + drawn_grid_rect.size.y); y++) { - Vector2i pos_in_rect = Vector2i(x, y) - drawn_grid_rect.position; - - // Fade out the border of the grid. - float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); - float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); - float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); - - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 0.5, 0.2, 0.5 * opacity), false); + bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + if (display_grid) { + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) { + drawn_grid_rect = drawn_grid_rect.grow(fading); + for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) { + for (int y = drawn_grid_rect.position.y; y < (drawn_grid_rect.position.y + drawn_grid_rect.size.y); y++) { + Vector2i pos_in_rect = Vector2i(x, y) - drawn_grid_rect.position; + + // Fade out the border of the grid. + float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); + + Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); + Color color = grid_color; + color.a = color.a * opacity; + tile_set->draw_tile_shape(p_overlay, cell_region, color, false); + } } } } // Draw the preview. for (Map<Vector2i, TileMapCell>::Element *E = preview.front(); E; E = E->next()) { + Vector2i size = tile_set->get_tile_size(); + Vector2 position = tile_map->map_to_world(E->key()) - size / 2; + Rect2 cell_region = xform.xform(Rect2(position, size)); if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) { - Vector2i size = tile_set->get_tile_size(); - Vector2 position = tile_map->map_to_world(E->key()) - size / 2; - Rect2 cell_region = xform.xform(Rect2(position, size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 1.0, 1.0, 0.5), true); } else { if (tile_set->has_source(E->get().source_id)) { @@ -629,12 +789,10 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over // Draw the tile. p_overlay->draw_texture_rect_region(atlas_source->get_texture(), dest_rect, source_rect, modulate * Color(1.0, 1.0, 1.0, 0.5), transpose, tile_set->is_uv_clipping()); + } else { + tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 1.0, 1.0, 0.5), true); } } else { - Vector2i size = tile_set->get_tile_size(); - Vector2 position = tile_map->map_to_world(E->key()) - size / 2; - Rect2 cell_region = xform.xform(Rect2(position, size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(0.0, 0.0, 0.0, 0.5), true); } } @@ -669,7 +827,9 @@ TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(const TileMapPattern *p_ TileSetSource *source = *tile_set->get_source(source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { - sum += Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile))->get_probability(); + TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile)); + ERR_FAIL_COND_V(!tile_data, TileMapCell()); + sum += tile_data->get_probability(); } else { sum += 1.0; } @@ -698,7 +858,7 @@ TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(const TileMapPattern *p_ return TileMapCell(); } -Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_drag_mouse_pos, Vector2 p_from_mouse_pos, Vector2i p_to_mouse_pos) { +Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_drag_mouse_pos, Vector2 p_from_mouse_pos, Vector2 p_to_mouse_pos) { TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); if (!tile_map) { return Map<Vector2i, TileMapCell>(); @@ -711,7 +871,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_ // Get or create the pattern. TileMapPattern erase_pattern; - erase_pattern.set_cell(Vector2i(0, 0), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + erase_pattern.set_cell(Vector2i(0, 0), -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern; Map<Vector2i, TileMapCell> output; @@ -763,7 +923,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start // Get or create the pattern. TileMapPattern erase_pattern; - erase_pattern.set_cell(Vector2i(0, 0), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + erase_pattern.set_cell(Vector2i(0, 0), -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern; // Compute the offset to align things to the bottom or right. @@ -814,7 +974,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i // Get or create the pattern. TileMapPattern erase_pattern; - erase_pattern.set_cell(Vector2i(0, 0), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + erase_pattern.set_cell(Vector2i(0, 0), -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern; Map<Vector2i, TileMapCell> output; @@ -930,14 +1090,14 @@ void TileMapEditorTilesPlugin::_stop_dragging() { undo_redo->create_action(TTR("Change selection")); undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection()); - if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT) && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT) && !Input::get_singleton()->is_key_pressed(KEY_CTRL)) { tile_map_selection.clear(); } Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos) - tile_map->world_to_map(drag_start_mouse_pos)).abs(); for (int x = rect.position.x; x <= rect.get_end().x; x++) { for (int y = rect.position.y; y <= rect.get_end().y; y++) { Vector2i coords = Vector2i(x, y); - if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (Input::get_singleton()->is_key_pressed(KEY_CTRL)) { if (tile_map_selection.has(coords)) { tile_map_selection.erase(coords); } @@ -1090,8 +1250,8 @@ void TileMapEditorTilesPlugin::_update_fix_selected_and_hovered() { TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); if (!tile_map) { hovered_tile.source_id = -1; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_selection.clear(); tile_map_selection.clear(); selection_pattern->clear(); @@ -1101,8 +1261,8 @@ void TileMapEditorTilesPlugin::_update_fix_selected_and_hovered() { Ref<TileSet> tile_set = tile_map->get_tileset(); if (!tile_set.is_valid()) { hovered_tile.source_id = -1; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_selection.clear(); tile_map_selection.clear(); selection_pattern->clear(); @@ -1112,8 +1272,8 @@ void TileMapEditorTilesPlugin::_update_fix_selected_and_hovered() { int source_index = sources_list->get_current(); if (source_index < 0 || source_index >= sources_list->get_item_count()) { hovered_tile.source_id = -1; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_selection.clear(); tile_map_selection.clear(); selection_pattern->clear(); @@ -1128,8 +1288,8 @@ void TileMapEditorTilesPlugin::_update_fix_selected_and_hovered() { !tile_set->get_source(hovered_tile.source_id)->has_tile(hovered_tile.get_atlas_coords()) || !tile_set->get_source(hovered_tile.source_id)->has_alternative_tile(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile)) { hovered_tile.source_id = -1; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; } // Selection if needed. @@ -1187,6 +1347,7 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection( per_source[E->get().source_id].push_back(&(E->get())); } + int vertical_offset = 0; for (Map<int, List<const TileMapCell *>>::Element *E_source = per_source.front(); E_source; E_source = E_source->next()) { // Per source. List<const TileMapCell *> unorganized; @@ -1199,24 +1360,21 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection( // Organize using coordinates. for (List<const TileMapCell *>::Element *E_cell = E_source->get().front(); E_cell; E_cell = E_cell->next()) { const TileMapCell *current = E_cell->get(); - if (organized_pattern.has(current->get_atlas_coords())) { - if (current->alternative_tile < organized_pattern[current->get_atlas_coords()]->alternative_tile) { - unorganized.push_back(organized_pattern[current->get_atlas_coords()]); - organized_pattern[current->get_atlas_coords()] = current; - } else { - unorganized.push_back(current); - } - } else { + if (current->alternative_tile == 0) { organized_pattern[current->get_atlas_coords()] = current; + } else { + unorganized.push_back(current); } } // Compute the encompassing rect for the organized pattern. Map<Vector2i, const TileMapCell *>::Element *E_cell = organized_pattern.front(); - encompassing_rect_coords = Rect2i(E_cell->key(), Vector2i(1, 1)); - for (; E_cell; E_cell = E_cell->next()) { - encompassing_rect_coords.expand_to(E_cell->key() + Vector2i(1, 1)); - encompassing_rect_coords.expand_to(E_cell->key()); + if (E_cell) { + encompassing_rect_coords = Rect2i(E_cell->key(), Vector2i(1, 1)); + for (; E_cell; E_cell = E_cell->next()) { + encompassing_rect_coords.expand_to(E_cell->key() + Vector2i(1, 1)); + encompassing_rect_coords.expand_to(E_cell->key()); + } } } else { // Add everything unorganized. @@ -1227,12 +1385,15 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection( // Now add everything to the output pattern. for (Map<Vector2i, const TileMapCell *>::Element *E_cell = organized_pattern.front(); E_cell; E_cell = E_cell->next()) { - selection_pattern->set_cell(E_cell->key() - encompassing_rect_coords.position, E_cell->get()->source_id, E_cell->get()->get_atlas_coords(), E_cell->get()->alternative_tile); + selection_pattern->set_cell(E_cell->key() - encompassing_rect_coords.position + Vector2i(0, vertical_offset), E_cell->get()->source_id, E_cell->get()->get_atlas_coords(), E_cell->get()->alternative_tile); } Vector2i organized_size = selection_pattern->get_size(); + int unorganized_index = 0; for (List<const TileMapCell *>::Element *E_cell = unorganized.front(); E_cell; E_cell = E_cell->next()) { - selection_pattern->set_cell(Vector2(organized_size.x, 0), E_cell->get()->source_id, E_cell->get()->get_atlas_coords(), E_cell->get()->alternative_tile); + selection_pattern->set_cell(Vector2(organized_size.x + unorganized_index, vertical_offset), E_cell->get()->source_id, E_cell->get()->get_atlas_coords(), E_cell->get()->alternative_tile); + unorganized_index++; } + vertical_offset += MAX(organized_size.y, 1); } CanvasItemEditor::get_singleton()->update_viewport(); } @@ -1246,7 +1407,7 @@ void TileMapEditorTilesPlugin::_update_tileset_selection_from_selection_pattern( tile_set_selection.insert(TileMapCell(selection_pattern->get_cell_source_id(coords), selection_pattern->get_cell_atlas_coords(coords), selection_pattern->get_cell_alternative_tile(coords))); } } - _update_atlas_view(); + _update_bottom_panel(); } void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { @@ -1276,14 +1437,16 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { } // Draw the selection. + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) { if (E->get().source_id == source_id && E->get().alternative_tile == 0) { - tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get().get_atlas_coords()), Color(0.0, 0.0, 1.0), false); + tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get().get_atlas_coords()), selection_color, false); } } // Draw the hovered tile. - if (hovered_tile.get_atlas_coords() != TileSetAtlasSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0 && !tile_set_dragging_selection) { + if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0 && !tile_set_dragging_selection) { tile_atlas_control->draw_rect(atlas->get_tile_texture_region(hovered_tile.get_atlas_coords()), Color(1.0, 1.0, 1.0), false); } @@ -1299,22 +1462,22 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { for (int x = region.position.x; x < region.get_end().x; x++) { for (int y = region.position.y; y < region.get_end().y; y++) { Vector2i tile = atlas->get_tile_at_coords(Vector2i(x, y)); - if (tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile != TileSetSource::INVALID_ATLAS_COORDS) { to_draw.insert(tile); } } } - + Color selection_rect_color = selection_color.lightened(0.2); for (Set<Vector2i>::Element *E = to_draw.front(); E; E = E->next()) { - tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get()), Color(0.8, 0.8, 1.0), false); + tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get()), selection_rect_color, false); } } } void TileMapEditorTilesPlugin::_tile_atlas_control_mouse_exited() { hovered_tile.source_id = -1; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_dragging_selection = false; tile_atlas_control->update(); } @@ -1347,12 +1510,12 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEven // Update the hovered tile hovered_tile.source_id = source_id; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { coords = atlas->get_tile_at_coords(coords); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { hovered_tile.set_atlas_coords(coords); hovered_tile.alternative_tile = 0; } @@ -1369,12 +1532,12 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEven if (mb->is_pressed()) { // Pressed tile_set_dragging_selection = true; tile_set_drag_start_mouse_pos = tile_atlas_control->get_local_mouse_position(); - if (!mb->get_shift()) { + if (!mb->is_shift_pressed()) { tile_set_selection.clear(); } - if (hovered_tile.get_atlas_coords() != TileSetAtlasSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0) { - if (mb->get_shift() && tile_set_selection.has(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0))) { + if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0) { + if (mb->is_shift_pressed() && tile_set_selection.has(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0))) { tile_set_selection.erase(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0)); } else { tile_set_selection.insert(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0)); @@ -1383,24 +1546,24 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEven _update_selection_pattern_from_tileset_selection(); } else { // Released if (tile_set_dragging_selection) { - if (!mb->get_shift()) { + if (!mb->is_shift_pressed()) { tile_set_selection.clear(); } // Compute the covered area. Vector2i start_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos); Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); - if (start_tile != TileSetAtlasSource::INVALID_ATLAS_COORDS && end_tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (start_tile != TileSetSource::INVALID_ATLAS_COORDS && end_tile != TileSetSource::INVALID_ATLAS_COORDS) { Rect2i region = Rect2i(start_tile, end_tile - start_tile).abs(); region.size += Vector2i(1, 1); // To update the selection, we copy the selected/not selected status of the tiles we drag from. Vector2i start_coords = atlas->get_tile_at_coords(start_tile); - if (mb->get_shift() && start_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && !tile_set_selection.has(TileMapCell(source_id, start_coords, 0))) { + if (mb->is_shift_pressed() && start_coords != TileSetSource::INVALID_ATLAS_COORDS && !tile_set_selection.has(TileMapCell(source_id, start_coords, 0))) { // Remove from the selection. for (int x = region.position.x; x < region.get_end().x; x++) { for (int y = region.position.y; y < region.get_end().y; y++) { Vector2i tile_coords = atlas->get_tile_at_coords(Vector2i(x, y)); - if (tile_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && tile_set_selection.has(TileMapCell(source_id, tile_coords, 0))) { + if (tile_coords != TileSetSource::INVALID_ATLAS_COORDS && tile_set_selection.has(TileMapCell(source_id, tile_coords, 0))) { tile_set_selection.erase(TileMapCell(source_id, tile_coords, 0)); } } @@ -1410,7 +1573,7 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEven for (int x = region.position.x; x < region.get_end().x; x++) { for (int y = region.position.y; y < region.get_end().y; y++) { Vector2i tile_coords = atlas->get_tile_at_coords(Vector2i(x, y)); - if (tile_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile_coords != TileSetSource::INVALID_ATLAS_COORDS) { tile_set_selection.insert(TileMapCell(source_id, tile_coords, 0)); } } @@ -1453,7 +1616,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() { // Draw the selection. for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) { - if (E->get().source_id == source_id && E->get().get_atlas_coords() != TileSetAtlasSource::INVALID_ATLAS_COORDS && E->get().alternative_tile > 0) { + if (E->get().source_id == source_id && E->get().get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && E->get().alternative_tile > 0) { Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E->get().get_atlas_coords(), E->get().alternative_tile); if (rect != Rect2i()) { alternative_tiles_control->draw_rect(rect, Color(0.2, 0.2, 1.0), false); @@ -1462,7 +1625,7 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() { } // Draw hovered tile. - if (hovered_tile.get_atlas_coords() != TileSetAtlasSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile > 0) { + if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile > 0) { Rect2i rect = tile_atlas_view->get_alternative_tile_rect(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile); if (rect != Rect2i()) { alternative_tiles_control->draw_rect(rect, Color(1.0, 1.0, 1.0), false); @@ -1472,8 +1635,8 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() { void TileMapEditorTilesPlugin::_tile_alternatives_control_mouse_exited() { hovered_tile.source_id = -1; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; tile_set_dragging_selection = false; alternative_tiles_control->update(); } @@ -1506,12 +1669,12 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input(const Ref<In // Update the hovered tile hovered_tile.source_id = source_id; - hovered_tile.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - hovered_tile.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; Vector3i alternative_coords = tile_atlas_view->get_alternative_tile_at_pos(alternative_tiles_control->get_local_mouse_position()); Vector2i coords = Vector2i(alternative_coords.x, alternative_coords.y); int alternative = alternative_coords.z; - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && alternative != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS && alternative != TileSetSource::INVALID_TILE_ALTERNATIVE) { hovered_tile.set_atlas_coords(coords); hovered_tile.alternative_tile = alternative; } @@ -1526,12 +1689,12 @@ void TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input(const Ref<In if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (mb->is_pressed()) { // Pressed // Left click pressed. - if (!mb->get_shift()) { + if (!mb->is_shift_pressed()) { tile_set_selection.clear(); } - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && alternative != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) { - if (mb->get_shift() && tile_set_selection.has(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile))) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS && alternative != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) { + if (mb->is_shift_pressed() && tile_set_selection.has(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile))) { tile_set_selection.erase(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile)); } else { tile_set_selection.insert(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile)); @@ -1565,13 +1728,14 @@ TypedArray<Vector2i> TileMapEditorTilesPlugin::_get_tile_map_selection() const { void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id) { tile_map_id = p_tile_map_id; - // Clean the selection. + // Clear the selection. tile_set_selection.clear(); tile_map_selection.clear(); selection_pattern->clear(); } void TileMapEditorTilesPlugin::_bind_methods() { + ClassDB::bind_method(D_METHOD("_scene_thumbnail_done"), &TileMapEditorTilesPlugin::_scene_thumbnail_done); ClassDB::bind_method(D_METHOD("_set_tile_map_selection", "selection"), &TileMapEditorTilesPlugin::_set_tile_map_selection); ClassDB::bind_method(D_METHOD("_get_tile_map_selection"), &TileMapEditorTilesPlugin::_get_tile_map_selection); } @@ -1588,6 +1752,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { // --- Toolbar --- toolbar = memnew(HBoxContainer); + toolbar->set_h_size_flags(SIZE_EXPAND_FILL); HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer); @@ -1632,7 +1797,6 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", "Bucket", KEY_B)); bucket_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(bucket_tool_button); - toolbar->add_child(tilemap_tiles_tools_buttons); // -- TileMap tool settings -- @@ -1671,7 +1835,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { // Random tile checkbox. random_tile_checkbox = memnew(CheckBox); random_tile_checkbox->set_flat(true); - random_tile_checkbox->set_text(TTR("Place random tile")); + random_tile_checkbox->set_text(TTR("Place Random Tile")); random_tile_checkbox->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled)); tools_settings->add_child(random_tile_checkbox); @@ -1692,6 +1856,18 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { _on_random_tile_checkbox_toggled(false); + // Wide empty separation control. + Control *h_empty_space = memnew(Control); + h_empty_space->set_h_size_flags(SIZE_EXPAND_FILL); + toolbar->add_child(h_empty_space); + + // Grid toggle. + toggle_grid_button = memnew(Button); + toggle_grid_button->set_flat(true); + toggle_grid_button->set_toggle_mode(true); + toggle_grid_button->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_grid_toggled)); + toolbar->add_child(toggle_grid_button); + // Default tool. paint_tool_button->set_pressed(true); _update_toolbar(); @@ -1718,20 +1894,20 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { sources_list->set_h_size_flags(SIZE_EXPAND_FILL); sources_list->set_stretch_ratio(0.25); sources_list->set_custom_minimum_size(Size2i(70, 0) * EDSCALE); + sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1)); - sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_atlas_view).unbind(1)); + sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_bottom_panel).unbind(1)); sources_list->connect("item_selected", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_atlas_sources_lists_current)); sources_list->connect("visibility_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::synchronize_atlas_sources_list), varray(sources_list)); - //sources_list->set_drag_forwarding(this); atlas_sources_split_container->add_child(sources_list); + // Tile atlas source. tile_atlas_view = memnew(TileAtlasView); tile_atlas_view->set_h_size_flags(SIZE_EXPAND_FILL); tile_atlas_view->set_v_size_flags(SIZE_EXPAND_FILL); tile_atlas_view->set_texture_grid_visible(false); tile_atlas_view->set_tile_shape_grid_visible(false); tile_atlas_view->connect("transform_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_atlas_view_transform)); - //tile_atlas_view->connect("visibility_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::synchronize_atlas_view), varray(tile_atlas_view)); atlas_sources_split_container->add_child(tile_atlas_view); tile_atlas_control = memnew(Control); @@ -1746,6 +1922,27 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { alternative_tiles_control->connect("gui_input", callable_mp(this, &TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input)); tile_atlas_view->add_control_over_alternative_tiles(alternative_tiles_control); + // Scenes collection source. + scene_tiles_list = memnew(ItemList); + scene_tiles_list->set_h_size_flags(SIZE_EXPAND_FILL); + scene_tiles_list->set_v_size_flags(SIZE_EXPAND_FILL); + scene_tiles_list->set_drag_forwarding(this); + scene_tiles_list->set_select_mode(ItemList::SELECT_MULTI); + scene_tiles_list->connect("multi_selected", callable_mp(this, &TileMapEditorTilesPlugin::_scenes_list_multi_selected)); + scene_tiles_list->connect("nothing_selected", callable_mp(this, &TileMapEditorTilesPlugin::_scenes_list_nothing_selected)); + scene_tiles_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); + atlas_sources_split_container->add_child(scene_tiles_list); + + // Invalid source label. + invalid_source_label = memnew(Label); + invalid_source_label->set_text(TTR("Invalid source selected.")); + invalid_source_label->set_h_size_flags(SIZE_EXPAND_FILL); + invalid_source_label->set_v_size_flags(SIZE_EXPAND_FILL); + invalid_source_label->set_align(Label::ALIGN_CENTER); + invalid_source_label->set_valign(Label::VALIGN_CENTER); + invalid_source_label->hide(); + atlas_sources_split_container->add_child(invalid_source_label); + _update_bottom_panel(); } @@ -2147,7 +2344,7 @@ Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_c Map<int, int> terrain_count; - // Count the number of occurences per terrain. + // Count the number of occurrences per terrain. Map<Vector2i, TileSet::CellNeighbor> overlapping_terrain_bits = c.get_overlapping_coords_and_peering_bits(); for (Map<Vector2i, TileSet::CellNeighbor>::Element *E_overlapping = overlapping_terrain_bits.front(); E_overlapping; E_overlapping = E_overlapping->next()) { if (!p_to_replace.has(E_overlapping->key())) { @@ -2165,7 +2362,7 @@ Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_c } } - // Get the terrain with the max number of occurences. + // Get the terrain with the max number of occurrences. int max = 0; int max_terrain = -1; for (Map<int, int>::Element *E_terrain_count = terrain_count.front(); E_terrain_count; E_terrain_count = E_terrain_count->next()) { @@ -2231,7 +2428,7 @@ Map<Vector2i, TileMapEditorTerrainsPlugin::TerrainsTilePattern> TileMapEditorTer per_cell_acceptable_tiles[E->get()] = _get_valid_terrains_tile_patterns_for_constraints(p_terrain_set, E->get(), constraints); } - // Ouput map. + // Output map. Map<Vector2i, TerrainsTilePattern> output; // Add all positions to a set. @@ -2450,7 +2647,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map output[E->key()] = _get_random_tile_from_pattern(p_terrain_set, E->get()); } - // Override the WFC results to make sure at least the painted tiles are acutally painted. + // Override the WFC results to make sure at least the painted tiles are actually painted. for (Map<Vector2i, TerrainsTilePattern>::Element *E_to_paint = p_to_paint.front(); E_to_paint; E_to_paint = E_to_paint->next()) { output[E_to_paint->key()] = _get_random_tile_from_pattern(p_terrain_set, E_to_paint->get()); } @@ -2587,7 +2784,7 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent> } if (need_tree_item_switch) { - for (tree_item = terrains_tree->get_root()->get_children(); tree_item; tree_item = tree_item->get_next_visible()) { + for (tree_item = terrains_tree->get_root()->get_first_child(); tree_item; tree_item = tree_item->get_next_visible()) { Dictionary metadata_dict = tree_item->get_metadata(0); if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) { int terrain_set = metadata_dict["terrain_set"]; @@ -2771,8 +2968,8 @@ void TileMapEditorTerrainsPlugin::_update_terrains_cache() { TileMapCell empty_cell; empty_cell.source_id = -1; - empty_cell.set_atlas_coords(TileSetAtlasSource::INVALID_ATLAS_COORDS); - empty_cell.alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + empty_cell.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS); + empty_cell.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; per_terrain_terrains_tile_patterns_tiles[i][empty_pattern].insert(empty_cell); } } @@ -2798,15 +2995,15 @@ void TileMapEditorTerrainsPlugin::_update_terrains_tree() { String matches; if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS_AND_SIDES) { terrain_set_tree_item->set_icon(0, get_theme_icon("TerrainMatchCornersAndSides", "EditorIcons")); - matches = String(TTR("Matches corners and sides")); + matches = String(TTR("Matches Corners and Sides")); } else if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS) { terrain_set_tree_item->set_icon(0, get_theme_icon("TerrainMatchCorners", "EditorIcons")); - matches = String(TTR("Matches corners only")); + matches = String(TTR("Matches Corners Only")); } else { terrain_set_tree_item->set_icon(0, get_theme_icon("TerrainMatchSides", "EditorIcons")); - matches = String(TTR("Matches sides only")); + matches = String(TTR("Matches Sides Only")); } - terrain_set_tree_item->set_text(0, vformat("Terrain set %d (%s)", terrain_set_index, matches)); + terrain_set_tree_item->set_text(0, vformat("Terrain Set %d (%s)", terrain_set_index, matches)); terrain_set_tree_item->set_selectable(0, false); for (int terrain_index = 0; terrain_index < tile_set->get_terrains_count(terrain_set_index); terrain_index++) { @@ -3263,19 +3460,25 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { } // Draw the grid. - for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) { - for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) { - Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position; + bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + if (display_grid) { + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) { + for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) { + Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position; - // Fade out the border of the grid. - float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); - float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); - float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); + // Fade out the border of the grid. + float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 0.5, 0.2, 0.5 * opacity), false); + Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); + Color color = grid_color; + color.a = color.a * opacity; + tile_set->draw_tile_shape(p_overlay, cell_region, color, false); + } } } @@ -3337,9 +3540,8 @@ TileMapEditor::TileMapEditor() { // --- TileMap toolbar --- tilemap_toolbar = memnew(HBoxContainer); - //tilemap_toolbar->add_child(memnew(VSeparator)); + tilemap_toolbar->set_h_size_flags(SIZE_EXPAND_FILL); tilemap_toolbar->add_child(tabs); - //tilemap_toolbar->add_child(memnew(VSeparator)); for (int i = 0; i < tile_map_editor_plugins.size(); i++) { tile_map_editor_plugins[i]->get_toolbar()->hide(); tilemap_toolbar->add_child(tile_map_editor_plugins[i]->get_toolbar()); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index f780686b82..a6f4ec3021 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -58,7 +58,7 @@ private: ObjectID tile_map_id; virtual void edit(ObjectID p_tile_map_id) override; - // Toolbar. + ///// Toolbar ///// HBoxContainer *toolbar; Ref<ButtonGroup> tool_buttons_group; @@ -82,9 +82,12 @@ private: void _on_random_tile_checkbox_toggled(bool p_pressed); void _on_scattering_spinbox_changed(double p_value); + Button *toggle_grid_button; + void _on_grid_toggled(bool p_pressed); + void _update_toolbar(); - // Tilemap editing. + ///// Tilemap editing. ///// bool has_mouse = false; void _mouse_exited_viewport(); @@ -105,12 +108,12 @@ private: Map<Vector2i, TileMapCell> drag_modified; TileMapCell _pick_random_tile(const TileMapPattern *p_pattern); - Map<Vector2i, TileMapCell> _draw_line(Vector2 p_start_drag_mouse_pos, Vector2 p_from_mouse_pos, Vector2i p_to_mouse_pos); - Map<Vector2i, TileMapCell> _draw_rect(Vector2i p_start_mouse_pos, Vector2i p_end_mouse_pos); + Map<Vector2i, TileMapCell> _draw_line(Vector2 p_start_drag_mouse_pos, Vector2 p_from_mouse_pos, Vector2 p_to_mouse_pos); + Map<Vector2i, TileMapCell> _draw_rect(Vector2i p_start_cell, Vector2i p_end_cell); Map<Vector2i, TileMapCell> _draw_bucket_fill(Vector2i p_coords, bool p_contiguous); void _stop_dragging(); - // Selection system. + ///// Selection system. ///// Set<Vector2i> tile_map_selection; TileMapPattern *tile_map_clipboard = memnew(TileMapPattern); TileMapPattern *selection_pattern = memnew(TileMapPattern); @@ -124,22 +127,24 @@ private: void _update_tileset_selection_from_selection_pattern(); void _update_fix_selected_and_hovered(); - // Bottom panel. - bool tile_set_dragging_selection = false; - Vector2i tile_set_drag_start_mouse_pos; - + ///// Bottom panel. ////. Label *missing_source_label; - HSplitContainer *atlas_sources_split_container; + Label *invalid_source_label; ItemList *sources_list; - TileAtlasView *tile_atlas_view; - Ref<Texture2D> missing_texture_texture; + + Ref<Texture2D> missing_atlas_texture_icon; void _update_tile_set_sources_list(); - void _update_atlas_view(); void _update_bottom_panel(); + // Atlas sources. TileMapCell hovered_tile; + TileAtlasView *tile_atlas_view; + HSplitContainer *atlas_sources_split_container; + + bool tile_set_dragging_selection = false; + Vector2i tile_set_drag_start_mouse_pos; Control *tile_atlas_control; void _tile_atlas_control_mouse_exited(); @@ -151,6 +156,16 @@ private: void _tile_alternatives_control_mouse_exited(); void _tile_alternatives_control_gui_input(const Ref<InputEvent> &p_event); + void _update_atlas_view(); + + // Scenes collection sources. + ItemList *scene_tiles_list; + + void _update_scenes_collection_view(); + void _scene_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud); + void _scenes_list_multi_selected(int p_index, bool p_selected); + void _scenes_list_nothing_selected(); + // Update callback virtual void tile_set_changed() override; diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 8492202122..8e7d613027 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -53,10 +53,10 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::set_id(int p_id) { if (source_id == p_id) { return; } - ERR_FAIL_COND_MSG(tile_set->has_source(p_id), vformat("Cannot change TileSet atlas source ID. Another atlas source exists with id %d.", p_id)); + ERR_FAIL_COND_MSG(tile_set->has_source(p_id), vformat("Cannot change TileSet Atlas Source ID. Another source exists with id %d.", p_id)); int previous_source = source_id; - source_id = p_id; // source_id must be updated before, because it's used by the atlas source list update. + source_id = p_id; // source_id must be updated before, because it's used by the source list update. tile_set->set_source_id(previous_source, p_id); emit_signal("changed", "id"); } @@ -126,7 +126,7 @@ void TileSetAtlasSourceEditor::TileSetAtlasSourceProxyObject::edit(Ref<TileSet> } // -- Proxy object used by the tile inspector -- -bool TileSetAtlasSourceEditor::TileProxyObject::_set(const StringName &p_name, const Variant &p_value) { +bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_name, const Variant &p_value) { if (!tile_set_atlas_source) { return false; } @@ -152,9 +152,9 @@ bool TileSetAtlasSourceEditor::TileProxyObject::_set(const StringName &p_name, c return true; } else if (alternative == 0 && p_name == "size_in_atlas") { Vector2i as_vector2i = Vector2i(p_value); - ERR_FAIL_COND_V(!tile_set_atlas_source->can_move_tile_in_atlas(coords, TileSetAtlasSource::INVALID_ATLAS_COORDS, as_vector2i), false); + ERR_FAIL_COND_V(!tile_set_atlas_source->can_move_tile_in_atlas(coords, TileSetSource::INVALID_ATLAS_COORDS, as_vector2i), false); - tile_set_atlas_source->move_tile_in_atlas(coords, TileSetAtlasSource::INVALID_ATLAS_COORDS, as_vector2i); + tile_set_atlas_source->move_tile_in_atlas(coords, TileSetSource::INVALID_ATLAS_COORDS, as_vector2i); emit_signal("changed", "size_in_atlas"); return true; } else if (alternative > 0 && p_name == "alternative_id") { @@ -197,7 +197,7 @@ bool TileSetAtlasSourceEditor::TileProxyObject::_set(const StringName &p_name, c return any_valid; } -bool TileSetAtlasSourceEditor::TileProxyObject::_get(const StringName &p_name, Variant &r_ret) const { +bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_get(const StringName &p_name, Variant &r_ret) const { if (!tile_set_atlas_source) { return false; } @@ -237,7 +237,7 @@ bool TileSetAtlasSourceEditor::TileProxyObject::_get(const StringName &p_name, V return false; } -void TileSetAtlasSourceEditor::TileProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { +void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { if (!tile_set_atlas_source) { return; } @@ -310,12 +310,11 @@ void TileSetAtlasSourceEditor::TileProxyObject::_get_property_list(List<Property } } -void TileSetAtlasSourceEditor::TileProxyObject::edit(TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id, Set<TileSelection> p_tiles) { +void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(TileSetAtlasSource *p_tile_set_atlas_source, Set<TileSelection> p_tiles) { ERR_FAIL_COND(!p_tile_set_atlas_source); - ERR_FAIL_COND(p_source_id < 0); ERR_FAIL_COND(p_tiles.is_empty()); for (Set<TileSelection>::Element *E = p_tiles.front(); E; E = E->next()) { - ERR_FAIL_COND(E->get().tile == TileSetAtlasSource::INVALID_ATLAS_COORDS); + ERR_FAIL_COND(E->get().tile == TileSetSource::INVALID_ATLAS_COORDS); ERR_FAIL_COND(E->get().alternative < 0); } @@ -333,7 +332,6 @@ void TileSetAtlasSourceEditor::TileProxyObject::edit(TileSetAtlasSource *p_tile_ } tile_set_atlas_source = p_tile_set_atlas_source; - source_id = p_source_id; tiles = Set<TileSelection>(p_tiles); // Connect to changes. @@ -352,7 +350,7 @@ void TileSetAtlasSourceEditor::TileProxyObject::edit(TileSetAtlasSource *p_tile_ notify_property_list_changed(); } -void TileSetAtlasSourceEditor::TileProxyObject::_bind_methods() { +void TileSetAtlasSourceEditor::AtlasTileProxyObject::_bind_methods() { ADD_SIGNAL(MethodInfo("changed", PropertyInfo(Variant::STRING, "what"))); } @@ -391,12 +389,12 @@ void TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles() { // Fix hovered. if (!tile_set_atlas_source->has_tile(hovered_base_tile_coords)) { - hovered_base_tile_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS; + hovered_base_tile_coords = TileSetSource::INVALID_ATLAS_COORDS; } Vector2i coords = Vector2i(hovered_alternative_tile_coords.x, hovered_alternative_tile_coords.y); int alternative = hovered_alternative_tile_coords.z; if (!tile_set_atlas_source->has_tile(coords) || !tile_set_atlas_source->has_alternative_tile(coords, alternative)) { - hovered_alternative_tile_coords = Vector3i(TileSetAtlasSource::INVALID_ATLAS_COORDS.x, TileSetAtlasSource::INVALID_ATLAS_COORDS.y, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + hovered_alternative_tile_coords = Vector3i(TileSetSource::INVALID_ATLAS_COORDS.x, TileSetSource::INVALID_ATLAS_COORDS.y, TileSetSource::INVALID_TILE_ALTERNATIVE); } } @@ -405,7 +403,7 @@ void TileSetAtlasSourceEditor::_update_tile_inspector() { // Update the proxy object. if (has_atlas_tile_selected) { - tile_proxy_object->edit(tile_set_atlas_source, tile_set_atlas_source_id, selection); + tile_proxy_object->edit(tile_set_atlas_source, selection); } // Update visibility. @@ -486,7 +484,7 @@ void TileSetAtlasSourceEditor::_update_toolbar() { } void TileSetAtlasSourceEditor::_tile_atlas_control_mouse_exited() { - hovered_base_tile_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS; + hovered_base_tile_coords = TileSetSource::INVALID_ATLAS_COORDS; tile_atlas_control->update(); tile_atlas_control_unscaled->update(); tile_atlas_view->update(); @@ -514,7 +512,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven if (selection.size() == 1) { // Change the cursor depending on the hovered thing. TileSelection selected = selection.front()->get(); - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS && selected.alternative == 0) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS && selected.alternative == 0) { Vector2 mouse_local_pos = tile_atlas_control->get_local_mouse_position(); Vector2i size_in_atlas = tile_set_atlas_source->get_tile_size_in_atlas(selected.tile); Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile); @@ -560,7 +558,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven Vector<Point2i> line = Geometry2D::bresenham_line(last_base_tiles_coords, new_base_tiles_coords); for (int i = 0; i < line.size(); i++) { - if (tile_set_atlas_source->get_tile_at_coords(line[i]) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile_set_atlas_source->get_tile_at_coords(line[i]) == TileSetSource::INVALID_ATLAS_COORDS) { tile_set_atlas_source->create_tile(line[i]); drag_modified_tiles.insert(line[i]); } @@ -576,7 +574,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven Vector<Point2i> line = Geometry2D::bresenham_line(last_base_tiles_coords, new_base_tiles_coords); for (int i = 0; i < line.size(); i++) { Vector2i base_tile_coords = tile_set_atlas_source->get_tile_at_coords(line[i]); - if (base_tile_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (base_tile_coords != TileSetSource::INVALID_ATLAS_COORDS) { drag_modified_tiles.insert(base_tile_coords); } } @@ -662,17 +660,17 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Remove a first tile. Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { coords = tile_set_atlas_source->get_tile_at_coords(coords); } - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { drag_modified_tiles.insert(coords); } } else { - if (mb->get_shift()) { + if (mb->is_shift_pressed()) { // Create a big tile. Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(mouse_local_pos); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS && tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { // Setup the dragging info, only if we start on an empty tile. drag_type = DRAG_TYPE_CREATE_BIG_TILE; drag_start_mouse_pos = mouse_local_pos; @@ -692,7 +690,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Create a first tile if needed. Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS && tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { tile_set_atlas_source->create_tile(coords); drag_modified_tiles.insert(coords); } @@ -707,10 +705,10 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven drag_start_mouse_pos = mouse_local_pos; drag_last_mouse_pos = drag_start_mouse_pos; } else { - if (mb->get_shift()) { + if (mb->is_shift_pressed()) { // Create a big tile. Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(mouse_local_pos); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS && tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS && tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { // Setup the dragging info, only if we start on an empty tile. drag_type = DRAG_TYPE_CREATE_BIG_TILE; drag_start_mouse_pos = mouse_local_pos; @@ -732,7 +730,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven drag_type = DRAG_TYPE_NONE; if (selection.size() == 1) { TileSelection selected = selection.front()->get(); - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS && selected.alternative == 0) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS && selected.alternative == 0) { Vector2i size_in_atlas = tile_set_atlas_source->get_tile_size_in_atlas(selected.tile); Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile); Size2 zoomed_size = resize_handle->get_size() / tile_atlas_view->get_zoom(); @@ -771,17 +769,17 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Selecting then dragging a tile. if (drag_type == DRAG_TYPE_NONE) { - TileSelection selected = { TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE }; + TileSelection selected = { TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE }; Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(mouse_local_pos); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { coords = tile_set_atlas_source->get_tile_at_coords(coords); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { selected = { coords, 0 }; } } - bool shift = mb->get_shift(); - if (!shift && selection.size() == 1 && selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS && selection.has(selected)) { + bool shift = mb->is_shift_pressed(); + if (!shift && selection.size() == 1 && selected.tile != TileSetSource::INVALID_ATLAS_COORDS && selection.has(selected)) { // Start move dragging. drag_type = DRAG_TYPE_MOVE_TILE; drag_start_mouse_pos = mouse_local_pos; @@ -812,13 +810,13 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven // Right click pressed. TileSelection selected = { tile_atlas_view->get_atlas_tile_coords_at_pos(mouse_local_pos), 0 }; - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS) { selected.tile = tile_set_atlas_source->get_tile_at_coords(selected.tile); } // Set the selection if needed. if (selection.size() <= 1) { - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS) { undo_redo->create_action(TTR("Select tiles")); undo_redo->add_undo_method(this, "_set_selection_from_array", _get_selection_as_array()); selection.clear(); @@ -831,15 +829,15 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven } // Pops up the correct menu, depending on whether we have a tile or not. - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS && selection.has(selected)) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS && selection.has(selected)) { // We have a tile. menu_option_coords = selected.tile; menu_option_alternative = 0; base_tile_popup_menu->popup(Rect2i(get_global_mouse_position(), Size2i())); - } else if (hovered_base_tile_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + } else if (hovered_base_tile_coords != TileSetSource::INVALID_ATLAS_COORDS) { // We don't have a tile, but can create one. menu_option_coords = hovered_base_tile_coords; - menu_option_alternative = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + menu_option_alternative = TileSetSource::INVALID_TILE_ALTERNATIVE; empty_base_tile_popup_menu->popup(Rect2i(get_global_mouse_position(), Size2i())); } } else { @@ -902,7 +900,7 @@ void TileSetAtlasSourceEditor::_end_dragging() { for (int x = area.get_position().x; x < area.get_end().x; x++) { for (int y = area.get_position().y; y < area.get_end().y; y++) { Vector2i coords = Vector2i(x, y); - if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { undo_redo->add_do_method(tile_set_atlas_source, "create_tile", coords); undo_redo->add_undo_method(tile_set_atlas_source, "remove_tile", coords); } @@ -923,7 +921,7 @@ void TileSetAtlasSourceEditor::_end_dragging() { for (int x = area.get_position().x; x < area.get_end().x; x++) { for (int y = area.get_position().y; y < area.get_end().y; y++) { Vector2i coords = tile_set_atlas_source->get_tile_at_coords(Vector2i(x, y)); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { to_delete.insert(coords); } } @@ -964,8 +962,8 @@ void TileSetAtlasSourceEditor::_end_dragging() { case DRAG_TYPE_RECT_SELECT: { Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); - ERR_FAIL_COND(start_base_tiles_coords == TileSetAtlasSource::INVALID_ATLAS_COORDS); - ERR_FAIL_COND(new_base_tiles_coords == TileSetAtlasSource::INVALID_ATLAS_COORDS); + ERR_FAIL_COND(start_base_tiles_coords == TileSetSource::INVALID_ATLAS_COORDS); + ERR_FAIL_COND(new_base_tiles_coords == TileSetSource::INVALID_ATLAS_COORDS); Rect2i region = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs(); region.size += Vector2i(1, 1); @@ -977,7 +975,7 @@ void TileSetAtlasSourceEditor::_end_dragging() { bool add_to_selection = true; if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { Vector2i coords = tile_set_atlas_source->get_tile_at_coords(start_base_tiles_coords); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { if (selection.has({ coords, 0 })) { add_to_selection = false; } @@ -991,7 +989,7 @@ void TileSetAtlasSourceEditor::_end_dragging() { for (int y = region.position.y; y < region.get_end().y; y++) { Vector2i coords = Vector2i(x, y); coords = tile_set_atlas_source->get_tile_at_coords(coords); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { if (add_to_selection && !selection.has({ coords, 0 })) { selection.insert({ coords, 0 }); } else if (!add_to_selection && selection.has({ coords, 0 })) { @@ -1180,6 +1178,10 @@ Array TileSetAtlasSourceEditor::_get_selection_as_array() { } void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { + // Colors. + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); + // Draw the selected tile. if (tools_button_group->get_pressed_button() == tool_select_button) { for (Set<TileSelection>::Element *E = selection.front(); E; E = E->next()) { @@ -1187,7 +1189,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { if (selected.alternative == 0) { // Draw the rect. Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile); - tile_atlas_control->draw_rect(region, Color(0.2, 0.2, 1.0), false); + tile_atlas_control->draw_rect(region, selection_color, false); } } @@ -1236,14 +1238,14 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { Color color = Color(0.0, 0.0, 0.0); if (drag_type == DRAG_TYPE_RECT_SELECT) { - color = Color(0.5, 0.5, 1.0); + color = selection_color.lightened(0.2); } Set<Vector2i> to_paint; for (int x = area.get_position().x; x < area.get_end().x; x++) { for (int y = area.get_position().y; y < area.get_end().y; y++) { Vector2i coords = tile_set_atlas_source->get_tile_at_coords(Vector2i(x, y)); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { to_paint.insert(coords); } } @@ -1266,7 +1268,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { for (int x = area.get_position().x; x < area.get_end().x; x++) { for (int y = area.get_position().y; y < area.get_end().y; y++) { Vector2i coords = Vector2i(x, y); - if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { Vector2i origin = margins + (coords * (tile_size + separation)); tile_atlas_control->draw_rect(Rect2i(origin, tile_size), Color(1.0, 1.0, 1.0), false); } @@ -1290,7 +1292,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size(); if (hovered_base_tile_coords.x >= 0 && hovered_base_tile_coords.y >= 0 && hovered_base_tile_coords.x < grid_size.x && hovered_base_tile_coords.y < grid_size.y) { Vector2i hovered_tile = tile_set_atlas_source->get_tile_at_coords(hovered_base_tile_coords); - if (hovered_tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (hovered_tile != TileSetSource::INVALID_ATLAS_COORDS) { // Draw existing hovered tile. tile_atlas_control->draw_rect(tile_set_atlas_source->get_tile_texture_region(hovered_tile), Color(1.0, 1.0, 1.0), false); } else { @@ -1349,7 +1351,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In selection.clear(); TileSelection selected = { Vector2i(tile.x, tile.y), int(tile.z) }; - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS) { selection.insert(selected); } @@ -1364,7 +1366,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In selection.clear(); TileSelection selected = { Vector2i(tile.x, tile.y), int(tile.z) }; - if (selected.tile != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (selected.tile != TileSetSource::INVALID_ATLAS_COORDS) { selection.insert(selected); } @@ -1387,7 +1389,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_gui_input(const Ref<In } void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() { - hovered_alternative_tile_coords = Vector3i(TileSetAtlasSource::INVALID_ATLAS_COORDS.x, TileSetAtlasSource::INVALID_ATLAS_COORDS.y, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + hovered_alternative_tile_coords = Vector3i(TileSetSource::INVALID_ATLAS_COORDS.x, TileSetSource::INVALID_ATLAS_COORDS.y, TileSetSource::INVALID_TILE_ALTERNATIVE); tile_atlas_control->update(); tile_atlas_control_unscaled->update(); alternative_tiles_control->update(); @@ -1395,11 +1397,14 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() { } void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() { + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); + // Update the hovered alternative tile. if (tools_button_group->get_pressed_button() == tool_select_button) { // Draw hovered tile. Vector2i coords = Vector2(hovered_alternative_tile_coords.x, hovered_alternative_tile_coords.y); - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { Rect2i rect = tile_atlas_view->get_alternative_tile_rect(coords, hovered_alternative_tile_coords.z); if (rect != Rect2i()) { alternative_tiles_control->draw_rect(rect, Color(1.0, 1.0, 1.0), false); @@ -1412,7 +1417,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() { if (selected.alternative >= 1) { Rect2i rect = tile_atlas_view->get_alternative_tile_rect(selected.tile, selected.alternative); if (rect != Rect2i()) { - alternative_tiles_control->draw_rect(rect, Color(0.2, 0.2, 1.0), false); + alternative_tiles_control->draw_rect(rect, selection_color, false); } } } @@ -1441,7 +1446,7 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo #define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, tile_data->get(property)); - TileProxyObject *tile_data = Object::cast_to<TileProxyObject>(p_edited); + AtlasTileProxyObject *tile_data = Object::cast_to<AtlasTileProxyObject>(p_edited); if (tile_data) { Vector<String> components = String(p_property).split("/", true, 2); if (components.size() == 2 && components[1] == "shapes_count") { @@ -1518,7 +1523,7 @@ void TileSetAtlasSourceEditor::_auto_create_tiles() { for (int x = 0; x < grid_size.x; x++) { // Check if we have a tile at the coord Vector2i coords = Vector2i(x, y); - if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (tile_set_atlas_source->get_tile_at_coords(coords) == TileSetSource::INVALID_ATLAS_COORDS) { // Check if the texture is empty at the given coords. Rect2i region = Rect2i(margins + (coords * (texture_region_size + separation)), texture_region_size); bool is_opaque = false; @@ -1669,11 +1674,11 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { // Tile inspector. tile_inspector_label = memnew(Label); - tile_inspector_label->set_text(TTR("Tile properties:")); + tile_inspector_label->set_text(TTR("Tile Properties:")); tile_inspector_label->hide(); middle_vbox_container->add_child(tile_inspector_label); - tile_proxy_object = memnew(TileProxyObject(this)); + tile_proxy_object = memnew(AtlasTileProxyObject(this)); tile_proxy_object->connect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_update_atlas_view).unbind(1)); tile_inspector = memnew(EditorInspector); @@ -1686,7 +1691,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { // Atlas source inspector. atlas_source_inspector_label = memnew(Label); - atlas_source_inspector_label->set_text(TTR("Atlas properties:")); + atlas_source_inspector_label->set_text(TTR("Atlas Properties:")); middle_vbox_container->add_child(atlas_source_inspector_label); atlas_source_proxy_object = memnew(TileSetAtlasSourceProxyObject()); @@ -1724,7 +1729,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tool_select_button->set_toggle_mode(true); tool_select_button->set_pressed(true); tool_select_button->set_button_group(tools_button_group); - tool_select_button->set_tooltip(TTR("Select tiles")); + tool_select_button->set_tooltip(TTR("Select tiles.")); tool_select_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles)); tool_select_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_tile_id_label)); tool_select_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_tile_inspector)); @@ -1736,7 +1741,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tool_add_remove_button->set_flat(true); tool_add_remove_button->set_toggle_mode(true); tool_add_remove_button->set_button_group(tools_button_group); - tool_add_remove_button->set_tooltip(TTR("Add/Remove tiles tool (use the shift key to create big tiles)")); + tool_add_remove_button->set_tooltip(TTR("Add/Remove tiles tool (use the shift key to create big tiles).")); tool_add_remove_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles)); tool_add_remove_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_tile_id_label)); tool_add_remove_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_tile_inspector)); @@ -1748,7 +1753,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tool_add_remove_rect_button->set_flat(true); tool_add_remove_rect_button->set_toggle_mode(true); tool_add_remove_rect_button->set_button_group(tools_button_group); - tool_add_remove_rect_button->set_tooltip(TTR("Add/Remove tiles rectangle tool (use the shift key to create big tiles)")); + tool_add_remove_rect_button->set_tooltip(TTR("Add/Remove tiles rectangle tool (use the shift key to create big tiles).")); tool_add_remove_rect_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_fix_selected_and_hovered_tiles)); tool_add_remove_rect_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_tile_id_label)); tool_add_remove_rect_button->connect("pressed", callable_mp(this, &TileSetAtlasSourceEditor::_update_tile_inspector)); @@ -1775,10 +1780,10 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tool_advanced_menu_buttom = memnew(MenuButton); tool_advanced_menu_buttom->set_flat(true); - tool_advanced_menu_buttom->get_popup()->add_item(TTR("Cleanup tiles outside texture"), ADVANCED_CLEANUP_TILES_OUTSIDE_TEXTURE); + tool_advanced_menu_buttom->get_popup()->add_item(TTR("Cleanup Tiles Outside Texture"), ADVANCED_CLEANUP_TILES_OUTSIDE_TEXTURE); tool_advanced_menu_buttom->get_popup()->set_item_disabled(0, true); - tool_advanced_menu_buttom->get_popup()->add_item(TTR("Create tiles in non-transparent texture regions."), ADVANCED_AUTO_CREATE_TILES); - tool_advanced_menu_buttom->get_popup()->add_item(TTR("Remove tiles in fully transparent texture regions."), ADVANCED_AUTO_REMOVE_TILES); + tool_advanced_menu_buttom->get_popup()->add_item(TTR("Create Tiles in Non-Transparent Texture Regions"), ADVANCED_AUTO_CREATE_TILES); + tool_advanced_menu_buttom->get_popup()->add_item(TTR("Remove Tiles in Fully Transparent Texture Regions"), ADVANCED_AUTO_REMOVE_TILES); tool_advanced_menu_buttom->get_popup()->connect("id_pressed", callable_mp(this, &TileSetAtlasSourceEditor::_menu_option)); toolbox->add_child(tool_advanced_menu_buttom); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h index ff68aa8288..70f2cdbe01 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.h +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h @@ -45,8 +45,8 @@ class TileSetAtlasSourceEditor : public HBoxContainer { private: // A class to store which tiles are selected. struct TileSelection { - Vector2i tile = TileSetAtlasSource::INVALID_ATLAS_COORDS; - int alternative = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + Vector2i tile = TileSetSource::INVALID_ATLAS_COORDS; + int alternative = TileSetSource::INVALID_TILE_ALTERNATIVE; bool operator<(const TileSelection &p_other) const { if (tile == p_other.tile) { @@ -80,14 +80,13 @@ private: }; // -- Proxy object for a tile, needed by the inspector -- - class TileProxyObject : public Object { - GDCLASS(TileProxyObject, Object); + class AtlasTileProxyObject : public Object { + GDCLASS(AtlasTileProxyObject, Object); private: TileSetAtlasSourceEditor *tiles_set_atlas_source_editor; TileSetAtlasSource *tile_set_atlas_source = nullptr; - int source_id; Set<TileSelection> tiles = Set<TileSelection>(); protected: @@ -99,10 +98,10 @@ private: public: // Update the proxyed object. - void edit(TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id = -1, Set<TileSelection> p_tiles = Set<TileSelection>()); + void edit(TileSetAtlasSource *p_tile_set_atlas_source, Set<TileSelection> p_tiles = Set<TileSelection>()); - TileProxyObject(TileSetAtlasSourceEditor *p_tiles_editor_source_tab) { - tiles_set_atlas_source_editor = p_tiles_editor_source_tab; + AtlasTileProxyObject(TileSetAtlasSourceEditor *p_tiles_set_atlas_source_editor) { + tiles_set_atlas_source_editor = p_tiles_set_atlas_source_editor; } }; @@ -115,7 +114,7 @@ private: bool tile_set_atlas_source_changed_needs_update = false; // -- Inspector -- - TileProxyObject *tile_proxy_object; + AtlasTileProxyObject *tile_proxy_object; Label *tile_inspector_label; EditorInspector *tile_inspector; String selected_property; @@ -175,7 +174,7 @@ private: ADVANCED_AUTO_REMOVE_TILES, }; Vector2i menu_option_coords; - int menu_option_alternative = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + int menu_option_alternative = TileSetSource::INVALID_TILE_ALTERNATIVE; void _menu_option(int p_option); // Tool buttons. @@ -198,7 +197,7 @@ private: Array _get_selection_as_array(); // A control on the tile atlas to draw and handle input events. - Vector2i hovered_base_tile_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS; + Vector2i hovered_base_tile_coords = TileSetSource::INVALID_ATLAS_COORDS; PopupMenu *base_tile_popup_menu; PopupMenu *empty_base_tile_popup_menu; @@ -213,7 +212,7 @@ private: void _tile_atlas_view_transform_changed(); // A control over the alternative tiles. - Vector3i hovered_alternative_tile_coords = Vector3i(TileSetAtlasSource::INVALID_ATLAS_COORDS.x, TileSetAtlasSource::INVALID_ATLAS_COORDS.y, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + Vector3i hovered_alternative_tile_coords = Vector3i(TileSetSource::INVALID_ATLAS_COORDS.x, TileSetSource::INVALID_ATLAS_COORDS.y, TileSetSource::INVALID_TILE_ALTERNATIVE); PopupMenu *alternative_tile_popup_menu; Control *alternative_tiles_control; diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 8a5890e9a4..6078c986cb 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -76,7 +76,7 @@ void TileSetEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, C tile_set_atlas_source_editor->init_source(); } - // Update the selected source (thus trigerring an update). + // Update the selected source (thus triggering an update). _update_atlas_sources_list(source_id); } } @@ -140,20 +140,39 @@ void TileSetEditor::_update_atlas_sources_list(int force_selected_id) { for (int i = 0; i < tile_set->get_source_count(); i++) { int source_id = tile_set->get_source_id(i); - // TODO: handle with virtual functions TileSetSource *source = *tile_set->get_source(source_id); + + Ref<Texture2D> texture; + String item_text; + + // Atlas source. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { - Ref<Texture2D> texture = atlas_source->get_texture(); + texture = atlas_source->get_texture(); if (texture.is_valid()) { - sources_list->add_item(vformat("%s - (id:%d)", texture->get_path().get_file(), source_id), texture); + item_text = vformat("%s (id:%d)", texture->get_path().get_file(), source_id); } else { - sources_list->add_item(vformat("No texture atlas source - (id:%d)", source_id), missing_texture_texture); + item_text = vformat(TTR("No Texture Atlas Source (id:%d)"), source_id); } - } else { - sources_list->add_item(vformat("Unknown type source - (id:%d)", source_id), missing_texture_texture); } - sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id); + + // Scene collection source. + TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + if (scene_collection_source) { + texture = get_theme_icon("PackedScene", "EditorIcons"); + item_text = vformat(TTR("Scene Collection Source (id:%d)"), source_id); + } + + // Use default if not valid. + if (item_text.is_empty()) { + item_text = vformat(TTR("Unknown Type Source (id:%d)"), source_id); + } + if (!texture.is_valid()) { + texture = missing_texture_texture; + } + + sources_list->add_item(item_text, texture); + sources_list->set_item_metadata(i, source_id); } // Set again the current selected item if needed. @@ -193,35 +212,63 @@ void TileSetEditor::_source_selected(int p_source_index) { if (p_source_index >= 0) { int source_id = sources_list->get_item_metadata(p_source_index); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(*tile_set->get_source(source_id)); + TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(*tile_set->get_source(source_id)); if (atlas_source) { - tile_set_atlas_source_editor->edit(*tile_set, atlas_source, source_id); no_source_selected_label->hide(); + tile_set_atlas_source_editor->edit(*tile_set, atlas_source, source_id); tile_set_atlas_source_editor->show(); + tile_set_scenes_collection_source_editor->hide(); + } else if (scenes_collection_source) { + no_source_selected_label->hide(); + tile_set_atlas_source_editor->hide(); + tile_set_scenes_collection_source_editor->edit(*tile_set, scenes_collection_source, source_id); + tile_set_scenes_collection_source_editor->show(); } else { no_source_selected_label->show(); tile_set_atlas_source_editor->hide(); + tile_set_scenes_collection_source_editor->hide(); } } else { no_source_selected_label->show(); tile_set_atlas_source_editor->hide(); + tile_set_scenes_collection_source_editor->hide(); } } -void TileSetEditor::_source_add_pressed() { +void TileSetEditor::_source_add_id_pressed(int p_id_pressed) { ERR_FAIL_COND(!tile_set.is_valid()); - int source_id = tile_set->get_next_source_id(); + switch (p_id_pressed) { + case 0: { + int source_id = tile_set->get_next_source_id(); - Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource); + Ref<TileSetAtlasSource> atlas_source = memnew(TileSetAtlasSource); - // Add a new source. - undo_redo->create_action(TTR("Add atlas source")); - undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); - undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); - undo_redo->add_undo_method(*tile_set, "remove_source", source_id); - undo_redo->commit_action(); + // Add a new source. + undo_redo->create_action(TTR("Add atlas source")); + undo_redo->add_do_method(*tile_set, "add_source", atlas_source, source_id); + undo_redo->add_do_method(*atlas_source, "set_texture_region_size", tile_set->get_tile_size()); + undo_redo->add_undo_method(*tile_set, "remove_source", source_id); + undo_redo->commit_action(); + + _update_atlas_sources_list(source_id); + } break; + case 1: { + int source_id = tile_set->get_next_source_id(); + + Ref<TileSetScenesCollectionSource> scene_collection_source = memnew(TileSetScenesCollectionSource); + + // Add a new source. + undo_redo->create_action(TTR("Add atlas source")); + undo_redo->add_do_method(*tile_set, "add_source", scene_collection_source, source_id); + undo_redo->add_undo_method(*tile_set, "remove_source", source_id); + undo_redo->commit_action(); - _update_atlas_sources_list(source_id); + _update_atlas_sources_list(source_id); + } break; + default: + ERR_FAIL(); + } } void TileSetEditor::_source_delete_pressed() { @@ -251,6 +298,9 @@ void TileSetEditor::_notification(int p_what) { break; case NOTIFICATION_INTERNAL_PROCESS: if (tile_set_changed_needs_update) { + if (tile_set.is_valid()) { + tile_set->set_edited(true); + } _update_atlas_sources_list(); tile_set_changed_needs_update = false; } @@ -398,7 +448,7 @@ TileDataEditor *TileSetEditor::get_tile_data_editor(String p_property) { } else if (p_property == "probability") { return tile_data_float_editor; } else if (p_property == "y_sort_origin") { - return tile_data_position_editor; + return tile_data_y_sort_editor; } else if (p_property == "texture_offset") { return tile_data_texture_offset_editor; } else if (components.size() >= 1 && components[0].begins_with("occlusion_layer_")) { @@ -434,6 +484,7 @@ void TileSetEditor::edit(Ref<TileSet> p_tile_set) { } tile_set_atlas_source_editor->hide(); + tile_set_scenes_collection_source_editor->hide(); no_source_selected_label->show(); } @@ -464,6 +515,7 @@ TileSetEditor::TileSetEditor() { sources_list->connect("item_selected", callable_mp(this, &TileSetEditor::_source_selected)); sources_list->connect("item_selected", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_atlas_sources_lists_current)); sources_list->connect("visibility_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::synchronize_atlas_sources_list), varray(sources_list)); + sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); sources_list->set_drag_forwarding(this); split_container_left_side->add_child(sources_list); @@ -477,11 +529,19 @@ TileSetEditor::TileSetEditor() { sources_delete_button->connect("pressed", callable_mp(this, &TileSetEditor::_source_delete_pressed)); sources_bottom_actions->add_child(sources_delete_button); - sources_add_button = memnew(Button); + sources_add_button = memnew(MenuButton); sources_add_button->set_flat(true); - sources_add_button->connect("pressed", callable_mp(this, &TileSetEditor::_source_add_pressed)); + sources_add_button->get_popup()->add_item(TTR("Atlas")); + sources_add_button->get_popup()->add_item(TTR("Scenes Collection")); + sources_add_button->get_popup()->connect("id_pressed", callable_mp(this, &TileSetEditor::_source_add_id_pressed)); sources_bottom_actions->add_child(sources_add_button); + // Right side container. + VBoxContainer *split_container_right_side = memnew(VBoxContainer); + split_container_right_side->set_h_size_flags(SIZE_EXPAND_FILL); + split_container_right_side->set_v_size_flags(SIZE_EXPAND_FILL); + split_container->add_child(split_container_right_side); + // No source selected. no_source_selected_label = memnew(Label); no_source_selected_label->set_text(TTR("No TileSet source selected. Select or create a TileSet source.")); @@ -489,16 +549,24 @@ TileSetEditor::TileSetEditor() { no_source_selected_label->set_v_size_flags(SIZE_EXPAND_FILL); no_source_selected_label->set_align(Label::ALIGN_CENTER); no_source_selected_label->set_valign(Label::VALIGN_CENTER); - split_container->add_child(no_source_selected_label); + split_container_right_side->add_child(no_source_selected_label); // Atlases editor. tile_set_atlas_source_editor = memnew(TileSetAtlasSourceEditor); tile_set_atlas_source_editor->set_h_size_flags(SIZE_EXPAND_FILL); tile_set_atlas_source_editor->set_v_size_flags(SIZE_EXPAND_FILL); tile_set_atlas_source_editor->connect("source_id_changed", callable_mp(this, &TileSetEditor::_update_atlas_sources_list)); - split_container->add_child(tile_set_atlas_source_editor); + split_container_right_side->add_child(tile_set_atlas_source_editor); tile_set_atlas_source_editor->hide(); + // Scenes collection editor. + tile_set_scenes_collection_source_editor = memnew(TileSetScenesCollectionSourceEditor); + tile_set_scenes_collection_source_editor->set_h_size_flags(SIZE_EXPAND_FILL); + tile_set_scenes_collection_source_editor->set_v_size_flags(SIZE_EXPAND_FILL); + tile_set_scenes_collection_source_editor->connect("source_id_changed", callable_mp(this, &TileSetEditor::_update_atlas_sources_list)); + split_container_right_side->add_child(tile_set_scenes_collection_source_editor); + tile_set_scenes_collection_source_editor->hide(); + // Registers UndoRedo inspector callback. EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &TileSetEditor::_undo_redo_inspector_callback)); } @@ -510,7 +578,7 @@ TileSetEditor::~TileSetEditor() { // Delete tile data editors. memdelete(tile_data_texture_offset_editor); - memdelete(tile_data_position_editor); + memdelete(tile_data_y_sort_editor); memdelete(tile_data_integer_editor); memdelete(tile_data_float_editor); memdelete(tile_data_occlusion_shape_editor); diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h index c4aebb40a2..f584c043cc 100644 --- a/editor/plugins/tiles/tile_set_editor.h +++ b/editor/plugins/tiles/tile_set_editor.h @@ -35,6 +35,7 @@ #include "scene/resources/tile_set.h" #include "tile_data_editors.h" #include "tile_set_atlas_source_editor.h" +#include "tile_set_scenes_collection_source_editor.h" class TileSetEditor : public VBoxContainer { GDCLASS(TileSetEditor, VBoxContainer); @@ -47,6 +48,7 @@ private: Label *no_source_selected_label; TileSetAtlasSourceEditor *tile_set_atlas_source_editor; + TileSetScenesCollectionSourceEditor *tile_set_scenes_collection_source_editor; UndoRedo *undo_redo = EditorNode::get_undo_redo(); @@ -54,7 +56,7 @@ private: // List of tile data editors. TileDataTextureOffsetEditor *tile_data_texture_offset_editor = memnew(TileDataTextureOffsetEditor); - TileDataPositionEditor *tile_data_position_editor = memnew(TileDataPositionEditor); + TileDataYSortEditor *tile_data_y_sort_editor = memnew(TileDataYSortEditor); TileDataIntegerEditor *tile_data_integer_editor = memnew(TileDataIntegerEditor); TileDataFloatEditor *tile_data_float_editor = memnew(TileDataFloatEditor); TileDataOcclusionShapeEditor *tile_data_occlusion_shape_editor = memnew(TileDataOcclusionShapeEditor); @@ -64,11 +66,11 @@ private: // -- Sources management -- Button *sources_delete_button; - Button *sources_add_button; + MenuButton *sources_add_button; ItemList *sources_list; Ref<Texture2D> missing_texture_texture; void _source_selected(int p_source_index); - void _source_add_pressed(); + void _source_add_id_pressed(int p_id_pressed); void _source_delete_pressed(); void _tile_set_changed(); diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp new file mode 100644 index 0000000000..568d4ca8d7 --- /dev/null +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -0,0 +1,511 @@ +/*************************************************************************/ +/* tile_set_scenes_collection_source_editor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "tile_set_scenes_collection_source_editor.h" + +#include "editor/editor_resource_preview.h" +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" + +#include "scene/gui/item_list.h" + +#include "core/core_string_names.h" + +void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::set_id(int p_id) { + ERR_FAIL_COND(p_id < 0); + if (source_id == p_id) { + return; + } + ERR_FAIL_COND_MSG(tile_set->has_source(p_id), vformat("Cannot change TileSet Scenes Collection source ID. Another TileSet source exists with id %d.", p_id)); + + int previous_source = source_id; + source_id = p_id; // source_id must be updated before, because it's used by the source list update. + tile_set->set_source_id(previous_source, p_id); + emit_signal("changed", "id"); +} + +int TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::get_id() { + return source_id; +} + +bool TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_set(const StringName &p_name, const Variant &p_value) { + bool valid = false; + tile_set_scenes_collection_source->set(p_name, p_value, &valid); + if (valid) { + emit_signal("changed", String(p_name).utf8().get_data()); + } + return valid; +} + +bool TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_get(const StringName &p_name, Variant &r_ret) const { + if (!tile_set_scenes_collection_source) { + return false; + } + bool valid = false; + r_ret = tile_set_scenes_collection_source->get(p_name, &valid); + return valid; +} + +void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::_bind_methods() { + // -- Shape and layout -- + ClassDB::bind_method(D_METHOD("set_id", "id"), &TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::set_id); + ClassDB::bind_method(D_METHOD("get_id"), &TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::get_id); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); + + ADD_SIGNAL(MethodInfo("changed", PropertyInfo(Variant::STRING, "what"))); +} + +void TileSetScenesCollectionSourceEditor::TileSetScenesCollectionProxyObject::edit(Ref<TileSet> p_tile_set, TileSetScenesCollectionSource *p_tile_set_scenes_collection_source, int p_source_id) { + ERR_FAIL_COND(!p_tile_set.is_valid()); + ERR_FAIL_COND(!p_tile_set_scenes_collection_source); + ERR_FAIL_COND(p_source_id < 0); + ERR_FAIL_COND(p_tile_set->get_source(p_source_id) != p_tile_set_scenes_collection_source); + + // Disconnect to changes. + if (tile_set_scenes_collection_source) { + tile_set_scenes_collection_source->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + } + + tile_set = p_tile_set; + tile_set_scenes_collection_source = p_tile_set_scenes_collection_source; + source_id = p_source_id; + + // Connect to changes. + if (tile_set_scenes_collection_source) { + if (!tile_set_scenes_collection_source->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) { + tile_set_scenes_collection_source->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + } + } + + notify_property_list_changed(); +} + +// -- Proxy object used by the tile inspector -- +bool TileSetScenesCollectionSourceEditor::SceneTileProxyObject::_set(const StringName &p_name, const Variant &p_value) { + if (!tile_set_scenes_collection_source) { + return false; + } + + if (p_name == "id") { + int as_int = int(p_value); + ERR_FAIL_COND_V(as_int < 0, false); + ERR_FAIL_COND_V(tile_set_scenes_collection_source->has_scene_tile_id(as_int), false); + tile_set_scenes_collection_source->set_scene_tile_id(scene_id, as_int); + scene_id = as_int; + emit_signal("changed", "id"); + for (int i = 0; i < tile_set_scenes_collection_source_editor->scene_tiles_list->get_item_count(); i++) { + if (int(tile_set_scenes_collection_source_editor->scene_tiles_list->get_item_metadata(i)) == scene_id) { + tile_set_scenes_collection_source_editor->scene_tiles_list->select(i); + break; + } + } + return true; + } else if (p_name == "scene") { + tile_set_scenes_collection_source->set_scene_tile_scene(scene_id, p_value); + emit_signal("changed", "scene"); + return true; + } else if (p_name == "display_placeholder") { + tile_set_scenes_collection_source->set_scene_tile_display_placeholder(scene_id, p_value); + emit_signal("changed", "display_placeholder"); + return true; + } + + return false; +} + +bool TileSetScenesCollectionSourceEditor::SceneTileProxyObject::_get(const StringName &p_name, Variant &r_ret) const { + if (!tile_set_scenes_collection_source) { + return false; + } + + if (p_name == "id") { + r_ret = scene_id; + return true; + } else if (p_name == "scene") { + r_ret = tile_set_scenes_collection_source->get_scene_tile_scene(scene_id); + return true; + } else if (p_name == "display_placeholder") { + r_ret = tile_set_scenes_collection_source->get_scene_tile_display_placeholder(scene_id); + return true; + } + + return false; +} + +void TileSetScenesCollectionSourceEditor::SceneTileProxyObject::_get_property_list(List<PropertyInfo> *p_list) const { + if (!tile_set_scenes_collection_source) { + return; + } + + p_list->push_back(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_NONE, "")); + p_list->push_back(PropertyInfo(Variant::OBJECT, "scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene")); + p_list->push_back(PropertyInfo(Variant::BOOL, "display_placeholder", PROPERTY_HINT_NONE, "")); +} + +void TileSetScenesCollectionSourceEditor::SceneTileProxyObject::edit(TileSetScenesCollectionSource *p_tile_set_scenes_collection_source, int p_scene_id) { + ERR_FAIL_COND(!p_tile_set_scenes_collection_source); + ERR_FAIL_COND(!p_tile_set_scenes_collection_source->has_scene_tile_id(p_scene_id)); + + tile_set_scenes_collection_source = p_tile_set_scenes_collection_source; + scene_id = p_scene_id; + + notify_property_list_changed(); +} + +void TileSetScenesCollectionSourceEditor::SceneTileProxyObject::_bind_methods() { + ADD_SIGNAL(MethodInfo("changed", PropertyInfo(Variant::STRING, "what"))); +} + +void TileSetScenesCollectionSourceEditor::_scenes_collection_source_proxy_object_changed(String p_what) { + if (p_what == "id") { + emit_signal("source_id_changed", scenes_collection_source_proxy_object->get_id()); + } +} + +void TileSetScenesCollectionSourceEditor::_tile_set_scenes_collection_source_changed() { + tile_set_scenes_collection_source_changed_needs_update = true; +} + +void TileSetScenesCollectionSourceEditor::_scene_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) { + int index = p_ud; + + if (index >= 0 && index < scene_tiles_list->get_item_count()) { + scene_tiles_list->set_item_icon(index, p_preview); + } +} + +void TileSetScenesCollectionSourceEditor::_scenes_list_item_activated(int p_index) { + Ref<PackedScene> packed_scene = tile_set_scenes_collection_source->get_scene_tile_scene(scene_tiles_list->get_item_metadata(p_index)); + if (packed_scene.is_valid()) { + EditorNode::get_singleton()->open_request(packed_scene->get_path()); + } +} + +void TileSetScenesCollectionSourceEditor::_source_add_pressed() { + int scene_id = tile_set_scenes_collection_source->get_next_scene_tile_id(); + undo_redo->create_action(TTR("Add a Scene Tile")); + undo_redo->add_do_method(tile_set_scenes_collection_source, "create_scene_tile", Ref<PackedScene>(), scene_id); + undo_redo->add_undo_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id); + undo_redo->commit_action(); + _update_scenes_list(); + _update_action_buttons(); + _update_tile_inspector(); +} + +void TileSetScenesCollectionSourceEditor::_source_delete_pressed() { + Vector<int> selected_indices = scene_tiles_list->get_selected_items(); + ERR_FAIL_COND(selected_indices.size() <= 0); + int scene_id = scene_tiles_list->get_item_metadata(selected_indices[0]); + + undo_redo->create_action(TTR("Remove a Scene Tile")); + undo_redo->add_do_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id); + undo_redo->add_undo_method(tile_set_scenes_collection_source, "create_scene_tile", tile_set_scenes_collection_source->get_scene_tile_scene(scene_id), scene_id); + undo_redo->commit_action(); + _update_scenes_list(); + _update_action_buttons(); + _update_tile_inspector(); +} + +void TileSetScenesCollectionSourceEditor::_update_source_inspector() { + // Update the proxy object. + scenes_collection_source_proxy_object->edit(tile_set, tile_set_scenes_collection_source, tile_set_source_id); +} + +void TileSetScenesCollectionSourceEditor::_update_tile_inspector() { + Vector<int> selected_indices = scene_tiles_list->get_selected_items(); + bool has_atlas_tile_selected = (selected_indices.size() > 0); + + // Update the proxy object. + if (has_atlas_tile_selected) { + int scene_id = scene_tiles_list->get_item_metadata(selected_indices[0]); + tile_proxy_object->edit(tile_set_scenes_collection_source, scene_id); + } + + // Update visibility. + tile_inspector_label->set_visible(has_atlas_tile_selected); + tile_inspector->set_visible(has_atlas_tile_selected); +} + +void TileSetScenesCollectionSourceEditor::_update_action_buttons() { + Vector<int> selected_indices = scene_tiles_list->get_selected_items(); + scene_tile_delete_button->set_disabled(selected_indices.size() <= 0); +} + +void TileSetScenesCollectionSourceEditor::_update_scenes_list() { + if (!tile_set_scenes_collection_source) { + return; + } + + // Get the previously selected id. + Vector<int> selected_indices = scene_tiles_list->get_selected_items(); + int old_selected_scene_id = (selected_indices.size() > 0) ? int(scene_tiles_list->get_item_metadata(selected_indices[0])) : -1; + + // Clear the list. + scene_tiles_list->clear(); + + // Rebuild the list. + int to_reselect = -1; + for (int i = 0; i < tile_set_scenes_collection_source->get_scene_tiles_count(); i++) { + int scene_id = tile_set_scenes_collection_source->get_scene_tile_id(i); + + Ref<PackedScene> scene = tile_set_scenes_collection_source->get_scene_tile_scene(scene_id); + + int item_index = 0; + if (scene.is_valid()) { + item_index = scene_tiles_list->add_item(vformat("%s (path:%s id:%d)", scene->get_path().get_file().get_basename(), scene->get_path(), scene_id)); + Variant udata = i; + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(scene, this, "_scene_thumbnail_done", udata); + } else { + item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), get_theme_icon("PackedScene", "EditorIcons")); + } + scene_tiles_list->set_item_metadata(item_index, scene_id); + + if (old_selected_scene_id >= 0 && scene_id == old_selected_scene_id) { + to_reselect = i; + } + } + + // Reselect if needed. + if (to_reselect >= 0) { + scene_tiles_list->select(to_reselect); + } + + // Icon size update. + int int_size = int(EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size")) * EDSCALE; + scene_tiles_list->set_fixed_icon_size(Vector2(int_size, int_size)); +} + +void TileSetScenesCollectionSourceEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: + scene_tile_add_button->set_icon(get_theme_icon("Add", "EditorIcons")); + scene_tile_delete_button->set_icon(get_theme_icon("Remove", "EditorIcons")); + _update_scenes_list(); + break; + case NOTIFICATION_INTERNAL_PROCESS: + if (tile_set_scenes_collection_source_changed_needs_update) { + // Update everything. + _update_source_inspector(); + _update_scenes_list(); + _update_action_buttons(); + _update_tile_inspector(); + tile_set_scenes_collection_source_changed_needs_update = false; + } + break; + case NOTIFICATION_VISIBILITY_CHANGED: + // Update things just in case. + _update_scenes_list(); + _update_action_buttons(); + break; + default: + break; + } +} + +void TileSetScenesCollectionSourceEditor::edit(Ref<TileSet> p_tile_set, TileSetScenesCollectionSource *p_tile_set_scenes_collection_source, int p_source_id) { + ERR_FAIL_COND(!p_tile_set.is_valid()); + ERR_FAIL_COND(!p_tile_set_scenes_collection_source); + ERR_FAIL_COND(p_source_id < 0); + ERR_FAIL_COND(p_tile_set->get_source(p_source_id) != p_tile_set_scenes_collection_source); + + if (p_tile_set == tile_set && p_tile_set_scenes_collection_source == tile_set_scenes_collection_source && p_source_id == tile_set_source_id) { + return; + } + + // Remove listener for old objects. + if (tile_set_scenes_collection_source) { + tile_set_scenes_collection_source->disconnect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_tile_set_scenes_collection_source_changed)); + } + + // Change the edited object. + tile_set = p_tile_set; + tile_set_scenes_collection_source = p_tile_set_scenes_collection_source; + tile_set_source_id = p_source_id; + + // Add the listener again. + if (tile_set_scenes_collection_source) { + tile_set_scenes_collection_source->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_tile_set_scenes_collection_source_changed)); + } + + // Update everything. + _update_source_inspector(); + _update_scenes_list(); + _update_action_buttons(); + _update_tile_inspector(); +} + +void TileSetScenesCollectionSourceEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + if (!can_drop_data_fw(p_point, p_data, p_from)) { + return; + } + + if (p_from == scene_tiles_list) { + // Handle dropping a texture in the list of atlas resources. + int scene_id = -1; + Dictionary d = p_data; + Vector<String> files = d["files"]; + for (int i = 0; i < files.size(); i++) { + Ref<PackedScene> resource = ResourceLoader::load(files[i]); + if (resource.is_valid()) { + scene_id = tile_set_scenes_collection_source->get_next_scene_tile_id(); + undo_redo->create_action(TTR("Add a Scene Tile")); + undo_redo->add_do_method(tile_set_scenes_collection_source, "create_scene_tile", resource, scene_id); + undo_redo->add_undo_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id); + undo_redo->commit_action(); + } + } + + _update_scenes_list(); + _update_action_buttons(); + _update_tile_inspector(); + } +} + +bool TileSetScenesCollectionSourceEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + if (p_from == scene_tiles_list) { + Dictionary d = p_data; + + if (!d.has("type")) { + return false; + } + + // Check if we have a Texture2D. + if (String(d["type"]) == "files") { + Vector<String> files = d["files"]; + + if (files.size() == 0) { + return false; + } + + for (int i = 0; i < files.size(); i++) { + String file = files[i]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + + if (!ClassDB::is_parent_class(ftype, "PackedScene")) { + return false; + } + } + + return true; + } + } + return false; +} + +void TileSetScenesCollectionSourceEditor::_bind_methods() { + ADD_SIGNAL(MethodInfo("source_id_changed", PropertyInfo(Variant::INT, "source_id"))); + + ClassDB::bind_method(D_METHOD("_scene_thumbnail_done"), &TileSetScenesCollectionSourceEditor::_scene_thumbnail_done); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &TileSetScenesCollectionSourceEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &TileSetScenesCollectionSourceEditor::drop_data_fw); +} + +TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { + // -- Right side -- + HSplitContainer *split_container_right_side = memnew(HSplitContainer); + split_container_right_side->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(split_container_right_side); + + // Middle panel. + ScrollContainer *middle_panel = memnew(ScrollContainer); + middle_panel->set_enable_h_scroll(false); + middle_panel->set_custom_minimum_size(Size2i(200, 0) * EDSCALE); + split_container_right_side->add_child(middle_panel); + + VBoxContainer *middle_vbox_container = memnew(VBoxContainer); + middle_vbox_container->set_h_size_flags(SIZE_EXPAND_FILL); + middle_panel->add_child(middle_vbox_container); + + // Scenes collection source inspector. + scenes_collection_source_inspector_label = memnew(Label); + scenes_collection_source_inspector_label->set_text(TTR("Scenes collection properties:")); + middle_vbox_container->add_child(scenes_collection_source_inspector_label); + + scenes_collection_source_proxy_object = memnew(TileSetScenesCollectionProxyObject()); + scenes_collection_source_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_scenes_collection_source_proxy_object_changed)); + + scenes_collection_source_inspector = memnew(EditorInspector); + scenes_collection_source_inspector->set_undo_redo(undo_redo); + scenes_collection_source_inspector->set_enable_v_scroll(false); + scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object); + middle_vbox_container->add_child(scenes_collection_source_inspector); + + // Tile inspector. + tile_inspector_label = memnew(Label); + tile_inspector_label->set_text(TTR("Tile properties:")); + tile_inspector_label->hide(); + middle_vbox_container->add_child(tile_inspector_label); + + tile_proxy_object = memnew(SceneTileProxyObject(this)); + tile_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_scenes_list).unbind(1)); + tile_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_action_buttons).unbind(1)); + + tile_inspector = memnew(EditorInspector); + tile_inspector->set_undo_redo(undo_redo); + tile_inspector->set_enable_v_scroll(false); + tile_inspector->edit(tile_proxy_object); + tile_inspector->set_use_folding(true); + middle_vbox_container->add_child(tile_inspector); + + // Scenes list. + VBoxContainer *right_vbox_container = memnew(VBoxContainer); + split_container_right_side->add_child(right_vbox_container); + + scene_tiles_list = memnew(ItemList); + scene_tiles_list->set_h_size_flags(SIZE_EXPAND_FILL); + scene_tiles_list->set_v_size_flags(SIZE_EXPAND_FILL); + scene_tiles_list->set_drag_forwarding(this); + scene_tiles_list->connect("item_selected", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_tile_inspector).unbind(1)); + scene_tiles_list->connect("item_selected", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_action_buttons).unbind(1)); + scene_tiles_list->connect("item_activated", callable_mp(this, &TileSetScenesCollectionSourceEditor::_scenes_list_item_activated)); + scene_tiles_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); + right_vbox_container->add_child(scene_tiles_list); + + HBoxContainer *scenes_bottom_actions = memnew(HBoxContainer); + right_vbox_container->add_child(scenes_bottom_actions); + + scene_tile_add_button = memnew(Button); + scene_tile_add_button->set_flat(true); + scene_tile_add_button->connect("pressed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_source_add_pressed)); + scenes_bottom_actions->add_child(scene_tile_add_button); + + scene_tile_delete_button = memnew(Button); + scene_tile_delete_button->set_flat(true); + scene_tile_delete_button->set_disabled(true); + scene_tile_delete_button->connect("pressed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_source_delete_pressed)); + scenes_bottom_actions->add_child(scene_tile_delete_button); +} + +TileSetScenesCollectionSourceEditor::~TileSetScenesCollectionSourceEditor() { + memdelete(scenes_collection_source_proxy_object); + memdelete(tile_proxy_object); +} diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h new file mode 100644 index 0000000000..195aa79bc4 --- /dev/null +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h @@ -0,0 +1,139 @@ +/*************************************************************************/ +/* tile_set_scenes_collection_source_editor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TILE_SET_SCENES_COLLECTION_SOURCE_EDITOR_H +#define TILE_SET_SCENES_COLLECTION_SOURCE_EDITOR_H + +#include "editor/editor_node.h" +#include "scene/gui/box_container.h" +#include "scene/resources/tile_set.h" + +class TileSetScenesCollectionSourceEditor : public HBoxContainer { + GDCLASS(TileSetScenesCollectionSourceEditor, HBoxContainer); + +private: + // -- Proxy object for an atlas source, needed by the inspector -- + class TileSetScenesCollectionProxyObject : public Object { + GDCLASS(TileSetScenesCollectionProxyObject, Object); + + private: + Ref<TileSet> tile_set; + TileSetScenesCollectionSource *tile_set_scenes_collection_source = nullptr; + int source_id = -1; + + protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + static void _bind_methods(); + + public: + void set_id(int p_id); + int get_id(); + + void edit(Ref<TileSet> p_tile_set, TileSetScenesCollectionSource *p_tile_set_scenes_collection_source, int p_source_id); + }; + + // -- Proxy object for a tile, needed by the inspector -- + class SceneTileProxyObject : public Object { + GDCLASS(SceneTileProxyObject, Object); + + private: + TileSetScenesCollectionSourceEditor *tile_set_scenes_collection_source_editor; + + TileSetScenesCollectionSource *tile_set_scenes_collection_source = nullptr; + int source_id; + int scene_id; + + protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + static void _bind_methods(); + + public: + // Update the proxyed object. + void edit(TileSetScenesCollectionSource *p_tile_set_atlas_source, int p_scene_id); + + SceneTileProxyObject(TileSetScenesCollectionSourceEditor *p_tiles_set_scenes_collection_source_editor) { + tile_set_scenes_collection_source_editor = p_tiles_set_scenes_collection_source_editor; + } + }; + +private: + Ref<TileSet> tile_set; + TileSetScenesCollectionSource *tile_set_scenes_collection_source = nullptr; + int tile_set_source_id = -1; + + UndoRedo *undo_redo = EditorNode::get_undo_redo(); + + bool tile_set_scenes_collection_source_changed_needs_update = false; + + // Source inspector. + TileSetScenesCollectionProxyObject *scenes_collection_source_proxy_object; + Label *scenes_collection_source_inspector_label; + EditorInspector *scenes_collection_source_inspector; + + // Tile inspector. + SceneTileProxyObject *tile_proxy_object; + Label *tile_inspector_label; + EditorInspector *tile_inspector; + + ItemList *scene_tiles_list; + Button *scene_tile_add_button; + Button *scene_tile_delete_button; + + void _tile_set_scenes_collection_source_changed(); + void _scenes_collection_source_proxy_object_changed(String p_what); + void _scene_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud); + void _scenes_list_item_activated(int p_index); + + void _source_add_pressed(); + void _source_delete_pressed(); + + // Update methods. + void _update_source_inspector(); + void _update_tile_inspector(); + void _update_scenes_list(); + void _update_action_buttons(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + void edit(Ref<TileSet> p_tile_set, TileSetScenesCollectionSource *p_tile_set_scenes_collection_source, int p_source_id); + void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + TileSetScenesCollectionSourceEditor(); + ~TileSetScenesCollectionSourceEditor(); +}; + +#endif diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 971ff15073..fb111efc17 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -202,6 +202,7 @@ TilesEditor::TilesEditor(EditorNode *p_editor) { // Toolbar. HBoxContainer *toolbar = memnew(HBoxContainer); + toolbar->set_h_size_flags(SIZE_EXPAND_FILL); add_child(toolbar); // Switch button. diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index 0af3b936cb..75a944e910 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -180,7 +180,7 @@ void VersionControlEditorPlugin::_stage_selected() { staged_files_count = 0; TreeItem *root = stage_files->get_root(); if (root) { - TreeItem *file_entry = root->get_children(); + TreeItem *file_entry = root->get_first_child(); while (file_entry) { if (file_entry->is_checked(0)) { EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0)); @@ -207,7 +207,7 @@ void VersionControlEditorPlugin::_stage_all() { staged_files_count = 0; TreeItem *root = stage_files->get_root(); if (root) { - TreeItem *file_entry = root->get_children(); + TreeItem *file_entry = root->get_first_child(); while (file_entry) { EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0)); file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color("success_color", "Editor")); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 1d4c23fee6..a0757439c3 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -322,6 +322,12 @@ void VisualShaderGraphPlugin::register_uniform_name(int p_node_id, LineEdit *p_u links[p_node_id].uniform_name = p_uniform_name; } +void VisualShaderGraphPlugin::update_theme() { + vector_expanded_color[0] = VisualShaderEditor::get_singleton()->get_theme_color("axis_x_color", "Editor"); // red + vector_expanded_color[1] = VisualShaderEditor::get_singleton()->get_theme_color("axis_y_color", "Editor"); // green + vector_expanded_color[2] = VisualShaderEditor::get_singleton()->get_theme_color("axis_z_color", "Editor"); // blue +} + void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (p_type != visual_shader->get_shader_type()) { return; @@ -340,6 +346,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Color(1.0, 1.0, 0.0), // sampler }; + static const String vector_expanded_name[3] = { + "red", + "green", + "blue" + }; + Ref<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id); Ref<VisualShaderNodeResizableBase> resizable_node = Object::cast_to<VisualShaderNodeResizableBase>(vsnode.ptr()); @@ -349,6 +361,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr()); bool is_group = !group_node.is_null(); + bool is_comment = false; + Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr()); bool is_expression = !expression_node.is_null(); String expression = ""; @@ -392,13 +406,13 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (is_resizable) { Ref<VisualShaderNodeComment> comment_node = Object::cast_to<VisualShaderNodeComment>(vsnode.ptr()); if (comment_node.is_valid()) { + is_comment = true; node->set_comment(true); Label *comment_label = memnew(Label); node->add_child(comment_label); comment_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); comment_label->set_v_size_flags(Control::SIZE_EXPAND_FILL); - comment_label->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_STOP); comment_label->set_text(comment_node->get_description()); } } @@ -551,13 +565,32 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } } - for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { + int output_port_count = 0; + for (int i = 0; i < vsnode->get_output_port_count(); i++) { + if (vsnode->_is_output_port_expanded(i)) { + if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) { + output_port_count += 3; + } + } + output_port_count++; + } + int max_ports = MAX(vsnode->get_input_port_count(), output_port_count); + VisualShaderNode::PortType expanded_type = VisualShaderNode::PORT_TYPE_SCALAR; + int expanded_port_counter = 0; + + for (int i = 0, j = 0; i < max_ports; i++, j++) { + if (expanded_type == VisualShaderNode::PORT_TYPE_VECTOR && expanded_port_counter >= 3) { + expanded_type = VisualShaderNode::PORT_TYPE_SCALAR; + expanded_port_counter = 0; + i -= 3; + } + if (vsnode->is_port_separator(i)) { node->add_child(memnew(HSeparator)); port_offset++; } - bool valid_left = i < vsnode->get_input_port_count(); + bool valid_left = j < vsnode->get_input_port_count(); VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR; bool port_left_used = false; String name_left; @@ -565,18 +598,24 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { name_left = vsnode->get_input_port_name(i); port_left = vsnode->get_input_port_type(i); for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().to_node == p_id && E->get().to_port == i) { + if (E->get().to_node == p_id && E->get().to_port == j) { port_left_used = true; } } } - bool valid_right = i < vsnode->get_output_port_count(); + bool valid_right = true; VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR; String name_right; - if (valid_right) { - name_right = vsnode->get_output_port_name(i); - port_right = vsnode->get_output_port_type(i); + + if (expanded_type == VisualShaderNode::PORT_TYPE_SCALAR) { + valid_right = i < vsnode->get_output_port_count(); + if (valid_right) { + name_right = vsnode->get_output_port_name(i); + port_right = vsnode->get_output_port_type(i); + } + } else { + name_right = vector_expanded_name[expanded_port_counter++]; } HBoxContainer *hb = memnew(HBoxContainer); @@ -684,17 +723,29 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } } - if (valid_right && visual_shader->get_shader_type() == VisualShader::TYPE_FRAGMENT && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) { - TextureButton *preview = memnew(TextureButton); - preview->set_toggle_mode(true); - preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons")); - preview->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityVisible", "EditorIcons")); - preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER); + if (valid_right) { + if (vsnode->is_output_port_expandable(i)) { + TextureButton *expand = memnew(TextureButton); + expand->set_toggle_mode(true); + expand->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiTreeArrowDown", "EditorIcons")); + expand->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiTreeArrowRight", "EditorIcons")); + expand->set_v_size_flags(Control::SIZE_SHRINK_CENTER); + expand->set_pressed(vsnode->_is_output_port_expanded(i)); + expand->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_expand_output_port), varray(p_id, i, !vsnode->_is_output_port_expanded(i)), CONNECT_DEFERRED); + hb->add_child(expand); + } + if (visual_shader->get_shader_type() == VisualShader::TYPE_FRAGMENT && port_right != VisualShaderNode::PORT_TYPE_TRANSFORM && port_right != VisualShaderNode::PORT_TYPE_SAMPLER) { + TextureButton *preview = memnew(TextureButton); + preview->set_toggle_mode(true); + preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons")); + preview->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityVisible", "EditorIcons")); + preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER); - register_output_port(p_id, i, preview); + register_output_port(p_id, j, preview); - preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, i), CONNECT_DEFERRED); - hb->add_child(preview); + preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, j), CONNECT_DEFERRED); + hb->add_child(preview); + } } if (is_group) { @@ -706,7 +757,40 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { node->add_child(hb); + if (expanded_type != VisualShaderNode::PORT_TYPE_SCALAR) { + continue; + } + node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); + + if (vsnode->_is_output_port_expanded(i)) { + if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) { + port_offset++; + valid_left = (i + 1) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 1); + } + node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]); + port_offset++; + + valid_left = (i + 2) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 2); + } + node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]); + port_offset++; + + valid_left = (i + 3) < vsnode->get_input_port_count(); + port_left = VisualShaderNode::PORT_TYPE_SCALAR; + if (valid_left) { + port_left = vsnode->get_input_port_type(i + 3); + } + node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]); + expanded_type = VisualShaderNode::PORT_TYPE_VECTOR; + } + } } if (vsnode->get_output_port_for_preview() >= 0) { @@ -729,7 +813,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { CodeEdit *expression_box = memnew(CodeEdit); Ref<CodeHighlighter> expression_syntax_highlighter; expression_syntax_highlighter.instance(); - expression_node->set_control(expression_box, 0); + expression_node->set_ctrl_pressed(expression_box, 0); node->add_child(expression_box); register_expression_edit(p_id, expression_box); @@ -773,6 +857,9 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (!uniform.is_valid()) { VisualShaderEditor::get_singleton()->graph->add_child(node); + if (is_comment) { + VisualShaderEditor::get_singleton()->graph->move_child(node, 0); // to prevents a bug where comment node overlaps its content + } VisualShaderEditor::get_singleton()->_update_created_node(node); if (is_resizable) { VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size); @@ -1288,6 +1375,7 @@ void VisualShaderEditor::_update_graph() { graph_plugin->clear_links(); graph_plugin->make_dirty(true); + graph_plugin->update_theme(); for (int n_i = 0; n_i < nodes.size(); n_i++) { graph_plugin->add_node(type, nodes[n_i]); @@ -1436,6 +1524,92 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object * undo_redo->commit_action(); } +void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expand) { + VisualShader::Type type = get_current_shader_type(); + + Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node); + ERR_FAIL_COND(!node.is_valid()); + + if (p_expand) { + undo_redo->create_action(TTR("Expand Output Port")); + } else { + undo_redo->create_action(TTR("Shrink Output Port")); + } + + undo_redo->add_do_method(node.ptr(), "_set_output_port_expanded", p_port, p_expand); + undo_redo->add_undo_method(node.ptr(), "_set_output_port_expanded", p_port, !p_expand); + + int type_size = 0; + if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_VECTOR) { + type_size = 3; + } + + List<VisualShader::Connection> conns; + visual_shader->get_node_connections(type, &conns); + + for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { + int from_node = E->get().from_node; + int from_port = E->get().from_port; + int to_node = E->get().to_node; + int to_port = E->get().to_port; + + if (from_node == p_node) { + if (p_expand) { + if (from_port > p_port) { // reconnect ports after expanded ports + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port + type_size, to_node, to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port + type_size, to_node, to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port + type_size, to_node, to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port + type_size, to_node, to_port); + } + } else { + if (from_port > p_port + type_size) { // reconnect ports after expanded ports + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + + undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_port - type_size, to_node, to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port - type_size, to_node, to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port - type_size, to_node, to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port - type_size, to_node, to_port); + } else if (from_port > p_port) { // disconnect component ports + undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes_forced", type, from_node, from_port, to_node, to_port); + + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_port, to_node, to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_port, to_node, to_port); + } + } + } + } + + int preview_port = node->get_output_port_for_preview(); + if (p_expand) { + if (preview_port > p_port) { + undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", preview_port + type_size); + undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", preview_port); + } + } else { + if (preview_port > p_port + type_size) { + undo_redo->add_do_method(node.ptr(), "set_output_port_for_preview", preview_port - type_size); + undo_redo->add_undo_method(node.ptr(), "set_output_port_for_preview", preview_port); + } + } + + undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node); + undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node); + undo_redo->commit_action(); +} + void VisualShaderEditor::_remove_input_port(int p_node, int p_port) { VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); @@ -1584,7 +1758,7 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(node.ptr()); Control *text_box = nullptr; if (!expression_node.is_null()) { - text_box = expression_node->get_control(0); + text_box = expression_node->is_ctrl_pressed(0); if (text_box) { text_box->set_custom_minimum_size(Size2(0, 0)); } @@ -1812,47 +1986,6 @@ void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, editing_port = p_port; } -void VisualShaderEditor::_add_custom_node(const String &p_path) { - int idx = -1; - - for (int i = custom_node_option_idx; i < add_options.size(); i++) { - if (add_options[i].script.is_valid()) { - if (add_options[i].script->get_path() == p_path) { - idx = i; - break; - } - } - } - if (idx != -1) { - _add_node(idx); - } -} - -void VisualShaderEditor::_add_cubemap_node(const String &p_path) { - VisualShaderNodeCubemap *cubemap = (VisualShaderNodeCubemap *)_add_node(cubemap_node_option_idx, -1); - cubemap->set_cube_map(ResourceLoader::load(p_path)); -} - -void VisualShaderEditor::_add_texture2d_node(const String &p_path) { - VisualShaderNodeTexture *texture2d = (VisualShaderNodeTexture *)_add_node(texture2d_node_option_idx, -1); - texture2d->set_texture(ResourceLoader::load(p_path)); -} - -void VisualShaderEditor::_add_texture2d_array_node(const String &p_path) { - VisualShaderNodeTexture2DArray *texture2d_array = (VisualShaderNodeTexture2DArray *)_add_node(texture2d_array_node_option_idx, -1); - texture2d_array->set_texture_array(ResourceLoader::load(p_path)); -} - -void VisualShaderEditor::_add_texture3d_node(const String &p_path) { - VisualShaderNodeTexture3D *texture3d = (VisualShaderNodeTexture3D *)_add_node(texture3d_node_option_idx, -1); - texture3d->set_texture(ResourceLoader::load(p_path)); -} - -void VisualShaderEditor::_add_curve_node(const String &p_path) { - VisualShaderNodeCurveTexture *curve = (VisualShaderNodeCurveTexture *)_add_node(curve_node_option_idx, -1); - curve->set_texture(ResourceLoader::load(p_path)); -} - void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { // FLOAT_OP { @@ -2041,8 +2174,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { } } -VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { - ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); +void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_path, int p_node_idx) { + ERR_FAIL_INDEX(p_idx, add_options.size()); Ref<VisualShaderNode> vsnode; @@ -2050,7 +2183,7 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { if (!is_custom && add_options[p_idx].type != String()) { VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); - ERR_FAIL_COND_V(!vsn, nullptr); + ERR_FAIL_COND(!vsn); VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); @@ -2072,10 +2205,10 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { vsnode = Ref<VisualShaderNode>(vsn); } else { - ERR_FAIL_COND_V(add_options[p_idx].script.is_null(), nullptr); + ERR_FAIL_COND(add_options[p_idx].script.is_null()); String base_type = add_options[p_idx].script->get_instance_base_type(); VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(base_type)); - ERR_FAIL_COND_V(!vsn, nullptr); + ERR_FAIL_COND(!vsn); vsnode = Ref<VisualShaderNode>(vsn); vsnode->set_script(add_options[p_idx].script); } @@ -2094,7 +2227,11 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { int id_to_use = visual_shader->get_valid_node_id(type); - undo_redo->create_action(TTR("Add Node to Visual Shader")); + if (p_resource_path.is_empty()) { + undo_redo->create_action(TTR("Add Node to Visual Shader")); + } else { + id_to_use += p_node_idx; + } undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, vsnode, position, id_to_use); undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_to_use); undo_redo->add_do_method(graph_plugin.ptr(), "add_node", type, id_to_use); @@ -2209,8 +2346,30 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { graph_plugin->call_deferred("update_curve", id_to_use); } - undo_redo->commit_action(); - return vsnode.ptr(); + if (p_resource_path.is_empty()) { + undo_redo->commit_action(); + } else { + //post-initialization + + VisualShaderNodeTexture *texture2d = Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr()); + VisualShaderNodeTexture3D *texture3d = Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr()); + + if (texture2d || texture3d || curve) { + undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path)); + return; + } + + VisualShaderNodeCubemap *cubemap = Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr()); + if (cubemap) { + undo_redo->add_do_method(vsnode.ptr(), "set_cube_map", ResourceLoader::load(p_resource_path)); + return; + } + + VisualShaderNodeTexture2DArray *texture2d_array = Object::cast_to<VisualShaderNodeTexture2DArray>(vsnode.ptr()); + if (texture2d_array) { + undo_redo->add_do_method(vsnode.ptr(), "set_texture_array", ResourceLoader::load(p_resource_path)); + } + } } void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) { @@ -2427,7 +2586,7 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { for (Set<int>::Element *E = current_set.front(); E; E = E->next()) { int node_id = E->get(); Ref<VisualShaderNode> node = visual_shader->get_node(type_id, node_id); - bool catched = false; + bool caught = false; Variant var; // float @@ -2436,112 +2595,112 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) { if (float_const.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatUniform"); var = float_const->get_constant(); - catched = true; + caught = true; } } else { Ref<VisualShaderNodeFloatUniform> float_uniform = Object::cast_to<VisualShaderNodeFloatUniform>(node.ptr()); if (float_uniform.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeFloatUniform", "VisualShaderNodeFloatConstant"); var = float_uniform->get_default_value(); - catched = true; + caught = true; } } // int - if (!catched) { + if (!caught) { if (!p_vice_versa) { Ref<VisualShaderNodeIntConstant> int_const = Object::cast_to<VisualShaderNodeIntConstant>(node.ptr()); if (int_const.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntUniform"); var = int_const->get_constant(); - catched = true; + caught = true; } } else { Ref<VisualShaderNodeIntUniform> int_uniform = Object::cast_to<VisualShaderNodeIntUniform>(node.ptr()); if (int_uniform.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeIntUniform", "VisualShaderNodeIntConstant"); var = int_uniform->get_default_value(); - catched = true; + caught = true; } } } // boolean - if (!catched) { + if (!caught) { if (!p_vice_versa) { Ref<VisualShaderNodeBooleanConstant> boolean_const = Object::cast_to<VisualShaderNodeBooleanConstant>(node.ptr()); if (boolean_const.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanUniform"); var = boolean_const->get_constant(); - catched = true; + caught = true; } } else { Ref<VisualShaderNodeBooleanUniform> boolean_uniform = Object::cast_to<VisualShaderNodeBooleanUniform>(node.ptr()); if (boolean_uniform.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanConstant"); var = boolean_uniform->get_default_value(); - catched = true; + caught = true; } } } // vec3 - if (!catched) { + if (!caught) { if (!p_vice_versa) { Ref<VisualShaderNodeVec3Constant> vec3_const = Object::cast_to<VisualShaderNodeVec3Constant>(node.ptr()); if (vec3_const.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Uniform"); var = vec3_const->get_constant(); - catched = true; + caught = true; } } else { Ref<VisualShaderNodeVec3Uniform> vec3_uniform = Object::cast_to<VisualShaderNodeVec3Uniform>(node.ptr()); if (vec3_uniform.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Constant"); var = vec3_uniform->get_default_value(); - catched = true; + caught = true; } } } // color - if (!catched) { + if (!caught) { if (!p_vice_versa) { Ref<VisualShaderNodeColorConstant> color_const = Object::cast_to<VisualShaderNodeColorConstant>(node.ptr()); if (color_const.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorUniform"); var = color_const->get_constant(); - catched = true; + caught = true; } } else { Ref<VisualShaderNodeColorUniform> color_uniform = Object::cast_to<VisualShaderNodeColorUniform>(node.ptr()); if (color_uniform.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeColorUniform", "VisualShaderNodeColorConstant"); var = color_uniform->get_default_value(); - catched = true; + caught = true; } } } // transform - if (!catched) { + if (!caught) { if (!p_vice_versa) { Ref<VisualShaderNodeTransformConstant> transform_const = Object::cast_to<VisualShaderNodeTransformConstant>(node.ptr()); if (transform_const.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformUniform"); var = transform_const->get_constant(); - catched = true; + caught = true; } } else { Ref<VisualShaderNodeTransformUniform> transform_uniform = Object::cast_to<VisualShaderNodeTransformUniform>(node.ptr()); if (transform_uniform.is_valid()) { _replace_node(type_id, node_id, "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformConstant"); var = transform_uniform->get_default_value(); - catched = true; + caught = true; } } } - ERR_CONTINUE(!catched); + ERR_CONTINUE(!caught); int preview_port = node->get_output_port_for_preview(); if (!p_vice_versa) { @@ -2762,10 +2921,10 @@ void VisualShaderEditor::_notification(int p_what) { // collapse tree by default - TreeItem *category = members->get_root()->get_children(); + TreeItem *category = members->get_root()->get_first_child(); while (category) { category->set_collapsed(true); - TreeItem *sub_category = category->get_children(); + TreeItem *sub_category = category->get_first_child(); while (sub_category) { sub_category->set_collapsed(true); sub_category = sub_category->get_next(); @@ -3210,14 +3369,14 @@ void VisualShaderEditor::_member_cancel() { } void VisualShaderEditor::_tools_menu_option(int p_idx) { - TreeItem *category = members->get_root()->get_children(); + TreeItem *category = members->get_root()->get_first_child(); switch (p_idx) { case EXPAND_ALL: while (category) { category->set_collapsed(false); - TreeItem *sub_category = category->get_children(); + TreeItem *sub_category = category->get_first_child(); while (sub_category) { sub_category->set_collapsed(false); sub_category = sub_category->get_next(); @@ -3231,7 +3390,7 @@ void VisualShaderEditor::_tools_menu_option(int p_idx) { while (category) { category->set_collapsed(true); - TreeItem *sub_category = category->get_children(); + TreeItem *sub_category = category->get_first_child(); while (sub_category) { sub_category->set_collapsed(true); sub_category = sub_category->get_next(); @@ -3333,47 +3492,56 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da saved_node_pos_dirty = true; _add_node(idx, add_options[idx].sub_func); } else if (d.has("files")) { + undo_redo->create_action(TTR("Add Node(s) to Visual Shader")); + if (d["files"].get_type() == Variant::PACKED_STRING_ARRAY) { - int j = 0; PackedStringArray arr = d["files"]; for (int i = 0; i < arr.size(); i++) { String type = ResourceLoader::get_resource_type(arr[i]); if (type == "GDScript") { Ref<Script> script = ResourceLoader::load(arr[i]); if (script->get_instance_base_type() == "VisualShaderNodeCustom") { - saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; - _add_custom_node(arr[i]); - j++; + + int idx = -1; + + for (int j = custom_node_option_idx; j < add_options.size(); j++) { + if (add_options[j].script.is_valid()) { + if (add_options[j].script->get_path() == arr[i]) { + idx = j; + break; + } + } + } + if (idx != -1) { + _add_node(idx, -1, arr[i], i); + } } } else if (type == "CurveTexture") { - saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; - _add_curve_node(arr[i]); - j++; + _add_node(curve_node_option_idx, -1, arr[i], i); } else if (ClassDB::get_parent_class(type) == "Texture2D") { - saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; - _add_texture2d_node(arr[i]); - j++; + _add_node(texture2d_node_option_idx, -1, arr[i], i); } else if (type == "Texture2DArray") { - saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; - _add_texture2d_array_node(arr[i]); - j++; + _add_node(texture2d_array_node_option_idx, -1, arr[i], i); } else if (ClassDB::get_parent_class(type) == "Texture3D") { - saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; - _add_texture3d_node(arr[i]); - j++; + _add_node(texture3d_node_option_idx, -1, arr[i], i); } else if (type == "Cubemap") { - saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE); saved_node_pos_dirty = true; - _add_cubemap_node(arr[i]); - j++; + _add_node(cubemap_node_option_idx, -1, arr[i], i); } } } + undo_redo->commit_action(); } } } @@ -3429,10 +3597,11 @@ void VisualShaderEditor::_update_preview() { Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); for (int i = 0; i < preview_text->get_line_count(); i++) { - preview_text->set_line_as_marked(i, false); + preview_text->set_line_background_color(i, Color(0, 0, 0, 0)); } if (err != OK) { - preview_text->set_line_as_marked(sl.get_error_line() - 1, true); + Color error_line_color = EDITOR_GET("text_editor/highlighting/mark_color"); + preview_text->set_line_background_color(sl.get_error_line() - 1, error_line_color); error_text->set_visible(true); String text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); @@ -3469,6 +3638,7 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected); ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant); ClassDB::bind_method("_update_uniform", &VisualShaderEditor::_update_uniform); + ClassDB::bind_method("_expand_output_port", &VisualShaderEditor::_expand_output_port); ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw); ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw); @@ -4090,6 +4260,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("TransformDecompose", "Transform", "Composition", "VisualShaderNodeTransformDecompose", TTR("Decomposes transform to four vectors."))); add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("GetBillboardMatrix", "Transform", "Functions", "VisualShaderNodeBillboard", TTR("Calculates how the object should face the camera to be applied on Model View Matrix output port for 3D objects."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL)); add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM)); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 6d57d38cab..b3510aafa1 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -83,6 +83,8 @@ private: List<VisualShader::Connection> connections; bool dirty = false; + Color vector_expanded_color[3]; + protected: static void _bind_methods(); @@ -119,6 +121,7 @@ public: void set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression); int get_constant_index(float p_constant) const; void update_node_size(int p_node_id); + void update_theme(); VisualShader::Type get_shader_type() const; VisualShaderGraphPlugin(); @@ -290,15 +293,8 @@ class VisualShaderEditor : public VBoxContainer { void _draw_color_over_button(Object *obj, Color p_color); - void _add_custom_node(const String &p_path); - void _add_cubemap_node(const String &p_path); - void _add_texture2d_node(const String &p_path); - void _add_texture2d_array_node(const String &p_path); - void _add_texture3d_node(const String &p_path); - void _add_curve_node(const String &p_path); - void _setup_node(VisualShaderNode *p_node, int p_op_idx); - VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1); + void _add_node(int p_idx, int p_op_idx = -1, String p_resource_path = "", int p_node_idx = -1); void _update_options_menu(); void _set_mode(int p_which); @@ -408,6 +404,7 @@ class VisualShaderEditor : public VBoxContainer { void _remove_output_port(int p_node, int p_port); void _change_output_port_type(int p_type, int p_node, int p_port); void _change_output_port_name(const String &p_text, Object *p_line_edit, int p_node, int p_port); + void _expand_output_port(int p_node, int p_port, bool p_expand); void _expression_focus_out(Object *code_edit, int p_node); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 3ede50320a..9b99372735 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -795,7 +795,7 @@ void ProjectExportDialog::_tree_changed() { } void ProjectExportDialog::_check_dir_recursive(TreeItem *p_dir, bool p_checked) { - for (TreeItem *child = p_dir->get_children(); child; child = child->get_next()) { + for (TreeItem *child = p_dir->get_first_child(); child; child = child->get_next()) { String path = child->get_metadata(0); child->set_checked(0, p_checked); @@ -818,7 +818,7 @@ void ProjectExportDialog::_refresh_parent_checks(TreeItem *p_item) { } bool checked = true; - for (TreeItem *child = parent->get_children(); child; child = child->get_next()) { + for (TreeItem *child = parent->get_first_child(); child; child = child->get_next()) { checked = checked && child->is_checked(0); if (!checked) { break; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 74eed8330d..8bde397b5c 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -100,7 +100,6 @@ private: FileDialog *fdialog_install; String zip_path; String zip_title; - String zip_root; AcceptDialog *dialog_error; String fav_dir; @@ -201,9 +200,7 @@ private: char fname[16384]; ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0); - String fname_str = String(fname); - if (fname_str.ends_with("project.godot")) { - zip_root = fname_str.substr(0, fname_str.rfind("project.godot")); + if (String(fname).ends_with("project.godot")) { break; } @@ -524,7 +521,24 @@ private: return; } + // Find the zip_root + String zip_root; int ret = unzGoToFirstFile(pkg); + while (ret == UNZ_OK) { + unz_file_info info; + char fname[16384]; + unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0); + + String name = fname; + if (name.ends_with("project.godot")) { + zip_root = name.substr(0, name.rfind("project.godot")); + break; + } + + ret = unzGoToNextFile(pkg); + } + + ret = unzGoToFirstFile(pkg); Vector<String> failed_files; @@ -1731,7 +1745,7 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { const Item &clicked_project = _projects[clicked_index]; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { - if (mb->get_shift() && _selected_project_keys.size() > 0 && _last_clicked != "" && clicked_project.project_key != _last_clicked) { + if (mb->is_shift_pressed() && _selected_project_keys.size() > 0 && _last_clicked != "" && clicked_project.project_key != _last_clicked) { int anchor_index = -1; for (int i = 0; i < _projects.size(); ++i) { const Item &p = _projects[i]; @@ -1743,7 +1757,7 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { CRASH_COND(anchor_index == -1); select_range(anchor_index, clicked_index); - } else if (mb->get_control()) { + } else if (mb->is_ctrl_pressed()) { toggle_select(clicked_index); } else { @@ -1753,7 +1767,7 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { emit_signal(SIGNAL_SELECTION_CHANGED); - if (!mb->get_control() && mb->is_double_click()) { + if (!mb->is_ctrl_pressed() && mb->is_double_click()) { emit_signal(SIGNAL_PROJECT_ASK_OPEN); } } @@ -1928,7 +1942,7 @@ void ProjectManager::_unhandled_key_input(const Ref<InputEvent> &p_ev) { } break; case KEY_UP: { - if (k->get_shift()) { + if (k->is_shift_pressed()) { break; } @@ -1942,7 +1956,7 @@ void ProjectManager::_unhandled_key_input(const Ref<InputEvent> &p_ev) { break; } case KEY_DOWN: { - if (k->get_shift()) { + if (k->is_shift_pressed()) { break; } @@ -1955,7 +1969,7 @@ void ProjectManager::_unhandled_key_input(const Ref<InputEvent> &p_ev) { } break; case KEY_F: { - if (k->get_command()) { + if (k->is_command_pressed()) { this->search_box->grab_focus(); } else { keycode_handled = false; @@ -2115,8 +2129,8 @@ void ProjectManager::_run_project_confirm() { const String &selected = selected_list[i].project_key; String path = EditorSettings::get_singleton()->get("projects/" + selected); - // `.right(6)` on `IMPORTED_FILES_PATH` strips away the leading "res://". - if (!DirAccess::exists(path.plus_file(ProjectSettings::IMPORTED_FILES_PATH.right(6)))) { + // `.substr(6)` on `IMPORTED_FILES_PATH` strips away the leading "res://". + if (!DirAccess::exists(path.plus_file(ProjectSettings::IMPORTED_FILES_PATH.substr(6)))) { run_error_diag->set_text(TTR("Can't run project: Assets need to be imported.\nPlease edit the project to trigger the initial import.")); run_error_diag->popup_centered(); continue; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 76290b4b62..e76d757516 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -72,17 +72,9 @@ void ProjectSettingsEditor::_setting_edited(const String &p_name) { queue_save(); } -void ProjectSettingsEditor::_advanced_pressed() { - if (advanced->is_pressed()) { - _update_advanced_bar(); - advanced_bar->show(); - EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", true); - inspector->set_restrict_to_basic_settings(false); - } else { - advanced_bar->hide(); - EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", false); - inspector->set_restrict_to_basic_settings(true); - } +void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) { + EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", p_button_pressed); + inspector->set_restrict_to_basic_settings(!p_button_pressed); } void ProjectSettingsEditor::_setting_selected(const String &p_path) { @@ -90,12 +82,9 @@ void ProjectSettingsEditor::_setting_selected(const String &p_path) { return; } - category_box->set_text(inspector->get_current_section()); - property_box->set_text(p_path); + property_box->set_text(inspector->get_current_section() + "/" + p_path); - if (advanced_bar->is_visible()) { - _update_advanced_bar(); // set_text doesn't trigger text_changed - } + _update_property_box(); // set_text doesn't trigger text_changed } void ProjectSettingsEditor::_add_setting() { @@ -104,7 +93,7 @@ void ProjectSettingsEditor::_add_setting() { // Initialize the property with the default value for the given type. Callable::CallError ce; Variant value; - Variant::construct(Variant::Type(type->get_selected_id()), value, nullptr, 0, ce); + Variant::construct(Variant::Type(type_box->get_selected_id()), value, nullptr, 0, ce); undo_redo->create_action(TTR("Add Project Setting")); undo_redo->add_do_property(ps, setting, value); @@ -117,19 +106,14 @@ void ProjectSettingsEditor::_add_setting() { undo_redo->commit_action(); inspector->set_current_section(setting.get_slice("/", 1)); + add_button->release_focus(); } -void ProjectSettingsEditor::_delete_setting(bool p_confirmed) { +void ProjectSettingsEditor::_delete_setting() { String setting = _get_setting_name(); Variant value = ps->get(setting); int order = ps->get_order(setting); - if (!p_confirmed) { - del_confirmation->set_text(vformat(TTR("Are you sure you want to delete '%s'?"), setting)); - del_confirmation->popup_centered(); - return; - } - undo_redo->create_action(TTR("Delete Item")); undo_redo->add_do_method(ps, "clear", setting); @@ -144,65 +128,84 @@ void ProjectSettingsEditor::_delete_setting(bool p_confirmed) { undo_redo->commit_action(); property_box->clear(); + del_button->release_focus(); } -void ProjectSettingsEditor::_text_field_changed(const String &p_text) { - _update_advanced_bar(); +void ProjectSettingsEditor::_property_box_changed(const String &p_text) { + _update_property_box(); } void ProjectSettingsEditor::_feature_selected(int p_index) { - _update_advanced_bar(); + Vector<String> t = property_box->get_text().strip_edges().split(".", true, 1); + const String feature = p_index ? "." + feature_box->get_item_text(p_index) : ""; + property_box->set_text(t[0] + feature); + _update_property_box(); } -void ProjectSettingsEditor::_update_advanced_bar() { - const String property_text = property_box->get_text().strip_edges(); +void ProjectSettingsEditor::_update_property_box() { + const String setting = _get_setting_name(); + const Vector<String> t = setting.split(".", true, 1); + const String name = t[0]; + const String feature = (t.size() == 2) ? t[1] : ""; + bool feature_invalid = (t.size() == 2) && (t[1] == ""); + + add_button->set_disabled(true); + del_button->set_disabled(true); + + if (feature != "") { + feature_invalid = true; + for (int i = 1; i < feature_box->get_item_count(); i++) { + if (feature == feature_box->get_item_text(i)) { + feature_invalid = false; + feature_box->select(i); + break; + } + } + } - String error_msg = ""; - bool disable_add = true; - bool disable_del = true; + if (feature == "" || feature_invalid) { + feature_box->select(0); + } - if (!property_box->get_text().is_empty()) { - const String setting = _get_setting_name(); - bool setting_exists = ps->has_setting(setting); - if (setting_exists) { - error_msg = TTR(" - Cannot add already existing setting."); + if (property_box->get_text() == "") { + return; + } - disable_del = ps->is_builtin_setting(setting); - if (disable_del) { - String msg = TTR(" - Cannot delete built-in setting."); - error_msg += (error_msg == "") ? msg : "\n" + msg; - } + if (ps->has_setting(setting)) { + del_button->set_disabled(ps->is_builtin_setting(setting)); + _select_type(ps->get_setting(setting).get_type()); + } else { + if (ps->has_setting(name)) { + _select_type(ps->get_setting(name).get_type()); } else { - bool bad_category = false; // Allow empty string. - Vector<String> cats = category_box->get_text().strip_edges().split("/"); - for (int i = 0; i < cats.size(); i++) { - if (!cats[i].is_valid_identifier()) { - bad_category = true; - error_msg = TTR(" - Invalid category name."); - break; - } - } + type_box->select(0); + } - disable_add = bad_category; + if (feature_invalid) { + return; + } - if (!property_text.is_valid_identifier()) { - disable_add = true; - String msg = TTR(" - Invalid property name."); - error_msg += (error_msg == "") ? msg : "\n" + msg; + const Vector<String> names = name.split("/"); + for (int i = 0; i < names.size(); i++) { + if (!names[i].is_valid_identifier()) { + return; } } + + add_button->set_disabled(false); } +} - add_button->set_disabled(disable_add); - del_button->set_disabled(disable_del); +void ProjectSettingsEditor::_select_type(Variant::Type p_type) { + type_box->select(type_box->get_item_index(p_type)); } String ProjectSettingsEditor::_get_setting_name() const { - const String cat = category_box->get_text(); - const String name = (cat.is_empty() ? "global" : cat.strip_edges()).plus_file(property_box->get_text().strip_edges()); - const String feature = feature_override->get_item_text(feature_override->get_selected()); - - return (feature == "") ? name : (name + "." + feature); + String name = property_box->get_text().strip_edges(); + if (name.find("/") == -1) { + name = "global/" + name; + } + return name; } void ProjectSettingsEditor::_add_feature_overrides() { @@ -248,11 +251,11 @@ void ProjectSettingsEditor::_add_feature_overrides() { } } - feature_override->clear(); - feature_override->add_item("", 0); // So it is always on top. + feature_box->clear(); + feature_box->add_item(TTR("(All)"), 0); // So it is always on top. int id = 1; for (Set<String>::Element *E = presets.front(); E; E = E->next()) { - feature_override->add_item(E->get(), id++); + feature_box->add_item(E->get(), id++); } } @@ -480,9 +483,6 @@ void ProjectSettingsEditor::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { inspector->edit(ps); - add_button->set_icon(get_theme_icon("Add", "EditorIcons")); - del_button->set_icon(get_theme_icon("Remove", "EditorIcons")); - search_box->set_right_icon(get_theme_icon("Search", "EditorIcons")); search_box->set_clear_button_enabled(true); @@ -525,87 +525,56 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { general_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); tab_container->add_child(general_editor); - VBoxContainer *header = memnew(VBoxContainer); - header->set_h_size_flags(Control::SIZE_EXPAND_FILL); - general_editor->add_child(header); + HBoxContainer *search_bar = memnew(HBoxContainer); + general_editor->add_child(search_bar); - { - // Search bar. - search_bar = memnew(HBoxContainer); - search_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL); - header->add_child(search_bar); - - search_box = memnew(LineEdit); - search_box->set_placeholder(TTR("Search")); - search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - search_bar->add_child(search_box); - - advanced = memnew(CheckButton); - advanced->set_text(TTR("Advanced Settings")); - advanced->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_advanced_pressed)); - search_bar->add_child(advanced); - } + search_box = memnew(LineEdit); + search_box->set_placeholder(TTR("Filter Settings")); + search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); + search_bar->add_child(search_box); - { - // Advanced bar. - advanced_bar = memnew(HBoxContainer); - advanced_bar->hide(); - header->add_child(advanced_bar); - - HBoxContainer *hbc = advanced_bar; - hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); - - category_box = memnew(LineEdit); - category_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - category_box->connect("text_changed", callable_mp(this, &ProjectSettingsEditor::_text_field_changed)); - category_box->set_placeholder(TTR("Category")); - hbc->add_child(category_box); - - Label *l = memnew(Label); - l->set_text(" / "); - hbc->add_child(l); - - property_box = memnew(LineEdit); - property_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - property_box->set_placeholder(TTR("Property")); - property_box->connect("text_changed", callable_mp(this, &ProjectSettingsEditor::_text_field_changed)); - hbc->add_child(property_box); - - l = memnew(Label); - l->set_text(TTR("Type:")); - hbc->add_child(l); - - type = memnew(OptionButton); - type->set_custom_minimum_size(Size2(100, 0) * EDSCALE); - hbc->add_child(type); - - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - // There's no point in adding Nil types, and Object types - // can't be serialized correctly in the project settings. - if (i != Variant::NIL && i != Variant::OBJECT) { - type->add_item(Variant::get_type_name(Variant::Type(i)), i); - } - } + advanced = memnew(CheckButton); + advanced->set_text(TTR("Advanced Settings")); + advanced->connect("toggled", callable_mp(this, &ProjectSettingsEditor::_advanced_toggled)); + search_bar->add_child(advanced); - l = memnew(Label); - l->set_text(TTR("Feature Override:")); - hbc->add_child(l); + HBoxContainer *header = memnew(HBoxContainer); + general_editor->add_child(header); - feature_override = memnew(OptionButton); - feature_override->set_custom_minimum_size(Size2(100, 0) * EDSCALE); - feature_override->connect("item_selected", callable_mp(this, &ProjectSettingsEditor::_feature_selected)); - hbc->add_child(feature_override); + property_box = memnew(LineEdit); + property_box->set_placeholder(TTR("Select a setting or type its name")); + property_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); + property_box->connect("text_changed", callable_mp(this, &ProjectSettingsEditor::_property_box_changed)); + header->add_child(property_box); + + feature_box = memnew(OptionButton); + feature_box->set_custom_minimum_size(Size2(120, 0) * EDSCALE); + feature_box->connect("item_selected", callable_mp(this, &ProjectSettingsEditor::_feature_selected)); + header->add_child(feature_box); + + type_box = memnew(OptionButton); + type_box->set_custom_minimum_size(Size2(120, 0) * EDSCALE); + header->add_child(type_box); + + for (int i = 0; i < Variant::VARIANT_MAX; i++) { + // There's no point in adding Nil types, and Object types + // can't be serialized correctly in the project settings. + if (i != Variant::NIL && i != Variant::OBJECT) { + type_box->add_item(Variant::get_type_name(Variant::Type(i)), i); + } + } - add_button = memnew(Button); - add_button->set_flat(true); - add_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_add_setting)); - hbc->add_child(add_button); + add_button = memnew(Button); + add_button->set_text(TTR("Add")); + add_button->set_disabled(true); + add_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_add_setting)); + header->add_child(add_button); - del_button = memnew(Button); - del_button->set_flat(true); - del_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_delete_setting), varray(false)); - hbc->add_child(del_button); - } + del_button = memnew(Button); + del_button->set_text(TTR("Delete")); + del_button->set_disabled(true); + del_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_delete_setting)); + header->add_child(del_button); inspector = memnew(SectionedInspector); inspector->get_inspector()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo()); @@ -676,10 +645,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { timer->set_one_shot(true); add_child(timer); - del_confirmation = memnew(ConfirmationDialog); - del_confirmation->connect("confirmed", callable_mp(this, &ProjectSettingsEditor::_delete_setting), varray(true)); - add_child(del_confirmation); - get_ok_button()->set_text(TTR("Close")); set_hide_on_ok(true); @@ -687,7 +652,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { if (use_advanced) { advanced->set_pressed(true); - advanced_bar->show(); } inspector->set_restrict_to_basic_settings(!use_advanced); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index cde46ac4c4..eb6c300d5b 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -51,25 +51,20 @@ class ProjectSettingsEditor : public AcceptDialog { TabContainer *tab_container; SectionedInspector *inspector; + ActionMapEditor *action_map; LocalizationEditor *localization_editor; EditorAutoloadSettings *autoload_settings; ShaderGlobalsEditor *shaders_global_variables_editor; EditorPluginSettings *plugin_settings; - ActionMapEditor *action_map; - HBoxContainer *search_bar; LineEdit *search_box; CheckButton *advanced; - HBoxContainer *advanced_bar; - LineEdit *category_box; LineEdit *property_box; + OptionButton *feature_box; + OptionButton *type_box; Button *add_button; Button *del_button; - OptionButton *type; - OptionButton *feature_override; - - ConfirmationDialog *del_confirmation; Label *restart_label; TextureRect *restart_icon; @@ -80,16 +75,17 @@ class ProjectSettingsEditor : public AcceptDialog { EditorData *data; UndoRedo *undo_redo; - void _advanced_pressed(); - void _update_advanced_bar(); - void _text_field_changed(const String &p_text); + void _advanced_toggled(bool p_button_pressed); + void _property_box_changed(const String &p_text); + void _update_property_box(); void _feature_selected(int p_index); + void _select_type(Variant::Type p_type); String _get_setting_name() const; void _setting_edited(const String &p_name); void _setting_selected(const String &p_path); void _add_setting(); - void _delete_setting(bool p_confirmed); + void _delete_setting(); void _editor_restart_request(); void _editor_restart(); diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index da798962e5..bf31be536c 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -52,7 +52,7 @@ void PropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) { search_box->accept_event(); TreeItem *root = search_options->get_root(); - if (!root->get_children()) { + if (!root->get_first_child()) { break; } @@ -150,7 +150,7 @@ void PropertySelector::_update_search() { for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { if (E->get().usage == PROPERTY_USAGE_CATEGORY) { - if (category && category->get_children() == nullptr) { + if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } category = search_options->create_item(root); @@ -192,7 +192,7 @@ void PropertySelector::_update_search() { item->set_selectable(0, true); } - if (category && category->get_children() == nullptr) { + if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } } else { @@ -225,7 +225,7 @@ void PropertySelector::_update_search() { for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { if (E->get().name.begins_with("*")) { - if (category && category->get_children() == nullptr) { + if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } category = search_options->create_item(root); @@ -316,12 +316,12 @@ void PropertySelector::_update_search() { } } - if (category && category->get_children() == nullptr) { + if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } } - get_ok_button()->set_disabled(root->get_children() == nullptr); + get_ok_button()->set_disabled(root->get_first_child() == nullptr); } void PropertySelector::_confirmed() { diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index 7f720d65d0..e8e13bab21 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -102,7 +102,7 @@ void EditorQuickOpen::_update_search() { ti->set_icon(0, *icons.lookup_ptr(entries[i].path.get_extension())); } - TreeItem *to_select = root->get_children(); + TreeItem *to_select = root->get_first_child(); to_select->select(0); to_select->set_as_cursor(0); search_options->scroll_to_item(to_select); @@ -170,7 +170,7 @@ void EditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) { if (allow_multi_select) { TreeItem *root = search_options->get_root(); - if (!root->get_children()) { + if (!root->get_first_child()) { break; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 4068a102df..349e05b47b 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1833,7 +1833,7 @@ bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const { TreeItem *item = needs_check.back()->get(); needs_check.pop_back(); - TreeItem *child = item->get_children(); + TreeItem *child = item->get_first_child(); is_branch_collapsed = item->is_collapsed() && child; if (is_branch_collapsed) { @@ -1857,7 +1857,7 @@ void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) item->set_collapsed(p_collapsed); - TreeItem *child = item->get_children(); + TreeItem *child = item->get_first_child(); while (child) { to_collapse.push_back(child); child = child->get_next(); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index d0bf83eb2d..6f9b0ae873 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -699,7 +699,7 @@ TreeItem *SceneTreeEditor::_find(TreeItem *p_node, const NodePath &p_path) { return p_node; } - TreeItem *children = p_node->get_children(); + TreeItem *children = p_node->get_first_child(); while (children) { TreeItem *n = _find(children, p_path); if (n) { @@ -883,7 +883,7 @@ void SceneTreeEditor::_update_selection(TreeItem *item) { item->deselect(0); } - TreeItem *c = item->get_children(); + TreeItem *c = item->get_first_child(); while (c) { _update_selection(c); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 541ec224b9..4cdf820877 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -235,8 +235,8 @@ void EditorSettingsDialog::_update_shortcuts() { // Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated. Map<String, bool> collapsed; - if (shortcuts->get_root() && shortcuts->get_root()->get_children()) { - for (TreeItem *item = shortcuts->get_root()->get_children(); item; item = item->get_next()) { + if (shortcuts->get_root() && shortcuts->get_root()->get_first_child()) { + for (TreeItem *item = shortcuts->get_root()->get_first_child(); item; item = item->get_next()) { collapsed[item->get_text(0)] = item->is_collapsed(); } } @@ -380,7 +380,7 @@ void EditorSettingsDialog::_update_shortcuts() { // remove sections with no shortcuts for (Map<String, TreeItem *>::Element *E = sections.front(); E; E = E->next()) { TreeItem *section = E->get(); - if (section->get_children() == nullptr) { + if (section->get_first_child() == nullptr) { root->remove_child(section); } } diff --git a/editor/translations/af.po b/editor/translations/af.po index 1b952d51b6..887b7983eb 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -2589,8 +2589,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -3005,6 +3006,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 9051e2cf82..a93fc9a473 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -55,8 +55,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-16 07:52+0000\n" -"Last-Translator: Hatim Jamal <hatimjamal8@gmail.com>\n" +"PO-Revision-Date: 2021-05-07 02:12+0000\n" +"Last-Translator: ILG - Game <moegypt277@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -65,7 +65,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2565,9 +2565,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "غير قادر علي تØÙ…يل النص البرمجي Ù„Ù„Ø¥Ø¶Ø§ÙØ© من المسار: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "غير قادر علي تØÙ…يل النص البرمجي Ø§Ù„Ø¥Ø¶Ø§ÙØ¨ من المسار: '%s' يبدو أن Ø´ÙÙØ±Ø© " "البرمجية يوجد بها أخطاء , الرجاء مراجعة الشÙÙØ±Ø© البرمجية." @@ -3016,6 +3018,10 @@ msgid "About" msgstr "ØÙˆÙ„" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "تشغيل المشروع." @@ -3826,9 +3832,8 @@ msgid "Duplicate..." msgstr "تكرير..." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Move to Trash" -msgstr "نقل التØÙ…يل التلقائي" +msgstr "نقل الي سلة Ø§Ù„Ù…ØØ°ÙˆÙات" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." @@ -3939,19 +3944,16 @@ msgid "Searching..." msgstr "جاري Ø§Ù„Ø¨ØØ«..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d تطابقات." +msgstr "d% تطابق ÙÙŠ d% الملÙ." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d تطابقات." +msgstr "d% تطابقات ÙÙŠ d% الملÙ." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d تطابقات." +msgstr "d% تطابقات ÙÙŠ d% الملÙ." #: editor/groups_editor.cpp msgid "Add to Group" @@ -4088,18 +4090,16 @@ msgid "Saving..." msgstr "جاري الØÙظ..." #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Select Importer" -msgstr "ØªØØ¯ÙŠØ¯ الوضع" +msgstr "ØØ¯Ø¯ المستورد" #: editor/import_defaults_editor.cpp msgid "Importer:" msgstr "المستورد:" #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Reset to Defaults" -msgstr "تØÙ…يل Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ" +msgstr "اعادة التعيين Ù„Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠØ§Øª" #: editor/import_dock.cpp msgid "Keep File (No Import)" @@ -4666,7 +4666,7 @@ msgstr "أدوات الرسم Ø§Ù„Ù…ØªØØ±Ùƒ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "الرسم Ø§Ù„Ù…ØªØØ±Ùƒ" +msgstr "رسوم Ù…ØªØØ±ÙƒØ©" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -5071,9 +5071,8 @@ msgid "Got:" msgstr "ما تم Ø§Ù„ØØµÙˆÙ„ عليه:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Failed SHA-256 hash check" -msgstr "ÙØ´Ù„ التاكد من ترميز sha256" +msgstr "ÙØ´Ù„ ÙÙŠ تجزئة SHA-256" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" @@ -5238,6 +5237,7 @@ msgstr "" "[0.0ØŒ1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "تم تجميع Ù…ØØ±Ø± Godot دون دعم لتتبع الأشعة. لا يمكن بناء خرائط الإضاءة." @@ -8354,7 +8354,7 @@ msgstr "تنقل" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Bitmask" -msgstr "قناع Ø§Ù„Ø¨ÙØª" +msgstr "قناع-Ø§Ù„Ø¨ÙØª" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Priority" diff --git a/editor/translations/az.po b/editor/translations/az.po new file mode 100644 index 0000000000..1dcbe3a7a5 --- /dev/null +++ b/editor/translations/az.po @@ -0,0 +1,12562 @@ +# Azerbaijani translation of the Godot Engine editor. +# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. +# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). +# This file is distributed under the same license as the Godot source code. +# +# Jafar Tarverdiyev <cefertarverdiyevv@gmail.com>, 2021. +msgid "" +msgstr "" +"Project-Id-Version: Godot Engine editor\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" +"Last-Translator: Jafar Tarverdiyev <cefertarverdiyevv@gmail.com>\n" +"Language-Team: Azerbaijani <https://hosted.weblate.org/projects/godot-engine/" +"godot/az/>\n" +"Language: az\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.7-dev\n" + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Invalid type argument to convert(), use TYPE_* constants." +msgstr "" +"convert() üçün uyÄŸun olmayan növdÉ™ arqument, TYPE_* sabitlÉ™rini istifadÉ™ " +"edin." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +msgid "Expected a string of length 1 (a character)." +msgstr "1 uzunluÄŸunda mÉ™tin (bir iÅŸarÉ™) gözlÉ™nilir." + +#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp +#: modules/mono/glue/gd_glue.cpp +#: modules/visual_script/visual_script_builtin_funcs.cpp +msgid "Not enough bytes for decoding bytes, or invalid format." +msgstr "" +"Baytların dekodlanması üçün kifayÉ™t qÉ™dÉ™r Bayt yoxdur, vÉ™ ya uyÄŸun olmayan " +"format." + +#: core/math/expression.cpp +msgid "Invalid input %i (not passed) in expression" +msgstr "İfadÉ™dÉ™ uyÄŸunsuz giriÅŸ %d (ötürülmÉ™di)" + +#: core/math/expression.cpp +msgid "self can't be used because instance is null (not passed)" +msgstr "self istifadÉ™ edilÉ™ bilmÉ™z, çünki \"instance\" null-dur (ötürülmÉ™di)" + +#: core/math/expression.cpp +#, fuzzy +msgid "Invalid operands to operator %s, %s and %s." +msgstr "%s, %s vÉ™ %s operatoruna sÉ™hv operandlar." + +#: core/math/expression.cpp +#, fuzzy +msgid "Invalid index of type %s for base type %s" +msgstr "%s baza növü üçün %s növünün sÉ™hv indeksi" + +#: core/math/expression.cpp +msgid "Invalid named index '%s' for base type %s" +msgstr "%s baza tipi üçün '% s' adlı etibarsız indeks" + +#: core/math/expression.cpp +msgid "Invalid arguments to construct '%s'" +msgstr "'%s' qurmaq üçün etibarsız arqumentlÉ™r" + +#: core/math/expression.cpp +#, fuzzy +msgid "On call to '%s':" +msgstr "'%s'-É™ çağırış zamanı:" + +#: core/ustring.cpp +msgid "B" +msgstr "B" + +#: core/ustring.cpp +msgid "KiB" +msgstr "KiB" + +#: core/ustring.cpp +msgid "MiB" +msgstr "MiB" + +#: core/ustring.cpp +msgid "GiB" +msgstr "GiB" + +#: core/ustring.cpp +msgid "TiB" +msgstr "TiB" + +#: core/ustring.cpp +msgid "PiB" +msgstr "PiB" + +#: core/ustring.cpp +msgid "EiB" +msgstr "EiB" + +#: editor/animation_bezier_editor.cpp +#, fuzzy +msgid "Free" +msgstr "SÉ™rbÉ™st" + +#: editor/animation_bezier_editor.cpp +msgid "Balanced" +msgstr "Balanslı" + +#: editor/animation_bezier_editor.cpp +msgid "Mirror" +msgstr "Güzgü" + +#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp +msgid "Time:" +msgstr "Vaxt:" + +#: editor/animation_bezier_editor.cpp +msgid "Value:" +msgstr "DÉ™yÉ™r:" + +#: editor/animation_bezier_editor.cpp +msgid "Insert Key Here" +msgstr "Açar sözü buraya daxil edin" + +#: editor/animation_bezier_editor.cpp +msgid "Duplicate Selected Key(s)" +msgstr "Seçili açar(lar)-ı çoxalt" + +#: editor/animation_bezier_editor.cpp +msgid "Delete Selected Key(s)" +msgstr "Seçili açar(lar)ı sil" + +#: editor/animation_bezier_editor.cpp +msgid "Add Bezier Point" +msgstr "Bezier NöqtÉ™si É™lavÉ™ edin" + +#: editor/animation_bezier_editor.cpp +#, fuzzy +msgid "Move Bezier Points" +msgstr "Bezier NöqtÉ™lÉ™rini Köçür" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Duplicate Keys" +msgstr "Animasya açarlarını çoxalt" + +#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +msgid "Anim Delete Keys" +msgstr "Animasya açarlarını sil" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Time" +msgstr "Animasya Açar-kadr(keyframe) vaxtını dÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Transition" +msgstr "Animasya keçidini dÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Anim Change Transform" +msgstr "Animasya transformasiyasını dÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Keyframe Value" +msgstr "Animasya Açar-kadr (Keyframe) dÉ™yÉ™rini dÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Anim Change Call" +msgstr "Animasiya DÉ™yiÅŸim Çağırısı" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Anim Multi Change Keyframe Time" +msgstr "Animasya Açar-kadr(Keyframe) vaxtını çoxlu(multiple) dÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transition" +msgstr "Animasya keçidinin çoxlu(Multi) dÉ™yiÅŸimi" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Transform" +msgstr "Animasya Transformasiyasinin çoxlu(Multi) deyiÅŸimi" + +#: editor/animation_track_editor.cpp +msgid "Anim Multi Change Keyframe Value" +msgstr "Animasya Açar-Kadr(keyframe) dÉ™yÉ™rinin Çoxlu (Multi) DÉ™yiÅŸimi" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Anim Multi Change Call" +msgstr "Animasya Çağırışının çoxlu(Multi) DÉ™yiÅŸimi" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Length" +msgstr "Animasya UzunluÄŸunu DÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Change Animation Loop" +msgstr "Animasya Döngüsünü DÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Property Track" +msgstr "XassÉ™" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "3D Transform Track" +msgstr "3D Transformasya izi" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Call Method Track" +msgstr "Metod çağırma izi" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Bezier Curve Track" +msgstr "Bezier Æyrisi izi" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Audio Playback Track" +msgstr "SÉ™s oxutma izi" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Animation Playback Track" +msgstr "Animasya oynatma izi" + +#: editor/animation_track_editor.cpp +msgid "Animation length (frames)" +msgstr "Animasiya uzunluÄŸu (kadrlar)" + +#: editor/animation_track_editor.cpp +msgid "Animation length (seconds)" +msgstr "Animasiya uzunluÄŸu (saniyÉ™lÉ™r)" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Add Track" +msgstr "İz É™lavÉ™ et" + +#: editor/animation_track_editor.cpp +msgid "Animation Looping" +msgstr "Animasiya Döngüsü" + +#: editor/animation_track_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Functions:" +msgstr "Funksiyalar:" + +#: editor/animation_track_editor.cpp +msgid "Audio Clips:" +msgstr "Audio kliplÉ™r:" + +#: editor/animation_track_editor.cpp +msgid "Anim Clips:" +msgstr "Animasiyalar:" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Change Track Path" +msgstr "İzin yolunu dÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Toggle this track on/off." +msgstr "Bu izi açın / söndürün." + +#: editor/animation_track_editor.cpp +msgid "Update Mode (How this property is set)" +msgstr "YenilÉ™mÉ™ rejimi (bu xüsusiyyÉ™t necÉ™ qurulur)" + +#: editor/animation_track_editor.cpp +msgid "Interpolation Mode" +msgstr "İnterpolasiya rejimi" + +#: editor/animation_track_editor.cpp +msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" +msgstr "Döngü BükmÉ™ Rejimi (DöngüdÉ™ baÅŸlayan interpolasyanın sonu)" + +#: editor/animation_track_editor.cpp +msgid "Remove this track." +msgstr "Bu izi sil." + +#: editor/animation_track_editor.cpp +msgid "Time (s): " +msgstr "Vaxt (sn): " + +#: editor/animation_track_editor.cpp +msgid "Toggle Track Enabled" +msgstr "İz funksiyasını aktiv edin" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Continuous" +msgstr "Davamlı" + +#: editor/animation_track_editor.cpp +msgid "Discrete" +msgstr "Ayrı" + +#: editor/animation_track_editor.cpp +msgid "Trigger" +msgstr "TÉ™tiklÉ™yici" + +#: editor/animation_track_editor.cpp +msgid "Capture" +msgstr "Tutmaq" + +#: editor/animation_track_editor.cpp +msgid "Nearest" +msgstr "Æn yaxın" + +#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp +#: editor/property_editor.cpp +msgid "Linear" +msgstr "XÉ™tti" + +#: editor/animation_track_editor.cpp +msgid "Cubic" +msgstr "Kubik" + +#: editor/animation_track_editor.cpp +msgid "Clamp Loop Interp" +msgstr "Döngü AradÉ™yÉ™rlÉ™ndirmÉ™sini(İnterp) Qısqacla" + +#: editor/animation_track_editor.cpp +msgid "Wrap Loop Interp" +msgstr "Döngü AradÉ™yÉ™rlÉ™ndirmÉ™sini(İnterp) Bük" + +#: editor/animation_track_editor.cpp +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key" +msgstr "Açar daxil et" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Key(s)" +msgstr "Açar(lar)ı çoxalt" + +#: editor/animation_track_editor.cpp +msgid "Delete Key(s)" +msgstr "Açar(lar)ı sil" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Update Mode" +msgstr "Animasya YenilÉ™mÉ™ Rejimini DÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Interpolation Mode" +msgstr "Animasya AradÉ™yÉ™rlÉ™ndirmÉ™(İnterpolation) Rejimini DÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Loop Mode" +msgstr "Animasya Döngü Rejimini DÉ™yiÅŸ" + +#: editor/animation_track_editor.cpp +msgid "Remove Anim Track" +msgstr "Animasya İzini Sil" + +#: editor/animation_track_editor.cpp +msgid "Create NEW track for %s and insert key?" +msgstr "%s üçün YENİ iz yaradılsın vÉ™ açar daxil edilsin?" + +#: editor/animation_track_editor.cpp +msgid "Create %d NEW tracks and insert keys?" +msgstr "%d YENİ izlÉ™r yarat vÉ™ açarları daxil et?" + +#: editor/animation_track_editor.cpp editor/create_dialog.cpp +#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/mesh_instance_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +#, fuzzy +msgid "Create" +msgstr "Yarat" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert" +msgstr "Animasiya Daxil Et" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "AnimationPlayer can't animate itself, only other players." +msgstr "AnimationPlayer özünü canlandıra bilmÉ™z, yalnız digÉ™r playerlÉ™r." + +#: editor/animation_track_editor.cpp +msgid "Anim Create & Insert" +msgstr "Animasiya yaradın vÉ™ É™lavÉ™ edin" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Track & Key" +msgstr "Animasya izi vÉ™ açarı É™lavÉ™ edin" + +#: editor/animation_track_editor.cpp +msgid "Anim Insert Key" +msgstr "Animasya açarı daxil edin" + +#: editor/animation_track_editor.cpp +msgid "Change Animation Step" +msgstr "Animasiya Addımını DÉ™yiÅŸdirin" + +#: editor/animation_track_editor.cpp +msgid "Rearrange Tracks" +msgstr "İzlÉ™ri yenidÉ™n sırala" + +#: editor/animation_track_editor.cpp +msgid "Transform tracks only apply to Spatial-based nodes." +msgstr "" +"Transformasya izlÉ™ri yalnız MÉ™kan Æsaslı(Spatial-Based) düyünlÉ™rÉ™ uyÄŸulana " +"bilÉ™r." + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "" +"Audio tracks can only point to nodes of type:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" +msgstr "" +"Audio treklÉ™r yalnız bu növ düyünlÉ™rÉ™ iÅŸarÉ™ edÉ™ bilÉ™r:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" + +#: editor/animation_track_editor.cpp +msgid "Animation tracks can only point to AnimationPlayer nodes." +msgstr "" +"Animasiya parçaları yalnız AnimationPlayer düyünlÉ™rini iÅŸarÉ™ edÉ™ bilÉ™r." + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "An animation player can't animate itself, only other players." +msgstr "Animasiya pleyeri özünü canlandıra bilmÉ™z, yalnız digÉ™r pleyerlÉ™r." + +#: editor/animation_track_editor.cpp +msgid "Not possible to add a new track without a root" +msgstr "Kök olmadan yeni iz É™lavÉ™ etmÉ™k mümkün deyil" + +#: editor/animation_track_editor.cpp +msgid "Invalid track for Bezier (no suitable sub-properties)" +msgstr "Bezier üçün sÉ™hv iz (uyÄŸun alt-xüsusiyyÉ™tlÉ™r yoxdur)" + +#: editor/animation_track_editor.cpp +msgid "Add Bezier Track" +msgstr "Bezier iz É™lavÉ™ edin" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a key." +msgstr "Yol (Track path) keçərsizdir, buna görÉ™ açar É™lavÉ™ edÉ™ bilmÉ™zsiniz." + +#: editor/animation_track_editor.cpp +msgid "Track is not of type Spatial, can't insert key" +msgstr "İz MÉ™kan tipli deyil, açarı É™lavÉ™ etmÉ™k mümkün deyil" + +#: editor/animation_track_editor.cpp +msgid "Add Transform Track Key" +msgstr "Transformasya İz Açarı É™lavÉ™ edin" + +#: editor/animation_track_editor.cpp +msgid "Add Track Key" +msgstr "İz Açarı ÆlavÉ™ Et" + +#: editor/animation_track_editor.cpp +msgid "Track path is invalid, so can't add a method key." +msgstr "" +"Yol (Track path) keçərsizdir, buna görÉ™ metod açarı É™lavÉ™ edÉ™ bilmÉ™zsiniz." + +#: editor/animation_track_editor.cpp +msgid "Add Method Track Key" +msgstr "Metod İz Açarı É™lavÉ™ edin" + +#: editor/animation_track_editor.cpp +msgid "Method not found in object: " +msgstr "Metod obyektdÉ™ tapılmadı: " + +#: editor/animation_track_editor.cpp +msgid "Anim Move Keys" +msgstr "Animasya KöçürmÉ™ Açarları" + +#: editor/animation_track_editor.cpp +msgid "Clipboard is empty" +msgstr "Panel(Clipboard) boÅŸdur" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Paste Tracks" +msgstr "İzlÉ™ri yapışdır" + +#: editor/animation_track_editor.cpp +msgid "Anim Scale Keys" +msgstr "Animasya Açarlarını ÖlçülÉ™" + +#: editor/animation_track_editor.cpp +msgid "" +"This option does not work for Bezier editing, as it's only a single track." +msgstr "Bu seçim Bezier redaktÉ™si üçün iÅŸlÉ™mir, çünki yalnız bir izlidir." + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "" +"This animation belongs to an imported scene, so changes to imported tracks " +"will not be saved.\n" +"\n" +"To enable the ability to add custom tracks, navigate to the scene's import " +"settings and set\n" +"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks" +"\", then re-import.\n" +"Alternatively, use an import preset that imports animations to separate " +"files." +msgstr "" +"Bu animasiya idxal olunan sÉ™hnÉ™yÉ™ mÉ™xsusdur, buna görÉ™ dÉ™ idxal olunan izdÉ™ " +"edilÉ™n dÉ™yiÅŸikliklÉ™r yadda saxlanılmayacaq.\n" +"\n" +"Xüsusi iz É™lavÉ™ etmÉ™k imkanını tÉ™min etmÉ™k üçün, sÉ™hnÉ™nin idxal ayarlarına " +"istiqamÉ™tlÉ™nin vÉ™ tÉ™yin edin\n" +"\"Animation > Storage\" to \"Files\", aktivləşdir \"Animation > Keep Custom " +"Tracks\", sonra yenidÉ™n idxal.\n" +"Alternativ olaraq, faylları ayırmaq üçün animasiya idxal edÉ™n É™vvÉ™lcÉ™dÉ™n " +"qurulmuÅŸ idxaldan(import preset) istifadÉ™ edin." + +#: editor/animation_track_editor.cpp +msgid "Warning: Editing imported animation" +msgstr "XÉ™bÉ™rdarlıq: İdxal edilmiÅŸ animasiyanın redaktÉ™si" + +#: editor/animation_track_editor.cpp +msgid "Select an AnimationPlayer node to create and edit animations." +msgstr "Animasiya yaratmaq vÉ™ redaktÉ™ etmÉ™k üçün AnimationPlayer düyünü seçin." + +#: editor/animation_track_editor.cpp +msgid "Only show tracks from nodes selected in tree." +msgstr "Yalnız aÄŸacda seçilÉ™n düyünlÉ™rdÉ™n izlÉ™ri göstÉ™r." + +#: editor/animation_track_editor.cpp +msgid "Group tracks by node or display them as plain list." +msgstr "" +"İzlÉ™ri düyünlÉ™rÉ™ görÉ™ qruplaÅŸdır vÉ™ ya onları sadÉ™ siyahı ÅŸÉ™klindÉ™ nümayiÅŸ " +"etdir." + +#: editor/animation_track_editor.cpp +msgid "Snap:" +msgstr "Yapışdır(Snap):" + +#: editor/animation_track_editor.cpp +msgid "Animation step value." +msgstr "Animasiya addım dÉ™yÉ™ri." + +#: editor/animation_track_editor.cpp +msgid "Seconds" +msgstr "SaniyÉ™" + +#: editor/animation_track_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "FPS" +msgstr "FPS" + +#: editor/animation_track_editor.cpp editor/editor_properties.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit" +msgstr "RedaktÉ™ et" + +#: editor/animation_track_editor.cpp +msgid "Animation properties." +msgstr "Animasiya xüsusiyyÉ™tlÉ™ri." + +#: editor/animation_track_editor.cpp +msgid "Copy Tracks" +msgstr "İzlÉ™ri Kopyala" + +#: editor/animation_track_editor.cpp +msgid "Scale Selection" +msgstr "ÖlçmÉ™ seçimi" + +#: editor/animation_track_editor.cpp +msgid "Scale From Cursor" +msgstr "Kursordan ÖlçülÉ™" + +#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp +msgid "Duplicate Selection" +msgstr "SeçilÉ™ni Çoxalt" + +#: editor/animation_track_editor.cpp +msgid "Duplicate Transposed" +msgstr "TÉ™rsinÉ™ çevrilmiÅŸi Çoxalt" + +#: editor/animation_track_editor.cpp +msgid "Delete Selection" +msgstr "SeçilÉ™ni Sil" + +#: editor/animation_track_editor.cpp +msgid "Go to Next Step" +msgstr "NövbÉ™ti addıma keç" + +#: editor/animation_track_editor.cpp +msgid "Go to Previous Step" +msgstr "ÆvvÉ™lki addıma keç" + +#: editor/animation_track_editor.cpp +msgid "Optimize Animation" +msgstr "Animasiyanı OptimallaÅŸdırma" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation" +msgstr "Animasiyanı TÉ™mizlÉ™mÉ™" + +#: editor/animation_track_editor.cpp +msgid "Pick the node that will be animated:" +msgstr "Animasiya edilÉ™cÉ™k düyünü seçin:" + +#: editor/animation_track_editor.cpp +msgid "Use Bezier Curves" +msgstr "Bezier Æyrisini istifadÉ™ edin" + +#: editor/animation_track_editor.cpp +msgid "Anim. Optimizer" +msgstr "Animasya Optimizator" + +#: editor/animation_track_editor.cpp +msgid "Max. Linear Error:" +msgstr "Maks. XÉ™tti XÉ™ta:" + +#: editor/animation_track_editor.cpp +msgid "Max. Angular Error:" +msgstr "Maks.Bucaqlı XÉ™ta:" + +#: editor/animation_track_editor.cpp +msgid "Max Optimizable Angle:" +msgstr "Maks Optimize EdilÉ™ BilÉ™n Bucaq:" + +#: editor/animation_track_editor.cpp +msgid "Optimize" +msgstr "OptimallaÅŸdır" + +#: editor/animation_track_editor.cpp +msgid "Remove invalid keys" +msgstr "SÉ™hv açarları sil" + +#: editor/animation_track_editor.cpp +msgid "Remove unresolved and empty tracks" +msgstr "HÉ™ll edilmÉ™miÅŸ vÉ™ boÅŸ izlÉ™ri sil" + +#: editor/animation_track_editor.cpp +msgid "Clean-up all animations" +msgstr "Bütün animasiyaları tÉ™mizlÉ™" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up Animation(s) (NO UNDO!)" +msgstr "Animasiya(lar)nı TÉ™mizlÉ™ (GERİ QAYTARMA YOXDUR!)" + +#: editor/animation_track_editor.cpp +msgid "Clean-Up" +msgstr "TÉ™mizlÉ™" + +#: editor/animation_track_editor.cpp +msgid "Scale Ratio:" +msgstr "Ölçüm NisbÉ™ti:" + +#: editor/animation_track_editor.cpp +msgid "Select Tracks to Copy" +msgstr "Kopyalanacaq izlÉ™ri seçin" + +#: editor/animation_track_editor.cpp editor/editor_log.cpp +#: editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Copy" +msgstr "Kopyala" + +#: editor/animation_track_editor.cpp +msgid "Select All/None" +msgstr "Hamısını Seç/SeçmÉ™" + +#: editor/animation_track_editor_plugins.cpp +#, fuzzy +msgid "Add Audio Track Clip" +msgstr "Audio İz Klipi É™lavÉ™ et" + +#: editor/animation_track_editor_plugins.cpp +#, fuzzy +msgid "Change Audio Track Clip Start Offset" +msgstr "Audio İz Klipinin BaÅŸlanğıc SürüşmÉ™sini DÉ™yiÅŸ" + +#: editor/animation_track_editor_plugins.cpp +msgid "Change Audio Track Clip End Offset" +msgstr "Audio İz Klipinin BitiÅŸ SürüşmÉ™sini DÉ™yiÅŸ" + +#: editor/array_property_edit.cpp +msgid "Resize Array" +msgstr "Massiv Ölçüsünü DÉ™yiÅŸ" + +#: editor/array_property_edit.cpp +msgid "Change Array Value Type" +msgstr "Massiv QiymÉ™t Növünü DÉ™yiÅŸ" + +#: editor/array_property_edit.cpp +msgid "Change Array Value" +msgstr "Massiv dÉ™yÉ™rini dÉ™yiÅŸ" + +#: editor/code_editor.cpp +msgid "Go to Line" +msgstr "SÉ™tirÉ™ get" + +#: editor/code_editor.cpp +msgid "Line Number:" +msgstr "SÉ™tir NömrÉ™si:" + +#: editor/code_editor.cpp +msgid "%d replaced." +msgstr "% d dÉ™yiÅŸdirildi." + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d match." +msgstr "%d uyÄŸun gÉ™lir." + +#: editor/code_editor.cpp editor/editor_help.cpp +msgid "%d matches." +msgstr "%d uyÄŸun gÉ™lir." + +#: editor/code_editor.cpp editor/find_in_files.cpp +#, fuzzy +msgid "Match Case" +msgstr "HÉ™rf UyÄŸunlaÅŸdır" + +#: editor/code_editor.cpp editor/find_in_files.cpp +msgid "Whole Words" +msgstr "Bütün sözlÉ™r" + +#: editor/code_editor.cpp +msgid "Replace" +msgstr "ÆvÉ™z Et" + +#: editor/code_editor.cpp +msgid "Replace All" +msgstr "Hamısını ÆvÉ™z Et" + +#: editor/code_editor.cpp +msgid "Selection Only" +msgstr "Yalnız Seçim" + +#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp +#: editor/plugins/text_editor.cpp +msgid "Standard" +msgstr "Standart" + +#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp +msgid "Toggle Scripts Panel" +msgstr "SkriptlÉ™r Panelini Aktivləşdir/Söndür" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom In" +msgstr "YaxınlaÅŸdır" + +#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Out" +msgstr "UzaqlaÅŸdır" + +#: editor/code_editor.cpp +msgid "Reset Zoom" +msgstr "YaxınlaÅŸdırmanı Sıfırla" + +#: editor/code_editor.cpp +msgid "Warnings" +msgstr "XÉ™bÉ™rdarlıqlar" + +#: editor/code_editor.cpp +msgid "Line and column numbers." +msgstr "SÉ™tir vÉ™ sütun É™dÉ™dlÉ™ri." + +#: editor/connections_dialog.cpp +msgid "Method in target node must be specified." +msgstr "HÉ™dÉ™f düyünündÉ™ metod göstÉ™rilmÉ™lidir." + +#: editor/connections_dialog.cpp +msgid "Method name must be a valid identifier." +msgstr "Metod adı hökmlü identifikativ olmalıdır." + +#: editor/connections_dialog.cpp +msgid "" +"Target method not found. Specify a valid method or attach a script to the " +"target node." +msgstr "" +"HÉ™dÉ™f metodu tapılmadı. HÉ™dÉ™f düyününÉ™ hökmlü bir metod tÉ™yin edin vÉ™ ya " +"skript yapışdırın." + +#: editor/connections_dialog.cpp +msgid "Connect to Node:" +msgstr "DüyünÉ™ qoÅŸulun:" + +#: editor/connections_dialog.cpp +msgid "Connect to Script:" +msgstr "SkriptÉ™ qoÅŸulun:" + +#: editor/connections_dialog.cpp +msgid "From Signal:" +msgstr "Siqnaldan:" + +#: editor/connections_dialog.cpp +msgid "Scene does not contain any script." +msgstr "SÉ™hnÉ™dÉ™ heç bir skript yoxdur." + +#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp +#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +msgid "Add" +msgstr "ÆlavÉ™ Et" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/editor_feature_profile.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp +msgid "Remove" +msgstr "Sil" + +#: editor/connections_dialog.cpp +msgid "Add Extra Call Argument:" +msgstr "Ekstra Çağırış Arqumenti ÆlavÉ™ Et:" + +#: editor/connections_dialog.cpp +msgid "Extra Call Arguments:" +msgstr "Ekstra Çağırış ArqumentlÉ™ri:" + +#: editor/connections_dialog.cpp +msgid "Receiver Method:" +msgstr "Alıcı metod:" + +#: editor/connections_dialog.cpp +msgid "Advanced" +msgstr "Qabaqcıl" + +#: editor/connections_dialog.cpp +msgid "Deferred" +msgstr "TÉ™xirÉ™ salınmış" + +#: editor/connections_dialog.cpp +msgid "" +"Defers the signal, storing it in a queue and only firing it at idle time." +msgstr "" +"Siqnalı tÉ™xirÉ™ salar, növbÉ™dÉ™ saxlayar vÉ™ yalnız prosessorun bikar vaxtında " +"atəşlÉ™r." + +#: editor/connections_dialog.cpp +msgid "Oneshot" +msgstr "TÉ™k atış" + +#: editor/connections_dialog.cpp +msgid "Disconnects the signal after its first emission." +msgstr "İlk buraxılışından sonra Siqnalı kÉ™sir." + +#: editor/connections_dialog.cpp +msgid "Cannot connect signal" +msgstr "Siqnala baÄŸlana bilmir" + +#: editor/connections_dialog.cpp editor/dependency_editor.cpp +#: editor/export_template_manager.cpp editor/groups_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/property_editor.cpp +#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Close" +msgstr "BaÄŸla" + +#: editor/connections_dialog.cpp +msgid "Connect" +msgstr "QoÅŸ" + +#: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "Siqnal:" + +#: editor/connections_dialog.cpp +msgid "Connect '%s' to '%s'" +msgstr "'%s' ilÉ™ '%s' qoÅŸ" + +#: editor/connections_dialog.cpp +msgid "Disconnect '%s' from '%s'" +msgstr "'%s' ilÉ™ '%s' arasında É™laqÉ™ni kÉ™s" + +#: editor/connections_dialog.cpp +#, fuzzy +msgid "Disconnect all from signal: '%s'" +msgstr "Hamısını '% s' Siqnalından ayır" + +#: editor/connections_dialog.cpp +msgid "Connect..." +msgstr "QoÅŸ ..." + +#: editor/connections_dialog.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Disconnect" +msgstr "Ayır" + +#: editor/connections_dialog.cpp +msgid "Connect a Signal to a Method" +msgstr "Siqnalı bir Metoda BaÄŸla" + +#: editor/connections_dialog.cpp +msgid "Edit Connection:" +msgstr "ÆlaqÉ™ni redaktÉ™ edin:" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from the \"%s\" signal?" +msgstr "" +"Æminsinizmi ki, bütün É™laqÉ™lÉ™ri \"%s\" siqnalından çıxartmaq istÉ™yirsiniz?" + +#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp +msgid "Signals" +msgstr "Siqnallar" + +#: editor/connections_dialog.cpp +msgid "Filter signals" +msgstr "Siqnalları filtirlÉ™" + +#: editor/connections_dialog.cpp +msgid "Are you sure you want to remove all connections from this signal?" +msgstr "Æminsinizmi ki, bütün É™laqÉ™lÉ™ri bu siqnaldan çıxartmaq istÉ™yirsiniz?" + +#: editor/connections_dialog.cpp +msgid "Disconnect All" +msgstr "Hamısını ayır" + +#: editor/connections_dialog.cpp +msgid "Edit..." +msgstr "RedaktÉ™ et..." + +#: editor/connections_dialog.cpp +msgid "Go To Method" +msgstr "Metoda Get" + +#: editor/create_dialog.cpp +msgid "Change %s Type" +msgstr "%s növünü dÉ™yiÅŸdirin" + +#: editor/create_dialog.cpp editor/project_settings_editor.cpp +msgid "Change" +msgstr "DÉ™yiÅŸdir" + +#: editor/create_dialog.cpp +msgid "Create New %s" +msgstr "Yeni %s yarat" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp +msgid "Favorites:" +msgstr "FavoritlÉ™r:" + +#: editor/create_dialog.cpp editor/editor_file_dialog.cpp +msgid "Recent:" +msgstr "Son:" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search:" +msgstr "Axtar:" + +#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Matches:" +msgstr "UyÄŸunlaÅŸmalar:" + +#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp +#: editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Description:" +msgstr "İzah:" + +#: editor/dependency_editor.cpp +msgid "Search Replacement For:" +msgstr "Bunun üçün DÉ™yiÅŸdirmÉ™ Axtar:" + +#: editor/dependency_editor.cpp +msgid "Dependencies For:" +msgstr "Bunun üçün Asılılıqlar:" + +#: editor/dependency_editor.cpp +msgid "" +"Scene '%s' is currently being edited.\n" +"Changes will only take effect when reloaded." +msgstr "" +"'%s' sÉ™hnÉ™si hazırda redaktÉ™ olunur.\n" +"DÉ™yiÅŸikliklÉ™r yalnız yenidÉ™n yüklÉ™ndikdÉ™ qüvvÉ™yÉ™ minÉ™cÉ™k." + +#: editor/dependency_editor.cpp +msgid "" +"Resource '%s' is in use.\n" +"Changes will only take effect when reloaded." +msgstr "" +"'%s' resursu istifadÉ™dÉ™dir.\n" +"DÉ™yiÅŸikliklÉ™r yalnız yenidÉ™n yüklÉ™ndikdÉ™ qüvvÉ™yÉ™ minÉ™cÉ™k." + +#: editor/dependency_editor.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dependencies" +msgstr "Asılılıqlar" + +#: editor/dependency_editor.cpp +msgid "Resource" +msgstr "MÉ™nbÉ™" + +#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp +#: editor/project_manager.cpp editor/project_settings_editor.cpp +msgid "Path" +msgstr "Yol" + +#: editor/dependency_editor.cpp +msgid "Dependencies:" +msgstr "Asılılıqlar:" + +#: editor/dependency_editor.cpp +msgid "Fix Broken" +msgstr "Qırılmışı düzÉ™ldin" + +#: editor/dependency_editor.cpp +msgid "Dependency Editor" +msgstr "Asılılıq redaktoru" + +#: editor/dependency_editor.cpp +msgid "Search Replacement Resource:" +msgstr "ÆvÉ™zetmÉ™ mÉ™nbÉ™yini axtarın:" + +#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/script_create_dialog.cpp +#: modules/visual_script/visual_script_property_selector.cpp +#: scene/gui/file_dialog.cpp +msgid "Open" +msgstr "Aç" + +#: editor/dependency_editor.cpp +msgid "Owners Of:" +msgstr "Bunların SahiblÉ™ri:" + +#: editor/dependency_editor.cpp +msgid "" +"Remove selected files from the project? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" +"Seçili fayllar layihÉ™nizdÉ™n silindi? (geri qaytarma yoxdur)\n" +"Aradan qaldırılan faylları sistemin zibil qutusunda tapıb bÉ™rpa edÉ™ " +"bilÉ™rsiniz." + +#: editor/dependency_editor.cpp +msgid "" +"The files being removed are required by other resources in order for them to " +"work.\n" +"Remove them anyway? (no undo)\n" +"You can find the removed files in the system trash to restore them." +msgstr "" +"Aradan qaldırılan fayllar iÅŸlÉ™mÉ™si üçün digÉ™r resurslar tÉ™rÉ™findÉ™n tÉ™lÉ™b " +"olunur.\n" +"YenÉ™ dÉ™ onlar silinsin? (geri qaytarma yoxdur)\n" +"Aradan qaldırılan faylları sistemin zibil qutusunda tapıb bÉ™rpa edÉ™ " +"bilÉ™rsiniz." + +#: editor/dependency_editor.cpp +msgid "Cannot remove:" +msgstr "SilinÉ™ bilmÉ™di:" + +#: editor/dependency_editor.cpp +msgid "Error loading:" +msgstr "YüklÉ™mÉ™ xÉ™tası:" + +#: editor/dependency_editor.cpp +msgid "Load failed due to missing dependencies:" +msgstr "Æksik asılılıqlar sÉ™bÉ™bindÉ™n yüklÉ™nmÉ™ uÄŸursuz oldu:" + +#: editor/dependency_editor.cpp editor/editor_node.cpp +msgid "Open Anyway" +msgstr "YenÉ™ dÉ™ aç" + +#: editor/dependency_editor.cpp +msgid "Which action should be taken?" +msgstr "Hansı tÉ™dbir görülmÉ™lidir?" + +#: editor/dependency_editor.cpp +msgid "Fix Dependencies" +msgstr "Asılılıqları düzÉ™lt" + +#: editor/dependency_editor.cpp +msgid "Errors loading!" +msgstr "YüklÉ™mÉ™ xÉ™taları!" + +#: editor/dependency_editor.cpp +msgid "Permanently delete %d item(s)? (No undo!)" +msgstr "%d MaddÉ™(lÉ™r)i Qalıcı olaraq silinsin?(Geri qaytarmaq yoxdu!)" + +#: editor/dependency_editor.cpp +msgid "Show Dependencies" +msgstr "Asılılıqları göstÉ™r" + +#: editor/dependency_editor.cpp +msgid "Orphan Resource Explorer" +msgstr "Orphan qaynaq SÉ™yyahı" + +#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/plugins/item_list_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp +#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp +msgid "Delete" +msgstr "Sil" + +#: editor/dependency_editor.cpp +msgid "Owns" +msgstr "SahiblÉ™r" + +#: editor/dependency_editor.cpp +msgid "Resources Without Explicit Ownership:" +msgstr "Açıq Sahibsiz Resurslar:" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Key" +msgstr "Lüğət Açarını DÉ™yiÅŸ" + +#: editor/dictionary_property_edit.cpp +msgid "Change Dictionary Value" +msgstr "Lüğət dÉ™yÉ™rini dÉ™yiÅŸ" + +#: editor/editor_about.cpp +msgid "Thanks from the Godot community!" +msgstr "Godot topluluÄŸundan təşəkkürlÉ™r!" + +#: editor/editor_about.cpp +msgid "Godot Engine contributors" +msgstr "Godot oyun motoruna töhvÉ™ verÉ™nlÉ™r" + +#: editor/editor_about.cpp +msgid "Project Founders" +msgstr "LayihÉ™ Qurucuları" + +#: editor/editor_about.cpp +msgid "Lead Developer" +msgstr "BaÅŸ Developer" + +#. TRANSLATORS: This refers to a job title. +#. The trailing space is used to distinguish with the project list application, +#. you do not have to keep it in your translation. +#: editor/editor_about.cpp +msgid "Project Manager " +msgstr "LayihÉ™ Meneceri " + +#: editor/editor_about.cpp +msgid "Developers" +msgstr "Developers" + +#: editor/editor_about.cpp +msgid "Authors" +msgstr "MüəlliflÉ™r" + +#: editor/editor_about.cpp +msgid "Platinum Sponsors" +msgstr "Platin Sponsorlar" + +#: editor/editor_about.cpp +msgid "Gold Sponsors" +msgstr "Qızıl Sponsorlar" + +#: editor/editor_about.cpp +msgid "Silver Sponsors" +msgstr "Gümüş Sponsorlar" + +#: editor/editor_about.cpp +msgid "Bronze Sponsors" +msgstr "Bürünc Sponsorlar" + +#: editor/editor_about.cpp +msgid "Mini Sponsors" +msgstr "Mini Sponsorlar" + +#: editor/editor_about.cpp +msgid "Gold Donors" +msgstr "Qızıl Donorlar" + +#: editor/editor_about.cpp +msgid "Silver Donors" +msgstr "Gümüş Donorlar" + +#: editor/editor_about.cpp +msgid "Bronze Donors" +msgstr "Bürünc Donorlar" + +#: editor/editor_about.cpp +msgid "Donors" +msgstr "Donorlar" + +#: editor/editor_about.cpp +msgid "License" +msgstr "Lisenziya" + +#: editor/editor_about.cpp +msgid "Third-party Licenses" +msgstr "Üçüncü tÉ™rÉ™f Lisenziyalar" + +#: editor/editor_about.cpp +msgid "" +"Godot Engine relies on a number of third-party free and open source " +"libraries, all compatible with the terms of its MIT license. The following " +"is an exhaustive list of all such third-party components with their " +"respective copyright statements and license terms." +msgstr "" +"Godot Engine, hamısı MIT lisenziyasının ÅŸÉ™rtlÉ™rinÉ™ uyÄŸun bir sıra üçüncü " +"tÉ™rÉ™f pulsuz vÉ™ açıq mÉ™nbÉ™li kitabxanalara etibar edir. AÅŸağıda, müvafiq " +"müəllif hüquqları bildiriÅŸlÉ™ri vÉ™ lisenziya ÅŸÉ™rtlÉ™ri ilÉ™ bütün bu üçüncü " +"tÉ™rÉ™f komponentlÉ™rinin tam siyahısı verilmiÅŸdir." + +#: editor/editor_about.cpp +msgid "All Components" +msgstr "Bütün komponentlÉ™r" + +#: editor/editor_about.cpp +msgid "Components" +msgstr "KomponentlÉ™r" + +#: editor/editor_about.cpp +msgid "Licenses" +msgstr "Lisenziyalar" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Error opening package file, not in ZIP format." +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "%s (Already Exists)" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "Uncompressing Assets" +msgstr "" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "The following files failed extraction from package:" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "And %s more files." +msgstr "" + +#: editor/editor_asset_installer.cpp editor/project_manager.cpp +msgid "Package installed successfully!" +msgstr "" + +#: editor/editor_asset_installer.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Success!" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "Package Contents:" +msgstr "" + +#: editor/editor_asset_installer.cpp editor/editor_node.cpp +msgid "Install" +msgstr "" + +#: editor/editor_asset_installer.cpp +msgid "Package Installer" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Speakers" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Rename Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Change Audio Bus Volume" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Solo" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Mute" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Toggle Audio Bus Bypass Effects" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Select Audio Bus Send" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Move Bus Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Delete Bus Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Drag & drop to rearrange." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Solo" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Mute" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Bypass" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Bus options" +msgstr "" + +#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Duplicate" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Reset Volume" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Delete Effect" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Audio" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Master bus can't be deleted!" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Delete Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Duplicate Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Reset Bus Volume" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Move Audio Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Save Audio Bus Layout As..." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Location for New Layout..." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Open Audio Bus Layout" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "There is no '%s' file." +msgstr "" + +#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp +msgid "Layout" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Invalid file, not an audio bus layout." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Error saving file: %s" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add Bus" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Add a new Audio Bus to this layout." +msgstr "" + +#: editor/editor_audio_buses.cpp editor/editor_properties.cpp +#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Load" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Load an existing Bus Layout." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Save As" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Save this Bus Layout to a file." +msgstr "" + +#: editor/editor_audio_buses.cpp editor/import_dock.cpp +msgid "Load Default" +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Load the default Bus Layout." +msgstr "" + +#: editor/editor_audio_buses.cpp +msgid "Create a new Bus Layout." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Invalid name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Valid characters:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing engine class name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing built-in type name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Must not collide with an existing global constant name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Keyword cannot be used as an autoload name." +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Autoload '%s' already exists!" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Rename Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Toggle AutoLoad Globals" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Move Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Remove Autoload" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp +msgid "Enable" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Rearrange Autoloads" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Can't add autoload:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Add AutoLoad" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp +msgid "Path:" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Node Name:" +msgstr "" + +#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp +#: editor/editor_profiler.cpp editor/project_manager.cpp +#: editor/settings_config_dialog.cpp +msgid "Name" +msgstr "" + +#: editor/editor_autoload_settings.cpp +msgid "Singleton" +msgstr "" + +#: editor/editor_data.cpp editor/inspector_dock.cpp +msgid "Paste Params" +msgstr "" + +#: editor/editor_data.cpp +msgid "Updating Scene" +msgstr "" + +#: editor/editor_data.cpp +msgid "Storing local changes..." +msgstr "" + +#: editor/editor_data.cpp +msgid "Updating scene..." +msgstr "" + +#: editor/editor_data.cpp editor/editor_properties.cpp +msgid "[empty]" +msgstr "" + +#: editor/editor_data.cpp +msgid "[unsaved]" +msgstr "" + +#: editor/editor_dir_dialog.cpp +msgid "Please select a base directory first." +msgstr "" + +#: editor/editor_dir_dialog.cpp +msgid "Choose a Directory" +msgstr "" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +#: scene/gui/file_dialog.cpp +msgid "Create Folder" +msgstr "" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp +#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp +msgid "Name:" +msgstr "" + +#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp +#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp +msgid "Could not create folder." +msgstr "" + +#: editor/editor_dir_dialog.cpp +msgid "Choose" +msgstr "" + +#: editor/editor_export.cpp +msgid "Storing File:" +msgstr "" + +#: editor/editor_export.cpp +msgid "No export template found at the expected path:" +msgstr "" + +#: editor/editor_export.cpp +msgid "Packing" +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " +"Etc' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' texture compression for GLES3. Enable " +"'Import Etc 2' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for GLES2. Enable " +"'Import Pvrtc' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " +"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." +msgstr "" + +#: editor/editor_export.cpp +msgid "" +"Target platform requires 'PVRTC' texture compression for the driver fallback " +"to GLES2.\n" +"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " +"Enabled'." +msgstr "" + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom debug template not found." +msgstr "" + +#: editor/editor_export.cpp platform/android/export/export.cpp +#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp +#: platform/osx/export/export.cpp platform/uwp/export/export.cpp +msgid "Custom release template not found." +msgstr "" + +#: editor/editor_export.cpp platform/javascript/export/export.cpp +msgid "Template file not found:" +msgstr "" + +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "3D Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Script Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Asset Library" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Scene Tree Editing" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Node Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "FileSystem Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Import Dock" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Erase profile '%s'? (no undo)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Profile must be a valid filename and must not contain '.'" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Profile with this name already exists." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled, Properties Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Properties Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "(Editor Disabled)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Class Options:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enable Contextual Editor" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Properties:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Features:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Enabled Classes:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "File '%s' format is invalid, import aborted." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "" +"Profile '%s' already exists. Remove it first before importing, import " +"aborted." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Error saving profile to path: '%s'." +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Unset" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Current Profile:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Make Current" +msgstr "" + +#: editor/editor_feature_profile.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "New" +msgstr "" + +#: editor/editor_feature_profile.cpp editor/editor_node.cpp +#: editor/project_manager.cpp +msgid "Import" +msgstr "" + +#: editor/editor_feature_profile.cpp editor/project_export.cpp +msgid "Export" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Available Profiles:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Class Options" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "New profile name:" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Erase Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Godot Feature Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Import Profile(s)" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Export Profile" +msgstr "" + +#: editor/editor_feature_profile.cpp +msgid "Manage Editor Feature Profiles" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select Current Folder" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File Exists, Overwrite?" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Select This Folder" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Copy Path" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "Open in File Manager" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/filesystem_dock.cpp editor/project_manager.cpp +msgid "Show in File Manager" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "New Folder..." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/find_in_files.cpp +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Refresh" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Recognized" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "All Files (*)" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open File(s)" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a Directory" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Open a File or Directory" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/editor_node.cpp +#: editor/editor_properties.cpp editor/import_defaults_editor.cpp +#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp +msgid "Save" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Save a File" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Back" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Forward" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go Up" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Hidden Files" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Favorite" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Toggle Mode" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Focus Path" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Up" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Move Favorite Down" +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go to previous folder." +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "Go to next folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Go to parent folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Refresh files." +msgstr "" + +#: editor/editor_file_dialog.cpp +msgid "(Un)favorite current folder." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Toggle the visibility of hidden files." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a grid of thumbnails." +msgstr "" + +#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp +msgid "View items as a list." +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "Directories & Files:" +msgstr "" + +#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp +#: editor/plugins/style_box_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Preview:" +msgstr "" + +#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp +msgid "File:" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "ScanSources" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "" +"There are multiple importers for different types pointing to file %s, import " +"aborted" +msgstr "" + +#: editor/editor_file_system.cpp +msgid "(Re)Importing Assets" +msgstr "" + +#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp +msgid "Top" +msgstr "" + +#: editor/editor_help.cpp +msgid "Class:" +msgstr "" + +#: editor/editor_help.cpp editor/scene_tree_editor.cpp +#: editor/script_create_dialog.cpp +msgid "Inherits:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Inherited by:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Description" +msgstr "" + +#: editor/editor_help.cpp +msgid "Online Tutorials" +msgstr "" + +#: editor/editor_help.cpp +msgid "Properties" +msgstr "" + +#: editor/editor_help.cpp +msgid "override:" +msgstr "" + +#: editor/editor_help.cpp +msgid "default:" +msgstr "" + +#: editor/editor_help.cpp +msgid "Methods" +msgstr "" + +#: editor/editor_help.cpp +msgid "Theme Properties" +msgstr "" + +#: editor/editor_help.cpp +msgid "Enumerations" +msgstr "" + +#: editor/editor_help.cpp +msgid "Constants" +msgstr "" + +#: editor/editor_help.cpp +msgid "Property Descriptions" +msgstr "" + +#: editor/editor_help.cpp +msgid "(value)" +msgstr "" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this property. Please help us by " +"[color=$color][url=$url]contributing one[/url][/color]!" +msgstr "" + +#: editor/editor_help.cpp +msgid "Method Descriptions" +msgstr "" + +#: editor/editor_help.cpp +msgid "" +"There is currently no description for this method. Please help us by [color=" +"$color][url=$url]contributing one[/url][/color]!" +msgstr "" + +#: editor/editor_help_search.cpp editor/editor_node.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Help" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Case Sensitive" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Show Hierarchy" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Display All" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Classes Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Methods Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Signals Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Constants Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Properties Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Theme Properties Only" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Member Type" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Class" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Method" +msgstr "" + +#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp +msgid "Signal" +msgstr "" + +#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp +msgid "Constant" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Property" +msgstr "" + +#: editor/editor_help_search.cpp +msgid "Theme Property" +msgstr "" + +#: editor/editor_inspector.cpp editor/project_settings_editor.cpp +msgid "Property:" +msgstr "" + +#: editor/editor_inspector.cpp +msgid "Set" +msgstr "" + +#: editor/editor_inspector.cpp +msgid "Set Multiple:" +msgstr "" + +#: editor/editor_log.cpp +msgid "Output:" +msgstr "" + +#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Copy Selection" +msgstr "" + +#: editor/editor_log.cpp editor/editor_network_profiler.cpp +#: editor/editor_profiler.cpp editor/editor_properties.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/property_editor.cpp editor/scene_tree_dock.cpp +#: editor/script_editor_debugger.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Clear" +msgstr "" + +#: editor/editor_log.cpp +msgid "Clear Output" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +#: editor/editor_profiler.cpp +msgid "Stop" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp +#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp +msgid "Start" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "%s/s" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Down" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Up" +msgstr "" + +#: editor/editor_network_profiler.cpp editor/editor_node.cpp +msgid "Node" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RPC" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Incoming RSET" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RPC" +msgstr "" + +#: editor/editor_network_profiler.cpp +msgid "Outgoing RSET" +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "New Window" +msgstr "" + +#: editor/editor_node.cpp +msgid "Imported resources can't be saved." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: scene/gui/dialogs.cpp +msgid "OK" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Error saving resource!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource can't be saved because it does not belong to the edited scene. " +"Make it unique first." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Save Resource As..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't open file for writing:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Requested file format unknown:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while saving." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Can't open '%s'. The file could have been moved or deleted." +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while parsing '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unexpected end of file '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Missing '%s' or its dependencies." +msgstr "" + +#: editor/editor_node.cpp +msgid "Error while loading '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Saving Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Analyzing" +msgstr "" + +#: editor/editor_node.cpp +msgid "Creating Thumbnail" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a tree root." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This scene can't be saved because there is a cyclic instancing inclusion.\n" +"Please resolve it and then attempt to save again." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " +"be satisfied." +msgstr "" + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "Can't overwrite scene that is still open!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load MeshLibrary for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving MeshLibrary!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't load TileSet for merging!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Error saving TileSet!" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"An error occurred while trying to save the editor layout.\n" +"Make sure the editor's user data path is writable." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Default editor layout overridden.\n" +"To restore the Default layout to its base settings, use the Delete Layout " +"option and delete the Default layout." +msgstr "" + +#: editor/editor_node.cpp +msgid "Layout name not found!" +msgstr "" + +#: editor/editor_node.cpp +msgid "Restored the Default layout to its base settings." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was imported, so it's not editable.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource belongs to a scene that was instanced or inherited.\n" +"Changes to it won't be kept when saving the current scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This resource was imported, so it's not editable. Change its settings in the " +"import panel and then re-import." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This scene was imported, so changes to it won't be kept.\n" +"Instancing it or inheriting will allow making changes to it.\n" +"Please read the documentation relevant to importing scenes to better " +"understand this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This is a remote object, so changes to it won't be kept.\n" +"Please read the documentation relevant to debugging to better understand " +"this workflow." +msgstr "" + +#: editor/editor_node.cpp +msgid "There is no defined scene to run." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save scene before running..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Could not start subprocess!" +msgstr "" + +#: editor/editor_node.cpp editor/filesystem_dock.cpp +msgid "Open Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Base Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Open Script..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save & Close" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes to '%s' before closing?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Saved %s modified resource(s)." +msgstr "" + +#: editor/editor_node.cpp +msgid "A root node is required to save the scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Scene As..." +msgstr "" + +#: editor/editor_node.cpp editor/scene_tree_dock.cpp +msgid "This operation can't be done without a scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Mesh Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a root node." +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Tile Set" +msgstr "" + +#: editor/editor_node.cpp +msgid "This operation can't be done without a selected node." +msgstr "" + +#: editor/editor_node.cpp +msgid "Current scene not saved. Open anyway?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Can't reload a scene that was never saved." +msgstr "" + +#: editor/editor_node.cpp +msgid "Reload Saved Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The current scene has unsaved changes.\n" +"Reload the saved scene anyway? This action cannot be undone." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quick Run Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quit" +msgstr "" + +#: editor/editor_node.cpp +msgid "Yes" +msgstr "" + +#: editor/editor_node.cpp +msgid "Exit the editor?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Manager?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save & Quit" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes to the following scene(s) before quitting?" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save changes the following scene(s) before opening Project Manager?" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This option is deprecated. Situations where refresh must be forced are now " +"considered a bug. Please report." +msgstr "" + +#: editor/editor_node.cpp +msgid "Pick a Main Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Reopen Closed Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to enable addon plugin at: '%s' parsing of config failed." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to find script field for addon plugin at: '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s'." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Unable to load addon script from path: '%s' Base type is not EditorPlugin." +msgstr "" + +#: editor/editor_node.cpp +msgid "Unable to load addon script from path: '%s' Script is not in tool mode." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Scene '%s' was automatically imported, so it can't be modified.\n" +"To make changes to it, a new inherited scene can be created." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Error loading scene, it must be inside the project path. Use 'Import' to " +"open the scene, then save it inside the project path." +msgstr "" + +#: editor/editor_node.cpp +msgid "Scene '%s' has broken dependencies:" +msgstr "" + +#: editor/editor_node.cpp +msgid "Clear Recent Scenes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"No main scene has ever been defined, select one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' does not exist, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"Selected scene '%s' is not a scene file, select a valid one?\n" +"You can change it later in \"Project Settings\" under the 'application' " +"category." +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Layout" +msgstr "" + +#: editor/editor_node.cpp +msgid "Delete Layout" +msgstr "" + +#: editor/editor_node.cpp editor/import_dock.cpp +#: editor/script_create_dialog.cpp +msgid "Default" +msgstr "" + +#: editor/editor_node.cpp editor/editor_properties.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp +msgid "Show in FileSystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play This Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Undo Close Tab" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Close Other Tabs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close Tabs to the Right" +msgstr "" + +#: editor/editor_node.cpp +msgid "Close All Tabs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Switch Scene Tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files or folders" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more folders" +msgstr "" + +#: editor/editor_node.cpp +msgid "%d more files" +msgstr "" + +#: editor/editor_node.cpp +msgid "Dock Position" +msgstr "" + +#: editor/editor_node.cpp +msgid "Distraction Free Mode" +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle distraction-free mode." +msgstr "" + +#: editor/editor_node.cpp +msgid "Add a new scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Go to previously opened scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Copy Text" +msgstr "" + +#: editor/editor_node.cpp +msgid "Next tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Previous tab" +msgstr "" + +#: editor/editor_node.cpp +msgid "Filter Files..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Operations with scene files." +msgstr "" + +#: editor/editor_node.cpp +msgid "New Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "New Inherited Scene..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Scene..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +msgid "Open Recent" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Save All Scenes" +msgstr "" + +#: editor/editor_node.cpp +msgid "Convert To..." +msgstr "" + +#: editor/editor_node.cpp +msgid "MeshLibrary..." +msgstr "" + +#: editor/editor_node.cpp +msgid "TileSet..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Undo" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Redo" +msgstr "" + +#: editor/editor_node.cpp +msgid "Miscellaneous project or scene-wide tools." +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +#: editor/script_create_dialog.cpp +msgid "Project" +msgstr "" + +#: editor/editor_node.cpp +msgid "Project Settings..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp +msgid "Set Up Version Control" +msgstr "" + +#: editor/editor_node.cpp +msgid "Shut Down Version Control" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Install Android Build Template..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Project Data Folder" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp +msgid "Tools" +msgstr "" + +#: editor/editor_node.cpp +msgid "Orphan Resource Explorer..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Quit to Project List" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/project_export.cpp +msgid "Debug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Deploy with Remote Debug" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy will make the executable " +"attempt to connect to this computer's IP so the running project can be " +"debugged.\n" +"This option is intended to be used for remote debugging (typically with a " +"mobile device).\n" +"You don't need to enable it to use the GDScript debugger locally." +msgstr "" + +#: editor/editor_node.cpp +msgid "Small Deploy with Network Filesystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, using one-click deploy for Android will only " +"export an executable without the project data.\n" +"The filesystem will be provided from the project by the editor over the " +"network.\n" +"On Android, deploying will use the USB cable for faster performance. This " +"option speeds up testing for projects with large assets." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Collision Shapes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, collision shapes and raycast nodes (for 2D and " +"3D) will be visible in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Visible Navigation" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, navigation meshes and polygons will be visible " +"in the running project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Scene Changes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any changes made to the scene in the editor " +"will be replicated in the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" + +#: editor/editor_node.cpp +msgid "Synchronize Script Changes" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"When this option is enabled, any script that is saved will be reloaded in " +"the running project.\n" +"When used remotely on a device, this is more efficient when the network " +"filesystem option is enabled." +msgstr "" + +#: editor/editor_node.cpp editor/script_create_dialog.cpp +msgid "Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Editor Settings..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Editor Layout" +msgstr "" + +#: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle Fullscreen" +msgstr "" + +#: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Data/Settings Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Data Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Editor Settings Folder" +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Editor Features..." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Export Templates..." +msgstr "" + +#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp +msgid "Help" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Online Docs" +msgstr "" + +#: editor/editor_node.cpp +msgid "Q&A" +msgstr "" + +#: editor/editor_node.cpp +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp +msgid "Community" +msgstr "" + +#: editor/editor_node.cpp +msgid "About" +msgstr "" + +#: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play the project." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play" +msgstr "" + +#: editor/editor_node.cpp +msgid "Pause the scene execution for debugging." +msgstr "" + +#: editor/editor_node.cpp +msgid "Pause Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Stop the scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play the edited scene." +msgstr "" + +#: editor/editor_node.cpp +msgid "Play Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play custom scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Play Custom Scene" +msgstr "" + +#: editor/editor_node.cpp +msgid "Changing the video driver requires restarting the editor." +msgstr "" + +#: editor/editor_node.cpp editor/project_settings_editor.cpp +#: editor/settings_config_dialog.cpp +msgid "Save & Restart" +msgstr "" + +#: editor/editor_node.cpp +msgid "Spins when the editor window redraws." +msgstr "" + +#: editor/editor_node.cpp +msgid "Update Continuously" +msgstr "" + +#: editor/editor_node.cpp +msgid "Update When Changed" +msgstr "" + +#: editor/editor_node.cpp +msgid "Hide Update Spinner" +msgstr "" + +#: editor/editor_node.cpp +msgid "FileSystem" +msgstr "" + +#: editor/editor_node.cpp +msgid "Inspector" +msgstr "" + +#: editor/editor_node.cpp +msgid "Expand Bottom Panel" +msgstr "" + +#: editor/editor_node.cpp +msgid "Output" +msgstr "" + +#: editor/editor_node.cpp +msgid "Don't Save" +msgstr "" + +#: editor/editor_node.cpp +msgid "Android build template is missing, please install relevant templates." +msgstr "" + +#: editor/editor_node.cpp +msgid "Manage Templates" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"This will set up your project for custom Android builds by installing the " +"source template to \"res://android/build\".\n" +"You can then apply modifications and build your own custom APK on export " +"(adding modules, changing the AndroidManifest.xml, etc.).\n" +"Note that in order to make custom builds instead of using pre-built APKs, " +"the \"Use Custom Build\" option should be enabled in the Android export " +"preset." +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The Android build template is already installed in this project and it won't " +"be overwritten.\n" +"Remove the \"res://android/build\" directory manually before attempting this " +"operation again." +msgstr "" + +#: editor/editor_node.cpp +msgid "Import Templates From ZIP File" +msgstr "" + +#: editor/editor_node.cpp +msgid "Template Package" +msgstr "" + +#: editor/editor_node.cpp +msgid "Export Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "Merge With Existing" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open & Run a Script" +msgstr "" + +#: editor/editor_node.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Reload" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/shader_editor_plugin.cpp +msgid "Resave" +msgstr "" + +#: editor/editor_node.cpp +msgid "New Inherited" +msgstr "" + +#: editor/editor_node.cpp +msgid "Load Errors" +msgstr "" + +#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp +msgid "Select" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open 2D Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open 3D Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open Script Editor" +msgstr "" + +#: editor/editor_node.cpp editor/project_manager.cpp +msgid "Open Asset Library" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open the next Editor" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open the previous Editor" +msgstr "" + +#: editor/editor_node.h +msgid "Warning!" +msgstr "" + +#: editor/editor_path.cpp +msgid "No sub-resources found." +msgstr "" + +#: editor/editor_plugin.cpp +msgid "Creating Mesh Previews" +msgstr "" + +#: editor/editor_plugin.cpp +msgid "Thumbnail..." +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Main Script:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Edit Plugin" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Installed Plugins:" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Update" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Version:" +msgstr "" + +#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp +msgid "Author:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Status:" +msgstr "" + +#: editor/editor_plugin_settings.cpp +msgid "Edit:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Measure:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame Time (sec)" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Average Time (sec)" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame %" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Physics Frame %" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Inclusive" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Self" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Frame #:" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Time" +msgstr "" + +#: editor/editor_profiler.cpp +msgid "Calls" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Edit Text:" +msgstr "" + +#: editor/editor_properties.cpp editor/script_create_dialog.cpp +msgid "On" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Layer" +msgstr "" + +#: editor/editor_properties.cpp +msgid "Bit %d, value %d" +msgstr "" + +#: editor/editor_properties.cpp +msgid "[Empty]" +msgstr "" + +#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp +msgid "Assign..." +msgstr "" + +#: editor/editor_properties.cpp +msgid "Invalid RID" +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"The selected resource (%s) does not match any type expected for this " +"property (%s)." +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on resources saved as a file.\n" +"Resource needs to belong to a scene." +msgstr "" + +#: editor/editor_properties.cpp +msgid "" +"Can't create a ViewportTexture on this resource because it's not set as " +"local to scene.\n" +"Please switch on the 'local to scene' property on it (and all resources " +"containing it up to a node)." +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Pick a Viewport" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New Script" +msgstr "" + +#: editor/editor_properties.cpp editor/scene_tree_dock.cpp +msgid "Extend Script" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "New %s" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Make Unique" +msgstr "" + +#: editor/editor_properties.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp +#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Paste" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Convert To %s" +msgstr "" + +#: editor/editor_properties.cpp editor/property_editor.cpp +msgid "Selected node is not a Viewport!" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Size: " +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Page: " +msgstr "" + +#: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "New Key:" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "New Value:" +msgstr "" + +#: editor/editor_properties_array_dict.cpp +msgid "Add Key/Value Pair" +msgstr "" + +#: editor/editor_run_native.cpp +msgid "" +"No runnable export preset found for this platform.\n" +"Please add a runnable preset in the Export menu or define an existing preset " +"as runnable." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Write your logic in the _run() method." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "There is an edited scene already." +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Couldn't instance script:" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Did you forget the 'tool' keyword?" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Couldn't run script:" +msgstr "" + +#: editor/editor_run_script.cpp +msgid "Did you forget the '_run' method?" +msgstr "" + +#: editor/editor_spin_slider.cpp +msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Select Node(s) to Import" +msgstr "" + +#: editor/editor_sub_scene.cpp editor/project_manager.cpp +msgid "Browse" +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Scene Path:" +msgstr "" + +#: editor/editor_sub_scene.cpp +msgid "Import From Node:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Redownload" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Uninstall" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Installed)" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Official export templates aren't available for development builds." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Missing)" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "(Current)" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Retrieving mirrors, please wait..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove template version '%s'?" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't open export templates zip." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Invalid version.txt format inside templates: %s." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "No version.txt found inside templates." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error creating path for templates:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Extracting Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Importing:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error getting the list of mirrors." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error parsing JSON of mirror list. Please report this issue!" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"No download links found for this version. Direct download is only available " +"for official releases." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Request Failed." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Redirect Loop." +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Complete." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Cannot remove temporary file:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "" +"Templates installation failed.\n" +"The problematic templates archives can be found at '%s'." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Error requesting URL:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connecting to Mirror..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Disconnected" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Resolving" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't Resolve" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connecting..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Can't Connect" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connected" +msgstr "" + +#: editor/export_template_manager.cpp +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Requesting..." +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Downloading" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Connection Error" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "SSL Handshake Error" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Uncompressing Android Build Sources" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Current Version:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Installed Versions:" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Install From File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Remove Template" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select Template File" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Godot Export Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Export Template Manager" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Download Templates" +msgstr "" + +#: editor/export_template_manager.cpp +msgid "Select mirror from list: (Shift+Click: Open in Browser)" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Status: Import of file failed. Please fix file and reimport manually." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"Importing has been disabled for this file, so it can't be opened for editing." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move/rename resources root." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Cannot move a folder into itself." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Error moving:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Error duplicating:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Unable to update dependencies:" +msgstr "" + +#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp +msgid "No name provided." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Provided name contains invalid characters." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "A file or folder with this name already exists." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Name contains invalid characters." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"The following files or folders conflict with items in the target location " +"'%s':\n" +"\n" +"%s\n" +"\n" +"Do you wish to overwrite them?" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Renaming file:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Renaming folder:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicating file:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicating folder:" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Inherited Scene" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Set As Main Scene" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Open Scenes" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Instance" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Add to Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Remove from Favorites" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Edit Dependencies..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "View Owners..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move To..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Scene..." +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "New Script..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "New Resource..." +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Expand All" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp +#: editor/script_editor_debugger.cpp +msgid "Collapse All" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Duplicate..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move to Trash" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +msgid "Rename..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Previous Folder/File" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Next Folder/File" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Re-Scan Filesystem" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Toggle Split Mode" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Search files" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "" +"Scanning Files,\n" +"Please Wait..." +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Move" +msgstr "" + +#: editor/filesystem_dock.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/project_manager.cpp editor/rename_dialog.cpp +#: editor/scene_tree_dock.cpp +msgid "Rename" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Overwrite" +msgstr "" + +#: editor/filesystem_dock.cpp +msgid "Create Scene" +msgstr "" + +#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp +msgid "Create Script" +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +msgid "Find in Files" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Find:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Folder:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Filters:" +msgstr "" + +#: editor/find_in_files.cpp +msgid "" +"Include the files with the following extensions. Add or remove them in " +"ProjectSettings." +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find..." +msgstr "" + +#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp +msgid "Replace..." +msgstr "" + +#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp +msgid "Cancel" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Find: " +msgstr "" + +#: editor/find_in_files.cpp +msgid "Replace: " +msgstr "" + +#: editor/find_in_files.cpp +msgid "Replace all (no undo)" +msgstr "" + +#: editor/find_in_files.cpp +msgid "Searching..." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d match in %d file." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d matches in %d file." +msgstr "" + +#: editor/find_in_files.cpp +msgid "%d matches in %d files." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Add to Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Remove from Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Group name already exists." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Invalid group name." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Rename Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Delete Group" +msgstr "" + +#: editor/groups_editor.cpp editor/node_dock.cpp +msgid "Groups" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Nodes Not in Group" +msgstr "" + +#: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp +msgid "Filter nodes" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Nodes in Group" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Empty groups will be automatically removed." +msgstr "" + +#: editor/groups_editor.cpp +msgid "Group Editor" +msgstr "" + +#: editor/groups_editor.cpp +msgid "Manage Groups" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Single Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Materials+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import with Separate Objects+Materials+Animations" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Import as Multiple Scenes+Materials" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import Scene" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Importing Scene..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating Lightmaps" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Generating for Mesh: " +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Running Custom Script..." +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Couldn't load post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Invalid/broken script for post-import (check console):" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Error running post-import script:" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Did you return a Node-derived object in the `post_import()` method?" +msgstr "" + +#: editor/import/resource_importer_scene.cpp +msgid "Saving..." +msgstr "" + +#: editor/import_defaults_editor.cpp +msgid "Select Importer" +msgstr "" + +#: editor/import_defaults_editor.cpp +msgid "Importer:" +msgstr "" + +#: editor/import_defaults_editor.cpp +msgid "Reset to Defaults" +msgstr "" + +#: editor/import_dock.cpp +msgid "Keep File (No Import)" +msgstr "" + +#: editor/import_dock.cpp +msgid "%d Files" +msgstr "" + +#: editor/import_dock.cpp +msgid "Set as Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Clear Default for '%s'" +msgstr "" + +#: editor/import_dock.cpp +msgid "Import As:" +msgstr "" + +#: editor/import_dock.cpp +msgid "Preset" +msgstr "" + +#: editor/import_dock.cpp +msgid "Reimport" +msgstr "" + +#: editor/import_dock.cpp +msgid "Save Scenes, Re-Import, and Restart" +msgstr "" + +#: editor/import_dock.cpp +msgid "Changing the type of an imported file requires editor restart." +msgstr "" + +#: editor/import_dock.cpp +msgid "" +"WARNING: Assets exist that use this resource, they may stop loading properly." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Failed to load resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Expand All Properties" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Collapse All Properties" +msgstr "" + +#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +msgid "Save As..." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Params" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Edit Resource Clipboard" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Copy Resource" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Built-In" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Make Sub-Resources Unique" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Open in Help" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Create a new resource in memory and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Load an existing resource from disk and edit it." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Save the currently edited resource." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the previous edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Go to the next edited object in history." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "History of recently edited objects." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Object properties." +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Filter properties" +msgstr "" + +#: editor/inspector_dock.cpp +msgid "Changes may be lost!" +msgstr "" + +#: editor/multi_node_edit.cpp +msgid "MultiNode Set" +msgstr "" + +#: editor/node_dock.cpp +msgid "Select a single node to edit its signals and groups." +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Edit a Plugin" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Create a Plugin" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Plugin Name:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Subfolder:" +msgstr "" + +#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp +msgid "Language:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Script Name:" +msgstr "" + +#: editor/plugin_config_dialog.cpp +msgid "Activate now?" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create points." +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "" +"Edit points.\n" +"LMB: Move Point\n" +"RMB: Erase Point" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Erase points." +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Insert Point" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Edit Polygon (Remove Point)" +msgstr "" + +#: editor/plugins/abstract_polygon_2d_editor.cpp +msgid "Remove Polygon And Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Animation" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Load..." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Move Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Change BlendSpace1D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "This type of node can't be used. Only root nodes are allowed." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Animation Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Remove BlendSpace1D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +msgid "Move BlendSpace1D Node Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"AnimationTree is inactive.\n" +"Activate to enable playback, check node warnings if activation fails." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Set the blending position within the space" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Select and move points, create points with RMB." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp +msgid "Enable snap and show grid." +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Point" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Open Editor" +msgstr "" + +#: editor/plugins/animation_blend_space_1d_editor.cpp +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Open Animation Node" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Triangle already exists." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Add Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Limits" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Change BlendSpace2D Labels" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Point" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Remove BlendSpace2D Triangle" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "BlendSpace2D does not belong to an AnimationTree node." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "No triangles exist, so no blending can take place." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Toggle Auto Triangles" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Create triangles by connecting points." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Erase points and triangles." +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +msgid "Generate blend triangles automatically (instead of manually)" +msgstr "" + +#: editor/plugins/animation_blend_space_2d_editor.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Parameter Changed" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Filters" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Output node can't be added to the blend tree." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Add Node to BlendTree" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Node Moved" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Unable to connect, port may be in use or connection may be invalid." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Connected" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Nodes Disconnected" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Set Animation" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Node" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/scene_tree_dock.cpp +msgid "Delete Node(s)" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Toggle Filter On/Off" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Change Filter" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "No animation player set, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Player path set is invalid, so unable to retrieve track names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "" +"Animation player has no valid root node path, so unable to retrieve track " +"names." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Anim Clips" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Audio Clips" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Functions" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Renamed" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node..." +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Edit Filtered Tracks:" +msgstr "" + +#: editor/plugins/animation_blend_tree_editor_plugin.cpp +msgid "Enable Filtering" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Toggle Autoplay" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "New Anim" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Animation?" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Remove Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Invalid animation name!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation name already exists!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Rename Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Next Changed" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Change Blend Time" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Load Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Duplicate Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to copy!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation resource on clipboard!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pasted Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Paste Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "No animation to edit!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from current pos. (A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation backwards from end. (Shift+A)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Stop animation playback. (S)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from start. (Shift+D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Play selected animation from current pos. (D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation position (in seconds)." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Scale animation playback globally for the node." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Tools" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Edit Transitions..." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Open in Inspector" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Display list of animations in player." +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Autoplay on Load" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Enable Onion Skinning" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Onion Skinning Options" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Directions" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Past" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Future" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Depth" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "1 step" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "2 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "3 steps" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Differences Only" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Force White Modulate" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Include Gizmos (3D)" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Pin AnimationPlayer" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Create New Animation" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Animation Name:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp +msgid "Error!" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Blend Times:" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Next (Auto Queue):" +msgstr "" + +#: editor/plugins/animation_player_editor_plugin.cpp +msgid "Cross-Animation Blend Times" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Move Node" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition exists!" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Add Transition" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "End" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Immediate" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Sync" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "At End" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Travel" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Start and end nodes are needed for a sub-transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "No playback resource set at path: %s." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Node Removed" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition Removed" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set Start Node (Autoplay)" +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "" +"Select and move nodes.\n" +"RMB to add new nodes.\n" +"Shift+LMB to create connections." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Create new nodes." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Connect nodes." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Remove selected node or transition." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Toggle autoplay this animation on start, restart or seek to zero." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Set the end animation. This is useful for sub-transitions." +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Transition: " +msgstr "" + +#: editor/plugins/animation_state_machine_editor.cpp +msgid "Play Mode:" +msgstr "" + +#: editor/plugins/animation_tree_editor_plugin.cpp +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "AnimationTree" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "New name:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Scale:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade In (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Fade Out (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Auto Restart:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Random Restart (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Start!" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Amount:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 0:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend 1:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "X-Fade Time (s):" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Current:" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Clear Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Set Auto-Advance" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Delete Input" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is valid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation tree is invalid." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Animation Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "OneShot Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Mix Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend2 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend3 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Blend4 Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeScale Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "TimeSeek Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Transition Node" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Import Animations..." +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Edit Node Filters" +msgstr "" + +#: editor/plugins/animation_tree_player_editor_plugin.cpp +msgid "Filters..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Contents:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "View Files" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Connection error, please try again." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't connect to host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No response from host:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Can't resolve hostname:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, return code:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Cannot save response to:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Write error." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, too many redirects" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Redirect loop." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Request failed, timeout" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Timeout." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Bad download hash, assuming file has been tampered with." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Expected:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Got:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Failed SHA-256 hash check" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Asset Download Error:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading (%s / %s)..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Downloading..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Resolving..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Error making request" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Idle" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Install..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Retry" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download Error" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Download for this asset is already in progress!" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Least Recently Updated" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (A-Z)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Name (Z-A)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (A-Z)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "License (Z-A)" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "First" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Previous" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Next" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Last" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "All" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "No results for \"%s\"." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Import..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Plugins..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp +msgid "Sort:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Category:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Site:" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Support" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Official" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Testing" +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Loading..." +msgstr "" + +#: editor/plugins/asset_library_editor_plugin.cpp +msgid "Assets ZIP File" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Can't determine a save path for lightmap images.\n" +"Save your scene and try again." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " +"Light' flag is on." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed creating lightmap images, make sure path is writable." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Failed determining lightmap size. Maximum lightmap size too small?" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Some mesh is invalid. Make sure the UV2 channel values are contained within " +"the [0.0,1.0] square region." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "" +"Godot editor was built without ray tracing support, lightmaps can't be baked." +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Bake Lightmaps" +msgstr "" + +#: editor/plugins/baked_lightmap_editor_plugin.cpp +msgid "Select lightmap bake file:" +msgstr "" + +#: editor/plugins/camera_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Preview" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Configure Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Grid Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Primary Line Every:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "steps" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Offset:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Step:" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Vertical Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Remove Horizontal Guide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Horizontal and Vertical Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotate CanvasItem \"%s\" to %d degrees" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale Node2D \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Resize Control \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale CanvasItem \"%s\" to (%s, %s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move %d CanvasItems" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Move CanvasItem \"%s\" to (%d, %d)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Children of containers have their anchors and margins values overridden by " +"their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Presets for the anchors and margins values of a Control node." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"When active, moving Control nodes changes their anchors instead of their " +"margins." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Left" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Top" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Right" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Bottom" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Left Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Top Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Right Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Bottom Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "VCenter Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "HCenter Wide" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Full Rect" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Keep Ratio" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Anchors only" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors and Margins" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Anchors" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"Overrides game camera with editor viewport camera." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Game Camera Override\n" +"No game instance running." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Group Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Ungroup Selected" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Paste Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Create Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear IK Chain" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Warning: Children of a container get their position and size determined only " +"by their parent." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/texture_region_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp +msgid "Zoom Reset" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Select Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Drag: Rotate" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+Drag: Move" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Move Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Show a list of all objects at the position clicked\n" +"(same as Alt+RMB in select mode)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Click to change object's rotation pivot." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Ruler Mode" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle smart snapping." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Smart Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Toggle grid snapping." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Grid Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snapping Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Rotation Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Scale Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap Relative" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Use Pixel Snap" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Smart Snapping" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Configure Snap..." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Parent" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Anchor" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Sides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Node Center" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Other Nodes" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Snap to Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock the selected object in place (can't be moved)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Unlock the selected object (can be moved)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Makes sure the object's children are not selectable." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Restores the object's children's ability to be selected." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Skeleton Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Make Custom Bone(s) from Node(s)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Custom Bones" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Always Show Grid" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Helpers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Rulers" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Guides" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Origin" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Viewport" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Show Group And Lock Icons" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Center Selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Frame Selection" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Preview Canvas Scale" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Translation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Rotation mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Scale mask for inserting keys." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert keys (based on mask)." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Auto insert keys when objects are translated, rotated or scaled (based on " +"mask).\n" +"Keys are only added to existing tracks, no new tracks will be created.\n" +"Keys must be inserted manually for the first time." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Auto Insert Key" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Animation Key and Pose Options" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Insert Key (Existing Tracks)" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Copy Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Clear Pose" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Multiply grid step by 2" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Divide grid step by 2" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Pan View" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Add %s" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Adding %s..." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Cannot instantiate multiple nodes without root." +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Create Node" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "Error instancing scene from %s" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "Change Default Type" +msgstr "" + +#: editor/plugins/canvas_item_editor_plugin.cpp +msgid "" +"Drag & drop + Shift : Add node as sibling\n" +"Drag & drop + Alt : Change node type" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Create Polygon3D" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly" +msgstr "" + +#: editor/plugins/collision_polygon_editor_plugin.cpp +msgid "Edit Poly (Remove Point)" +msgstr "" + +#: editor/plugins/collision_shape_2d_editor_plugin.cpp +msgid "Set Handle" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Load Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Clear Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Particles" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generated Point Count:" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Mask" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Solid Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Directed Border Pixels" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Capture from Pixel" +msgstr "" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Emission Colors" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +msgid "CPUParticles" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Mesh" +msgstr "" + +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emission Points From Node" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 0" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Flat 1" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease In" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp +msgid "Ease Out" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Smoothstep" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Modify Curve Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Curve Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Add Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Left Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right Linear" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Load Preset" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Remove Curve Point" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Toggle Curve Linear Tangent" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Hold Shift to edit tangents individually" +msgstr "" + +#: editor/plugins/curve_editor_plugin.cpp +msgid "Right click to add point" +msgstr "" + +#: editor/plugins/gi_probe_editor_plugin.cpp +msgid "Bake GI Probe" +msgstr "" + +#: editor/plugins/gradient_editor_plugin.cpp +msgid "Gradient Edited" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item %d" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Items" +msgstr "" + +#: editor/plugins/item_list_editor_plugin.cpp +msgid "Item List Editor" +msgstr "" + +#: editor/plugins/light_occluder_2d_editor_plugin.cpp +msgid "Create Occluder Polygon" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh is empty!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a Trimesh collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Static Trimesh Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "This doesn't work on scene root!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create a single convex collision shape for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create a single convex collision shape." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Shape" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Can't create multiple convex collision shapes for the scene root." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Couldn't create any collision shapes." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Shapes" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Navigation Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Contained Mesh is not of type ArrayMesh." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Unwrap failed, mesh may not be manifold?" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "No mesh to debug." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Model has no UV in this layer" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "MeshInstance lacks a Mesh!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh has not surface to create outlines from!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Could not create outline!" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Static Body" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a StaticBody and assigns a polygon-based collision shape to it " +"automatically.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Trimesh Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is the most accurate (but slowest) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Single Convex Collision Sibling" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a single convex collision shape.\n" +"This is the fastest (but least accurate) option for collision detection." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Multiple Convex Collision Siblings" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a polygon-based collision shape.\n" +"This is a performance middle-ground between the two above options." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh..." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "" +"Creates a static outline mesh. The outline mesh will have its normals " +"flipped automatically.\n" +"This can be used instead of the SpatialMaterial Grow property when using " +"that property isn't possible." +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV1" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "View UV2" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Unwrap UV2 for Lightmap/AO" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Create Outline Mesh" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "Outline Size:" +msgstr "" + +#: editor/plugins/mesh_instance_editor_plugin.cpp +msgid "UV Channel Debug" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove item %d?" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "" +"Update from existing scene?:\n" +"%s" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Mesh Library" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Remove Selected Item" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Import from Scene" +msgstr "" + +#: editor/plugins/mesh_library_editor_plugin.cpp +msgid "Update from Scene" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and no MultiMesh set in node)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No mesh source specified (and MultiMesh contains no Mesh)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (not a MeshInstance)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh source is invalid (contains no Mesh resource)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "No surface source specified." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (invalid path)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no geometry)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Surface source is invalid (no faces)." +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Select a Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate Surface" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate MultiMesh" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Target Surface:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Source Mesh:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "X-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Y-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Z-Axis" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Mesh Up Axis:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Rotation:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Tilt:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Random Scale:" +msgstr "" + +#: editor/plugins/multimesh_editor_plugin.cpp +msgid "Populate" +msgstr "" + +#: editor/plugins/navigation_polygon_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Navigation Polygon" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Convert to CPUParticles" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generating Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Generate Visibility Rect" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Can only set point into a ParticlesMaterial process material" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +msgid "Convert to CPUParticles2D" +msgstr "" + +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generation Time (sec):" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry's faces don't contain any area." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "The geometry doesn't contain any faces." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't inherit from Spatial." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "\"%s\" doesn't contain face geometry." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Create Emitter" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Points:" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Surface Points+Normal (Directed)" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Volume" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Emission Source: " +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "A processor material of type 'ParticlesMaterial' is required." +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generating AABB" +msgstr "" + +#: editor/plugins/particles_editor_plugin.cpp +msgid "Generate Visibility AABB" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Point from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove Out-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Remove In-Control from Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point to Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Split Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Point in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move In-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Move Out-Control in Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Select Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Shift+Drag: Select Control Points" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Click: Add Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Left Click: Split Segment (in curve)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Right Click: Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +msgid "Select Control Points (Shift+Drag)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Add Point (in empty space)" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Delete Point" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Close Curve" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp +msgid "Options" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Angles" +msgstr "" + +#: editor/plugins/path_2d_editor_plugin.cpp +#: editor/plugins/path_editor_plugin.cpp +msgid "Mirror Handle Lengths" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Curve Point #" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Point Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve In Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Set Curve Out Position" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Path" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Path Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove Out-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Remove In-Control Point" +msgstr "" + +#: editor/plugins/path_editor_plugin.cpp +msgid "Split Segment (in curve)" +msgstr "" + +#: editor/plugins/physical_bone_plugin.cpp +msgid "Move Joint" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"The skeleton property of the Polygon2D does not point to a Skeleton2D node" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"No texture in this polygon.\n" +"Set a texture to be able to edit UV." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create UV Map" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Polygon 2D has internal vertices, so it can no longer be edited in the " +"viewport." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Polygon & UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Internal Vertex" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Invalid Polygon (need 3 different vertices)" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Add Custom Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Remove Custom Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform UV Map" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Transform Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint Bone Weights" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Open Polygon 2D UV editor." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygon 2D UV Editor" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Points" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Polygons" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Bones" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Points" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Command: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift: Move All" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Command: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Ctrl: Rotate" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Shift+Ctrl: Scale" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Move Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Rotate Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Scale Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Create a custom polygon. Enables custom polygon rendering." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "" +"Remove a custom polygon. If none remain, custom polygon rendering is " +"disabled." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Paint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Unpaint weights with specified intensity." +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Radius:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy Polygon to UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Copy UV to Polygon" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Clear UV" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Settings" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Snap" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Enable Snap" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Show Grid" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Configure Grid:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Offset Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step X:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Grid Step Y:" +msgstr "" + +#: editor/plugins/polygon_2d_editor_plugin.cpp +msgid "Sync Bones to Polygon" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ERROR: Couldn't load resource!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Add Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Rename Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Delete Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Resource clipboard is empty!" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Paste Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "Load Resource" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +msgid "ResourcePreloader" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "AnimationTree has no path set to an AnimationPlayer" +msgstr "" + +#: editor/plugins/root_motion_editor_plugin.cpp +msgid "Path to AnimationPlayer is invalid" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Files" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close and save changes?" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error writing TextFile:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Could not load file at:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving file!" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Saving" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error importing theme." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error Importing" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "New Text File..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open File" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save File As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Can't obtain the script for running." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script failed reloading, check console for errors." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Script is not in tool mode, will not be able to run." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"To run this script, it must inherit EditorScript and be set to tool mode." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error while saving theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Error saving" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme As..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "%s Class Reference" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +msgid "Find Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Toggle alphabetical sorting of the method list." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Sort" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Up" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Move Down" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Next script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Previous script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "File" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reopen Closed Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save All" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Soft Reload Script" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Copy Script Path" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Previous" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "History Next" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Import Theme..." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Reload Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Save Theme" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close All" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Close Docs" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +msgid "Run" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Search" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Into" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Step Over" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Break" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp +#: editor/script_editor_debugger.cpp +msgid "Continue" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Keep Debugger Open" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Debug with External Editor" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Open Godot online documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search the reference documentation." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to previous edited document." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Go to next edited document." +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Discard" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "" +"The following files are newer on disk.\n" +"What action should be taken?:" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp +msgid "Debugger" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Search Results" +msgstr "" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Clear Recent Scripts" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Connections to method:" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp +msgid "Source" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Target" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "" +"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "[Ignore]" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Only resources from filesystem can be dropped." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't drop nodes because script '%s' is not used in this scene." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Lookup Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Pick Color" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Convert Case" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Uppercase" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Lowercase" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Capitalize" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp +msgid "Syntax Highlighter" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Bookmarks" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Cut" +msgstr "" + +#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp +#: scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Delete Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Left" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Indent Right" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Comment" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold/Unfold Line" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Fold All Lines" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Unfold All Lines" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Complete Symbol" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Evaluate Selection" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Trim Trailing Whitespace" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Spaces" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Convert Indent to Tabs" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Auto Indent" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Find in Files..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Contextual Help" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Toggle Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Bookmark" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Bookmarks" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Function..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Line..." +msgstr "" + +#: editor/plugins/script_text_editor.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Toggle Breakpoint" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Remove All Breakpoints" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Next Breakpoint" +msgstr "" + +#: editor/plugins/script_text_editor.cpp +msgid "Go to Previous Breakpoint" +msgstr "" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "" +"This shader has been modified on on disk.\n" +"What action should be taken?" +msgstr "" + +#: editor/plugins/shader_editor_plugin.cpp +msgid "Shader" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "This skeleton has no bones, create some children Bone2D nodes." +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Create Rest Pose from Bones" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Rest Pose to Bones" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Skeleton2D" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Make Rest Pose (From Bones)" +msgstr "" + +#: editor/plugins/skeleton_2d_editor_plugin.cpp +msgid "Set Bones to Rest Pose" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical bones" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Skeleton" +msgstr "" + +#: editor/plugins/skeleton_editor_plugin.cpp +msgid "Create physical skeleton" +msgstr "" + +#: editor/plugins/skeleton_ik_editor_plugin.cpp +msgid "Play IK" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Orthogonal" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Aborted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "X-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Y-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Z-Axis Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Plane Transform." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scaling: " +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translating: " +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotating %s degrees." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Keying is disabled (no key inserted)." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Animation Key Inserted." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pitch" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Yaw" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Size" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Objects Drawn" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Material Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Shader Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Surface Changes" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Draw Calls" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Vertices" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Transform with View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Align Rotation with View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "No parent to instance a child at." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp +msgid "This operation requires a single selected node." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Lock View Rotation" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Normal" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Wireframe" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Overdraw" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Display Unshaded" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Environment" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Information" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View FPS" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Half Resolution" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Audio Listener" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Enable Doppler" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Cinematic Preview" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Not available when using the GLES2 renderer." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Left" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Right" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Forward" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Backwards" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Up" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Down" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Speed Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Freelook Slow Modifier" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"To zoom further, change the camera's clipping planes (View -> Settings...)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "XForm Dialog" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Click to toggle between visibility states.\n" +"\n" +"Open eye: Gizmo is visible.\n" +"Closed eye: Gizmo is hidden.\n" +"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Nodes To Floor" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Couldn't find a solid floor to snap the selection to." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "" +"Drag: Rotate\n" +"Alt+Drag: Move\n" +"Alt+RMB: Depth list selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Local Space" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Use Snap" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Bottom View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Top View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rear View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Front View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Left View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Right View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Switch Perspective/Orthogonal View" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Insert Animation Key" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Focus Selection" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Toggle Freelook" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Object to Floor" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Dialog..." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "1 Viewport" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "2 Viewports (Alt)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "3 Viewports (Alt)" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "4 Viewports" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Gizmos" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Origin" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Grid" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Settings..." +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Snap Settings" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate Snap:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate Snap (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale Snap (%):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Viewport Settings" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Perspective FOV (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Near:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "View Z-Far:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Change" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Translate:" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Rotate (deg.):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Scale (ratio):" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Transform Type" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Pre" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Post" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp +msgid "Nameless gizmo" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Mesh2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create Polygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Polygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "CollisionPolygon2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "LightOccluder2D Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite is empty!" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Can't convert a sprite using animation frames to mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't replace by mesh." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Mesh2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Convert to Polygon2D" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create collision polygon." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create CollisionPolygon2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Invalid geometry, can't create light occluder." +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Create LightOccluder2D Sibling" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Sprite" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Simplification: " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Shrink (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Grow (Pixels): " +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Update Preview" +msgstr "" + +#: editor/plugins/sprite_editor_plugin.cpp +msgid "Settings:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "No Frames Selected" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add %d Frame(s)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Unable to load images" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "ERROR: Couldn't load frame resource!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Resource clipboard is empty or not a texture!" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Paste Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Empty" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Change Animation FPS" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "(empty)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move Frame" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animations:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "New Animation" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Speed:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Loop" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Animation Frames:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add a Texture from File" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Add Frames from a Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Insert Empty (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (Before)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Move (After)" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Horizontal:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Vertical:" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Select/Clear All Frames" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Create Frames from Sprite Sheet" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "SpriteFrames" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Region Rect" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Set Margin" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Snap Mode:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +#: scene/resources/visual_shader.cpp +msgid "None" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Pixel Snap" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Grid Snap" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Auto Slice" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Offset:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Step:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "Sep.:" +msgstr "" + +#: editor/plugins/texture_region_editor_plugin.cpp +msgid "TextureRegion" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove All Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp +msgid "Remove All" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Edit Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme editing menu." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Add Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Class Items" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create Empty Editor Template" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Create From Current Editor Theme" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Toggle Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Button" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Check Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Checked Radio Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Named Sep." +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Submenu" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subitem 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Many" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Disabled LineEdit" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 1" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 2" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Tab 3" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Editable Item" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Subtree" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Has,Many,Options" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Data Type:" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp +msgid "Style" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Font" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Color" +msgstr "" + +#: editor/plugins/theme_editor_plugin.cpp +msgid "Theme File" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Fix Invalid Tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cut Selection" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Line Draw" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Bucket Fill" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Erase TileMap" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Find Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Transpose" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Disable Autotile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Enable Priority" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Filter tiles" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Give a TileSet resource to this TileMap to use its tiles." +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Paint Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Command+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "" +"Shift+LMB: Line Draw\n" +"Shift+Ctrl+LMB: Rectangle Paint" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Pick Tile" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Left" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Rotate Right" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Horizontally" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Flip Vertically" +msgstr "" + +#: editor/plugins/tile_map_editor_plugin.cpp +msgid "Clear Transform" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Add Texture(s) to TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected Texture from TileSet." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from Scene" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Single Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Autotile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Atlas" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Next Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the next shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Previous Coordinate" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Select the previous shape, subtile, or Tile." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Region Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Collision Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Occlusion Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Navigation Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Bitmask Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Priority Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Icon Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Z Index Mode" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Copy bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Erase bitmask." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new rectangle." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Rectangle" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create a new polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "New Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete Selected Shape" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Keep polygon inside region Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Enable snap and show grid (configurable via the Inspector)." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Display Tile Names (Hold Alt Key)" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Add or select a texture on the left panel to edit the tiles bound to it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove selected texture? This will remove all tiles which use it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "You haven't selected a texture to remove." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create from scene? This will overwrite all current tiles." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Merge from scene?" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Texture" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "%s file(s) were not added because was already on the list." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Drag handles to edit Rect.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete selected Rect." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select current edited sub-tile.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Delete polygon." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"LMB: Set bit on.\n" +"RMB: Set bit off.\n" +"Shift+LMB: Set wildcard bit.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to use as icon, this will be also used on invalid autotile " +"bindings.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its priority.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "" +"Select sub-tile to change its z index.\n" +"Click on another Tile to edit it." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Region" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Set Tile Icon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Paste Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Clear Tile Bitmask" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Polygon Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Tile" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Remove Navigation Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Priority" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Edit Tile Z Index" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Convex" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Make Concave" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Collision Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "Create Occlusion Polygon" +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "This property can't be changed." +msgstr "" + +#: editor/plugins/tile_set_editor_plugin.cpp +msgid "TileSet" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No VCS addons are available." +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Error" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No files added to stage" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "VCS Addon is not initialized" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Version Control System" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Initialize" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Staging area" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect new changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Modified" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Renamed" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Deleted" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Typechange" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage Selected" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Stage All" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Commit Changes" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Status" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "View file diffs before committing them to the latest version" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "No file diff is active" +msgstr "" + +#: editor/plugins/version_control_editor_plugin.cpp +msgid "Detect changes in file diff" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(GLES3 only)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Output" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sampler" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port type" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change input port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Change output port name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove input port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Remove output port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set expression" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Resize VisualShader node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Uniform Name" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Set Input Default Port" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Add Node to Visual Shader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Node(s) Moved" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Duplicate Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Delete Nodes" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Input Type Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "UniformRef Name Changed" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vertex" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Fragment" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Light" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Show resulted shader code." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Create Shader Node" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Grayscale function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts HSV vector to RGB equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts RGB vector to HSV equivalent." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sepia function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Burn operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Darken operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Difference operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Dodge operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "HardLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Lighten operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Overlay operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Screen operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "SoftLight operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Color uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the %s comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Equal (==)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than (>)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Greater Than or Equal (>=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided scalars are equal, greater or " +"less." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between NaN and a scalar " +"parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than (<)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Less Than or Equal (<=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Not Equal (!=)" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated vector if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns an associated scalar if the provided boolean value is true or false." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the boolean result of the comparison between two parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the boolean result of the comparison between INF (or NaN) and a " +"scalar parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Boolean uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for all shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Input parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for light shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "E constant (2.718282). Represents the base of the natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Epsilon constant (0.00001). Smallest possible scalar number." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Phi constant (1.618034). Golden ratio." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/4 constant (0.785398) or 45 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi/2 constant (1.570796) or 90 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Pi constant (3.141593) or 180 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Tau constant (6.283185) or 360 degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Sqrt2 constant (1.414214). Square root of 2." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the absolute value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the arc-tangent of the parameters." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Finds the nearest integer that is greater than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Constrains a value to lie between two further values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic cosine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in radians to degrees." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-e Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 Exponential." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer less than or equal to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Computes the fractional part of the argument." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the inverse of the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Natural logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Base-2 logarithm." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the greater of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the lesser of two values." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the opposite value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the value of the first parameter raised to the power of the second." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Converts a quantity in degrees to radians." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / scalar" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the nearest even integer to the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Clamps the value between 0.0 and 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Extracts the sign of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic sine of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the square root of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), scalar(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the hyperbolic tangent of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Finds the truncated value of the parameter." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds scalar to scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies scalar by scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts scalar from scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Scalar uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the cubic texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Perform the texture lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Cubic texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "2D texture uniform lookup with triplanar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Calculate the outer product of a pair of vectors.\n" +"\n" +"OuterProduct treats the first parameter 'c' as a column vector (matrix with " +"one column) and the second parameter 'r' as a row vector (matrix with one " +"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix " +"whose number of rows is the number of components in 'c' and whose number of " +"columns is the number of components in 'r'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes transform from four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes transform to four vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the determinant of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the inverse of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the transpose of a transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies transform by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by transform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Transform uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector operator." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Composes vector from three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Decomposes vector to three scalars." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the cross product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the distance between two points." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the dot product of two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the same direction as a reference vector. " +"The function has three vector parameters : N, the vector to orient, I, the " +"incident vector, and Nref, the reference vector. If the dot product of I and " +"Nref is smaller than zero the return value is N. Otherwise -N is returned." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the length of a vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Linear interpolation between two vectors using scalar." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Calculates the normalize product of vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 - vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "1.0 / vector" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns the vector that points in the direction of reflection ( a : incident " +"vector, b : normal vector )." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the vector that points in the direction of refraction." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than " +"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " +"using Hermite polynomials." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( vector(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Step function( scalar(edge), vector(x) ).\n" +"\n" +"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Adds vector to vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Divides vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Multiplies vector by vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Returns the remainder of the two vectors." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Subtracts vector from vector." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector constant." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Vector uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, with custom amount of input and " +"output ports. This is a direct injection of code into the vertex/fragment/" +"light function, do not use it to write the function declarations inside." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Returns falloff based on the dot product of surface normal and view " +"direction of camera (pass associated inputs to it)." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"Custom Godot Shader Language expression, which is placed on top of the " +"resulted shader. You can place various function definitions inside and call " +"it later in the Expressions. You can also declare varyings, uniforms and " +"constants." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "A reference to an existing uniform." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Scalar derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "(Fragment/Light mode only) Vector derivative function." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local " +"differencing." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "" +"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and " +"'y'." +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "VisualShader" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Edit Visual Property" +msgstr "" + +#: editor/plugins/visual_shader_editor_plugin.cpp +msgid "Visual Shader Mode Changed" +msgstr "" + +#: editor/project_export.cpp +msgid "Runnable" +msgstr "" + +#: editor/project_export.cpp +msgid "Delete preset '%s'?" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"Export templates seem to be missing or invalid." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Failed to export the project for platform '%s'.\n" +"This might be due to a configuration issue in the export preset or your " +"export settings." +msgstr "" + +#: editor/project_export.cpp +msgid "Release" +msgstr "" + +#: editor/project_export.cpp +msgid "Exporting All" +msgstr "" + +#: editor/project_export.cpp +msgid "The given export path doesn't exist:" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing/corrupted:" +msgstr "" + +#: editor/project_export.cpp +msgid "Presets" +msgstr "" + +#: editor/project_export.cpp editor/project_settings_editor.cpp +msgid "Add..." +msgstr "" + +#: editor/project_export.cpp +msgid "" +"If checked, the preset will be available for use in one-click deploy.\n" +"Only one preset per platform may be marked as runnable." +msgstr "" + +#: editor/project_export.cpp +msgid "Export Path" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources" +msgstr "" + +#: editor/project_export.cpp +msgid "Export all resources in the project" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected scenes (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export selected resources (and dependencies)" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Resources to export:" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to export non-resource files/folders\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "" +"Filters to exclude files/folders from project\n" +"(comma-separated, e.g: *.json, *.txt, docs/*)" +msgstr "" + +#: editor/project_export.cpp +msgid "Features" +msgstr "" + +#: editor/project_export.cpp +msgid "Custom (comma-separated):" +msgstr "" + +#: editor/project_export.cpp +msgid "Feature List:" +msgstr "" + +#: editor/project_export.cpp +msgid "Script" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Export Mode:" +msgstr "" + +#: editor/project_export.cpp +msgid "Text" +msgstr "" + +#: editor/project_export.cpp +msgid "Compiled" +msgstr "" + +#: editor/project_export.cpp +msgid "Encrypted (Provide Key Below)" +msgstr "" + +#: editor/project_export.cpp +msgid "Invalid Encryption Key (must be 64 characters long)" +msgstr "" + +#: editor/project_export.cpp +msgid "Script Encryption Key (256-bits as hex):" +msgstr "" + +#: editor/project_export.cpp +msgid "Export PCK/Zip" +msgstr "" + +#: editor/project_export.cpp +msgid "Export Project" +msgstr "" + +#: editor/project_export.cpp +msgid "Export mode?" +msgstr "" + +#: editor/project_export.cpp +msgid "Export All" +msgstr "" + +#: editor/project_export.cpp editor/project_manager.cpp +msgid "ZIP File" +msgstr "" + +#: editor/project_export.cpp +msgid "Godot Game Pack" +msgstr "" + +#: editor/project_export.cpp +msgid "Export templates for this platform are missing:" +msgstr "" + +#: editor/project_export.cpp +msgid "Manage Export Templates" +msgstr "" + +#: editor/project_export.cpp +msgid "Export With Debug" +msgstr "" + +#: editor/project_manager.cpp +msgid "The path specified doesn't exist." +msgstr "" + +#: editor/project_manager.cpp +msgid "Error opening package file (it's not in ZIP format)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose an empty folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "Please choose a \"project.godot\" or \".zip\" file." +msgstr "" + +#: editor/project_manager.cpp +msgid "This directory already contains a Godot project." +msgstr "" + +#: editor/project_manager.cpp +msgid "New Game Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Imported Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Invalid Project Name." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't create folder." +msgstr "" + +#: editor/project_manager.cpp +msgid "There is already a folder in this path with the specified name." +msgstr "" + +#: editor/project_manager.cpp +msgid "It would be a good idea to name your project." +msgstr "" + +#: editor/project_manager.cpp +msgid "Invalid project path (changed anything?)." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't edit project.godot in project path." +msgstr "" + +#: editor/project_manager.cpp +msgid "Couldn't create project.godot in project path." +msgstr "" + +#: editor/project_manager.cpp +msgid "Rename Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Import Existing Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Import & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Create New Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Create & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Install Project:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Install & Edit" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Name:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Path:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Project Installation Path:" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer:" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 3.0" +msgstr "" + +#: editor/project_manager.cpp +msgid "Not supported by your GPU drivers." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Higher visual quality\n" +"All features available\n" +"Incompatible with older hardware\n" +"Not recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "OpenGL ES 2.0" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Lower visual quality\n" +"Some features not available\n" +"Works on most hardware\n" +"Recommended for web games" +msgstr "" + +#: editor/project_manager.cpp +msgid "Renderer can be changed later, but scenes may need to be adjusted." +msgstr "" + +#: editor/project_manager.cpp +msgid "Unnamed Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Missing Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Error: Project is missing on the filesystem." +msgstr "" + +#: editor/project_manager.cpp +msgid "Can't open project at '%s'." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to open more than one project?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file does not specify the version of Godot " +"through which it was created.\n" +"\n" +"%s\n" +"\n" +"If you proceed with opening it, it will be converted to Godot's current " +"configuration file format.\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The following project settings file was generated by an older engine " +"version, and needs to be converted for this version:\n" +"\n" +"%s\n" +"\n" +"Do you want to convert it?\n" +"Warning: You won't be able to open the project with previous versions of the " +"engine anymore." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The project settings were created by a newer engine version, whose settings " +"are not compatible with this version." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Can't run project: no main scene defined.\n" +"Please edit the project and set the main scene in the Project Settings under " +"the \"Application\" category." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Can't run project: Assets need to be imported.\n" +"Please edit the project to trigger the initial import." +msgstr "" + +#: editor/project_manager.cpp +msgid "Are you sure to run %d projects at once?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove %d projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove this project from the list?\n" +"The project folder's contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Remove all missing projects from the list?\n" +"The project folders' contents won't be modified." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Language changed.\n" +"The interface will update after restarting the editor or project manager." +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"Are you sure to scan %s folders for existing Godot projects?\n" +"This could take a while." +msgstr "" + +#. TRANSLATORS: This refers to the application where users manage their Godot projects. +#: editor/project_manager.cpp +msgid "Project Manager" +msgstr "" + +#: editor/project_manager.cpp +msgid "Projects" +msgstr "" + +#: editor/project_manager.cpp +msgid "Loading, please wait..." +msgstr "" + +#: editor/project_manager.cpp +msgid "Last Modified" +msgstr "" + +#: editor/project_manager.cpp +msgid "Scan" +msgstr "" + +#: editor/project_manager.cpp +msgid "Select a Folder to Scan" +msgstr "" + +#: editor/project_manager.cpp +msgid "New Project" +msgstr "" + +#: editor/project_manager.cpp +msgid "Remove Missing" +msgstr "" + +#: editor/project_manager.cpp +msgid "Templates" +msgstr "" + +#: editor/project_manager.cpp +msgid "Restart Now" +msgstr "" + +#: editor/project_manager.cpp +msgid "Can't run project" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"You currently don't have any projects.\n" +"Would you like to explore official example projects in the Asset Library?" +msgstr "" + +#: editor/project_manager.cpp +msgid "" +"The search box filters projects by name and last path component.\n" +"To filter projects by name and full path, the query must contain at least " +"one `/` character." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Key " +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joy Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joy Axis" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "An action with the name '%s' already exists." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Rename Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Action deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "All Devices" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device" +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "Press a Key..." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Mouse Button Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Left Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Right Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Middle Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Left Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Right Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "X Button 1" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "X Button 2" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joypad Axis Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Axis" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Joypad Button Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Erase Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Button" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Left Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Right Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Middle Button." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Up." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Wheel Down." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Global Property" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Select a setting item first!" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "No property '%s' exists." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Setting '%s' is internal, and it can't be deleted." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Delete Item" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "" +"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " +"'\"'." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Input Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Error saving settings." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Settings saved OK." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Moved Input Action Event" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Override for Feature" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Translation" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Translation" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Add Remapped Path" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resource Remap Add Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Change Resource Remap Language" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remove Resource Remap Option" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Changed Locale Filter Mode" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Project Settings (project.godot)" +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "General" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Override For..." +msgstr "" + +#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp +msgid "The editor must be restarted for changes to take effect." +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Input Map" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Action:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Action" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Deadzone" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Device:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Index:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Localization" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Translations" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Translations:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remaps" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Resources:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Remaps by Locale:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locale" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locales Filter" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Show All Locales" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Show Selected Locales Only" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Filter mode:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Locales:" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "AutoLoad" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Plugins" +msgstr "" + +#: editor/project_settings_editor.cpp +msgid "Import Defaults" +msgstr "" + +#: editor/property_editor.cpp +msgid "Preset..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Zero" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing In-Out" +msgstr "" + +#: editor/property_editor.cpp +msgid "Easing Out-In" +msgstr "" + +#: editor/property_editor.cpp +msgid "File..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Dir..." +msgstr "" + +#: editor/property_editor.cpp +msgid "Assign" +msgstr "" + +#: editor/property_editor.cpp +msgid "Select Node" +msgstr "" + +#: editor/property_editor.cpp +msgid "Error loading file: Not a resource!" +msgstr "" + +#: editor/property_editor.cpp +msgid "Pick a Node" +msgstr "" + +#: editor/property_editor.cpp +msgid "Bit %d, val %d." +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Property" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Virtual Method" +msgstr "" + +#: editor/property_selector.cpp +msgid "Select Method" +msgstr "" + +#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp +msgid "Batch Rename" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Replace:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Prefix:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Suffix:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Use Regular Expressions" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Advanced Options" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Substitute" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node's parent name, if available" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Node type" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Current scene name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Root node name" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Sequential integer counter.\n" +"Compare counter options." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Per-level Counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "If set, the counter restarts for each group of child nodes." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Initial value for the counter" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Step" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Amount by which counter is incremented for each node" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Padding" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "" +"Minimum number of digits for the counter.\n" +"Missing digits are padded with leading zeros." +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Post-Process" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Keep" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "PascalCase to snake_case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "snake_case to PascalCase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Case" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Lowercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "To Uppercase" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Reset" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "Regular Expression Error:" +msgstr "" + +#: editor/rename_dialog.cpp +msgid "At character %s" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent Node" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Reparent Location (Select new Parent):" +msgstr "" + +#: editor/reparent_dialog.cpp +msgid "Keep Global Transform" +msgstr "" + +#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp +msgid "Reparent" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Run Mode:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Current Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Main Scene Arguments:" +msgstr "" + +#: editor/run_settings_dialog.cpp +msgid "Scene Run Settings" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "No parent to instance the scenes at." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error loading scene from %s" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot instance the scene '%s' because the current scene exists within one " +"of its nodes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Scene(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Replace with Branch Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instance Child Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't paste root node into the same scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Paste Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on the tree root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Node In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Move Nodes In Parent" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Duplicate Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Node must belong to the edited scene to become root." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Instantiated scenes can't become root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make node as Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes and any children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete %d nodes?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete the root node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\" and its children?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete node \"%s\"?" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can not perform with the root node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "This operation can't be done on instanced scenes." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Save New Scene As..." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Disabling \"editable_instance\" will cause all properties of the node to be " +"reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and " +"cause all properties of the node to be reverted to their default." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "New Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Create Root Node:" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "2D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "3D Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "User Interface" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Other Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes from a foreign scene!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Can't operate on nodes the current scene inherits from!" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach Script" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Cut Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remove Node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change type of node(s)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Couldn't save new scene. Likely dependencies (instances) couldn't be " +"satisfied." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error saving scene." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Error duplicating scene to save it." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Sub-Resources" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Editable Children" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Load As Placeholder" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Open Documentation" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Cannot attach a script: there are no languages registered.\n" +"This is probably because this editor was built with all language modules " +"disabled." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add Child Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Change Type" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Reparent to New Node" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Make Scene Root" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Merge From Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Save Branch as Scene" +msgstr "" + +#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp +msgid "Copy Node Path" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Delete (No Confirm)" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Add/Create a New Node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"Instance a scene file as a Node. Creates an inherited scene if no root node " +"exists." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Attach a new or existing script to the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Detach the script from the selected node." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Remote" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "" +"If selected, the Remote scene tree dock will cause the project to stutter " +"every time it updates.\n" +"Switch back to the Local scene tree dock to improve performance." +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Local" +msgstr "" + +#: editor/scene_tree_dock.cpp +msgid "Clear Inheritance? (No Undo!)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visible" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Unlock Node" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Button Group" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "(Connecting From)" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node configuration warning:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s) and %s group(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node has %s connection(s).\n" +"Click to show signals dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is in %s group(s).\n" +"Click to show groups dock." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Open Script:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Node is locked.\n" +"Click to unlock it." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"Children are not selectable.\n" +"Click to make selectable." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Toggle Visibility" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "" +"AnimationPlayer is pinned.\n" +"Click to unpin." +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Invalid node name, the following characters are not allowed:" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Rename Node" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Scene Tree (Nodes):" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Node Configuration Warning!" +msgstr "" + +#: editor/scene_tree_editor.cpp +msgid "Select a Node" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Path is empty." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Filename is empty." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Path is not local." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid base path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "A directory with the same name exists." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "File does not exist." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid extension." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Wrong extension chosen." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error loading template '%s'" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error - Could not create script in filesystem." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Error loading script from %s" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Overrides" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "N/A" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Open Script / Choose Location" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Open Script" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "File exists, it will be reused." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid class name." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Invalid inherited parent name or path." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Script path/name is valid." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Allowed: a-z, A-Z, 0-9, _ and ." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Built-in script (into scene file)." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Will create a new script file." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Will load an existing script file." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Script file already exists." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Class Name:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Template:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Built-in Script:" +msgstr "" + +#: editor/script_create_dialog.cpp +msgid "Attach Node Script" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Remote " +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Bytes:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Warning:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Error:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Error:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Source:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "C++ Source:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Trace" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Errors" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Child process connected." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Copy Error" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Video RAM" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Skip Breakpoints" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Previous Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Inspect Next Instance" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Stack Frames" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Profiler" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Network Profiler" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Monitor" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Value" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Monitors" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Pick one or more items from the list to display the graph." +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "List of Video Memory Usage by Resource:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Total:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export list to a CSV file" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Resource Path" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Type" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Format" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Usage" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Misc" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Clicked Control Type:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Live Edit Root:" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Set From Tree" +msgstr "" + +#: editor/script_editor_debugger.cpp +msgid "Export measures as CSV" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Erase Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Restore Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Change Shortcut" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Editor Settings" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Shortcuts" +msgstr "" + +#: editor/settings_config_dialog.cpp +msgid "Binding" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Light Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change AudioStreamPlayer3D Emission Angle" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera FOV" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Camera Size" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Notifier AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Particles AABB" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Probe Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Sphere Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp +msgid "Change Box Shape Extents" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Capsule Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Radius" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Cylinder Shape Height" +msgstr "" + +#: editor/spatial_editor_gizmos.cpp +msgid "Change Ray Shape Length" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Cylinder Height" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Inner Radius" +msgstr "" + +#: modules/csg/csg_gizmos.cpp +msgid "Change Torus Outer Radius" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select the dynamic library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Select dependencies of the library for this entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Remove current entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Double click to create a new entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform:" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Platform" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Dynamic Library" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "Add an architecture entry" +msgstr "" + +#: modules/gdnative/gdnative_library_editor_plugin.cpp +msgid "GDNativeLibrary" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Enabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Disabled GDNative Singleton" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Library" +msgstr "" + +#: modules/gdnative/gdnative_library_singleton_editor.cpp +msgid "Libraries: " +msgstr "" + +#: modules/gdnative/register_types.cpp +msgid "GDNative" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Step argument is zero!" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not a script with an instance" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a script" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Not based on a resource file" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (missing @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (can't load script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary format (invalid script at @path)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Invalid instance dictionary (invalid subclasses)" +msgstr "" + +#: modules/gdscript/gdscript_functions.cpp +msgid "Object can't provide a length." +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Delete Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paste Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Paint" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Disabled" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Above" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clip Below" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit X Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Y Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Edit Z Axis" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate X" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Y" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Back Rotate Z" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Cursor Clear Rotation" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Paste Selects" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Clear Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Fill Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Settings" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Pick Distance:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Filter meshes" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Give a MeshLibrary resource to this GridMap to use its meshes." +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Begin Bake" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Preparing data structures" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Generate buffers" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Direct lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Indirect lighting" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Post processing" +msgstr "" + +#: modules/lightmapper_cpu/lightmapper_cpu.cpp +msgid "Plotting lightmaps" +msgstr "" + +#: modules/mono/csharp_script.cpp +msgid "Class name can't be a reserved keyword" +msgstr "" + +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Bake NavMesh" +msgstr "" + +#: modules/recast/navigation_mesh_editor_plugin.cpp +msgid "Clear the navigation mesh." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Setting up Configuration..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Calculating grid size..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Marking walkable triangles..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Constructing compact heightfield..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Eroding walkable area..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Partitioning..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating contours..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Creating polymesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Converting to native navigation mesh..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Navigation Mesh Generator Setup:" +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Parsing Geometry..." +msgstr "" + +#: modules/recast/navigation_mesh_generator.cpp +msgid "Done!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"A node yielded without working memory, please read the docs on how to yield " +"properly!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Node yielded, but did not return a function state in the first working " +"memory." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "" +"Return value must be assigned to first element of node working memory! Fix " +"your node please." +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Node returned an invalid sequence output: " +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Found sequence bit but not the node in the stack, report bug!" +msgstr "" + +#: modules/visual_script/visual_script.cpp +msgid "Stack overflow with stack depth: " +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Signal Arguments" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Argument name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Default Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Set Variable Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Override an existing built-in function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new function." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Variables:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new variable." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Signals:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create a new signal." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name is not a valid identifier:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Name already in use by another func/var/signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Rename Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete input port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Input Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Output Port" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Expression" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Duplicate VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a simple reference to the node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold %s to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Hold Ctrl to drop a Variable Setter." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Preload Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Node(s) From Tree" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "" +"Can't drop properties because script '%s' is not used in this scene.\n" +"Drop holding 'Shift' to just copy the signature." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Getter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Setter Property" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Move Node(s)" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove VisualScript Node" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Disconnect Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Data" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Connect Node Sequence" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Script already has function '%s'" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Input Value" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Resize Comment" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't copy the function node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Clipboard is empty!" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Paste VisualScript Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function with a function node." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Can't create function of nodes from nodes of multiple functions." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select at least one node with sequence port." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Try to only have one sequence input in selection." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Create Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Variable" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Variable:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Remove Signal" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Editing Signal:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Tool:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Members:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Change Base Type:" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Nodes..." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Add Function..." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "function_name" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Select or create a function to edit its graph." +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Delete Selected" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Find Node Type" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Copy Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Cut Nodes" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Make Function" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Refresh Graph" +msgstr "" + +#: modules/visual_script/visual_script_editor.cpp +msgid "Edit Member" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Input type not iterable: " +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid" +msgstr "" + +#: modules/visual_script/visual_script_flow_control.cpp +msgid "Iterator became invalid: " +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name." +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Base object is not a Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Path does not lead Node!" +msgstr "" + +#: modules/visual_script/visual_script_func_nodes.cpp +msgid "Invalid index property name '%s' in node %s." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid argument of type: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid ": Invalid arguments: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableGet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "VariableSet not found in script: " +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "Custom node has no _step() method, can't process graph." +msgstr "" + +#: modules/visual_script/visual_script_nodes.cpp +msgid "" +"Invalid return value from _step(), must be integer (seq out), or string " +"(error)." +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Search VisualScript" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Get %s" +msgstr "" + +#: modules/visual_script/visual_script_property_selector.cpp +msgid "Set %s" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package name is missing." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Package segments must be of non-zero length." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' is not allowed in Android application package names." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A digit cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The character '%s' cannot be the first character in a package segment." +msgstr "" + +#: platform/android/export/export.cpp +msgid "The package must have at least one '.' separator." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Select device from the list" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find the 'apksigner' tool." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build template not installed in the project. Install it from the " +"Project menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Debug keystore not configured in the Editor Settings nor in the preset." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Release keystore incorrectly configured in the export preset." +msgstr "" + +#: platform/android/export/export.cpp +msgid "A valid Android SDK path is required in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid Android SDK path in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'platform-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK platform-tools' adb command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Please check in the Android SDK directory specified in Editor Settings." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Missing 'build-tools' directory!" +msgstr "" + +#: platform/android/export/export.cpp +msgid "Unable to find Android SDK build-tools' apksigner command." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid public key for APK expansion." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid package name:" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" " +"project setting (changed in Godot 3.2.2).\n" +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Use Custom Build\" must be enabled to use the plugins." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR" +"\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"." +msgstr "" + +#: platform/android/export/export.cpp +msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android App Bundle requires the *.aab extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "APK Expansion not compatible with Android App Bundle." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Invalid filename! Android APK requires the *.apk extension." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Trying to build from a custom built template, but no version info for it " +"exists. Please reinstall from the 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Android build version mismatch:\n" +" Template installed: %s\n" +" Godot Version: %s\n" +"Please reinstall Android build template from 'Project' menu." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Building Android Project (gradle)" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Building of Android project failed, check output for the error.\n" +"Alternatively visit docs.godotengine.org for Android build documentation." +msgstr "" + +#: platform/android/export/export.cpp +msgid "Moving output" +msgstr "" + +#: platform/android/export/export.cpp +msgid "" +"Unable to copy and rename export file, check gradle project directory for " +"outputs." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Identifier is missing." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "The character '%s' is not allowed in Identifier." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "App Store Team ID not specified - cannot configure the project." +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Invalid Identifier:" +msgstr "" + +#: platform/iphone/export/export.cpp +msgid "Required icon is not specified in the preset." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Stop HTTP Server" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run in Browser" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Run exported HTML in the system's default browser." +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not write file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not open template for export:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Invalid export template:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read custom HTML shell:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Could not read boot splash image file:" +msgstr "" + +#: platform/javascript/export/export.cpp +msgid "Using default boot splash image." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package short name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package unique name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid package publisher display name." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid product GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid publisher GUID." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid background color." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid Store Logo image dimensions (should be 50x50)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." +msgstr "" + +#: platform/uwp/export/export.cpp +msgid "Invalid splash screen image dimensions (should be 620x300)." +msgstr "" + +#: scene/2d/animated_sprite.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite to display frames." +msgstr "" + +#: scene/2d/canvas_modulate.cpp +msgid "" +"Only one visible CanvasModulate is allowed per scene (or set of instanced " +"scenes). The first created one will work, while the rest will be ignored." +msgstr "" + +#: scene/2d/collision_object_2d.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " +"define its shape." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "" +"CollisionPolygon2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "An empty CollisionPolygon2D has no effect on collision." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode." +msgstr "" + +#: scene/2d/collision_polygon_2d.cpp +msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"CollisionShape2D only serves to provide a collision shape to a " +"CollisionObject2D derived node. Please only use it as a child of Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"A shape must be provided for CollisionShape2D to function. Please create a " +"shape resource for it!" +msgstr "" + +#: scene/2d/collision_shape_2d.cpp +msgid "" +"Polygon-based shapes are not meant be used nor edited directly through the " +"CollisionShape2D node. Please use the CollisionPolygon2D node instead." +msgstr "" + +#: scene/2d/cpu_particles_2d.cpp +msgid "" +"CPUParticles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be PhysicsBody2Ds" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A must be a PhysicsBody2D" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node B must be a PhysicsBody2D" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Joint is not connected to two PhysicsBody2Ds" +msgstr "" + +#: scene/2d/joints_2d.cpp +msgid "Node A and Node B must be different PhysicsBody2Ds" +msgstr "" + +#: scene/2d/light_2d.cpp +msgid "" +"A texture with the shape of the light must be supplied to the \"Texture\" " +"property." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "" +"An occluder polygon must be set (or drawn) for this occluder to take effect." +msgstr "" + +#: scene/2d/light_occluder_2d.cpp +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"A NavigationPolygon resource must be set or created for this node to work. " +"Please set a property or draw a polygon." +msgstr "" + +#: scene/2d/navigation_polygon.cpp +msgid "" +"NavigationPolygonInstance must be a child or grandchild to a Navigation2D " +"node. It only provides navigation data." +msgstr "" + +#: scene/2d/parallax_layer.cpp +msgid "" +"ParallaxLayer node only works when set as child of a ParallaxBackground node." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles2D node instead. You can use the \"Convert to " +"CPUParticles\" option for this purpose." +msgstr "" + +#: scene/2d/particles_2d.cpp scene/3d/particles.cpp +msgid "" +"A material to process the particles is not assigned, so no behavior is " +"imprinted." +msgstr "" + +#: scene/2d/particles_2d.cpp +msgid "" +"Particles2D animation requires the usage of a CanvasItemMaterial with " +"\"Particles Animation\" enabled." +msgstr "" + +#: scene/2d/path_2d.cpp +msgid "PathFollow2D only works when set as a child of a Path2D node." +msgstr "" + +#: scene/2d/physics_body_2d.cpp +msgid "" +"Size changes to RigidBody2D (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/2d/remote_transform_2d.cpp +msgid "Path property must point to a valid Node2D node to work." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "This Bone2D chain should end at a Skeleton2D node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." +msgstr "" + +#: scene/2d/skeleton_2d.cpp +msgid "" +"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." +msgstr "" + +#: scene/2d/tile_map.cpp +msgid "" +"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes " +"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, " +"KinematicBody2D, etc. to give them a shape." +msgstr "" + +#: scene/2d/visibility_notifier_2d.cpp +msgid "" +"VisibilityEnabler2D works best when used with the edited scene root directly " +"as parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRCamera must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRController must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The controller ID must not be 0 or this controller won't be bound to an " +"actual controller." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVRAnchor must have an ARVROrigin node as its parent." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "" +"The anchor ID must not be 0 or this anchor won't be bound to an actual " +"anchor." +msgstr "" + +#: scene/3d/arvr_nodes.cpp +msgid "ARVROrigin requires an ARVRCamera child node." +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Finding meshes and lights" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing geometry (%d/%d)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Preparing environment" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Generating capture" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Saving lightmaps" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "Done" +msgstr "" + +#: scene/3d/collision_object.cpp +msgid "" +"This node has no shape, so it can't collide or interact with other objects.\n" +"Consider adding a CollisionShape or CollisionPolygon as a child to define " +"its shape." +msgstr "" + +#: scene/3d/collision_polygon.cpp +msgid "" +"CollisionPolygon only serves to provide a collision shape to a " +"CollisionObject derived node. Please only use it as a child of Area, " +"StaticBody, RigidBody, KinematicBody, etc. to give them a shape." +msgstr "" + +#: scene/3d/collision_polygon.cpp +msgid "An empty CollisionPolygon has no effect on collision." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"CollisionShape only serves to provide a collision shape to a CollisionObject " +"derived node. Please only use it as a child of Area, StaticBody, RigidBody, " +"KinematicBody, etc. to give them a shape." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"A shape must be provided for CollisionShape to function. Please create a " +"shape resource for it." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"Plane shapes don't work well and will be removed in future versions. Please " +"don't use them." +msgstr "" + +#: scene/3d/collision_shape.cpp +msgid "" +"ConcavePolygonShape doesn't support RigidBody in another mode than static." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "Nothing is visible because no mesh has been assigned." +msgstr "" + +#: scene/3d/cpu_particles.cpp +msgid "" +"CPUParticles animation requires the usage of a SpatialMaterial whose " +"Billboard Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Plotting Meshes" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "Finishing Plot" +msgstr "" + +#: scene/3d/gi_probe.cpp +msgid "" +"GIProbes are not supported by the GLES2 video driver.\n" +"Use a BakedLightmap instead." +msgstr "" + +#: scene/3d/light.cpp +msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "A NavigationMesh resource must be set or created for this node to work." +msgstr "" + +#: scene/3d/navigation_mesh.cpp +msgid "" +"NavigationMeshInstance must be a child or grandchild to a Navigation node. " +"It only provides navigation data." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"GPU-based particles are not supported by the GLES2 video driver.\n" +"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" +"\" option for this purpose." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Nothing is visible because meshes have not been assigned to draw passes." +msgstr "" + +#: scene/3d/particles.cpp +msgid "" +"Particles animation requires the usage of a SpatialMaterial whose Billboard " +"Mode is set to \"Particle Billboard\"." +msgstr "" + +#: scene/3d/path.cpp +msgid "PathFollow only works when set as a child of a Path node." +msgstr "" + +#: scene/3d/path.cpp +msgid "" +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." +msgstr "" + +#: scene/3d/physics_body.cpp +msgid "" +"Size changes to RigidBody (in character or rigid modes) will be overridden " +"by the physics engine when running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A must be a PhysicsBody" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node B must be a PhysicsBody" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Joint is not connected to any PhysicsBodies" +msgstr "" + +#: scene/3d/physics_joint.cpp +msgid "Node A and Node B must be different PhysicsBodies" +msgstr "" + +#: scene/3d/remote_transform.cpp +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "This body will be ignored until you set a mesh." +msgstr "" + +#: scene/3d/soft_body.cpp +msgid "" +"Size changes to SoftBody will be overridden by the physics engine when " +"running.\n" +"Change the size in children collision shapes instead." +msgstr "" + +#: scene/3d/sprite_3d.cpp +msgid "" +"A SpriteFrames resource must be created or set in the \"Frames\" property in " +"order for AnimatedSprite3D to display frames." +msgstr "" + +#: scene/3d/vehicle_body.cpp +msgid "" +"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " +"it as a child of a VehicleBody." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)." +msgstr "" + +#: scene/3d/world_environment.cpp +msgid "" +"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " +"this environment's Background Mode to Canvas (for 2D scenes)." +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "On BlendTree node '%s', animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_blend_tree.cpp +msgid "Animation not found: '%s'" +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "In node '%s', invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Invalid animation: '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Nothing connected to input '%s' of node '%s'." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "No root AnimationNode for the graph is set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path to an AnimationPlayer node containing animations is not set." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." +msgstr "" + +#: scene/animation/animation_tree.cpp +msgid "The AnimationPlayer root node is not a valid node." +msgstr "" + +#: scene/animation/animation_tree_player.cpp +msgid "This node has been deprecated. Use AnimationTree instead." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "" +"Color: #%s\n" +"LMB: Set color\n" +"RMB: Remove preset" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Pick a color from the editor window." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Switch between hexadecimal and code values." +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Add current color as a preset." +msgstr "" + +#: scene/gui/container.cpp +msgid "" +"Container by itself serves no purpose unless a script configures its " +"children placement behavior.\n" +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" + +#: scene/gui/control.cpp +msgid "" +"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to " +"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"." +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Alert!" +msgstr "" + +#: scene/gui/dialogs.cpp +msgid "Please Confirm..." +msgstr "" + +#: scene/gui/file_dialog.cpp +msgid "Must use a valid extension." +msgstr "" + +#: scene/gui/graph_edit.cpp +msgid "Enable grid minimap." +msgstr "" + +#: scene/gui/popup.cpp +msgid "" +"Popups will hide by default unless you call popup() or any of the popup*() " +"functions. Making them visible for editing is fine, but they will hide upon " +"running." +msgstr "" + +#: scene/gui/range.cpp +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." +msgstr "" + +#: scene/gui/scroll_container.cpp +msgid "" +"ScrollContainer is intended to work with a single child control.\n" +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " +"minimum size manually." +msgstr "" + +#: scene/gui/tree.cpp +msgid "(Other)" +msgstr "" + +#: scene/main/scene_tree.cpp +msgid "" +"Default Environment as specified in Project Settings (Rendering -> " +"Environment -> Default Environment) could not be loaded." +msgstr "" + +#: scene/main/viewport.cpp +msgid "" +"This viewport is not set as render target. If you intend for it to display " +"its contents directly to the screen, make it a child of a Control so it can " +"obtain a size. Otherwise, make it a RenderTarget and assign its internal " +"texture to some node for display." +msgstr "" + +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "" +"The sampler port is connected but not used. Consider changing the source to " +"'SamplerPort'." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for preview." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for shader." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp +msgid "Invalid comparison function for that type." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Assignment to uniform." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Varyings can only be assigned in vertex function." +msgstr "" + +#: servers/visual/shader_language.cpp +msgid "Constants cannot be modified." +msgstr "" diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 548d71df18..4005ff2090 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -2454,9 +2454,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Ðе може да Ñе зареди добавката-Ñкрипт от: „%s“." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Ðе може да Ñе зареди добавката-Ñкрипт от: „%s“. Изглежда има грешка в кода. " "МолÑ, проверете ÑинтакÑиÑа." @@ -2884,6 +2886,10 @@ msgid "About" msgstr "ОтноÑно" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "ПуÑкане на проекта." @@ -5063,6 +5069,7 @@ msgstr "" "принадлежат на квадратната облаÑÑ‚ [0.0,1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index 21144a829b..5192cd4164 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -7,7 +7,7 @@ # Tahmid Karim <tahmidk15@gmail.com>, 2016. # Tawhid H. <Tawhidk757@yahoo.com>, 2019. # Hasibul Hasan <hasibeng78@gmail.com>, 2019. -# Oymate <dhruboadittya96@gmail.com>, 2020. +# Oymate <dhruboadittya96@gmail.com>, 2020, 2021. # Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020, 2021. # Sagen Soren <sagensoren03@gmail.com>, 2020. # Hasibul Hasan <d1hasib@yahoo.com>, 2020. @@ -15,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-02-15 10:51+0000\n" -"Last-Translator: Mokarrom Hossain <mhb2016.bzs@gmail.com>\n" +"PO-Revision-Date: 2021-05-14 11:19+0000\n" +"Last-Translator: Oymate <dhruboadittya96@gmail.com>\n" "Language-Team: Bengali <https://hosted.weblate.org/projects/godot-engine/" "godot/bn/>\n" "Language: bn\n" @@ -24,7 +24,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Weblate 4.5-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -729,7 +729,7 @@ msgstr "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° নিরà§à¦¬à¦¾à¦šà¦¿à¦¤à¦¸à¦®à§‚হ" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "আদরà§à¦¶" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -1179,11 +1179,11 @@ msgstr "লেখক" #: editor/editor_about.cpp msgid "Platinum Sponsors" -msgstr "পà§à¦²à§à¦¯à¦¾à¦Ÿà¦¿à¦¨à¦¾à¦® সà§à¦ªà¦¨à¦¸à¦°" +msgstr "পà§à¦²à§à¦¯à¦¾à¦Ÿà¦¿à¦¨à¦¾à¦® বিজà§à¦žà¦¾à¦ªà¦•" #: editor/editor_about.cpp msgid "Gold Sponsors" -msgstr "গোলà§à¦¡ সà§à¦ªà¦¨à¦¸à¦°" +msgstr "সোনালি বিজà§à¦žà¦¾à¦ªà¦•" #: editor/editor_about.cpp #, fuzzy @@ -1197,7 +1197,7 @@ msgstr "বà§à¦°à§‹à¦žà§à¦œ ডোনার" #: editor/editor_about.cpp msgid "Mini Sponsors" -msgstr "মিনি সà§à¦ªà¦¨à¦¸à¦°" +msgstr "কà§à¦·à§à¦¦à§à¦° বিজà§à¦žà¦¾à¦ªà¦•" #: editor/editor_about.cpp msgid "Gold Donors" @@ -1375,7 +1375,7 @@ msgstr "ইফেকà§à¦Ÿ ডিলিট করà§à¦¨" #: editor/editor_audio_buses.cpp msgid "Audio" -msgstr "" +msgstr "শবà§à¦¦" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" @@ -1581,7 +1581,7 @@ msgstr "(খালি/শূনà§à¦¯)" #: editor/editor_data.cpp msgid "[unsaved]" -msgstr "" +msgstr "[অসংরকà§à¦·à¦¿à¦¤]" #: editor/editor_dir_dialog.cpp #, fuzzy @@ -2654,8 +2654,9 @@ msgstr "%s হতে সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ তà§à¦²à¦¤à§‡/লোডে ঠ#: editor/editor_node.cpp #, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "'%s' পাথ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করে অà§à¦¯à¦¾à¦¡-অন সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ লোড করা সমà§à¦à¦¬ হয়নি। সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà¦Ÿà¦¿ টà§à¦² মোডে নেই।" @@ -3135,6 +3136,10 @@ msgid "About" msgstr "সমà§à¦¬à¦¨à§à¦§à§‡" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "পà§à¦°à¦•লà§à¦ªà¦Ÿà¦¿ চালান।" @@ -3441,7 +3446,7 @@ msgstr "চালà§" #: editor/editor_properties.cpp msgid "Layer" -msgstr "" +msgstr "সà§à¦¤à¦°" #: editor/editor_properties.cpp #, fuzzy @@ -3537,7 +3542,7 @@ msgstr "সেল (Cell)-à¦à¦° আকার:" #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "পাতা: " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -4480,7 +4485,7 @@ msgstr "পà§à¦²à¦¾à¦—ইন-সমূহ" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" -msgstr "" +msgstr "উপফোলà§à¦¡à¦¾à¦°:" #: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp #, fuzzy @@ -4993,7 +4998,7 @@ msgstr "গঠনবিনà§à¦¯à¦¾à¦¸" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" -msgstr "" +msgstr "গà¦à§€à¦°à¦¤à¦¾" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" @@ -5078,11 +5083,11 @@ msgstr "সমাপà§à¦¤à¦¿(সমূহ)" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "তাৎকà§à¦·à¦£à¦¿à¦•" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "সিঙà§à¦•" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" @@ -5090,7 +5095,7 @@ msgstr "" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "à¦à§à¦°à¦®à¦£" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." @@ -5467,7 +5472,7 @@ msgstr "পরবরà§à¦¤à§€" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Last" -msgstr "" +msgstr "শেষ" #: editor/plugins/asset_library_editor_plugin.cpp msgid "All" @@ -7021,7 +7026,7 @@ msgstr "Polygon 2D UV à¦à¦¡à¦¿à¦Ÿà¦°" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV" -msgstr "" +msgstr "অতিবেগà§à¦¨à§€" #: editor/plugins/polygon_2d_editor_plugin.cpp #, fuzzy @@ -7097,7 +7102,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Radius:" -msgstr "" +msgstr "বà§à¦¯à¦¾à¦¸à¦¾à¦°à§à¦§:" #: editor/plugins/polygon_2d_editor_plugin.cpp #, fuzzy @@ -8364,7 +8369,7 @@ msgstr "ফà§à¦°à§‡à¦®à¦¸à¦®à§‚হ সà§à¦¤à§‚প করà§à¦¨" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " -msgstr "" +msgstr "সরলীকরণ: " #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -8556,7 +8561,7 @@ msgstr "পদকà§à¦·à§‡à¦ª:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Sep.:" -msgstr "" +msgstr "বিà¦à¦•à§à¦¤à¦•ারক:" #: editor/plugins/texture_region_editor_plugin.cpp #, fuzzy @@ -10970,7 +10975,7 @@ msgstr "পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾/অà§à¦¯à¦¾à¦•শন" #: editor/project_settings_editor.cpp msgid "Deadzone" -msgstr "" +msgstr "মৃতসà§à¦¥à¦¾à¦¨" #: editor/project_settings_editor.cpp msgid "Device:" @@ -12225,7 +12230,7 @@ msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Plane:" -msgstr "" +msgstr "সমতল:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Floor" @@ -12238,7 +12243,7 @@ msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" -msgstr "" +msgstr "মেà¦à§‡:" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy @@ -13796,7 +13801,7 @@ msgstr "" #: scene/gui/tree.cpp msgid "(Other)" -msgstr "" +msgstr "(অনà§à¦¯à¦¾à¦¨à§à¦¯)" #: scene/main/scene_tree.cpp msgid "" diff --git a/editor/translations/br.po b/editor/translations/br.po index 4d03911bbe..dfab47a0e2 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -2456,8 +2456,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2862,6 +2863,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 01e60b0fac..3346449af2 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -11,13 +11,16 @@ # Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2020. # Xavier Gomez <hiulit@gmail.com>, 2020. # Aina <ainasoga@gmail.com>, 2020. -# Alex Mancha <codingstain@gmail.com>, 2020. +# Alex Mancha <codingstain@gmail.com>, 2020, 2021. +# Carles Pastor Badosa <cpbadosa@gmail.com>, 2021. +# Roberto Pérez <djleizar@gmail.com>, 2021. +# Joel Garcia Cascalló <jocsencat@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-06-15 01:48+0000\n" -"Last-Translator: roger <616steam@gmail.com>\n" +"PO-Revision-Date: 2021-05-14 11:19+0000\n" +"Last-Translator: Joel Garcia Cascalló <jocsencat@gmail.com>\n" "Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/" "godot/ca/>\n" "Language: ca\n" @@ -25,7 +28,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.1-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -766,17 +769,16 @@ msgid "Method in target node must be specified." msgstr "S'ha d'especificar el mètode al node de destinació." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method name must be a valid identifier." -msgstr "El nom no és un identificador và lid:" +msgstr "El nom del mètode no és un identificador và lid." #: editor/connections_dialog.cpp msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"El mètode objectiu no s'ha trobat. Especifiqueu un mètode và lid o adjunteu-" -"li un script." +"El mètode objectiu no s'ha trobat. Especifiqueu un mètode và lid o adjunteu " +"un script al node." #: editor/connections_dialog.cpp msgid "Connect to Node:" @@ -813,7 +815,7 @@ msgstr "Treu" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "Arguments de Crida addicionals:" +msgstr "Afegir arguments de crida addicionals:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" @@ -862,11 +864,11 @@ msgstr "No es pot connectar el senyal" #: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Close" -msgstr "Tanca" +msgstr "Tancar" #: editor/connections_dialog.cpp msgid "Connect" -msgstr "Connecta" +msgstr "Connectar" #: editor/connections_dialog.cpp msgid "Signal:" @@ -874,11 +876,11 @@ msgstr "Senyal:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" -msgstr "Connecta '%s' amb '%s'" +msgstr "Connectar '%s' amb '%s'" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" -msgstr "Desconnecta '%s' de '%s'" +msgstr "Desconnectar '%s' de '%s'" #: editor/connections_dialog.cpp msgid "Disconnect all from signal: '%s'" @@ -886,12 +888,12 @@ msgstr "Desconnecta-ho tot del senyal: '%s'" #: editor/connections_dialog.cpp msgid "Connect..." -msgstr "Connecta..." +msgstr "Connectar..." #: editor/connections_dialog.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Disconnect" -msgstr "Desconnecta" +msgstr "Desconnectar" #: editor/connections_dialog.cpp msgid "Connect a Signal to a Method" @@ -911,9 +913,8 @@ msgid "Signals" msgstr "Senyals" #: editor/connections_dialog.cpp -#, fuzzy msgid "Filter signals" -msgstr "Filtrat de Fitxers" +msgstr "Filtrat de senyals" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" @@ -1483,7 +1484,7 @@ msgstr "Treu Autocà rrega" #: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" -msgstr "Activa" +msgstr "Activar" #: editor/editor_autoload_settings.cpp msgid "Rearrange Autoloads" @@ -1491,7 +1492,7 @@ msgstr "Reorganitza AutoCà rregues" #: editor/editor_autoload_settings.cpp msgid "Can't add autoload:" -msgstr "" +msgstr "No es pot afegir l'autocà rrega:" #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" @@ -2369,14 +2370,13 @@ msgstr "" "panell d'importació i torneu-lo a importar." #: editor/editor_node.cpp -#, fuzzy msgid "" "This scene was imported, so changes to it won't be kept.\n" "Instancing it or inheriting will allow making changes to it.\n" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" -"En ser una escena importada, no se'n conservaran els canvis. \n" +"En ser una escena importada, no se'n conservaran els canvis.\n" "Instanciar o heretar l'escena permetria la seva modificació.\n" "Referiu-vos a la documentació rellevant sobre la importació d'escenes per a " "més informació." @@ -2558,9 +2558,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Error carregant l'Script complement des del camÃ: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "No es pot carregar l'script d'addon des del camÃ: '%s' Sembla que hi ha un " "error en el codi, si us plau comproveu la sintaxi." @@ -3015,6 +3017,10 @@ msgid "About" msgstr "Quant a" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Reprodueix el projecte." @@ -3159,13 +3165,12 @@ msgid "Open & Run a Script" msgstr "Obre i Executa un Script" #: editor/editor_node.cpp -#, fuzzy msgid "" "The following files are newer on disk.\n" "What action should be taken?" msgstr "" -"El disc conté versions més recents dels fitxer següents. \n" -"Quina acció voleu seguir?:" +"El disc conté versions més recents dels fitxer següents.\n" +"Quina acció voleu seguir?" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp @@ -4803,9 +4808,8 @@ msgid "Move Node" msgstr "Moure Node" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition exists!" -msgstr "Transició: " +msgstr "La transició existeix!" #: editor/plugins/animation_state_machine_editor.cpp msgid "Add Transition" @@ -7500,9 +7504,8 @@ msgid "Yaw" msgstr "Guinyada" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Size" -msgstr "Mida: " +msgstr "Mida:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" @@ -10780,9 +10783,8 @@ msgid "Batch Rename" msgstr "Reanomena" #: editor/rename_dialog.cpp -#, fuzzy msgid "Replace:" -msgstr "Reemplaça: " +msgstr "Reemplaça:" #: editor/rename_dialog.cpp #, fuzzy @@ -11543,7 +11545,7 @@ msgstr "Procés Fill Connectat" #: editor/script_editor_debugger.cpp msgid "Copy Error" -msgstr "Error de Còpia" +msgstr "Copia l'error" #: editor/script_editor_debugger.cpp #, fuzzy @@ -13258,15 +13260,15 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be PhysicsBodies" -msgstr "" +msgstr "Node A i Node B han de ser PhysicsBodies" #: scene/3d/physics_joint.cpp msgid "Node A must be a PhysicsBody" -msgstr "" +msgstr "El node A ha de ser de tipus PhysicsBody" #: scene/3d/physics_joint.cpp msgid "Node B must be a PhysicsBody" -msgstr "" +msgstr "El node B ha de ser de tipus PhysicsBody" #: scene/3d/physics_joint.cpp msgid "Joint is not connected to any PhysicsBodies" @@ -13274,7 +13276,7 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Node A and Node B must be different PhysicsBodies" -msgstr "" +msgstr "El Node A i el Node B han de ser PhysicsBodies diferents" #: scene/3d/remote_transform.cpp #, fuzzy @@ -13343,18 +13345,16 @@ msgid "On BlendTree node '%s', animation not found: '%s'" msgstr "" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Animation not found: '%s'" -msgstr "Eines d'Animació" +msgstr "Animació no trobada: '%s'" #: scene/animation/animation_tree.cpp msgid "In node '%s', invalid animation: '%s'." msgstr "En el node '%s', l'animació no és valida: '%s'." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Invalid animation: '%s'." -msgstr "ERROR: El Nom de l'Animació no és và lid!" +msgstr "Animació invà lida: '%s'." #: scene/animation/animation_tree.cpp #, fuzzy @@ -13382,7 +13382,7 @@ msgstr "L'arbre d'animació no és và lid." #: scene/animation/animation_tree_player.cpp msgid "This node has been deprecated. Use AnimationTree instead." -msgstr "" +msgstr "Aquest node està en desús. Fes servir AnimationTree." #: scene/gui/color_picker.cpp #, fuzzy @@ -13443,9 +13443,8 @@ msgid "Must use a valid extension." msgstr "Cal utilitzar una extensió và lida." #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Enable grid minimap." -msgstr "Activar Ajustament" +msgstr "Activar graella del minimapa" #: scene/gui/popup.cpp #, fuzzy diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 79163c835f..b37f9a6a3f 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -29,8 +29,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-21 07:35+0000\n" -"Last-Translator: ZbynÄ›k <zbynek.fiala@gmail.com>\n" +"PO-Revision-Date: 2021-05-03 06:13+0000\n" +"Last-Translator: VojtÄ›ch Å amla <auzkok@seznam.cz>\n" "Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/" "cs/>\n" "Language: cs\n" @@ -2547,9 +2547,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Nelze naÄÃst skript rozÅ¡ÃÅ™enà z cesty: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Nelze naÄÃst skript rozÅ¡ÃÅ™enà z cesty: '%s'. Zdá se, že se v kódu nacházà " "chyba. ProsÃm, zkontrolujte syntax." @@ -2992,6 +2994,10 @@ msgid "About" msgstr "O aplikaci" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Spustit projekt." @@ -5178,14 +5184,12 @@ msgid "Assets ZIP File" msgstr "ZIP soubor asetů" #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" "Save your scene and try again." msgstr "" "Nelze urÄit cestu pro uloženà obrázků svÄ›telné mapy.\n" -"Uložte scénu (obrázky se uložà do stejného adresáře) nebo vyberte cestu pro " -"uloženà z vlastnosti BakedLightmap." +"Uložte scénu a zkuste to znovu." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5215,6 +5219,7 @@ msgstr "" "Ätvercové oblasti [0.0, 1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" diff --git a/editor/translations/da.po b/editor/translations/da.po index 01d6dbc42e..3cb65a5d82 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -5,7 +5,7 @@ # Dankse Memes <purplelops@gmail.com>, 2018. # David Lamhauge <davidlamhauge@gmail.com>, 2016, 2018. # Esben Damkjær Sørensen <esben@damkjaergaard.com>, 2018. -# Kim Nielsen <kimmowich@stofanet.dk>, 2017, 2018. +# Kim Nielsen <kimmowich@stofanet.dk>, 2017, 2018, 2021. # Michael Madsen <mim@michael-madsen.dk>, 2017. # Christoffer Schindel <ceas@outlook.com>, 2018. # frederikzt <frederikzt@gmail.com>, 2018. @@ -22,8 +22,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-20 04:18+0000\n" -"Last-Translator: snakatk <snaqii@live.dk>\n" +"PO-Revision-Date: 2021-04-26 22:31+0000\n" +"Last-Translator: Kim Nielsen <kimmowich@stofanet.dk>\n" "Language-Team: Danish <https://hosted.weblate.org/projects/godot-engine/" "godot/da/>\n" "Language: da\n" @@ -31,7 +31,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5.2-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2636,9 +2636,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Kan ikke indlæse addon script fra stien: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Kan ikke indlæse tilføjelse script fra sti: '%s' Der ser ud til at være en " "fejl i koden, tjek syntaksen." @@ -3100,6 +3102,10 @@ msgid "About" msgstr "Om" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Spil dit projekt." @@ -4813,47 +4819,43 @@ msgstr "Animationsposition (i sekunder)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "" +msgstr "Skalér animation afspilningen globalt for node." #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Animation Tools" -msgstr "Animation Værktøjer" +msgstr "Animations Værktøjer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" msgstr "Animation" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Edit Transitions..." msgstr "Rediger Overgange..." #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Open in Inspector" -msgstr "Inspektør" +msgstr "Ã…ben i Inspector" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "" +msgstr "Vis liste over animationer i afspiller" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Autoplay ved Load" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "Aktivér Onion Skin" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning Options" -msgstr "" +msgstr "Onion Skin Muligheder" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Directions" -msgstr "Beskrivelse" +msgstr "Retninger" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -4862,7 +4864,7 @@ msgstr "Indsæt" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "Fremtid" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -4883,15 +4885,15 @@ msgstr "3 trin" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Kun Forskelle" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "Tving Hvid Modulate" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" -msgstr "" +msgstr "Inkludér Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -4904,7 +4906,7 @@ msgstr "Opret Ny Animation" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "Animation Navn:" +msgstr "Animations Navn:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp @@ -4918,7 +4920,6 @@ msgid "Blend Times:" msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Next (Auto Queue):" msgstr "Næste (Auto Kø):" @@ -4927,9 +4928,8 @@ msgid "Cross-Animation Blend Times" msgstr "" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Move Node" -msgstr "Flyt Node(s)" +msgstr "Flyt Node" #: editor/plugins/animation_state_machine_editor.cpp msgid "Transition exists!" @@ -4946,32 +4946,31 @@ msgstr "Tilføj Node" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "" +msgstr "Slut" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "Umiddelbart" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "Synkroniser" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" -msgstr "" +msgstr "I Slutningen" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "Rejse" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." -msgstr "" +msgstr "Start og slut nodes er nødvendige for en under-overgang." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "No playback resource set at path: %s." -msgstr "Ikke i stien for ressource." +msgstr "Ingen afspilnings ressource indstillet pÃ¥ stien: %s" #: editor/plugins/animation_state_machine_editor.cpp msgid "Node Removed" @@ -4983,7 +4982,7 @@ msgstr "Overgang Fjernet" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set Start Node (Autoplay)" -msgstr "" +msgstr "Sæt Start Node (Autoplay)" #: editor/plugins/animation_state_machine_editor.cpp msgid "" @@ -4991,44 +4990,43 @@ msgid "" "RMB to add new nodes.\n" "Shift+LMB to create connections." msgstr "" +"Vælg og flyt nodes.\n" +"RMB for at tilføje ny nodes.\n" +"Shift+LMB for at oprette forbindelse." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Create new nodes." -msgstr "Opret Ny %s" +msgstr "Opret ny nodes." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Connect nodes." -msgstr "Forbind Nodes" +msgstr "Forbind nodes." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Remove selected node or transition." -msgstr "Fjern valgte spor." +msgstr "Fjern valgte node eller overgang." #: editor/plugins/animation_state_machine_editor.cpp msgid "Toggle autoplay this animation on start, restart or seek to zero." msgstr "" +"Skift autoplay pÃ¥ denne animation ved start, genstart eller seek til zero." #: editor/plugins/animation_state_machine_editor.cpp msgid "Set the end animation. This is useful for sub-transitions." -msgstr "" +msgstr "Sæt slut animation. Dette er nyttigt ved under-overgange." #: editor/plugins/animation_state_machine_editor.cpp msgid "Transition: " msgstr "Overgang: " #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Play Mode:" -msgstr "Eksporter Projekt" +msgstr "Afspil Mode:" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp -#, fuzzy msgid "AnimationTree" -msgstr "Animation Zoom." +msgstr "Animation Tree" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" @@ -5037,7 +5035,7 @@ msgstr "Nyt navn:" #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Scale:" -msgstr "" +msgstr "Skalér:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Fade In (s):" @@ -5062,7 +5060,7 @@ msgstr "Auto Genstart:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Restart (s):" -msgstr "" +msgstr "Genstart:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Random Restart (s):" @@ -5116,11 +5114,11 @@ msgstr "Fjern Input" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation tree is valid." -msgstr "" +msgstr "Animationstræ er gyldigt." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation tree is invalid." -msgstr "" +msgstr "Animationstræ er ugyldigt." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation Node" diff --git a/editor/translations/de.po b/editor/translations/de.po index 9b49a15db4..1c6136ff6f 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -44,7 +44,7 @@ # datenbauer <d-vaupel@web.de>, 2019. # Alexander Hausmann <alexander-hausmann+weblate@posteo.de>, 2019. # Nicolas Mohr <81moni1bif@hft-stuttgart.de>, 2019. -# Linux User <no-ads@mail.de>, 2019. +# Linux User <no-ads@mail.de>, 2019, 2021. # David May <wasser@gmail.com>, 2019. # Draco Drache <jan.holger.te@gmail.com>, 2019. # Jonas <dotchucknorris@gmx.de>, 2019. @@ -52,7 +52,7 @@ # artism90 <artism90@googlemail.com>, 2020. # Jaigskim <filzstift112@gmail.com>, 2020. # Jacqueline Ulken <Jacqueline.Ulken@protonmail.com>, 2020. -# Günther Bohn <ciscouser@gmx.de>, 2020. +# Günther Bohn <ciscouser@gmx.de>, 2020, 2021. # Tom Wor <mail@tomwor.com>, 2020. # Bjarne Hiller <bjarne.hiller@gmail.com>, 2020. # Dirk Federmann <weblategodot@dirkfedermann.de>, 2020. @@ -67,11 +67,12 @@ # Raphipod <podraphi@googlemail.com>, 2021. # Daniel Plaster <danimineiromc@googlemail.com>, 2021. # El Captian <elcaptian@posteo.me>, 2021. +# Ron Eric Hackländer <mail@roneric.net>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-31 03:53+0000\n" +"PO-Revision-Date: 2021-05-14 20:34+0000\n" "Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" @@ -80,7 +81,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -176,15 +177,15 @@ msgstr "Wert:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" -msgstr "Hier Schlüsselbild einfügen" +msgstr "Schlüsselbild hier einfügen" #: editor/animation_bezier_editor.cpp msgid "Duplicate Selected Key(s)" -msgstr "Ausgewählte Schlüssel duplizieren" +msgstr "Ausgewählte Schlüsselbilder duplizieren" #: editor/animation_bezier_editor.cpp msgid "Delete Selected Key(s)" -msgstr "Ausgewählte Schlüssel löschen" +msgstr "Ausgewählte Schlüsselbilder löschen" #: editor/animation_bezier_editor.cpp msgid "Add Bezier Point" @@ -1372,15 +1373,15 @@ msgstr "Mittels Drag&Drop umordnen." #: editor/editor_audio_buses.cpp msgid "Solo" -msgstr "Solo" +msgstr "Allein" #: editor/editor_audio_buses.cpp msgid "Mute" -msgstr "Stumm" +msgstr "Stummschalten" #: editor/editor_audio_buses.cpp msgid "Bypass" -msgstr "Bypass" +msgstr "Brücke" #: editor/editor_audio_buses.cpp msgid "Bus options" @@ -1572,7 +1573,7 @@ msgstr "Name" #: editor/editor_autoload_settings.cpp msgid "Singleton" -msgstr "Singleton" +msgstr "Einzelelement" #: editor/editor_data.cpp editor/inspector_dock.cpp msgid "Paste Params" @@ -1728,7 +1729,7 @@ msgstr "Skript Editor" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "Bestandsbibliothek" +msgstr "Bestandsbibliothek (AssetLib)" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" @@ -2169,7 +2170,7 @@ msgstr "Methode" #: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp msgid "Signal" -msgstr "Signal" +msgstr "Ereignis" #: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constant" @@ -2617,11 +2618,13 @@ msgstr "Erweiterungsskript konnte nicht geladen werden: ‚%s‘." #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"Erweiterungsskript konnte nicht von folgendem Pfad geladen werden: ‚%s‘. Es " -"scheint ein Fehler im Quellcode zu sein. Bitte Syntax überprüfen." +"Erweiterungsskript auf folgendem Pfad konnte nicht geladen werden: ‚%s‘. Es " +"scheint ein Fehler in dessen Quellcode zu sein.\n" +"Die Erweiterung ‚%s‘ wird deaktiviert um weitere Fehler zu verhindern." #: editor/editor_node.cpp msgid "" @@ -3065,13 +3068,17 @@ msgstr "Dokumentationsvorschläge senden" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" -msgstr "Gemeinschaft" +msgstr "Community" #: editor/editor_node.cpp msgid "About" msgstr "Über" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Projekt abspielen." @@ -4160,7 +4167,7 @@ msgstr "Importer auswählen" #: editor/import_defaults_editor.cpp msgid "Importer:" -msgstr "Importer:" +msgstr "Importierer:" #: editor/import_defaults_editor.cpp msgid "Reset to Defaults" @@ -5309,10 +5316,11 @@ msgstr "" "Kanals im Bereich von 0.0 bis 1.0 liegen." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" -"Diese Godot-Version wurde ohne Raytracing-Unterstützung erstellt, Lightmaps " +"Der Godot-Editor wurde ohne Raytracing-Unterstützung erstellt; Lightmaps " "können damit nicht gebacken werden." #: editor/plugins/baked_lightmap_editor_plugin.cpp @@ -7142,7 +7150,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "Debugger" +msgstr "Testhilfsprogramm" #: editor/plugins/script_editor_plugin.cpp msgid "Search Results" @@ -7649,6 +7657,8 @@ msgstr "Sichtrotation gesperrt" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Um weiter zoomen zu können müssen die Kameraausschnittebenen geändert werden " +"(Anzeige -> Einstellungen… )" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -7943,7 +7953,7 @@ msgstr "LightOccluder2D erzeugen" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" -msgstr "Sprite" +msgstr "Bild" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " @@ -8712,7 +8722,7 @@ msgstr "Diese Eigenschaft kann nicht geändert werden." #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" -msgstr "TileSet" +msgstr "Kachelsatz" #: editor/plugins/version_control_editor_plugin.cpp msgid "No VCS addons are available." @@ -8823,7 +8833,7 @@ msgstr "Boolean" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sampler" -msgstr "Sampler" +msgstr "Abtaster" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add input port" @@ -8904,7 +8914,7 @@ msgstr "UniformRef-Name geändert" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" -msgstr "Vertex" +msgstr "Eckpunkt" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Fragment" @@ -10617,7 +10627,7 @@ msgstr "Präfix:" #: editor/rename_dialog.cpp msgid "Suffix:" -msgstr "Suffix:" +msgstr "Endung:" #: editor/rename_dialog.cpp msgid "Use Regular Expressions" @@ -10918,7 +10928,7 @@ msgstr "Benutzerschnittstelle" #: editor/scene_tree_dock.cpp msgid "Other Node" -msgstr "Anderer Node" +msgstr "Anderes Node" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -11055,6 +11065,10 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Falls ausgewählt wird das Panel für den Fern-Szenenbaum jedes mal beim " +"Aktualisieren das Projekt zum Ruckeln bringen.\n" +"Für bessere Geschwindigkeit sollte diese Option auf Lokaler Szenenbaum " +"gestellt werden." #: editor/scene_tree_dock.cpp msgid "Local" @@ -13314,6 +13328,18 @@ msgid "Constants cannot be modified." msgstr "Konstanten können nicht verändert werden." #~ msgid "" +#~ "Godot editor was built without ray tracing support; lightmaps can't be " +#~ "baked.\n" +#~ "If you are using an Apple Silicon-based Mac, try forcing Rosetta " +#~ "emulation on Godot.app in the application settings\n" +#~ "then restart the editor." +#~ msgstr "" +#~ "Der Godot-Editor wurde ohne Raytracing-Unterstützung gebaut; Lightmaps " +#~ "können nicht gebacken werden.\n" +#~ "Nutzer eines Macs basierend auf Apple Silicon sollten Rosetta-Emulation " +#~ "in den Anwendungseinstellungen aktivieren und den Editor neu starten." + +#~ msgid "" #~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0." #~ msgstr "" #~ "InterpolatedCamera ist veraltet und wird in Godot 4.0 entfernt werden." diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 1c44e9dd5c..5ffb9f106d 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -2434,8 +2434,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2840,6 +2841,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index 4648f83a72..591ad55930 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -16,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-29 21:57+0000\n" -"Last-Translator: leriaz <leriaz@live.com>\n" +"PO-Revision-Date: 2021-04-26 22:31+0000\n" +"Last-Translator: Michalis <michalisntovas@yahoo.gr>\n" "Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/" "el/>\n" "Language: el\n" @@ -25,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2557,9 +2557,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "ΑδÏνατη η φόÏτωση δÎσμης ενεÏγειών Ï€ÏοσθÎτου από τη διαδÏομή: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Αποτυχία φόÏτωσης δÎσμης ενεÏγειών Ï€ÏοσθÎτου από τη διαδÏομή: '%s'. Φαίνεται " "πως υπάÏχει λάθος στον κώδικα." @@ -3013,6 +3015,10 @@ msgid "About" msgstr "Σχετικά" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "ΑναπαÏαγωγή του ÎÏγου." @@ -10362,7 +10368,7 @@ msgstr "Σφάλμα κατά την αποθήκευση Ïυθμίσεων." #: editor/project_settings_editor.cpp msgid "Settings saved OK." -msgstr "Οι Ïυθμίσεις αποθηκεÏτικαν εντάξει." +msgstr "Οι Ïυθμίσεις αποθηκεÏτηκαν εντάξει." #: editor/project_settings_editor.cpp msgid "Moved Input Action Event" diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 3fe7877be0..4bb0dcbeae 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2021-04-19 22:33+0000\n" +"PO-Revision-Date: 2021-05-11 06:54+0000\n" "Last-Translator: mourning20s <mourning20s@protonmail.com>\n" "Language-Team: Esperanto <https://hosted.weblate.org/projects/godot-engine/" "godot/eo/>\n" @@ -1831,7 +1831,7 @@ msgstr "Aktualigi" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" -msgstr "" +msgstr "Ĉiaj rekonaj dosiertipoj" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" @@ -1992,7 +1992,6 @@ msgid "Properties" msgstr "Atributoj" #: editor/editor_help.cpp -#, fuzzy msgid "override:" msgstr "redifino:" @@ -2126,7 +2125,6 @@ msgid "Set Multiple:" msgstr "Agordi pluroblan:" #: editor/editor_log.cpp -#, fuzzy msgid "Output:" msgstr "Eligo:" @@ -2208,13 +2206,12 @@ msgid "Error saving resource!" msgstr "Eraras konservi risurcon!" #: editor/editor_node.cpp -#, fuzzy msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" -"Ĉi tiu risurco ne konserveblas, ĉar Äi ne apartenas la redaktita sceno. " -"Farigu Äin unikan unue." +"Ĉi tiun risurcon ne konserveblas ĉar Äi ne apartenas al la redaktita sceno. " +"Unikigu Äin unue." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." @@ -2241,31 +2238,31 @@ msgstr "Ne malfermeblas '%s'. La dosiero estus movita aÅ forigita." #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "" +msgstr "Eraras dum la analizo de '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "" +msgstr "Neatenda dosierfino '%s'." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "" +msgstr "'%s' aÅ Äiaj dependoj forestas." #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "" +msgstr "Eraro dum Åarginto de '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "" +msgstr "Konservas scenon" #: editor/editor_node.cpp msgid "Analyzing" -msgstr "" +msgstr "Analizas" #: editor/editor_node.cpp msgid "Creating Thumbnail" -msgstr "" +msgstr "Kreas bildeton" #: editor/editor_node.cpp msgid "This operation can't be done without a tree root." @@ -2282,26 +2279,29 @@ msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" +"Ne eble konservi scenon. VerÅajne dependoj (ekzemploj aÅ heredito) ne " +"verigus." #: editor/editor_node.cpp editor/scene_tree_dock.cpp +#, fuzzy msgid "Can't overwrite scene that is still open!" -msgstr "" +msgstr "Ne eble anstataÅigas scenon ke esti ankoraÅ malferma!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "" +msgstr "Ne eble Åargas MeshLibrary por la kunfando!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "" +msgstr "Eraras konservi MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "" +msgstr "Ne eble Åargas TileSet por la kunfando!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "" +msgstr "Eraras konservi TileSet!" #: editor/editor_node.cpp msgid "" @@ -2318,7 +2318,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "" +msgstr "Nomon de aranÄo ne trovis!" #: editor/editor_node.cpp msgid "Restored the Default layout to its base settings." @@ -2364,19 +2364,19 @@ msgstr "" #: editor/editor_node.cpp msgid "Save scene before running..." -msgstr "" +msgstr "Konservu scenon antaÅ ruloto..." #: editor/editor_node.cpp msgid "Could not start subprocess!" -msgstr "" +msgstr "Ne eble komencas subprocezon!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" -msgstr "" +msgstr "Malfermi scenon" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "" +msgstr "Malfermi scenon de bazo" #: editor/editor_node.cpp msgid "Quick Open..." @@ -2400,7 +2400,7 @@ msgstr "Konservi ÅanÄojn al '%s' antaÅ fermo?" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." -msgstr "" +msgstr "Konservis %s modifikita(j)n risurco(j)n." #: editor/editor_node.cpp msgid "A root node is required to save the scene." @@ -2517,8 +2517,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2582,7 +2583,7 @@ msgstr "" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "" +msgstr "DefaÅlto" #: editor/editor_node.cpp editor/editor_properties.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp @@ -2591,60 +2592,59 @@ msgstr "Montri en dosiersistemo" #: editor/editor_node.cpp msgid "Play This Scene" -msgstr "" +msgstr "Starti ĉi tiu scenon" #: editor/editor_node.cpp msgid "Close Tab" -msgstr "" +msgstr "Fermi langeton" #: editor/editor_node.cpp -#, fuzzy msgid "Undo Close Tab" -msgstr "Malfari fermi langeto" +msgstr "Malfari ferminton de la langeto" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "" +msgstr "Fermi aliajn langetojn" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Fermi langetojn dekstre" #: editor/editor_node.cpp msgid "Close All Tabs" -msgstr "" +msgstr "Fermi ĉiu langetojn" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "" +msgstr "InterÅanÄi langeton de sceno" #: editor/editor_node.cpp msgid "%d more files or folders" -msgstr "" +msgstr "%d plu dosiero(j) aÅ dosierujo(j)" #: editor/editor_node.cpp msgid "%d more folders" -msgstr "" +msgstr "%d plu dosierujo(j)" #: editor/editor_node.cpp msgid "%d more files" -msgstr "" +msgstr "%d plu dosiero(j)" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "" +msgstr "Pozicio de doko" #: editor/editor_node.cpp msgid "Distraction Free Mode" -msgstr "" +msgstr "Sendistra reÄimo" #: editor/editor_node.cpp msgid "Toggle distraction-free mode." -msgstr "" +msgstr "Baskuli sendistran reÄimon." #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "" +msgstr "Aldoni novan scenon." #: editor/editor_node.cpp msgid "Scene" @@ -2655,25 +2655,24 @@ msgid "Go to previously opened scene." msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Copy Text" -msgstr "Duplikati" +msgstr "Kopii la tekston" #: editor/editor_node.cpp msgid "Next tab" -msgstr "" +msgstr "Posta tabo" #: editor/editor_node.cpp msgid "Previous tab" -msgstr "" +msgstr "AntaÅa tabo" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "" +msgstr "Filtri dosierojn..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "" +msgstr "Operacioj kun scenaj dosieroj." #: editor/editor_node.cpp msgid "New Scene" @@ -2700,7 +2699,6 @@ msgid "Save All Scenes" msgstr "Konservi ĉiujn scenojn" #: editor/editor_node.cpp -#, fuzzy msgid "Convert To..." msgstr "Konverti al..." @@ -2710,7 +2708,7 @@ msgstr "MaÅo biblioteko..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "" +msgstr "TileSet..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -2842,9 +2840,8 @@ msgstr "" "agordo estas Åaltita." #: editor/editor_node.cpp -#, fuzzy msgid "Synchronize Scene Changes" -msgstr "Sinkronigi scenan ÅanÄojn" +msgstr "Sinkronigi ÅanÄojn en sceno" #: editor/editor_node.cpp #, fuzzy @@ -2859,9 +2856,8 @@ msgstr "" "Kiam uzantis malproksime en aparato, estas pli efika kun reta dosiersistemo." #: editor/editor_node.cpp -#, fuzzy msgid "Synchronize Script Changes" -msgstr "Sinkronigi skriptajn ÅanÄojn" +msgstr "Sinkronigi ÅanÄojn en skripto" #: editor/editor_node.cpp #, fuzzy @@ -2877,7 +2873,7 @@ msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "" +msgstr "Redaktilo" #: editor/editor_node.cpp msgid "Editor Settings..." @@ -2901,7 +2897,7 @@ msgstr "Baskuli plenekranon" #: editor/editor_node.cpp msgid "Toggle System Console" -msgstr "" +msgstr "Baskuli la konzolon de sistemo" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" @@ -2935,85 +2931,90 @@ msgstr "Enreta dokoj" #: editor/editor_node.cpp msgid "Q&A" -msgstr "" +msgstr "Demandoj kaj respondoj" #: editor/editor_node.cpp msgid "Report a Bug" -msgstr "" +msgstr "Raporti cimon" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Sendi rimarkojn pri la dokumentaro" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" -msgstr "" +msgstr "Komunumo" #: editor/editor_node.cpp msgid "About" +msgstr "Pri" + +#: editor/editor_node.cpp +msgid "Support Godot Development" msgstr "" #: editor/editor_node.cpp msgid "Play the project." -msgstr "" +msgstr "Stari la projekton." #: editor/editor_node.cpp msgid "Play" -msgstr "" +msgstr "Starti" #: editor/editor_node.cpp msgid "Pause the scene execution for debugging." -msgstr "" +msgstr "PaÅzi la plenumon de la sceno por sencimigo." #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "" +msgstr "PaÅzi scenon" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "" +msgstr "Halti la scenon." #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "" +msgstr "Starti la redaktantan scenon." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "" +msgstr "Starti scenon" #: editor/editor_node.cpp msgid "Play custom scene" -msgstr "" +msgstr "Starti propran scenon" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "" +msgstr "Starti propran scenon" #: editor/editor_node.cpp +#, fuzzy msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "ÅœanÄanto de la videa pelilo postulas rekomenci la redaktilon." #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp msgid "Save & Restart" -msgstr "" +msgstr "Konservi kaj rekomenci" #: editor/editor_node.cpp msgid "Spins when the editor window redraws." -msgstr "" +msgstr "Rotacius kiam la fenestron de la redaktilo redesegniÄi." #: editor/editor_node.cpp -#, fuzzy msgid "Update Continuously" -msgstr "Seninterrompa" +msgstr "Äœisdatigi kontinue" #: editor/editor_node.cpp +#, fuzzy msgid "Update When Changed" -msgstr "" +msgstr "Äœisdatigi kiam ÅanÄitis" #: editor/editor_node.cpp msgid "Hide Update Spinner" -msgstr "" +msgstr "KaÅi la Äisdatan indikilon" #: editor/editor_node.cpp msgid "FileSystem" @@ -3021,7 +3022,7 @@ msgstr "Dosiersistemo" #: editor/editor_node.cpp msgid "Inspector" -msgstr "" +msgstr "Inspektoro" #: editor/editor_node.cpp msgid "Expand Bottom Panel" @@ -3029,11 +3030,11 @@ msgstr "" #: editor/editor_node.cpp msgid "Output" -msgstr "" +msgstr "Eligo" #: editor/editor_node.cpp msgid "Don't Save" -msgstr "" +msgstr "Ne konservi" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." @@ -3109,48 +3110,47 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Select" -msgstr "" +msgstr "Elekti" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "" +msgstr "Malfermi 2D-an redaktilon" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "" +msgstr "Malfermi 3D-an redaktilon" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "" +msgstr "Malfermi la redaktilon de skripto" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "" +msgstr "Malfermi bibliotekon de havaĵo" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "" +msgstr "Malfermi la postan redaktilon" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "" +msgstr "Malfermi la antaÅan redaktilon" #: editor/editor_node.h -#, fuzzy msgid "Warning!" -msgstr "Avertoj" +msgstr "Avert!" #: editor/editor_path.cpp msgid "No sub-resources found." -msgstr "" +msgstr "Ne sub-risurcojn trovis." #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "" +msgstr "Kreas antaÅvidojn de maÅoj" #: editor/editor_plugin.cpp msgid "Thumbnail..." -msgstr "" +msgstr "Bildeto..." #: editor/editor_plugin_settings.cpp #, fuzzy @@ -3167,20 +3167,20 @@ msgstr "" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Update" -msgstr "" +msgstr "Äœisdatigi" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Version:" -msgstr "" +msgstr "Versio:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Author:" -msgstr "" +msgstr "AÅtoro:" #: editor/editor_plugin_settings.cpp msgid "Status:" -msgstr "" +msgstr "Stato:" #: editor/editor_plugin_settings.cpp msgid "Edit:" @@ -3188,43 +3188,43 @@ msgstr "" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "Mezuro:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "" +msgstr "Tempo kadre (sekundoj)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" -msgstr "" +msgstr "Meza tempo (sekundoj)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "" +msgstr "Kadro %" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "" +msgstr "Fiziko-kadro %" #: editor/editor_profiler.cpp msgid "Inclusive" -msgstr "" +msgstr "Inkluziva" #: editor/editor_profiler.cpp msgid "Self" -msgstr "" +msgstr "Memo" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "" +msgstr "Kadro #:" #: editor/editor_profiler.cpp msgid "Time" -msgstr "" +msgstr "Tempo" #: editor/editor_profiler.cpp msgid "Calls" -msgstr "" +msgstr "Alvokoj" #: editor/editor_properties.cpp msgid "Edit Text:" @@ -3252,7 +3252,7 @@ msgstr "" #: editor/editor_properties.cpp msgid "Invalid RID" -msgstr "" +msgstr "Malvalida RID" #: editor/editor_properties.cpp msgid "" @@ -3280,19 +3280,19 @@ msgstr "" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" -msgstr "" +msgstr "Nova skripto" #: editor/editor_properties.cpp editor/scene_tree_dock.cpp msgid "Extend Script" -msgstr "" +msgstr "Etendi skripton" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" -msgstr "" +msgstr "Nova %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" -msgstr "" +msgstr "Farigi unikan" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3306,11 +3306,11 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp #: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" -msgstr "" +msgstr "Alglui" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Convert To %s" -msgstr "" +msgstr "Konverti al %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Selected node is not a Viewport!" @@ -3318,28 +3318,28 @@ msgstr "" #: editor/editor_properties_array_dict.cpp msgid "Size: " -msgstr "" +msgstr "Grando: " #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "PaÄo: " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Item" -msgstr "" +msgstr "Forigi elementon" #: editor/editor_properties_array_dict.cpp msgid "New Key:" -msgstr "" +msgstr "Nova Ålosilo:" #: editor/editor_properties_array_dict.cpp msgid "New Value:" -msgstr "" +msgstr "Nova valoro:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "" +msgstr "Aldoni Ålosilo/valoro paro" #: editor/editor_run_native.cpp msgid "" @@ -3399,11 +3399,11 @@ msgstr "ReelÅuti" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "Malinstali" #: editor/export_template_manager.cpp msgid "(Installed)" -msgstr "" +msgstr "(Instalita)" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3412,15 +3412,15 @@ msgstr "ElÅuti" #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." -msgstr "" +msgstr "Oficaj eksportaj Åablonoj estas ne haveblaj por programistaj muntoj." #: editor/export_template_manager.cpp msgid "(Missing)" -msgstr "" +msgstr "(Manka)" #: editor/export_template_manager.cpp msgid "(Current)" -msgstr "" +msgstr "(Aktuala)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait..." @@ -3603,7 +3603,7 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Favorites" -msgstr "" +msgstr "Favoritaj" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." @@ -3636,19 +3636,19 @@ msgstr "" #: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp msgid "No name provided." -msgstr "" +msgstr "Ne nomon provizis." #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters." -msgstr "" +msgstr "Provizita nomo enhavas malvalidajn signojn." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "Dosiero aÅ dosierujo kun ĉi tiu nomo jam ekzistas." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "Nomo enhavas malvalidajn signojn." #: editor/filesystem_dock.cpp msgid "" @@ -3687,31 +3687,31 @@ msgstr "Konservi ĉiujn scenojn" #: editor/filesystem_dock.cpp msgid "Open Scenes" -msgstr "" +msgstr "Malfermi scenojn" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "Ekzemplodoni" #: editor/filesystem_dock.cpp msgid "Add to Favorites" -msgstr "" +msgstr "Aldoni al favoritaj" #: editor/filesystem_dock.cpp msgid "Remove from Favorites" -msgstr "" +msgstr "Forigi el favoritaj" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." -msgstr "" +msgstr "Redakti dependojn..." #: editor/filesystem_dock.cpp msgid "View Owners..." -msgstr "" +msgstr "Vidi posedojn..." #: editor/filesystem_dock.cpp msgid "Move To..." -msgstr "" +msgstr "Movi al..." #: editor/filesystem_dock.cpp msgid "New Scene..." @@ -3719,11 +3719,11 @@ msgstr "Nova sceno..." #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "New Script..." -msgstr "" +msgstr "Nova skripto..." #: editor/filesystem_dock.cpp msgid "New Resource..." -msgstr "" +msgstr "Nova risurco..." #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp @@ -3737,35 +3737,35 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Duplicate..." -msgstr "" +msgstr "Duobligi..." #: editor/filesystem_dock.cpp msgid "Move to Trash" -msgstr "" +msgstr "Movi al rubujo" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." -msgstr "" +msgstr "Renomi..." #: editor/filesystem_dock.cpp msgid "Previous Folder/File" -msgstr "" +msgstr "AntaÅa dosierujo/dosiero" #: editor/filesystem_dock.cpp msgid "Next Folder/File" -msgstr "" +msgstr "Posta dosierujo/dosiero" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "Reesplori dosiersistemo" +msgstr "Reesplori dosiersistemon" #: editor/filesystem_dock.cpp msgid "Toggle Split Mode" -msgstr "" +msgstr "Baskuli dividan reÄimon" #: editor/filesystem_dock.cpp msgid "Search files" -msgstr "Serĉi dosieroj" +msgstr "Serĉi dosierojn" #: editor/filesystem_dock.cpp msgid "" @@ -3775,7 +3775,7 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "Movi" #: editor/filesystem_dock.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -3970,20 +3970,19 @@ msgstr "Enportas scenon..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" -msgstr "" +msgstr "Naskas lummapojn" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "Naskas por maÅo: " #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Running Custom Script..." -msgstr "Rulas propra skripto..." +msgstr "Rulas propran skripton..." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "Ne elbe Åargis la post-enportan skripton:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" @@ -3999,17 +3998,15 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Saving..." -msgstr "" +msgstr "Konservas..." #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Select Importer" -msgstr "Selektu nodo(j)n por enporti" +msgstr "Elektu enportilon" #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Importer:" -msgstr "Enporti" +msgstr "Enportilo:" #: editor/import_defaults_editor.cpp msgid "Reset to Defaults" @@ -4034,7 +4031,7 @@ msgstr "" #: editor/import_dock.cpp msgid "Import As:" -msgstr "" +msgstr "Enporti kiel:" #: editor/import_dock.cpp msgid "Preset" @@ -4053,9 +4050,11 @@ msgid "Changing the type of an imported file requires editor restart." msgstr "" #: editor/import_dock.cpp +#, fuzzy msgid "" "WARNING: Assets exist that use this resource, they may stop loading properly." msgstr "" +"AVERTO: Havaĵoj ekzistas ke uzis ĉi tiu risurcon, ili povas ĉesi Åargi dece." #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4072,7 +4071,7 @@ msgstr "" #: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Save As..." -msgstr "" +msgstr "Konservi kiel..." #: editor/inspector_dock.cpp msgid "Copy Params" @@ -4294,7 +4293,7 @@ msgstr "" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Open Editor" -msgstr "" +msgstr "Malfermi la redaktilon" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4572,7 +4571,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "Animacio" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -4580,7 +4579,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Open in Inspector" -msgstr "" +msgstr "Malfermi en la Inspektoro" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." @@ -5580,7 +5579,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "" +msgstr "Vido" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Always Show Grid" @@ -6191,7 +6190,7 @@ msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Convert to CPUParticles" -msgstr "" +msgstr "Konverti al CPUParticles" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generating Visibility Rect" @@ -6207,7 +6206,7 @@ msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Convert to CPUParticles2D" -msgstr "" +msgstr "Konverti al CPUParticles2D" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -6643,7 +6642,7 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Open in Editor" -msgstr "" +msgstr "Malfermi en la Redaktilo" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Load Resource" @@ -6679,7 +6678,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Error saving file!" -msgstr "" +msgstr "Eraras konservi dosieron!" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme." @@ -6699,15 +6698,15 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "New Text File..." -msgstr "" +msgstr "Nova teksta dosiero..." #: editor/plugins/script_editor_plugin.cpp msgid "Open File" -msgstr "" +msgstr "Malfermi dosieron" #: editor/plugins/script_editor_plugin.cpp msgid "Save File As..." -msgstr "" +msgstr "Konservi dosieron kiel..." #: editor/plugins/script_editor_plugin.cpp msgid "Can't obtain the script for running." @@ -6740,7 +6739,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As..." -msgstr "" +msgstr "Konservi etoson kiel..." #: editor/plugins/script_editor_plugin.cpp msgid "%s Class Reference" @@ -6794,7 +6793,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "File" -msgstr "" +msgstr "Dosiero" #: editor/plugins/script_editor_plugin.cpp msgid "Open..." @@ -6806,11 +6805,11 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Save All" -msgstr "" +msgstr "Konservi tuton" #: editor/plugins/script_editor_plugin.cpp msgid "Soft Reload Script" -msgstr "" +msgstr "Varme reÅargi skripton" #: editor/plugins/script_editor_plugin.cpp msgid "Copy Script Path" @@ -6915,7 +6914,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "" +msgstr "Sencimigilo" #: editor/plugins/script_editor_plugin.cpp msgid "Search Results" @@ -7062,11 +7061,11 @@ msgstr "" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent to Spaces" -msgstr "" +msgstr "Konverti krommarÄenon al spacoj" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent to Tabs" -msgstr "" +msgstr "Konverti krommarÄenon al taboj" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" @@ -7505,7 +7504,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Transform" -msgstr "" +msgstr "Transformo" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Object to Floor" @@ -9454,7 +9453,7 @@ msgstr "" #: editor/project_export.cpp msgid "Script" -msgstr "" +msgstr "Skripto" #: editor/project_export.cpp msgid "Script Export Mode:" @@ -10391,7 +10390,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Instance Child Scene" -msgstr "" +msgstr "Ekzemplodoni infanan scenon" #: editor/scene_tree_dock.cpp msgid "Can't paste root node into the same scene." @@ -10496,7 +10495,7 @@ msgstr "Nova radiko de sceno" #: editor/scene_tree_dock.cpp msgid "Create Root Node:" -msgstr "" +msgstr "Krei radikan nodon:" #: editor/scene_tree_dock.cpp msgid "2D Scene" @@ -10628,10 +10627,12 @@ msgid "" "Instance a scene file as a Node. Creates an inherited scene if no root node " "exists." msgstr "" +"Ekzemplodoni scenan dosieron kiel Nodo. Kreus hereditan scenon se radika " +"nodo ne ekzistas." #: editor/scene_tree_dock.cpp msgid "Attach a new or existing script to the selected node." -msgstr "" +msgstr "Alfiksi novan aÅ ekzistantan skripton al la elektinta nodo." #: editor/scene_tree_dock.cpp msgid "Detach the script from the selected node." @@ -11515,7 +11516,7 @@ msgstr "" #: modules/visual_script/visual_script_editor.cpp msgid "Signals:" -msgstr "" +msgstr "Signaloj:" #: modules/visual_script/visual_script_editor.cpp #, fuzzy diff --git a/editor/translations/es.po b/editor/translations/es.po index e83d33e9fa..643fb16a57 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -60,12 +60,13 @@ # Lucasdelpiero <lucasdelpiero98@gmail.com>, 2021. # SteamGoblin <SteamGoblin860@gmail.com>, 2021. # Francisco C <pruebasfrancisco17@gmail.com>, 2021. +# Cam <cameron.toms@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-19 22:33+0000\n" -"Last-Translator: Francisco C <pruebasfrancisco17@gmail.com>\n" +"PO-Revision-Date: 2021-04-27 22:12+0000\n" +"Last-Translator: Cam <cameron.toms@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -658,7 +659,7 @@ msgstr "Usar Curvas Bezier" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" -msgstr "Optimizador de Animación" +msgstr "Optimizar animación" #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" @@ -865,7 +866,7 @@ msgstr "Eliminar" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "Añadir Argumento Extra de Llamada:" +msgstr "Añadir argumento extra de llamada:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" @@ -2074,7 +2075,7 @@ msgstr "Métodos" #: editor/editor_help.cpp msgid "Theme Properties" -msgstr "Propiedades del Tema" +msgstr "Propiedades de Temas" #: editor/editor_help.cpp msgid "Enumerations" @@ -2086,7 +2087,7 @@ msgstr "Constantes" #: editor/editor_help.cpp msgid "Property Descriptions" -msgstr "Descripciones de Propiedad" +msgstr "Descripciones de Propiedades" #: editor/editor_help.cpp msgid "(value)" @@ -2610,9 +2611,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "No se pudo cargar el script addon desde la ruta: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "No se puede cargar el script de addon desde la ruta: '%s' Parece que hay un " "error en el código, por favor compruebe la sintaxis." @@ -3065,6 +3068,10 @@ msgid "About" msgstr "Acerca de" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Reproducir el proyecto." @@ -5309,6 +5316,7 @@ msgstr "" "están contenidos dentro de la región cuadrangular [0,0,1,0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7647,6 +7655,8 @@ msgstr "Bloquear Rotación de Vista" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Para alejar más, cambia los planos de corte de la cámara (Vista -> " +"Configuración...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -11048,6 +11058,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Si está seleccionado, el panel de árbol de escena Remota provocará saltos de " +"framerate en el proyecto cada vez que se actualice.\n" +"Vuelve a seleccionar el árbol de escena Local para mejorar el rendimiento." #: editor/scene_tree_dock.cpp msgid "Local" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index d9e193da4e..5441d3def1 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -8,7 +8,7 @@ # Sebastian Silva <sebastian@sugarlabs.org>, 2016. # Jose Luis Bossio <joseluisbossio@gmail.com>, 2018. # Reynaldo Cruz <rcruz60@gmail.com>, 2018. -# Javier Ocampos <xavier.ocampos@gmail.com>, 2018, 2019, 2020. +# Javier Ocampos <xavier.ocampos@gmail.com>, 2018, 2019, 2020, 2021. # Andrés S <andres.segovia.dev@gmail.com>, 2019. # Florencia Menéndez <mariaflormz2@gmail.com>, 2019. # roger <616steam@gmail.com>, 2019, 2020. @@ -21,8 +21,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-31 03:53+0000\n" -"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" +"PO-Revision-Date: 2021-04-22 14:39+0000\n" +"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" "Language: es_AR\n" @@ -30,7 +30,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2564,9 +2564,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "No se pudo cargar el script de addon desde la ruta: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "No se pudo cargar el script de addon desde la ruta: '%s' Parece haber un " "error en el código. Por favor, revisá la sintaxis." @@ -3017,6 +3019,10 @@ msgid "About" msgstr "Acerca de" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Reproducir el proyecto." @@ -5260,6 +5266,7 @@ msgstr "" "contenidos dentro de la región cuadrada [0,0,1,0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7592,6 +7599,8 @@ msgstr "Rotación de Vista Trabada" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Para alejar más, cambiá los planos de corte de la cámara (Vista -> " +"Configuración...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -10992,6 +11001,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Al seleccionar, el panel de árbol de escena remota causará saltos de " +"framerate en el proyecto cada vez que se actualice.\n" +"Volvé a seleccionar escena local para mejorar el rendimiento." #: editor/scene_tree_dock.cpp msgid "Local" diff --git a/editor/translations/et.po b/editor/translations/et.po index de0b0360ee..e4b33e89a0 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2021-03-07 06:04+0000\n" +"PO-Revision-Date: 2021-05-10 15:32+0000\n" "Last-Translator: Kritzmensch <streef.gtx@gmail.com>\n" "Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/" "godot/et/>\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5.1\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2481,9 +2481,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Lisa-skripti ei olnud võimalik laadida teelt: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Lisa-skripti ei olnud võimalik laadida teelt: '%s'. Tundub, et koodis on " "viga, palun kontrolli süntaksi." @@ -2895,6 +2897,10 @@ msgid "About" msgstr "Teave" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Mängi projekti." @@ -4058,7 +4064,7 @@ msgstr "Filtreeri atribuudid" #: editor/inspector_dock.cpp msgid "Changes may be lost!" -msgstr "" +msgstr "Muudatused võivad kaduma minna!" #: editor/multi_node_edit.cpp msgid "MultiNode Set" diff --git a/editor/translations/eu.po b/editor/translations/eu.po index 421a255054..26f1c1a3bd 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -2449,8 +2449,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2855,6 +2856,10 @@ msgid "About" msgstr "Honi buruz" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index 4a1906f4e3..54cf408469 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -2491,8 +2491,9 @@ msgstr "امکان بارگیری اسکریپت Ø§ÙØ²ÙˆÙ†Ù‡ از مسیر وج #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2906,6 +2907,10 @@ msgid "About" msgstr "درباره" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "اجرای پروژه." diff --git a/editor/translations/fi.po b/editor/translations/fi.po index dd1d5da4e8..912e0f14f4 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -16,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-05 14:28+0000\n" -"Last-Translator: Severi Vidnäs <severi.vidnas@gmail.com>\n" +"PO-Revision-Date: 2021-05-18 10:00+0000\n" +"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" "Language: fi\n" @@ -25,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2540,11 +2540,13 @@ msgstr "Virhe ladattaessa lisäosaa polusta: '%s'." #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"Virhe ladattaessa lisäosaa polusta: '%s'. Koodissa vaikuttaa olevan virhe, " -"ole hyvä ja tarkista syntaksi." +"Lisäosaskriptin lataus ei onnistunut polusta: '%s'. Tämä saattaa johtua " +"koodivirheestä skriptissä.\n" +"Lisäosa '%s' poistetaan käytöstä tulevien virheiden estämiseksi." #: editor/editor_node.cpp msgid "" @@ -2983,6 +2985,10 @@ msgid "About" msgstr "Tietoja" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Käynnistä projekti." @@ -5216,6 +5222,7 @@ msgstr "" "välisen neliön alueella." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7545,6 +7552,8 @@ msgstr "Näkymän kierto lukittu" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Lähentääksesi tai loitontaaksesi enemmän, muuta kameran leikkaustasoja " +"(Näytä -> Asetukset...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -10935,6 +10944,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Jos tämä on valittuna, etäskenepuun telakka saa projektin nykimään aina " +"päivittyessään.\n" +"Vaihda takaisin paikallisen skenepuun telakkaan parantaaksesi suorituskykyä." #: editor/scene_tree_dock.cpp msgid "Local" @@ -13157,6 +13169,19 @@ msgid "Constants cannot be modified." msgstr "Vakioita ei voi muokata." #~ msgid "" +#~ "Godot editor was built without ray tracing support; lightmaps can't be " +#~ "baked.\n" +#~ "If you are using an Apple Silicon-based Mac, try forcing Rosetta " +#~ "emulation on Godot.app in the application settings\n" +#~ "then restart the editor." +#~ msgstr "" +#~ "Godot-editori on käännetty ilman ray tracing -tukea, joten lightmappeja " +#~ "ei voi kehittää.\n" +#~ "Jos käytät Apple Silicon -pohjaista Mac-tietokonetta, yritä pakottaa " +#~ "Rosetta-emulaatio Godot.app:iin sovelluksen asetuksissa\n" +#~ "ja käynnistä sitten editori uudestaan." + +#~ msgid "" #~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0." #~ msgstr "" #~ "InterpolatedCamera on vanhentunut ja poistetaan Godot 4.0 versiossa." diff --git a/editor/translations/fil.po b/editor/translations/fil.po index 99964e6ee8..525dc19561 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -2449,8 +2449,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2855,6 +2856,10 @@ msgid "About" msgstr "Tungkol" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 1ce05a4b93..95af6d8a20 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -78,12 +78,14 @@ # Joseph Boudou <joseph.boudou@matabio.net>, 2020. # Vincent Foulon <vincent.foulon80@gmail.com>, 2020. # TechnoPorg <jonah.janzen@gmail.com>, 2021. +# ASTRALE <jules.cercy@etu.univ-lyon1.fr>, 2021. +# Julien Vanelian <julienvanelian@hotmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-21 12:25+0000\n" -"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n" +"PO-Revision-Date: 2021-04-30 23:03+0000\n" +"Last-Translator: Julien Vanelian <julienvanelian@hotmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -91,7 +93,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.5.2-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -107,7 +109,7 @@ msgstr "Une chaîne de caractères de longueur 1 est attendue (un caractère)." #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "Pas assez d’octets pour le décodage, ou format non valide." +msgstr "Pas assez d’octets pour le décodage, ou format invalide." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -1244,7 +1246,7 @@ msgstr "Sponsors Bronze" #: editor/editor_about.cpp msgid "Mini Sponsors" -msgstr "Mini Sponsors" +msgstr "Petits Sponsors" #: editor/editor_about.cpp msgid "Gold Donors" @@ -2633,11 +2635,13 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"Impossible de charger le script de l’extension depuis le chemin : « %s ». Il " -"semble y avoir une erreur dans le code, merci de vérifier la syntaxe." +"Impossible de charger le script de l’extension depuis le chemin : « %s ». " +"Cela peut être dû à une erreur de programmation dans ce script.\n" +"L'extension « %s » a été désactivée pour prévenir de nouvelles erreures." #: editor/editor_node.cpp msgid "" @@ -3088,6 +3092,10 @@ msgid "About" msgstr "À propos" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "Soutenir le développement de Godot" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Lancer le projet." @@ -3194,7 +3202,7 @@ msgstr "" "personnalisé à l'exportation (ajout de modules, modification du fichier " "AndroidManifest.xml, etc.).\n" "Notez que pour faire des compilations personnalisées au lieu d'utiliser des " -"APKs pré-construits, l'option \"Use Custom Build\" doit être activée dans le " +"APKs préconstruits, l'option \"Use Custom Build\" doit être activée dans le " "Preset d'exportation Android." #: editor/editor_node.cpp @@ -5337,7 +5345,7 @@ msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" "L'éditeur Godot a été compilé sans support du ray tracing, les lightmaps ne " -"peuvent pas être pré-calculées." +"peuvent pas être précalculées." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" @@ -5345,7 +5353,7 @@ msgstr "Précalculer les lightmaps" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Select lightmap bake file:" -msgstr "Sélectionnez le fichier de pré-calcul de lightmap :" +msgstr "Sélectionnez le fichier de précalcul de lightmap :" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6315,7 +6323,7 @@ msgstr "" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Mesh Library" -msgstr "Mesh Library" +msgstr "Librairie de maillages" #: editor/plugins/mesh_library_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -7392,7 +7400,7 @@ msgstr "" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" -msgstr "Shader" +msgstr "Ombrage" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "This skeleton has no bones, create some children Bone2D nodes." @@ -7680,6 +7688,8 @@ msgstr "Rotation de la vue verrouillée" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Pour zoomer d'avantage, modifiez les plans de détourage de la caméra " +"(Affichage -> Paramètres...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -11088,6 +11098,10 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"S'il est sélectionné, le dock de l'arborescence de la scène distante sera " +"instable à chaque mise à jour de celui-ci.\n" +"Revenez au dock de l'arborescence de la scène locale afin d'améliorer les " +"performances." #: editor/scene_tree_dock.cpp msgid "Local" @@ -11789,7 +11803,7 @@ msgstr "" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Begin Bake" -msgstr "Commencer le pré-calcul" +msgstr "Commencer le précalcul" #: modules/lightmapper_cpu/lightmapper_cpu.cpp msgid "Preparing data structures" diff --git a/editor/translations/ga.po b/editor/translations/ga.po index 8a6c2a3f0b..cbecefd928 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -2444,8 +2444,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2850,6 +2851,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/gl.po b/editor/translations/gl.po index 771b0f07e6..0e30715772 100644 --- a/editor/translations/gl.po +++ b/editor/translations/gl.po @@ -5,18 +5,19 @@ # # Andy Barcia <andybarcia4@gmail.com>, 2021. # PokeGalaico <abloodyfreaks@gmail.com>, 2021. +# Kkai <kaieltroll@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2021-02-15 10:51+0000\n" -"Last-Translator: Andy Barcia <andybarcia4@gmail.com>\n" +"PO-Revision-Date: 2021-04-26 22:32+0000\n" +"Last-Translator: Kkai <kaieltroll@gmail.com>\n" "Language-Team: Galician <https://hosted.weblate.org/projects/godot-engine/" "godot/gl/>\n" "Language: gl\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -36,7 +37,7 @@ msgstr "" #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "Entrada inválida %i (non recibida) na expresión" +msgstr "Entrada inválida %i (non pasada) na expresión" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -659,11 +660,11 @@ msgstr "Engadir Clip de Pista de Audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "Cambiar Inicio do Clip na Pista de Audio" +msgstr "Cambiar Offset de Inicio de Clip de Pista de Audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "Cambiar Final do Clip na Pista de Audio" +msgstr "Cambiar Offset Final del Clip de Pista de Audio" #: editor/array_property_edit.cpp msgid "Resize Array" @@ -1278,7 +1279,7 @@ msgstr "Act./Desact. Silencio do Bus de Son" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "" +msgstr "Act./Desact. Bypass de Efectos do Bus de Son" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" @@ -1310,7 +1311,7 @@ msgstr "Silenciar" #: editor/editor_audio_buses.cpp msgid "Bypass" -msgstr "" +msgstr "Bypass" #: editor/editor_audio_buses.cpp msgid "Bus options" @@ -1445,11 +1446,11 @@ msgstr "Non debe coincidir co nome dunha constante global xa existente." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "Unha palabra clave non pode usarse como nome dun AutoCargador." +msgstr "A palabra clave non pode empregarse como nome dun AutoCargador." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "Xa existe un AutoCargador nomeado '%s'!" +msgstr "AutoCargador '%s' xa existe!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" @@ -1457,7 +1458,7 @@ msgstr "Renomear AutoCargador" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" -msgstr "" +msgstr "Act./Desact. Globais de AutoCargador" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" @@ -1502,7 +1503,7 @@ msgstr "Nome" #: editor/editor_autoload_settings.cpp msgid "Singleton" -msgstr "" +msgstr "Singleton" #: editor/editor_data.cpp editor/inspector_dock.cpp msgid "Paste Params" @@ -1560,7 +1561,7 @@ msgstr "Elixir" #: editor/editor_export.cpp msgid "Storing File:" -msgstr "Gardando Arquivo:" +msgstr "Almacenando Arquivo:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" @@ -1637,7 +1638,7 @@ msgstr "Non se encontrou un modelo de depuración personalizado." #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom release template not found." -msgstr "" +msgstr "Non se encontrou un modelo release personalizado." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" @@ -1665,15 +1666,15 @@ msgstr "Edición de Ãrbore de Escenas" #: editor/editor_feature_profile.cpp msgid "Node Dock" -msgstr "Panel de Nodos" +msgstr "Nodos" #: editor/editor_feature_profile.cpp msgid "FileSystem Dock" -msgstr "Panel de Sistema de Arquivos" +msgstr "Sistema de Arquivos" #: editor/editor_feature_profile.cpp msgid "Import Dock" -msgstr "Panel de Importación" +msgstr "Importación" #: editor/editor_feature_profile.cpp msgid "Erase profile '%s'? (no undo)" @@ -1732,11 +1733,11 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "Error saving profile to path: '%s'." -msgstr "Erro gardando o perfil á ruta: '%s'." +msgstr "Erro ao gardar o perfil na ruta: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Desactivar" #: editor/editor_feature_profile.cpp msgid "Current Profile:" @@ -1755,7 +1756,7 @@ msgstr "Novo" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "Importación" +msgstr "Importar" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -1763,15 +1764,15 @@ msgstr "Exportación" #: editor/editor_feature_profile.cpp msgid "Available Profiles:" -msgstr "Perfils Dispoñibles:" +msgstr "PerfÃs Dispoñibles:" #: editor/editor_feature_profile.cpp msgid "Class Options" -msgstr "Opcións de Clase" +msgstr "Opcións de Clases" #: editor/editor_feature_profile.cpp msgid "New profile name:" -msgstr "Nome do novo perfil:" +msgstr "Novo nome de perfil:" #: editor/editor_feature_profile.cpp msgid "Erase Profile" @@ -1783,7 +1784,7 @@ msgstr "Perfil de CaracterÃsticas de Godot" #: editor/editor_feature_profile.cpp msgid "Import Profile(s)" -msgstr "Importar Perfil(s)" +msgstr "Importar Perf(il/Ãs)" #: editor/editor_feature_profile.cpp msgid "Export Profile" @@ -1875,7 +1876,6 @@ msgid "Go Up" msgstr "Subir" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle Hidden Files" msgstr "Amosar/Ocultar Arquivos Ocultos" @@ -2001,7 +2001,6 @@ msgid "Methods" msgstr "Métodos" #: editor/editor_help.cpp -#, fuzzy msgid "Theme Properties" msgstr "Propiedades do Tema" @@ -2287,19 +2286,19 @@ msgstr "Non se pode sobreescribir escena que sigue aberta!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "" +msgstr "Non se pode cargar MeshLibrary para fusionarse!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "" +msgstr "Erro ao gardar MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "" +msgstr "Non se pode cargar TileSet para fusionarse!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "" +msgstr "Erro ao gardar TileSet!" #: editor/editor_node.cpp msgid "" @@ -2531,11 +2530,10 @@ msgstr "" "sintáctica da configuración de '%s'." #: editor/editor_node.cpp -#, fuzzy msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" "Non se puido encontrar o campo do Script na caracterÃstica adicional " -"(Plugin) en 'res://addons/%s'." +"(Plugin) en '%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." @@ -2543,9 +2541,11 @@ msgstr "" "Non se puido cargar Script de caracterÃstica adicional (Addon) na ruta: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Non se puido cargar Script de caracterÃstica adicional (Addon) na ruta: " "'%s'. Parece que hai un erro no código; por favor, comproba a sintaxe." @@ -2797,7 +2797,7 @@ msgstr "Exportar..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "Instalar plantilla de compilación de Android..." #: editor/editor_node.cpp msgid "Open Project Data Folder" @@ -2993,6 +2993,10 @@ msgid "About" msgstr "Acerca De" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Reproduce o proxecto." @@ -4055,9 +4059,8 @@ msgid "Select Importer" msgstr "Elixir Modo" #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Importer:" -msgstr "Importación" +msgstr "Importador:" #: editor/import_defaults_editor.cpp #, fuzzy @@ -9915,11 +9918,8 @@ msgid "Projects" msgstr "Proxectos" #: editor/project_manager.cpp -#, fuzzy msgid "Loading, please wait..." -msgstr "" -"Examinando arquivos,\n" -"Por favor, espere..." +msgstr "Cargando, por favor agarde..." #: editor/project_manager.cpp msgid "Last Modified" diff --git a/editor/translations/he.po b/editor/translations/he.po index 2966711057..bb16512835 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -19,12 +19,13 @@ # Guy Dadon <guydadon14@gmail.com>, 2020. # bruvzg <bruvzg13@gmail.com>, 2020. # Omer I.S. <omeritzicschwartz@gmail.com>, 2021. +# Ram Tourgeman <ramtorgeman@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-11 22:02+0000\n" -"Last-Translator: Omer I.S. <omeritzicschwartz@gmail.com>\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" +"Last-Translator: Ram Tourgeman <ramtorgeman@gmail.com>\n" "Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/" "godot/he/>\n" "Language: he\n" @@ -33,7 +34,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -212,9 +213,8 @@ msgid "3D Transform Track" msgstr "רצועת ×©×™× ×•×™ 3D" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Call Method Track" -msgstr "רצועת שיטה" +msgstr "רצועת קרי×ת ×¤×•× ×§×¦×™×”" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" @@ -462,7 +462,7 @@ msgstr "הוספת רצועות חדשות." #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "×”× ×ª×™×‘ לרצועה ××™× ×• תקין, ולכן מפתח לשיטה (מתודה) ×œ× ×™×›×œ להתווסף" #: editor/animation_track_editor.cpp #, fuzzy @@ -475,7 +475,7 @@ msgstr "×œ× × ×ž×¦××” מתודה בעצ×: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" -msgstr "" +msgstr "מפתחות הזזת ×× ×™×ž×¦×™×™×”" #: editor/animation_track_editor.cpp msgid "Clipboard is empty" @@ -487,7 +487,7 @@ msgstr "הדבקת רצועות" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "" +msgstr "×”× ×¤×©×” - ×©× ×” גודל של רצועות מפתח" #: editor/animation_track_editor.cpp msgid "" @@ -883,11 +883,11 @@ msgstr "× ×™×ª×•×§ '%s' מ-'%s'" #: editor/connections_dialog.cpp msgid "Disconnect all from signal: '%s'" -msgstr "" +msgstr "× ×ª×§ הכל מה×ות '%s'" #: editor/connections_dialog.cpp msgid "Connect..." -msgstr "" +msgstr "התחבר..." #: editor/connections_dialog.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -905,7 +905,7 @@ msgstr "עריכת חיבור:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" -msgstr "" +msgstr "×”×× ×תה בטוח ש×תה רוצה להסיר ×ת כל ×”×—×™×‘×•×¨×™× ×ž×”×ות \"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -918,7 +918,7 @@ msgstr "מ××¤×™×™× ×™ פריט." #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" -msgstr "" +msgstr "×”×× ×תה בטוח ש×תה רוצה להסיר ×ת כל ×”×—×™×‘×•×¨×™× ×ž×”×ות ×”×–×”?" #: editor/connections_dialog.cpp #, fuzzy @@ -935,7 +935,7 @@ msgstr "מעבר למתודה" #: editor/create_dialog.cpp msgid "Change %s Type" -msgstr "" +msgstr "×©× ×” ×ת הסוג של s%" #: editor/create_dialog.cpp editor/project_settings_editor.cpp msgid "Change" @@ -987,12 +987,16 @@ msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" +"×¡×¦× ×” 's%' × ×ž×¦×ת כרגע בעריכה.\n" +"×©×™× ×•×™×™× ×™×›× ×¡×• לתוקף ×‘×˜×¢×™× ×” מחדש." #: editor/dependency_editor.cpp msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" +"מש×ב 's%' × ×ž×¦× ×‘×©×™×ž×•×©.\n" +"×©×™× ×•×™×™× ×™×›× ×¡×• לתוקף רק ×‘×˜×¢×™× ×” מחדש." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -1036,7 +1040,7 @@ msgstr "פתיחה" #: editor/dependency_editor.cpp msgid "Owners Of:" -msgstr "" +msgstr "×‘×¢×œ×™× ×©×œ:" #: editor/dependency_editor.cpp #, fuzzy @@ -1105,7 +1109,7 @@ msgstr "מחיקה" #: editor/dependency_editor.cpp msgid "Owns" -msgstr "" +msgstr "בעליו של" #: editor/dependency_editor.cpp msgid "Resources Without Explicit Ownership:" @@ -2537,9 +2541,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "×œ× × ×™×ª×Ÿ לטעון סקריפט הרחבה ×ž× ×ª×™×‘: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "×œ× × ×™×ª×Ÿ לטעון סקריפט הרחבה ×ž× ×ª×™×‘: '%s' × ×¨××” שיש שגי××” בקוד, ×× × ×‘×“×•×§ ×ת " "התחביר." @@ -2974,6 +2980,10 @@ msgid "About" msgstr "על ×ודות" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "הרצת המיז×." @@ -6334,9 +6344,8 @@ msgid "Convert to CPUParticles" msgstr "המרה ל×ותיות גדולות" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Generating Visibility Rect" -msgstr "× ×•×¦×¨ ×ž×™×–× C#‎…" +msgstr "חולל × ×¨×ות ריבוע" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index 6c465ad015..cf1ab6d57a 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -13,12 +13,13 @@ # Abhay Patel <Traumaticbean@protonmail.com>, 2020. # Bishwajeet Parhi <bishwajeet.techmaster@gmail.com>, 2020. # l4KKY <greenforcesave@gmail.com>, 2020. +# harvinder rathor <harvinderr09@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-06 18:29+0000\n" -"Last-Translator: Shirious <sad3119823@gmail.com>\n" +"PO-Revision-Date: 2021-05-03 21:29+0000\n" +"Last-Translator: harvinder rathor <harvinderr09@gmail.com>\n" "Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/" "hi/>\n" "Language: hi\n" @@ -26,7 +27,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -759,9 +760,8 @@ msgid "Method in target node must be specified." msgstr "Method को target node में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कीजिà¤." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method name must be a valid identifier." -msgstr "Method को target node में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कीजिà¤." +msgstr "विधि नाम à¤à¤• मानà¥à¤¯ पहचानकरà¥à¤¤à¤¾ होना चाहिà¤à¥¤" #: editor/connections_dialog.cpp msgid "" @@ -901,9 +901,8 @@ msgid "Signals" msgstr "संकेत" #: editor/connections_dialog.cpp -#, fuzzy msgid "Filter signals" -msgstr "फ़िलà¥à¤Ÿà¤° फ़ाइलें..." +msgstr "सà¥à¤•à¥à¤°à¥€à¤¨à¤¿à¤‚ग सिगà¥à¤¨à¤²" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" @@ -1031,22 +1030,23 @@ msgid "Owners Of:" msgstr "के सà¥à¤µà¤¾à¤®à¥€:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Remove selected files from the project? (no undo)\n" "You can find the removed files in the system trash to restore them." -msgstr "परियोजना से चयनित फ़ाइलों को हटा दें? (बहाल नहीं किया जा सकता है)" +msgstr "" +"कà¥à¤¯à¤¾ आप पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ से चयनित फ़ाइल को हटाना चाहते हैं? (पूरà¥à¤µà¤µà¤¤ नहीं किया जा सकता है)\n" +"आप सिसà¥à¤Ÿà¤® रीसायकल बिन में हटाई गई फ़ाइलों को पà¥à¤¨à¤°à¥à¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ कर सकते हैं।" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "The files being removed are required by other resources in order for them to " "work.\n" "Remove them anyway? (no undo)\n" "You can find the removed files in the system trash to restore them." msgstr "" -"निकाली गई फ़ाइलों को दूसरे संसाधनों दà¥à¤µà¤¾à¤°à¤¾ उनके लिठकाम करने के लिठआवशà¥à¤¯à¤• है\n" -"वैसे à¤à¥€ उनà¥à¤¹à¥‡à¤‚ निकालें? (कोई पूरà¥à¤µà¤µà¤¤ नहीं)" +"हटाई जाने वाली फ़ाइल अनà¥à¤¯ संसाधनों पर निरà¥à¤à¤° है।\n" +"कà¥à¤¯à¤¾ आप अà¤à¥€ à¤à¥€ हटाना चाहते हैं? (पूरà¥à¤µà¤µà¤¤ नहीं किया जा सकता है)\n" +"आप सिसà¥à¤Ÿà¤® रीसायकल बिन में हटाई गई फ़ाइलों को पà¥à¤¨à¤°à¥à¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ कर सकते हैं।" #: editor/dependency_editor.cpp msgid "Cannot remove:" @@ -1156,9 +1156,8 @@ msgid "Silver Sponsors" msgstr "रजत पà¥à¤°à¤¾à¤¯à¥‹à¤œà¤•" #: editor/editor_about.cpp -#, fuzzy msgid "Bronze Sponsors" -msgstr "कांसà¥à¤¯ दाताओं" +msgstr "कांसà¥à¤¯ पà¥à¤°à¤¾à¤¯à¥‹à¤œà¤•" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -1598,34 +1597,31 @@ msgstr "" "निषà¥à¤•à¥à¤°à¤¿à¤¯ करे." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" -"GLES2 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. 'Import Etc' " -"को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे." +"लकà¥à¤·à¥à¤¯ मंच को GLES2 के \"PVRTC\" बनावट संपीड़न की आवशà¥à¤¯à¤•ता है। पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸ में \"आयात " +"Pvrtc\" सकà¥à¤·à¤® करें।" #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" -"GLES3 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC2' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. 'Import Etc " -"2' को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे." +"लकà¥à¤·à¥à¤¯ मंच को GLES2 के \"PVRTC\" बनावट संपीड़न की आवशà¥à¤¯à¤•ता है। पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸ में \"आयात " +"Pvrtc\" सकà¥à¤·à¤® करें।" #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'PVRTC' texture compression for the driver fallback " "to GLES2.\n" "Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"GLES2 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. \n" -"'Import Etc' को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे, या 'Driver Fallback Enabled' को " -"निषà¥à¤•à¥à¤°à¤¿à¤¯ करे." +"डà¥à¤°à¤¾à¤‡à¤µà¤° के लिठGLES2 पर वापस आने के लिठलकà¥à¤·à¥à¤¯ पà¥à¤²à¥‡à¤Ÿà¤«à¤¼à¥‰à¤°à¥à¤® को \"PVRTC\" बनावट संपीड़न की " +"आवशà¥à¤¯à¤•ता होती है।\n" +"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸ में \"आयात Pvrtc\" सकà¥à¤·à¤® करें, या \"डà¥à¤°à¤¾à¤‡à¤µà¤° फ़ॉलबैक सकà¥à¤·à¤®\" अकà¥à¤·à¤® करें।" #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1668,9 +1664,8 @@ msgid "Node Dock" msgstr "नोड डॉक" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "FileSystem Dock" -msgstr "फ़ाइल" +msgstr "फाइल सिसà¥à¤Ÿà¤® पैनल" #: editor/editor_feature_profile.cpp msgid "Import Dock" @@ -1755,7 +1750,7 @@ msgstr "नई" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "इंपोरà¥à¤Ÿ" +msgstr "आयात" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -1986,7 +1981,7 @@ msgstr "ऑनलाइन टà¥à¤¯à¥‚टोरियल" #: editor/editor_help.cpp msgid "Properties" -msgstr "पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ" +msgstr "विशेषता" #: editor/editor_help.cpp msgid "override:" @@ -1998,15 +1993,15 @@ msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤•:" #: editor/editor_help.cpp msgid "Methods" -msgstr "मेथड" +msgstr "तरीकों" #: editor/editor_help.cpp msgid "Theme Properties" -msgstr "थिम पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ" +msgstr "थीम विशेषता" #: editor/editor_help.cpp msgid "Enumerations" -msgstr "à¤à¤¨à¥à¤¯à¥à¤®à¤°à¥‡à¤¶à¤¨" +msgstr "गणना" #: editor/editor_help.cpp msgid "Constants" @@ -2316,9 +2311,8 @@ msgid "Layout name not found!" msgstr "लेआउट नाम नहीं मिला!" #: editor/editor_node.cpp -#, fuzzy msgid "Restored the Default layout to its base settings." -msgstr "आधार सेटिंगà¥à¤¸ के लिठडिफ़ॉलà¥à¤Ÿ लेआउट बहाल।" +msgstr "डिफ़ॉलà¥à¤Ÿ लेआउट को मूल सामगà¥à¤°à¥€ पर बहाल कर दिया गया है।" #: editor/editor_node.cpp msgid "" @@ -2374,7 +2368,7 @@ msgstr "चलाने के लिठकोई परिà¤à¤¾à¤·à¤¿à¤¤ दà #: editor/editor_node.cpp msgid "Save scene before running..." -msgstr "" +msgstr "अंजाम देने से पहले सीन को बचाà¤à¤‚ ..." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -2449,9 +2443,8 @@ msgid "Can't reload a scene that was never saved." msgstr "à¤à¤• दृशà¥à¤¯ है कि कà¤à¥€ नहीं बचाया गया था फिर से लोड नहीं कर सकते ।" #: editor/editor_node.cpp -#, fuzzy msgid "Reload Saved Scene" -msgstr "दृशà¥à¤¯ बचाओ" +msgstr "सहेजे गठदृशà¥à¤¯ को पà¥à¤¨à¤ƒ लोड करें" #: editor/editor_node.cpp msgid "" @@ -2518,18 +2511,19 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन को सकà¥à¤·à¤® करने में असमरà¥à¤¥: '%' कॉनà¥à¤«à¤¿à¤— का पारà¥à¤¸à¤¿à¤‚ग विफल रहा।" #: editor/editor_node.cpp -#, fuzzy msgid "Unable to find script field for addon plugin at: '%s'." -msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन के लिठसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ फ़ीलà¥à¤¡ खोजने में असमरà¥à¤¥: 'res://addons/% s'।" +msgstr "à¤à¤¡-इन का सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ फ़ीलà¥à¤¡ \"% s\" पर नहीं पाया जा सका।" #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' ।" #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "रासà¥à¤¤à¥‡ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '% à¤à¤¸' कोड में गड़बड़ी लगती है, कृपया सिंटेकà¥à¤¸ की " "जांच करें।" @@ -2815,12 +2809,10 @@ msgstr "" "इसे GDScript इसि मशीन पर डिबग करने के लिये इसे सकà¥à¤°à¤¿à¤¯ करने कि जरà¥à¤°à¤¤ नही|" #: editor/editor_node.cpp -#, fuzzy msgid "Small Deploy with Network Filesystem" -msgstr "नेटवरà¥à¤• à¤à¤«à¤à¤¸ के साथ छोटे तैनात" +msgstr "छोटी तैनाती के लिठनेटवरà¥à¤• फाइल सिसà¥à¤Ÿà¤® का उपयोग करें" #: editor/editor_node.cpp -#, fuzzy msgid "" "When this option is enabled, using one-click deploy for Android will only " "export an executable without the project data.\n" @@ -2829,70 +2821,67 @@ msgid "" "On Android, deploying will use the USB cable for faster performance. This " "option speeds up testing for projects with large assets." msgstr "" -"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो निरà¥à¤¯à¤¾à¤¤ या तैनाती नà¥à¤¯à¥‚नतम निषà¥à¤ªà¤¾à¤¦à¤¿à¤¤ उतà¥à¤ªà¤¾à¤¦à¤¨ करेगी।\n" -"नेटवरà¥à¤• के ऊपर संपादक दà¥à¤µà¤¾à¤°à¤¾ परियोजना से फाइलसिसà¥à¤Ÿà¤® उपलबà¥à¤§ कराया जाà¤à¤—ा।\n" -"à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ पर, तैनात तेजी से पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ के लिठयूà¤à¤¸à¤¬à¥€ केबल का उपयोग करेंगे । यह विकलà¥à¤ª à¤à¤• बड़े " -"पदचिहà¥à¤¨ के साथ खेल के लिठपरीकà¥à¤·à¤£ को गति देता है।" +"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो Android पर à¤à¤•-कà¥à¤²à¤¿à¤• परिनियोजन के दौरान निरà¥à¤¯à¤¾à¤¤ " +"की गई निषà¥à¤ªà¤¾à¤¦à¤¨ योगà¥à¤¯ फ़ाइल में पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डेटा नहीं होगा।\n" +"फ़ाइल सिसà¥à¤Ÿà¤® परियोजना पर आधारित नेटवरà¥à¤• पर संपादक दà¥à¤µà¤¾à¤°à¤¾ पà¥à¤°à¤¦à¤¾à¤¨ किया जाà¤à¤—ा।\n" +"Android पà¥à¤²à¥‡à¤Ÿà¤«à¥‰à¤°à¥à¤® पर, पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ में सà¥à¤§à¤¾à¤° के लिठà¤à¤• USB केबल के माधà¥à¤¯à¤® से तैनाती की जाà¤à¤—ी। " +"यदि पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ में बड़ी सामगà¥à¤°à¥€ है, तो यह विकलà¥à¤ª परीकà¥à¤·à¤£ की गति बढ़ा सकता है।" #: editor/editor_node.cpp msgid "Visible Collision Shapes" msgstr "दृशà¥à¤¯à¤®à¤¾à¤¨ टकराव आकार" #: editor/editor_node.cpp -#, fuzzy msgid "" "When this option is enabled, collision shapes and raycast nodes (for 2D and " "3D) will be visible in the running project." msgstr "" -"यदि यह विकलà¥à¤ª चालू हो जाता है तो टकराव के आकार और रेकासà¥à¤Ÿ नोडà¥à¤¸ (2डी और 3 डी के लिà¤) " -"चल रहे खेल पर दिखाई देंगे।" +"जब यह विकलà¥à¤ª चालू होता है, तो पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ निषà¥à¤ªà¤¾à¤¦à¤¿à¤¤ होने पर टकà¥à¤•र कà¥à¤·à¥‡à¤¤à¥à¤° और किरण नोडà¥à¤¸ (2D " +"और 3D) दिखाई देगा।" #: editor/editor_node.cpp msgid "Visible Navigation" msgstr "दरà¥à¤¶à¤¨à¥€à¤¯ नेविगेशन" #: editor/editor_node.cpp -#, fuzzy msgid "" "When this option is enabled, navigation meshes and polygons will be visible " "in the running project." -msgstr "यदि यह विकलà¥à¤ª चालू हो जाता है तो नेविगेशन मेशेस और बहà¥à¤à¥à¤œ चल रहे खेल पर दिखाई देंगे।" +msgstr "" +"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ चालू होने पर नेविगेशन गà¥à¤°à¤¿à¤¡ और बहà¥à¤à¥à¤œ दिखाई " +"देंगे।" #: editor/editor_node.cpp -#, fuzzy msgid "Synchronize Scene Changes" -msgstr "सिंक सीन बदलता है" +msgstr "दृशà¥à¤¯ संशोधन सिंकà¥à¤°à¤¨à¤¾à¤‡à¤œà¤¼ करें" #: editor/editor_node.cpp -#, fuzzy msgid "" "When this option is enabled, any changes made to the scene in the editor " "will be replicated in the running project.\n" "When used remotely on a device, this is more efficient when the network " "filesystem option is enabled." msgstr "" -"जब इस विकलà¥à¤ª को चालू किया जाता है, तो संपादक में दृशà¥à¤¯ में किठगठकिसी à¤à¥€ परिवरà¥à¤¤à¤¨ को " -"चल रहे खेल में दोहराया जाà¤à¤—ा।\n" -"जब किसी डिवाइस पर दूर से उपयोग किया जाता है, तो यह नेटवरà¥à¤• फाइलसिसà¥à¤Ÿà¤® के साथ अधिक " -"कà¥à¤¶à¤² होता है।" +"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो संपादक के दृशà¥à¤¯ में कोई à¤à¥€ बदलाव रनिंग पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ पर लागू " +"किया जाà¤à¤—ा।\n" +"यदि इसका उपयोग दूरसà¥à¤¥ डिवाइस पर किया जाता है, तो नेटवरà¥à¤• फ़ाइल सिसà¥à¤Ÿà¤® NFS का उपयोग " +"सरà¥à¤µà¤¶à¥à¤°à¥‡à¤·à¥à¤ पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ के लिठकिया जा सकता है।" #: editor/editor_node.cpp -#, fuzzy msgid "Synchronize Script Changes" -msgstr "सिंक सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ परिवरà¥à¤¤à¤¨" +msgstr "सिंक सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ संशोधन" #: editor/editor_node.cpp -#, fuzzy msgid "" "When this option is enabled, any script that is saved will be reloaded in " "the running project.\n" "When used remotely on a device, this is more efficient when the network " "filesystem option is enabled." msgstr "" -"जब यह विकलà¥à¤ª चालू हो जाà¤à¤—ा, तो सहेजी गई किसी à¤à¥€ सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ को चल रहे गेम पर फिर से लोड " -"किया जाà¤à¤—ा।\n" -"जब किसी डिवाइस पर दूर से उपयोग किया जाता है, तो यह नेटवरà¥à¤• फाइलसिसà¥à¤Ÿà¤® के साथ अधिक " -"कà¥à¤¶à¤² होता है।" +"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो किसी à¤à¥€ सहेजी गई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ को रनिंग पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ दà¥à¤µà¤¾à¤°à¤¾ " +"पà¥à¤¨à¤ƒ लोड किया जाà¤à¤—ा।\n" +"जब दूरसà¥à¤¥ उपकरणों में उपयोग किया जाता है, तो नेटवरà¥à¤• फ़ाइल सिसà¥à¤Ÿà¤® को सकà¥à¤·à¤® करना संपादन " +"दकà¥à¤·à¤¤à¤¾ में सà¥à¤§à¤¾à¤° कर सकता है।" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" @@ -2972,6 +2961,10 @@ msgid "About" msgstr "के बारे में" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ चलाà¤à¤‚।" @@ -3110,21 +3103,22 @@ msgid "Open & Run a Script" msgstr "ओपन à¤à¤‚ड रन à¤à¤• सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ" #: editor/editor_node.cpp -#, fuzzy msgid "" "The following files are newer on disk.\n" "What action should be taken?" -msgstr "निमà¥à¤¨ फ़ाइलों का निसà¥à¤¸à¤¾à¤°à¤£ नहीं हो पाया:" +msgstr "" +"डिसà¥à¤• पर निमà¥à¤¨ फ़ाइलें नई हैं।\n" +"कà¥à¤¯à¤¾ किया जाà¤?" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Reload" -msgstr "" +msgstr "पà¥à¤¨à¤ƒ लोड करें" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Resave" -msgstr "" +msgstr "पà¥à¤¨: सहेज" #: editor/editor_node.cpp msgid "New Inherited" @@ -3372,14 +3366,14 @@ msgid "Add Key/Value Pair" msgstr "कà¥à¤‚जी/मूलà¥à¤¯ जोड़ी जोड़ें" #: editor/editor_run_native.cpp -#, fuzzy msgid "" "No runnable export preset found for this platform.\n" "Please add a runnable preset in the Export menu or define an existing preset " "as runnable." msgstr "" -"इस मंच के लिठकोई रननयोगà¥à¤¯ निरà¥à¤¯à¤¾à¤¤ पूरà¥à¤µ निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं मिला।\n" -"कृपया निरà¥à¤¯à¤¾à¤¤ मेनू में à¤à¤• रननेबल पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ जोड़ें।" +"पà¥à¤²à¥‡à¤Ÿà¤«à¤¼à¥‰à¤°à¥à¤® के अनà¥à¤°à¥‚प कोई निषà¥à¤ªà¤¾à¤¦à¤¨ योगà¥à¤¯ पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ नहीं है।\n" +"कृपया निरà¥à¤¯à¤¾à¤¤ मेनू में à¤à¤• निषà¥à¤ªà¤¾à¤¦à¤¨ योगà¥à¤¯ पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ जोड़ें, या मौजूदा पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ को निषà¥à¤ªà¤¾à¤¦à¤¨ योगà¥à¤¯ के " +"रूप में सेट करें।" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -3649,6 +3643,7 @@ msgstr "" msgid "" "Importing has been disabled for this file, so it can't be opened for editing." msgstr "" +"इस फ़ाइल का आयात अकà¥à¤·à¤® कर दिया गया है, इसलिठइसे संपादन के लिठनहीं खोला जा सकता है।" #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." @@ -3780,9 +3775,8 @@ msgid "Duplicate..." msgstr "डà¥à¤ªà¥à¤²à¤¿à¤•ेट..." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Move to Trash" -msgstr "औटोलोड हिलाइये" +msgstr "टà¥à¤°à¥ˆà¤¶ में ले जाà¤à¤‚" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." @@ -3892,19 +3886,16 @@ msgid "Searching..." msgstr "खोज..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "%d मिल गया।" +msgstr "%d मैच, कà¥à¤² %d फाइलें।" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "%d मिल गया।" +msgstr "%d मिलान परिणाम (%d फ़ाइलों में)।" #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "%d मिल गया।" +msgstr "%d मैच, कà¥à¤² %d फाइलें।" #: editor/groups_editor.cpp msgid "Add to Group" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index dc71edeec3..a78a4f01c3 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -2456,8 +2456,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2862,6 +2863,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 2ef5783de9..76aaf2da96 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -2561,9 +2561,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Nem sikerült az addon szkript betöltése a következÅ‘ útvonalról: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Nem lehet betölteni az addon szkriptet a(z) '%s' útvonalról. Úgy tűnik, hiba " "történt a kódban, ellenÅ‘rizze a szintaxist." @@ -3007,6 +3009,10 @@ msgid "About" msgstr "Névjegy" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Projekt futtatása." diff --git a/editor/translations/id.po b/editor/translations/id.po index e97e193d0f..13ce1dba23 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -2561,9 +2561,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Tidak bisa memuat script addon dari lokasi: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Tidak dapat memuat script addon dari path: '%s' Mungkin ada kesalahan dalam " "kode, mohon periksa sintaks." @@ -3009,6 +3011,10 @@ msgid "About" msgstr "Tentang" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Mainkan proyek." @@ -5229,6 +5235,7 @@ msgstr "" "persegi [0.0,1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" diff --git a/editor/translations/is.po b/editor/translations/is.po index fd9e23d91b..693a6f9397 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -2481,8 +2481,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2890,6 +2891,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index d1b39155c9..e087489c94 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -57,12 +57,14 @@ # Ziv D <wizdavid@gmail.com>, 2020. # Riteo Siuga <lorenzocerqua@tutanota.com>, 2021. # Alessandro Mandelli <mandelli.alessandro@ngi.it>, 2021. +# Jusef Azzolina <rosarioazzolina33@gmail.com>, 2021. +# Daniele Basso <tiziodcaio@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-16 07:52+0000\n" -"Last-Translator: Marco Galli <mrcgll98@gmail.com>\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" +"Last-Translator: Riteo Siuga <lorenzocerqua@tutanota.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -70,7 +72,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -105,15 +107,15 @@ msgstr "Indice di tipo %s non valido per il tipo base %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "Nome dell'indice '%s' non valido per il tipo base %s" +msgstr "Nome dell'indice \"%s\" non valido per il tipo base %s" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" -msgstr "Argomenti non validi per costruire '%s'" +msgstr "Argomenti non validi per costruire \"%s\"" #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "Alla chiamata di '%s':" +msgstr "Alla chiamata di \"%s\":" #: core/ustring.cpp msgid "B" @@ -250,7 +252,7 @@ msgstr "Traccia di trasformazioni 3D" #: editor/animation_track_editor.cpp msgid "Call Method Track" -msgstr "Traccia di chiamate di metodo" +msgstr "Traccia di metodi" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" @@ -258,11 +260,11 @@ msgstr "Traccia di curve di Bézier" #: editor/animation_track_editor.cpp msgid "Audio Playback Track" -msgstr "Traccia di riproduzione audio" +msgstr "Traccia sonora" #: editor/animation_track_editor.cpp msgid "Animation Playback Track" -msgstr "Traccia di riproduzione di animazioni" +msgstr "Traccia di animazioni" #: editor/animation_track_editor.cpp msgid "Animation length (frames)" @@ -385,7 +387,7 @@ msgstr "Cambia la modalità d'interpolazione di un'animazione" #: editor/animation_track_editor.cpp msgid "Change Animation Loop Mode" -msgstr "Cambia Modalità Loop Animazione" +msgstr "Cambia la modalità del ciclo di un'animazione" #: editor/animation_track_editor.cpp msgid "Remove Anim Track" @@ -397,7 +399,7 @@ msgstr "Creare una NUOVA traccia per %s e inserire la chiave?" #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "Crea %d NUOVE tracce ed inserire fotogrammi chiave?" +msgstr "Creare %d NUOVE tracce e inserirci i fotogrammi chiavi?" #: editor/animation_track_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp @@ -417,19 +419,19 @@ msgstr "Inserisci un'animazione" #: editor/animation_track_editor.cpp msgid "AnimationPlayer can't animate itself, only other players." -msgstr "AnimationPlayer può solo animare altri riproduttori, non se stesso." +msgstr "AnimationPlayer non può animare se stesso, solo altri nodi." #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" -msgstr "Crea & Inserisci Animazione" +msgstr "Crea un'animazione e inserisci un fotogramma chiave" #: editor/animation_track_editor.cpp msgid "Anim Insert Track & Key" -msgstr "Inserisci Traccia e Fotogramma Chiave Animazione" +msgstr "Inserisci un traccia con un fotogramma chiave in un'animazione" #: editor/animation_track_editor.cpp msgid "Anim Insert Key" -msgstr "Inserisci Fotogramma Chiave Animazione" +msgstr "Inserisci un fotogramma chiave in un'animazione" #: editor/animation_track_editor.cpp msgid "Change Animation Step" @@ -442,8 +444,7 @@ msgstr "Riordina delle tracce" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." msgstr "" -"Le tracce di trasformazione possono essere applicate soltanto ai nodi basati " -"sul nodo Spatial." +"Le tracce di trasformazioni 3D si applicano solo a nodi di tipo Spatial." #: editor/animation_track_editor.cpp msgid "" @@ -460,14 +461,11 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Animation tracks can only point to AnimationPlayer nodes." msgstr "" -"Le tracce di riproduzione di animazioni possono puntare solo a nodi di tipo " -"AnimationPlayer." +"Le tracce di animazioni possono puntare solo a nodi di tipo AnimationPlayer." #: editor/animation_track_editor.cpp msgid "An animation player can't animate itself, only other players." -msgstr "" -"Un riproduttore di animazioni può solo animare altri riproduttori, non se " -"stesso." +msgstr "Un AnimationPlayer non può animare se stesso, solo altri riproduttori." #: editor/animation_track_editor.cpp msgid "Not possible to add a new track without a root" @@ -475,7 +473,8 @@ msgstr "Non è possibile aggiungere una nuova traccia senza un nodo radice" #: editor/animation_track_editor.cpp msgid "Invalid track for Bezier (no suitable sub-properties)" -msgstr "Traccia non valida per Bezier (nessuna sotto-proprietà valida)" +msgstr "" +"Traccia non valida per una curva di Bézier (nessuna sotto-proprietà adatta)" #: editor/animation_track_editor.cpp msgid "Add Bezier Track" @@ -500,12 +499,12 @@ msgstr "Aggiungi una chiave a una traccia" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." msgstr "" -"La traccia non è valida, quindi, non è stato possibile aggiungere una chiave " -"chiamata metodo." +"La traccia non è valida, quindi non è stato possibile aggiungere una chiave " +"di metodo." #: editor/animation_track_editor.cpp msgid "Add Method Track Key" -msgstr "Aggiungi una chiave a una traccia di chiamate di metodi" +msgstr "Aggiungi una chiave a una traccia di chiamate metodi" #: editor/animation_track_editor.cpp msgid "Method not found in object: " @@ -521,11 +520,11 @@ msgstr "Gli appunti sono vuoti" #: editor/animation_track_editor.cpp msgid "Paste Tracks" -msgstr "Incolla Tracce" +msgstr "Incolla delle tracce" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "Scala Chiavi Animazione" +msgstr "Scala delle chiavi d'animazione" #: editor/animation_track_editor.cpp msgid "" @@ -546,23 +545,24 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" -"Questa animazione appartiene ad una scena importata, quindi i cambiamenti " -"alle tracce importate non saranno salvate.\n" +"Quest'animazione appartiene a una scena importata, eventuali modifiche fatte " +"alle tracce importate non verranno salvate.\n" "\n" -"Per abilitare l'aggiunta di tracce personalizzate, naviga alle impostazioni " -"d'importazione della scena ed imposta\n" -"\"Animation > Storage\" a \"Files\", abilita \"Animation > Keep Custom Tracks" -"\", e poi re-importa.\n" -"In alternativa, usa un preset d'importo che importa le animazioni da file " -"separati." +"Per abilitare la possibilità di aggiungere ulteriori tracce, è necessario " +"andare nelle impostazioni d'importazione della scena, impostare\n" +"\"Animation > Storage\" su \"Files\", attivare \"Animation > Keep Custom " +"Tracks\" e infine reimportare la scena.\n" +"In alternativa è possibile usare una preimpostazione che importi le " +"animazioni in file separati." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "Attenzione: stai modificando un'animazione importata" +msgstr "Attenzione: sta venendo modificata un'animazione importata" #: editor/animation_track_editor.cpp msgid "Select an AnimationPlayer node to create and edit animations." -msgstr "Seleziona un nodo AnimationPlayer per creare e modificare animazioni." +msgstr "" +"Selezionare un nodo AnimationPlayer per creare e modificare animazioni." #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -621,7 +621,7 @@ msgstr "Duplica la selezione" #: editor/animation_track_editor.cpp msgid "Duplicate Transposed" -msgstr "Duplica Trasposto" +msgstr "Duplica trasposto" #: editor/animation_track_editor.cpp msgid "Delete Selection" @@ -629,11 +629,11 @@ msgstr "Elimina la selezione" #: editor/animation_track_editor.cpp msgid "Go to Next Step" -msgstr "Vai allo Step Successivo" +msgstr "Vai al passo successivo" #: editor/animation_track_editor.cpp msgid "Go to Previous Step" -msgstr "Vai allo Step Precedente" +msgstr "Vai al passo precedente" #: editor/animation_track_editor.cpp msgid "Optimize Animation" @@ -657,15 +657,15 @@ msgstr "Ottimizzatore anim." #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" -msgstr "Max Errore Lineare:" +msgstr "Max errore lineare:" #: editor/animation_track_editor.cpp msgid "Max. Angular Error:" -msgstr "Max Errore Angolare:" +msgstr "Max errore angolare:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "Max Angolo Ottimizzabile:" +msgstr "Max angolo ottimizzabile:" #: editor/animation_track_editor.cpp msgid "Optimize" @@ -710,47 +710,47 @@ msgstr "Copia" #: editor/animation_track_editor.cpp msgid "Select All/None" -msgstr "De/Seleziona Tutto" +msgstr "Seleziona/Deseleziona tutto" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" -msgstr "Aggiungi audio in una traccia di riproduzione audio" +msgstr "Aggiungi audio in una traccia sonora" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "Cambia Offset Inizio Clip Traccia Audio" +msgstr "Cambia lo scostamento dell'inizio della traccia audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "Cambia Offset Fine Clip Traccia Audio" +msgstr "Cambia lo scostamento della fine della traccia audio" #: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "Ridimensiona Array" +msgstr "Ridimensiona lista" #: editor/array_property_edit.cpp msgid "Change Array Value Type" -msgstr "Cambia Tipo Valore Array" +msgstr "Cambia il tipo del valore della lista" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "Cambia Valore Array" +msgstr "Cambia il valore della lista" #: editor/code_editor.cpp msgid "Go to Line" -msgstr "Vai alla Linea" +msgstr "Vai alla linea" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "Numero Linea:" +msgstr "Numero della linea:" #: editor/code_editor.cpp msgid "%d replaced." -msgstr "%d rimpiazzato." +msgstr "%d sostituito." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "%d corrispondenza." +msgstr "%d corrispondenze." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." @@ -758,11 +758,11 @@ msgstr "%d corrispondenze." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "Distingui Maiuscole" +msgstr "Maiuscole distinte" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" -msgstr "Parole Intere" +msgstr "Parole intere" #: editor/code_editor.cpp msgid "Replace" @@ -770,11 +770,11 @@ msgstr "Sostituisci" #: editor/code_editor.cpp msgid "Replace All" -msgstr "Rimpiazza Tutti" +msgstr "Sostituisci tutti" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "Solo Selezione" +msgstr "Solo nella selezione" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp @@ -783,7 +783,7 @@ msgstr "Standard" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "Toggle Pannello Script" +msgstr "Commuta il pannello degli script" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -799,7 +799,7 @@ msgstr "Rimpicciolisci" #: editor/code_editor.cpp msgid "Reset Zoom" -msgstr "Reimposta ingrandimento" +msgstr "Reimposta l'ingrandimento" #: editor/code_editor.cpp msgid "Warnings" @@ -822,8 +822,8 @@ msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Metodo di destinazione non trovato. Specifica un metodo valido o attribuisci " -"uno script al nodo di destinazione." +"Metodo di destinazione non trovato. Specifica un metodo valido o assegna uno " +"script al nodo di destinazione." #: editor/connections_dialog.cpp msgid "Connect to Node:" @@ -831,11 +831,11 @@ msgstr "Connetti al Nodo:" #: editor/connections_dialog.cpp msgid "Connect to Script:" -msgstr "Connetti allo Script:" +msgstr "Connetti allo script:" #: editor/connections_dialog.cpp msgid "From Signal:" -msgstr "Dal Segnale:" +msgstr "Dal segnale:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." @@ -860,15 +860,15 @@ msgstr "Rimuovi" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "Aggiungi argomento extra di chiamata:" +msgstr "Aggiungi un argomento di chiamata aggiuntivo:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" -msgstr "Argomenti chiamata extra:" +msgstr "Argomenti di chiamata aggiuntivi:" #: editor/connections_dialog.cpp msgid "Receiver Method:" -msgstr "Metodo Ricevitore:" +msgstr "Metodo ricevitore:" #: editor/connections_dialog.cpp msgid "Advanced" @@ -882,8 +882,8 @@ msgstr "Differita" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" -"Differisce il segnale memorizzandolo in una coda ed emettendolo in fase di " -"inattività ." +"Differisce il segnale memorizzandolo in una coda ed emettendolo in fase " +"d'inattività ." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -921,15 +921,15 @@ msgstr "Segnale:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" -msgstr "Connetti '%s' a '%s'" +msgstr "Connetti \"%s\" a \"%s\"" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" -msgstr "Disconnetti '%s' da '%s'" +msgstr "Disconnetti \"%s\" da \"%s\"" #: editor/connections_dialog.cpp msgid "Disconnect all from signal: '%s'" -msgstr "Disconnetti tutto dal segnale: '%s'" +msgstr "Disconnetti tutto dal segnale: \"%s\"" #: editor/connections_dialog.cpp msgid "Connect..." @@ -942,11 +942,11 @@ msgstr "Disconnetti" #: editor/connections_dialog.cpp msgid "Connect a Signal to a Method" -msgstr "Connetti un Segnale a un Metodo" +msgstr "Connetti un segnale a un metodo" #: editor/connections_dialog.cpp msgid "Edit Connection:" -msgstr "Modifica Connessione:" +msgstr "Modifica una connessione:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -962,7 +962,7 @@ msgstr "Filtra segnali" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" -msgstr "Sei sicuro di voler rimuovere tutte le connessioni da questo segnale?" +msgstr "Confermare la rimozione di tutte le connessioni da questo segnale?" #: editor/connections_dialog.cpp msgid "Disconnect All" @@ -974,11 +974,11 @@ msgstr "Modifica..." #: editor/connections_dialog.cpp msgid "Go To Method" -msgstr "Va' al metodo" +msgstr "Vai al metodo" #: editor/create_dialog.cpp msgid "Change %s Type" -msgstr "Cambia tipo di %s" +msgstr "Cambia il tipo di %s" #: editor/create_dialog.cpp editor/project_settings_editor.cpp msgid "Change" @@ -986,7 +986,7 @@ msgstr "Cambia" #: editor/create_dialog.cpp msgid "Create New %s" -msgstr "Crea nuovo %s" +msgstr "Crea un nuovo %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -1030,16 +1030,16 @@ msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"La scena '%s' è al momento in modifica.\n" -"I cambiamenti avranno effetto quando sarà ricaricata." +"La scena \"%s\" sta venendo modificata in questo momento.\n" +"I cambiamenti avranno effetto solo una volta ricaricata." #: editor/dependency_editor.cpp msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"La risorsa '%s' è in uso.\n" -"I cambiamenti avranno effetto quando sarà ricaricata." +"La risorsa \"%s\" è in uso.\n" +"I cambiamenti avranno effetto una volta ricaricata." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -1061,11 +1061,11 @@ msgstr "Dipendenze:" #: editor/dependency_editor.cpp msgid "Fix Broken" -msgstr "Ripara rotti" +msgstr "Ripara le dipendenze rotte" #: editor/dependency_editor.cpp msgid "Dependency Editor" -msgstr "Editor Dipendenze" +msgstr "Editor di dipendenze" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" @@ -1090,8 +1090,8 @@ msgid "" "Remove selected files from the project? (no undo)\n" "You can find the removed files in the system trash to restore them." msgstr "" -"Rimuovere i file selezionati dal progetto? (Non può essere annullato)\n" -"Puoi trovare i file rimossi nel cestino di sistema per ripristinarli." +"Rimuovere i file selezionati dal progetto? (non annullabile)\n" +"Sarà possibile ripristinarli accedendo al cestino di sistema." #: editor/dependency_editor.cpp msgid "" @@ -1103,7 +1103,7 @@ msgstr "" "I file che stanno per essere rimossi sono richiesti per il funzionamento di " "altre risorse.\n" "Rimuoverli comunque? (non annullabile)\n" -"Puoi trovare i file rimossi nel cestino di sistema per ripristinarli." +"Sarà possibile ripristinarli accedendo al cestino di sistema." #: editor/dependency_editor.cpp msgid "Cannot remove:" @@ -1127,19 +1127,19 @@ msgstr "Quale azione deve essere intrapresa?" #: editor/dependency_editor.cpp msgid "Fix Dependencies" -msgstr "Ripara dipendenze" +msgstr "Ripara delle dipendenze" #: editor/dependency_editor.cpp msgid "Errors loading!" -msgstr "Errori in caricamento!" +msgstr "Errori durante il caricamento!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "Eliminare permanentemente %d elementi? (Non annullabile!)" +msgstr "Eliminare definitivamente %d elementi? (Non annullabile!)" #: editor/dependency_editor.cpp msgid "Show Dependencies" -msgstr "Mostra Dipendenze" +msgstr "Mostra le dipendenze" #: editor/dependency_editor.cpp msgid "Orphan Resource Explorer" @@ -1159,15 +1159,15 @@ msgstr "Possiede" #: editor/dependency_editor.cpp msgid "Resources Without Explicit Ownership:" -msgstr "Risorse senza proprietario esplicito:" +msgstr "Risorse senza un proprietario esplicito:" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Key" -msgstr "Cambia Chiave Dizionario" +msgstr "Cambia una chiave di un dizionario" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Value" -msgstr "Cambia valore del dizionario" +msgstr "Cambia il valore di un dizionario" #: editor/editor_about.cpp msgid "Thanks from the Godot community!" @@ -1175,7 +1175,7 @@ msgstr "Grazie dalla comunità di Godot!" #: editor/editor_about.cpp msgid "Godot Engine contributors" -msgstr "Contributori di Godot engine" +msgstr "Contributori di Godot Engine" #: editor/editor_about.cpp msgid "Project Founders" @@ -1190,7 +1190,7 @@ msgstr "Sviluppatore principale" #. you do not have to keep it in your translation. #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Gestore progetto " +msgstr "Gestore del progetto " #: editor/editor_about.cpp msgid "Developers" @@ -1210,11 +1210,11 @@ msgstr "Sponsor oro" #: editor/editor_about.cpp msgid "Silver Sponsors" -msgstr "Sponsor Argento" +msgstr "Sponsor argento" #: editor/editor_about.cpp msgid "Bronze Sponsors" -msgstr "Sponsor Bronzo" +msgstr "Sponsor bronzo" #: editor/editor_about.cpp msgid "Mini Sponsors" @@ -1242,7 +1242,7 @@ msgstr "Licenza" #: editor/editor_about.cpp msgid "Third-party Licenses" -msgstr "Licenza di terze parti" +msgstr "Licenze di terze parti" #: editor/editor_about.cpp msgid "" @@ -1251,14 +1251,14 @@ msgid "" "is an exhaustive list of all such third-party components with their " "respective copyright statements and license terms." msgstr "" -"Godot Engine si basa su parecchie librerie gratuite ed open source, tutte " -"compatibili con i termini della licenza MIT dell'engine. Qui di seguito " -"trovi una lista esaustiva di tutti i componenti di terze parti con le " -"rispettive dichiarazioni sui diritti d'autore e termini di licenza." +"Godot Engine dipende da molte librerie di terze parti gratuite e aperte, " +"tutte compatibili con i termini della sua licenza MIT. Qui di seguito una " +"lista esaustiva di tutti i componenti di terze parti con le rispettive " +"dichiarazioni sui loro diritti d'autore e termini di licenza." #: editor/editor_about.cpp msgid "All Components" -msgstr "Tutte le componenti" +msgstr "Tutti i componenti" #: editor/editor_about.cpp msgid "Components" @@ -1270,7 +1270,7 @@ msgstr "Licenze" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Error opening package file, not in ZIP format." -msgstr "Errore nell'apertura del file package: non è in formato ZIP." +msgstr "Errore nell'apertura del file del pacchetto, non è in formato ZIP." #: editor/editor_asset_installer.cpp msgid "%s (Already Exists)" @@ -1282,7 +1282,7 @@ msgstr "Estrazione asset" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "The following files failed extraction from package:" -msgstr "Impossibile estrarre i file seguenti dal pacchetto:" +msgstr "Impossibile estrarre i seguenti file dal pacchetto:" #: editor/editor_asset_installer.cpp msgid "And %s more files." @@ -1307,7 +1307,7 @@ msgstr "Installa" #: editor/editor_asset_installer.cpp msgid "Package Installer" -msgstr "Installatore pacchetto" +msgstr "Installatore di pacchetti" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -1327,11 +1327,11 @@ msgstr "Cambia il volume del bus audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "Imposta bus audio su solo" +msgstr "Commuta lo stato di solista di un bus audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "Imposta bus audio su Muto" +msgstr "Commuta l'ammutolimento di un bus audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" @@ -1343,15 +1343,15 @@ msgstr "Seleziona invio del bus audio" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" -msgstr "Aggiungi un effetto bus audio" +msgstr "Aggiungi un effetto a un bus audio" #: editor/editor_audio_buses.cpp msgid "Move Bus Effect" -msgstr "Sposta effetti bus" +msgstr "Sposta un effetto di un bus" #: editor/editor_audio_buses.cpp msgid "Delete Bus Effect" -msgstr "Cancella effetto bus" +msgstr "Cancella un effetto di un bus" #: editor/editor_audio_buses.cpp msgid "Drag & drop to rearrange." @@ -1359,7 +1359,7 @@ msgstr "Trascina e rilascia per riordinare." #: editor/editor_audio_buses.cpp msgid "Solo" -msgstr "Solo" +msgstr "Solista" #: editor/editor_audio_buses.cpp msgid "Mute" @@ -1371,7 +1371,7 @@ msgstr "Bypassa" #: editor/editor_audio_buses.cpp msgid "Bus options" -msgstr "Opzioni bus" +msgstr "Opzioni del bus" #: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -1380,11 +1380,11 @@ msgstr "Duplica" #: editor/editor_audio_buses.cpp msgid "Reset Volume" -msgstr "Ripristina volume" +msgstr "Ripristina il volume" #: editor/editor_audio_buses.cpp msgid "Delete Effect" -msgstr "Elimina effetto" +msgstr "Elimina l'effetto" #: editor/editor_audio_buses.cpp msgid "Audio" @@ -1392,7 +1392,7 @@ msgstr "Audio" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" -msgstr "Aggiungi bus audio" +msgstr "Aggiungi un bus audio" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" @@ -1400,23 +1400,23 @@ msgstr "Il bus principale non può essere cancellato!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" -msgstr "Elimina bus audio" +msgstr "Elimina un bus audio" #: editor/editor_audio_buses.cpp msgid "Duplicate Audio Bus" -msgstr "Duplica bus audio" +msgstr "Duplica un bus audio" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "Ripristina volume del Bus" +msgstr "Ripristina il volume di un bus" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" -msgstr "Sposta bus audio" +msgstr "Sposta un bus audio" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "Salva disposizione del bus audio come..." +msgstr "Salva la disposizione del bus audio come..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." @@ -1424,11 +1424,11 @@ msgstr "Posizione per la nuova disposizione..." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "Apri disposizione bus audio" +msgstr "Apri la disposizione di un bus audio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "File '%s' assente." +msgstr "File \"%s\" assente." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1440,7 +1440,7 @@ msgstr "File non valido, non è una disposizione di un bus audio." #: editor/editor_audio_buses.cpp msgid "Error saving file: %s" -msgstr "Errore nel salvataggio file: %s" +msgstr "Errore nel salvataggio del file: %s" #: editor/editor_audio_buses.cpp msgid "Add Bus" @@ -1458,7 +1458,7 @@ msgstr "Carica" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." -msgstr "Carica una disposizione bus esistente." +msgstr "Carica una disposizione di bus esistente." #: editor/editor_audio_buses.cpp msgid "Save As" @@ -1466,19 +1466,19 @@ msgstr "Salva come" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "Salva questa disposizione bus in un file." +msgstr "Salva questa disposizione di bus in un file." #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" -msgstr "Carica Predefiniti" +msgstr "Carica i predefiniti" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "Carica la disposizione dei bus predefinita." +msgstr "Carica la disposizione di bus predefinita." #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "Crea una nuova disposizione dei bus." +msgstr "Crea una nuova disposizione di bus." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1490,29 +1490,27 @@ msgstr "Caratteri validi:" #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing engine class name." -msgstr "" -"Non deve essere in conflitto con un nome di una classe esistente dell'engine." +msgstr "Non deve collidere con il nome di una classe del motore esistente." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing built-in type name." -msgstr "Non deve essere in conflitto con un nome di tipo built-in esistente." +msgstr "Non deve collidere con il nome di un tipo built-in esistente." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing global constant name." -msgstr "" -"Non deve essere in conflitto con un nome di una costante globale esistente." +msgstr "Non deve collidere con il nome di una costante globale esistente." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "La parola chiave non può essere utilizzata come nome di un Autoload." +msgstr "Una parola chiave non può essere utilizzata come nome di un Autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "Autoload '%s' esiste già !" +msgstr "L'Autoload \"%s\" esiste già !" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" -msgstr "Rinomina Autoload" +msgstr "Rinomina un Autoload" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" @@ -1520,11 +1518,11 @@ msgstr "Commuta AutoLoad globals" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" -msgstr "Sposta Autoload" +msgstr "Sposta un Autoload" #: editor/editor_autoload_settings.cpp msgid "Remove Autoload" -msgstr "Rimuovi Autoload" +msgstr "Rimuovi un Autoload" #: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" @@ -1540,7 +1538,7 @@ msgstr "Non è possibile aggiungere l'autoload:" #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" -msgstr "Aggiungi Autoload" +msgstr "Aggiungi un Autoload" #: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp @@ -1551,7 +1549,7 @@ msgstr "Percorso:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" -msgstr "Nome nodo:" +msgstr "Nome del nodo:" #: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp #: editor/editor_profiler.cpp editor/project_manager.cpp @@ -1565,11 +1563,11 @@ msgstr "Singleton" #: editor/editor_data.cpp editor/inspector_dock.cpp msgid "Paste Params" -msgstr "Incolla Parametri" +msgstr "Incolla dei parametri" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "Aggiornamento scena" +msgstr "Aggiornamento della scena" #: editor/editor_data.cpp msgid "Storing local changes..." @@ -1593,13 +1591,13 @@ msgstr "Si prega di selezionare prima una cartella di base." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" -msgstr "Scegli una cartella" +msgstr "Scegliere una cartella" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp #: scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "Crea cartella" +msgstr "Crea una cartella" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -1623,7 +1621,7 @@ msgstr "Memorizzazione file:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" -msgstr "Nessun modello di esportazione trovato nel percorso previsto:" +msgstr "Nessun modello d'esportazione trovato nel percorso previsto:" #: editor/editor_export.cpp msgid "Packing" @@ -1634,16 +1632,16 @@ msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" -"La piattaforma di destinazione richiede la compressione 'ETC' delle texture " -"per GLES2. Attiva 'Import Etc' nelle impostazioni del progetto." +"La piattaforma di destinazione richiede la compressione \"ETC\" delle " +"texture per GLES2. Attiva \"Import Etc\" nelle impostazioni del progetto." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" -"La piattaforma di destinazione richiede la compressione 'ETC2' delle texture " -"per GLES3. Attiva 'Import Etc 2' nelle impostazioni del progetto." +"La piattaforma di destinazione richiede la compressione \"ETC2\" delle " +"texture per GLES3. Attiva \"Import Etc 2\" nelle impostazioni del progetto." #: editor/editor_export.cpp msgid "" @@ -1652,26 +1650,26 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"La piattaforma di destinazione richiede la compressione 'ETC' delle texture " -"per il fallback del driver a GLES2.\n" -"Attivare 'Import Etc' nelle impostazioni del progetto, oppure disattivare " -"'Driver Fallback Enabled'." +"La piattaforma di destinazione richiede la compressione \"ETC\" delle " +"texture per il fallback del driver a GLES2.\n" +"Attivare \"Import Etc\" nelle impostazioni del progetto, oppure disattivare " +"\"Driver Fallback Enabled\"." #: editor/editor_export.cpp msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" -"La piattaforma di destinazione richiede la compressione 'PVRTC' delle " -"texture per GLES2. Attiva 'Import Pvrtc' nelle impostazioni del progetto." +"La piattaforma di destinazione richiede la compressione \"PVRTC\" delle " +"texture per GLES2. Attivare \"Import Pvrtc\" nelle impostazioni del progetto." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" -"La piattaforma di destinazione richiede la compressione 'ETC2' o 'PVRTC' " -"delle texture per GLES3. Attiva 'Import Etc 2' oppure 'Import Pvrtc' nelle " +"La piattaforma di destinazione richiede la compressione \"ETC2\" o \"PVRTC\" " +"delle texture per GLES3. Attivare \"Import Etc 2\" o \"Import Pvrtc\" nelle " "impostazioni del progetto." #: editor/editor_export.cpp @@ -1681,31 +1679,32 @@ msgid "" "Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"La piattaforma di destinazione richiede la compressione 'PVRTC' delle " +"La piattaforma di destinazione richiede la compressione \"PVRTC\" delle " "texture per il fallback del driver a GLES2.\n" -"Attiva 'Import Pvrtc' nelle impostazioni del progetto, oppure disattiva " -"'Driver Fallback Enabled'." +"Attiva \"Import Pvrtc\" nelle impostazioni del progetto, oppure disattiva " +"\"Driver Fallback Enabled\"." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom debug template not found." -msgstr "Modello di debug personalizzato non trovato." +msgstr "Modello di sviluppo personalizzato non trovato." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom release template not found." -msgstr "Modello di release personalizzato non trovato." +msgstr "Modello di rilascio personalizzato non trovato." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" -msgstr "Modello non trovato:" +msgstr "File del modello non trovato:" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." msgstr "" -"Su export di 32-bit il PCK integrato non può essere più grande di 4 GiB." +"Il PCK integrato non può essere più grande di 4 GiB nelle esportazioni a 32 " +"bit." #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -1725,23 +1724,24 @@ msgstr "Editor delle scene" #: editor/editor_feature_profile.cpp msgid "Node Dock" -msgstr "Nodo" +msgstr "Riquadro dei nodi" #: editor/editor_feature_profile.cpp msgid "FileSystem Dock" -msgstr "Riquadro FileSystem" +msgstr "Riquadro del FileSystem" #: editor/editor_feature_profile.cpp msgid "Import Dock" -msgstr "Importa" +msgstr "Riquadro d'importazione" #: editor/editor_feature_profile.cpp msgid "Erase profile '%s'? (no undo)" -msgstr "Eliminare il profilo '%s'? (non annullabile)" +msgstr "Eliminare il profilo \"%s\"? (non annullabile)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "Il profilo deve essere un nome di file valido e non può contenere '.'" +msgstr "" +"Il profilo deve essere un nome di file valido e non può contenere \".\"" #: editor/editor_feature_profile.cpp msgid "Profile with this name already exists." @@ -1781,19 +1781,19 @@ msgstr "Classi abilitate:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "Il formato del file '%s' non è valido, importazione annullata." +msgstr "Il formato del file \"%s\" non è valido, importazione annullata." #: editor/editor_feature_profile.cpp msgid "" "Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" -"Il profilo '%s' è già presente, rimuovilo prima dell'importazione. " +"Il profilo \"%s\" è già presente, rimuoverlo prima dell'importazione. " "Operazione annullata." #: editor/editor_feature_profile.cpp msgid "Error saving profile to path: '%s'." -msgstr "Errore di salvataggio del profilo nel percorso: '%s'." +msgstr "Errore di salvataggio del profilo nel percorso: \"%s\"." #: editor/editor_feature_profile.cpp msgid "Unset" @@ -1801,7 +1801,7 @@ msgstr "Disattiva" #: editor/editor_feature_profile.cpp msgid "Current Profile:" -msgstr "Profilo corrente:" +msgstr "Profilo attuale:" #: editor/editor_feature_profile.cpp msgid "Make Current" @@ -1816,7 +1816,7 @@ msgstr "Nuovo" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "Importare" +msgstr "Importazione" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -1836,23 +1836,23 @@ msgstr "Nome del nuovo profilo:" #: editor/editor_feature_profile.cpp msgid "Erase Profile" -msgstr "Cancella profilo" +msgstr "Cancella il profilo" #: editor/editor_feature_profile.cpp msgid "Godot Feature Profile" -msgstr "Profilo Caratteristiche Godot" +msgstr "Profilo di funzionalità di Godot" #: editor/editor_feature_profile.cpp msgid "Import Profile(s)" -msgstr "Importa profili" +msgstr "Importa i profili" #: editor/editor_feature_profile.cpp msgid "Export Profile" -msgstr "Esporta profilo" +msgstr "Esporta il profilo" #: editor/editor_feature_profile.cpp msgid "Manage Editor Feature Profiles" -msgstr "Gestisci i profili delle funzionalità dell'editor" +msgstr "Gestisci i profili di funzionalità dell'editor" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1868,16 +1868,16 @@ msgstr "Seleziona questa cartella" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" -msgstr "Copia percorso" +msgstr "Copia il percorso" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Open in File Manager" -msgstr "Apri nel gestore file" +msgstr "Apri nel gestore dei file" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp msgid "Show in File Manager" -msgstr "Mostra nel gestore file" +msgstr "Mostra nel gestore dei file" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "New Folder..." @@ -1902,7 +1902,7 @@ msgstr "Apri un file" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open File(s)" -msgstr "Apri file" +msgstr "Apri i file" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a Directory" @@ -1937,15 +1937,15 @@ msgstr "Vai su" #: editor/editor_file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "Mostra/nascondi file nascosti" +msgstr "Commuta la visibilità dei file nascosti" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "Attiva/disattiva preferito" +msgstr "Commuta preferito" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" -msgstr "Commuta Modalità " +msgstr "Commuta la modalità " #: editor/editor_file_dialog.cpp msgid "Focus Path" @@ -1953,11 +1953,11 @@ msgstr "Metti a fuoco il percorso" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" -msgstr "Sposta preferito in su" +msgstr "Sposta il preferito su" #: editor/editor_file_dialog.cpp msgid "Move Favorite Down" -msgstr "Sposta preferito in giù" +msgstr "Sposta il preferito giù" #: editor/editor_file_dialog.cpp msgid "Go to previous folder." @@ -1969,23 +1969,23 @@ msgstr "Vai alla cartella successiva." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Go to parent folder." -msgstr "Va' alla cartella superiore." +msgstr "Vai alla cartella superiore." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Refresh files." -msgstr "Ricarica files." +msgstr "Ricarica i file." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." -msgstr "Aggiungi/rimuovi cartella attuale dai preferiti." +msgstr "Aggiungi/rimuovi la cartella attuale dai preferiti." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle the visibility of hidden files." -msgstr "Attiva/disattiva visibilità dei file nascosti." +msgstr "Commuta la visibilità dei file nascosti." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "Visualizza elementi in una griglia di miniature." +msgstr "Visualizza gli elementi in una griglia di miniature." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." @@ -2291,23 +2291,24 @@ msgstr "Errore durante il salvataggio." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." msgstr "" -"Impossibile aprire '%s'. Il file potrebbe essere stato spostato o eliminato." +"Impossibile aprire \"%s\". Il file potrebbe essere stato spostato o " +"eliminato." #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "Errore durante l'elaborazione di '%s'." +msgstr "Errore durante l'elaborazione di \"%s\"." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "Fine del file '%s' non prevista." +msgstr "Fine del file \"%s\" non prevista." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "'%s' mancante o dipendenze mancanti." +msgstr "\"%s\" mancante o dipendenze mancanti." #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "Errore durante il caricamento di '%s'." +msgstr "Errore durante il caricamento di \"%s\"." #: editor/editor_node.cpp msgid "Saving Scene" @@ -2479,7 +2480,7 @@ msgstr "Salva e chiudi" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" -msgstr "Salvare le modifiche a '%s' prima di chiudere?" +msgstr "Salvare le modifiche a \"%s\" prima di chiudere?" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." @@ -2590,47 +2591,49 @@ msgstr "Riapri la scena chiusa" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" -"Impossibile abilitare il componente aggiuntivo in: '%s' lettura della " +"Impossibile abilitare il componente aggiuntivo in: \"%s\" lettura della " "configurazione fallita." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: '%s'." msgstr "" -"Impossibile trovare il campo script per il plugin addon in posizione: '%s'." +"Impossibile trovare il campo script per il plugin addon in posizione: \"%s\"." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." msgstr "" -"Impossibile caricare lo script di un componente aggiuntivo dal percorso: " -"'%s'." +"Impossibile caricare lo script di un componente aggiuntivo dal percorso: \"%s" +"\"." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"Impossibile caricare uno script aggiuntivo dal percorso: '%s' Sembra esserci " -"un errore nel codice, controlla la sintassi." +"Impossibile caricare uno script aggiuntivo dal percorso: \"%s\" Sembra " +"esserci un errore nel codice, controlla la sintassi." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" "Impossibile caricare uno script aggiuntivo dal percorso: La tipologia di " -"base di '%s' non è EditorPlugin." +"base di \"%s\" non è EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" -"Impossibile caricare lo script di un componente aggiuntivo dal percorso: " -"'%s' Lo script non è in modalità strumento." +"Impossibile caricare lo script di un componente aggiuntivo dal percorso: \"%s" +"\" Lo script non è in modalità strumento." #: editor/editor_node.cpp msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" -"La scena '%s' è stata automaticamente importata, pertanto non può essere " +"La scena \"%s\" è stata automaticamente importata, pertanto non può essere " "modificata.\n" "Per modificarla, può essere creata una nuova scena ereditata." @@ -2640,12 +2643,12 @@ msgid "" "open the scene, then save it inside the project path." msgstr "" "Errore di caricamento della scena, deve essere all'interno del percorso del " -"progetto. Usare 'Importa' per aprire la scena e salvarla nel percorso del " +"progetto. Usare \"Importa\" per aprire la scena e salvarla nel percorso del " "progetto." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "La scena '%s' ha rotto le dipendenze:" +msgstr "La scena \"%s\" ha rotto le dipendenze:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" @@ -2659,7 +2662,7 @@ msgid "" msgstr "" "Non è stata definita alcuna scena principale, selezionarne una?\n" "Potrai cambiarla successivamente da \"Impostazioni progetto\" sotto la " -"categoria 'applicazioni'." +"categoria \"applicazioni\"." #: editor/editor_node.cpp msgid "" @@ -2667,9 +2670,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"La scena selezionata '%s' non esiste, sceglierne una valida?\n" +"La scena selezionata \"%s\" non esiste, sceglierne una valida?\n" "Puoi cambiarla successivamente da \"Impostazioni progetto\" sotto la " -"categoria 'applicazioni'." +"categoria \"applicazioni\"." #: editor/editor_node.cpp msgid "" @@ -2677,9 +2680,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"La scena selezionata '%s non è un file scena, sceglierne una valida?\n" +"La scena selezionata \"%s non è un file scena, sceglierne una valida?\n" "Puoi cambiarla successivamente da \"Impostazioni progetto\" sotto la " -"categoria 'applicazioni'." +"categoria \"applicazioni\"." #: editor/editor_node.cpp msgid "Save Layout" @@ -3057,6 +3060,10 @@ msgid "About" msgstr "Informazioni su Godot" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Esegui il progetto." @@ -3488,7 +3495,7 @@ msgstr "Impossibile istanziare script:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "Hai dimenticato la keyword 'tool'?" +msgstr "Hai dimenticato la keyword \"tool\"?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" @@ -3496,7 +3503,7 @@ msgstr "Impossibile eseguire lo script:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "Hai dimenticato il metodo '_run'?" +msgstr "Hai dimenticato il metodo \"_run\"?" #: editor/editor_spin_slider.cpp msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." @@ -3557,7 +3564,7 @@ msgstr "Recupero dei mirror, attendi..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" -msgstr "Rimuovere versione '%s' del template?" +msgstr "Rimuovere versione \"%s\" del template?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." @@ -3643,7 +3650,7 @@ msgid "" "The problematic templates archives can be found at '%s'." msgstr "" "Installazione del template fallita.\n" -"Gli archivi dei template problematici possono essere trovati qui: '%s'." +"Gli archivi dei template problematici possono essere trovati qui: \"%s\"." #: editor/export_template_manager.cpp msgid "Error requesting URL:" @@ -3749,6 +3756,8 @@ msgstr "" msgid "" "Importing has been disabled for this file, so it can't be opened for editing." msgstr "" +"L'importazione è stata disabilitata per questo file, perciò non possiamo " +"aprirlo per modificarlo." #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." @@ -3796,7 +3805,7 @@ msgid "" "Do you wish to overwrite them?" msgstr "" "I seguenti file o cartelle vanno in conflitto con gli oggetti nel percorso " -"di destinazione '%s':\n" +"di destinazione \"%s\":\n" "\n" "%s\n" "\n" @@ -3970,7 +3979,7 @@ msgstr "Trova..." #: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp msgid "Replace..." -msgstr "Rimpiazza..." +msgstr "Sostituisci..." #: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" @@ -4153,7 +4162,7 @@ msgstr "Ripristinare le impostazioni predefinite" #: editor/import_dock.cpp msgid "Keep File (No Import)" -msgstr "" +msgstr "Mantieni il file ( Non importare)" #: editor/import_dock.cpp msgid "%d Files" @@ -4161,11 +4170,11 @@ msgstr "%d File" #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "Imposta come Predefinito per '%s'" +msgstr "Imposta come Predefinito per \"%s\"" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "Elimina Predefinito per '%s'" +msgstr "Elimina Predefinito per \"%s\"" #: editor/import_dock.cpp msgid "Import As:" @@ -5273,7 +5282,7 @@ msgid "" "Light' flag is on." msgstr "" "Nessuna mesh da preprocessare. Assicurarsi che contengano un canale UV2 e " -"che la spunta 'Bake Light' sia abilitata." +"che la spunta \"Bake Light\" sia abilitata." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed creating lightmap images, make sure path is writable." @@ -5296,6 +5305,7 @@ msgstr "" "all'interno nella regione [0.0,1.0] quadra." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -5607,8 +5617,8 @@ msgstr "Alt+Drag: Muovi" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" -"Premi 'v' per Cambiare Perno, 'Shift+v' per Trascinare il Pernno (durante lo " -"spostamento)." +"Premi \"v\" per Cambiare Perno, \"Shift+v\" per Trascinare il Pernno " +"(durante lo spostamento)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" @@ -6468,7 +6478,7 @@ msgstr "Sorgente Emissione: " #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." -msgstr "Un processor material di tipo 'ParticlesMaterial' é richiesto." +msgstr "Un processor material di tipo \"ParticlesMaterial\" é richiesto." #: editor/plugins/particles_editor_plugin.cpp msgid "Generating AABB" @@ -7159,7 +7169,8 @@ msgstr "Target" msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." msgstr "" -"Manca il metodo connesso '%s' per il segnale '%s' dal nodo '%s' al nodo '%s'." +"Manca il metodo connesso \"%s\" per il segnale \"%s\" dal nodo \"%s\" al " +"nodo \"%s\"." #: editor/plugins/script_text_editor.cpp msgid "[Ignore]" @@ -7181,7 +7192,7 @@ msgstr "Solo le risorse dal filesystem possono essere eliminate." #: modules/visual_script/visual_script_editor.cpp msgid "Can't drop nodes because script '%s' is not used in this scene." msgstr "" -"Impossibile rilasciare i nodi perché lo script '%s' non è usato in questa " +"Impossibile rilasciare i nodi perché lo script \"%s\" non è usato in questa " "scena." #: editor/plugins/script_text_editor.cpp @@ -9065,7 +9076,7 @@ msgstr "Uniforme booleana." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for all shader modes." -msgstr "Parametro di input '%s' per tutte le modalità shader." +msgstr "Parametro di input \"%s\" per tutte le modalità shader." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Input parameter." @@ -9073,27 +9084,27 @@ msgstr "Parametro di input." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex and fragment shader modes." -msgstr "Parametro di input '%s' per le modalità shader vertice e frammento." +msgstr "Parametro di input \"%s\" per le modalità shader vertice e frammento." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for fragment and light shader modes." -msgstr "Parametro di input '%s' per le modalità shader frammento e luce." +msgstr "Parametro di input \"%s\" per le modalità shader frammento e luce." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for fragment shader mode." -msgstr "Parametro di input '%s' per la modalità shader frammento." +msgstr "Parametro di input \"%s\" per la modalità shader frammento." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for light shader mode." -msgstr "Parametro di input '%s' per la modalità shader luce." +msgstr "Parametro di input \"%s\" per la modalità shader luce." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex shader mode." -msgstr "Parametro di input '%s' per la modalità shader vertice." +msgstr "Parametro di input \"%s\" per la modalità shader vertice." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex and fragment shader mode." -msgstr "Parametro di input '%s' per la modalità shader vertice e frammento." +msgstr "Parametro di input \"%s\" per la modalità shader vertice e frammento." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Scalar function." @@ -9290,9 +9301,9 @@ msgid "" msgstr "" "SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" "\n" -"Restituisce 0.0 se 'x' è più piccolo di 'edge0', o 1.0 se 'x' è più grande " -"di 'edge1'. Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 " -"usando i polinomi di Hermite." +"Restituisce 0.0 se \"x\" è più piccolo di \"edge0\", o 1.0 se \"x\" è più " +"grande di \"edge1\". Altrimenti, il valore di ritorno è interpolato tra 0.0 " +"ed 1.0 usando i polinomi di Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9302,7 +9313,7 @@ msgid "" msgstr "" "Step function( scalar(edge), scalar(x) ).\n" "\n" -"Restituisce 0.0 se 'x' è più piccolo di 'edge', altrimenti 1.0." +"Restituisce 0.0 se \"x\" è più piccolo di \"edge\", altrimenti 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." @@ -9380,11 +9391,12 @@ msgid "" msgstr "" "Calcola il prodotto esterno di una coppia di vettori.\n" "\n" -"OuterProduct considera il primo parametro 'c' come un vettore colonna " -"(matrice con una colonna) ed il secondo, 'r', come un vettore riga (matrice " -"con una riga) ed esegue una moltiplicazione algebrica lineare di matrici 'c " -"* r', creando una matrice i cui numeri di righe sono il numero di componenti " -"di 'c' e le cui colonne sono il numero di componenti in 'r'." +"OuterProduct considera il primo parametro \"c\" come un vettore colonna " +"(matrice con una colonna) ed il secondo, \"r\", come un vettore riga " +"(matrice con una riga) ed esegue una moltiplicazione algebrica lineare di " +"matrici \"c * r\", creando una matrice i cui numeri di righe sono il numero " +"di componenti di \"c\" e le cui colonne sono il numero di componenti in \"r" +"\"." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." @@ -9509,8 +9521,8 @@ msgid "" msgstr "" "SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" "\n" -"Restituisce 0.0 se 'x' è minore di 'edge0', ed 1.0 se 'x' è più grande di " -"'edge1'. Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 " +"Restituisce 0.0 se \"x\" è minore di \"edge0\", ed 1.0 se \"x\" è più grande " +"di \"edge1\". Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 " "usando i polinomiali di Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9523,8 +9535,8 @@ msgid "" msgstr "" "SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" "\n" -"Restituisce 0.0 se 'x' è minore di 'edge0', ed 1.0 se 'x' è più grande di " -"'edge1'. Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 " +"Restituisce 0.0 se \"x\" è minore di \"edge0\", ed 1.0 se \"x\" è più grande " +"di \"edge1\". Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 " "usando i polinomiali di Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9535,7 +9547,7 @@ msgid "" msgstr "" "Step function( vector(edge), vector(x) ).\n" "\n" -"Restituisce 0.0 se 'x' è minore di 'edge', altrimenti 1.0." +"Restituisce 0.0 se \"x\" è minore di \"edge\", altrimenti 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9545,7 +9557,7 @@ msgid "" msgstr "" "Step function( scalar(edge), vector(x) ).\n" "\n" -"Restituisce 0.0 se 'x' è minore di 'edge', altrimenti 1.0." +"Restituisce 0.0 se \"x\" è minore di \"edge\", altrimenti 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." @@ -9623,7 +9635,7 @@ msgid "" "(Fragment/Light mode only) (Vector) Derivative in 'x' using local " "differencing." msgstr "" -"(Solo modalità Fragment/Light) (Vettore) Derivata in 'x' usando la " +"(Solo modalità Fragment/Light) (Vettore) Derivata in \"x\" usando la " "differenziazione locale." #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9631,7 +9643,7 @@ msgid "" "(Fragment/Light mode only) (Scalar) Derivative in 'x' using local " "differencing." msgstr "" -"(Solo modalità Fragment/Light) (Scalare) Derivata in 'x' usando la " +"(Solo modalità Fragment/Light) (Scalare) Derivata in \"x\" usando la " "differeziazione locale." #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9639,7 +9651,7 @@ msgid "" "(Fragment/Light mode only) (Vector) Derivative in 'y' using local " "differencing." msgstr "" -"(Soltanto modalità Fragment/Light) (Vettore) Derivata in 'y' usando la " +"(Soltanto modalità Fragment/Light) (Vettore) Derivata in \"y\" usando la " "differenziazione locale." #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9647,7 +9659,7 @@ msgid "" "(Fragment/Light mode only) (Scalar) Derivative in 'y' using local " "differencing." msgstr "" -"(Soltanto modalità Fragment/Light) (Scalare) Derivata in 'y' usando la " +"(Soltanto modalità Fragment/Light) (Scalare) Derivata in \"y\" usando la " "differenziazione locale." #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9656,7 +9668,7 @@ msgid "" "'y'." msgstr "" "(Soltanto modalità Fragment/Light) (Vettore) Somma delle derivate assolute " -"in 'x' ed 'y'." +"in \"x\" ed \"y\"." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9664,7 +9676,7 @@ msgid "" "'y'." msgstr "" "(Soltanto modalità Fragment/Light) (Scalare) Somma delle derivate assolute " -"in 'x' ed 'y'." +"in \"x\" ed \"y\"." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -9684,14 +9696,14 @@ msgstr "Eseguibile" #: editor/project_export.cpp msgid "Delete preset '%s'?" -msgstr "Eliminare preset '%s'?" +msgstr "Eliminare preset \"%s\"?" #: editor/project_export.cpp msgid "" "Failed to export the project for platform '%s'.\n" "Export templates seem to be missing or invalid." msgstr "" -"Impossibile esportare il progetto per la piattaforma '%s'.\n" +"Impossibile esportare il progetto per la piattaforma \"%s\".\n" "I template di esportazione sembrano essere mancanti o non validi." #: editor/project_export.cpp @@ -9700,7 +9712,7 @@ msgid "" "This might be due to a configuration issue in the export preset or your " "export settings." msgstr "" -"Impossibile esportare il progetto per la piattaforma '%s'.\n" +"Impossibile esportare il progetto per la piattaforma \"%s\".\n" "Questo potrebbe essere dovuto ad un problema di configurazione nel preset di " "esportazione o nelle impostazioni di esportazione." @@ -9870,8 +9882,8 @@ msgstr "Errore nell'apertura del file package (non è in formato ZIP)." msgid "" "Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." msgstr "" -"File progetto '.zip' non valido; non contiene un file denominato 'project." -"godot'." +"File progetto \".zip\" non valido; non contiene un file denominato \"project." +"godot\"." #: editor/project_manager.cpp msgid "Please choose an empty folder." @@ -9879,7 +9891,7 @@ msgstr "Si prega di scegliere una cartella vuota." #: editor/project_manager.cpp msgid "Please choose a \"project.godot\" or \".zip\" file." -msgstr "Perfavore, scegli un file 'project.godot' o '.zip'." +msgstr "Perfavore, scegli un file \"project.godot\" o \".zip\"." #: editor/project_manager.cpp msgid "This directory already contains a Godot project." @@ -10029,7 +10041,7 @@ msgstr "Errore: il Progetto non è presente nel filesystem." #: editor/project_manager.cpp msgid "Can't open project at '%s'." -msgstr "Impossibile aprire il progetto a '%s'." +msgstr "Impossibile aprire il progetto a \"%s\"." #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" @@ -10234,12 +10246,12 @@ msgid "" "Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'" msgstr "" -"Nome dell'azione non valido. Non può essere vuoto o contenere '/', ':', '=', " -"'\\' oppure '\"'" +"Nome dell'azione non valido. Non può essere vuoto o contenere \"/\", \":\", " +"\"=\", \"\\\" oppure \"\"\"" #: editor/project_settings_editor.cpp msgid "An action with the name '%s' already exists." -msgstr "Un'azione col nome '%s' è già esistente." +msgstr "Un'azione col nome \"%s\" è già esistente." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -10363,11 +10375,11 @@ msgstr "Prima seleziona un oggetto di impostazione!" #: editor/project_settings_editor.cpp msgid "No property '%s' exists." -msgstr "Non esiste nessuna proprietà '%s'." +msgstr "Non esiste nessuna proprietà \"%s\"." #: editor/project_settings_editor.cpp msgid "Setting '%s' is internal, and it can't be deleted." -msgstr "L'impostazione '%s' è interna e non può essere rimossa." +msgstr "L'impostazione \"%s\" è interna e non può essere rimossa." #: editor/project_settings_editor.cpp msgid "Delete Item" @@ -10378,8 +10390,8 @@ msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" -"Nome azione non valida. Non può essere vuoto né contenere '/', ':', '=', " -"'\\' o '\"'." +"Nome azione non valida. Non può essere vuoto né contenere \"/\", \":\", \"=" +"\", \"\\\" o \"\"\"." #: editor/project_settings_editor.cpp msgid "Add Input Action" @@ -10771,8 +10783,8 @@ msgid "" "Cannot instance the scene '%s' because the current scene exists within one " "of its nodes." msgstr "" -"Impossibile istanziale la scena '%s' perché la scena corrente esiste in uno " -"dei suoi nodi." +"Impossibile istanziale la scena \"%s\" perché la scena corrente esiste in " +"uno dei suoi nodi." #: editor/scene_tree_dock.cpp msgid "Instance Scene(s)" @@ -11044,6 +11056,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Se selezionato, il riquadro della scena remota farà ricaricare il progetto " +"ogni volta che viene aggiornato.\n" +"Torna al riquadro della scena Locale per migliorare le prestazioni." #: editor/scene_tree_dock.cpp msgid "Local" @@ -11183,7 +11198,7 @@ msgstr "Selezionata estensione errata." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" -msgstr "Errore caricamento template '%s'" +msgstr "Errore caricamento template \"%s\"" #: editor/script_create_dialog.cpp msgid "Error - Could not create script in filesystem." @@ -12019,9 +12034,9 @@ msgid "" "Can't drop properties because script '%s' is not used in this scene.\n" "Drop holding 'Shift' to just copy the signature." msgstr "" -"Impossibile lasciare le proprietà perché lo script '%s' non è usato nella " +"Impossibile lasciare le proprietà perché lo script \"%s\" non è usato nella " "scena.\n" -"Lascia andare premendo 'Shift (Maiuscolo)' per copiare solo la firma." +"Lascia andare premendo \"Shift (Maiuscolo)\" per copiare solo la firma." #: modules/visual_script/visual_script_editor.cpp msgid "Add Getter Property" @@ -12061,7 +12076,7 @@ msgstr "Connetti Sequenza del Nodo" #: modules/visual_script/visual_script_editor.cpp msgid "Script already has function '%s'" -msgstr "Lo Script ha già la funzione '%s'" +msgstr "Lo Script ha già la funzione \"%s\"" #: modules/visual_script/visual_script_editor.cpp msgid "Change Input Value" @@ -12205,7 +12220,7 @@ msgstr "Il percorso non conduce ad un Nodo!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." -msgstr "Nome proprietà indice invalido '%s' nel nodo %s." +msgstr "Nome proprietà indice invalido \"%s\" nel nodo %s." #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " @@ -12260,8 +12275,8 @@ msgstr "I segmenti del pacchetto devono essere di lunghezza diversa da zero." #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." msgstr "" -"Il carattere '%s' non è consentito nei nomi dei pacchetti delle applicazioni " -"Android." +"Il carattere \"%s\" non è consentito nei nomi dei pacchetti delle " +"applicazioni Android." #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." @@ -12271,12 +12286,12 @@ msgstr "" #: platform/android/export/export.cpp msgid "The character '%s' cannot be the first character in a package segment." msgstr "" -"Il carattere '%s' non può essere il primo carattere di un segmento di " +"Il carattere \"%s\" non può essere il primo carattere di un segmento di " "pacchetto." #: platform/android/export/export.cpp msgid "The package must have at least one '.' separator." -msgstr "Il pacchetto deve avere almeno un '.' separatore." +msgstr "Il pacchetto deve avere almeno un \".\" separatore." #: platform/android/export/export.cpp msgid "Select device from the list" @@ -12284,7 +12299,7 @@ msgstr "Seleziona il dispositivo dall'elenco" #: platform/android/export/export.cpp msgid "Unable to find the 'apksigner' tool." -msgstr "Impossibile trovare lo strumento 'apksigner'." +msgstr "Impossibile trovare lo strumento \"apksigner\"." #: platform/android/export/export.cpp msgid "" @@ -12315,7 +12330,7 @@ msgstr "Un percorso invalido per il SDK Android nelle Impostazioni Editor." #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" -msgstr "Cartella 'platform-tools' inesistente!" +msgstr "Cartella \"platform-tools\" inesistente!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK platform-tools' adb command." @@ -12331,7 +12346,7 @@ msgstr "" #: platform/android/export/export.cpp msgid "Missing 'build-tools' directory!" -msgstr "Cartella 'build-tools' inesistente!" +msgstr "Cartella \"build-tools\" inesistente!" #: platform/android/export/export.cpp msgid "Unable to find Android SDK build-tools' apksigner command." @@ -12405,7 +12420,7 @@ msgid "" msgstr "" "Tentativo di costruire da un template build personalizzato, ma nesuna " "informazione sulla sua versione esiste. Perfavore, reinstallalo dal menu " -"'Progetto'." +"\"Progetto\"." #: platform/android/export/export.cpp msgid "" @@ -12417,7 +12432,7 @@ msgstr "" "Versione build di Android non coerente:\n" " Template installato: %s\n" " Versione Godot: %s\n" -"Perfavore, reinstalla il build template di Android dal menu 'Progetto'." +"Perfavore, reinstalla il build template di Android dal menu \"Progetto\"." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" @@ -12451,7 +12466,7 @@ msgstr "L'identificatore è mancante." #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." -msgstr "Il carattere '%s' non è consentito nell'Identificatore." +msgstr "Il carattere \"%s\" non è consentito nell'Identificatore." #: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." @@ -12614,13 +12629,13 @@ msgstr "Un CollisionPolygon2D vuoto non ha effetti sulla collisione." msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode." msgstr "" "Poligono non valido. Sono necessari almeno 3 punti nella modalità di " -"costruzione 'Solidi'." +"costruzione \"Solidi\"." #: scene/2d/collision_polygon_2d.cpp msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode." msgstr "" "Poligono non valido. Sono necessari almeno 2 punti nella modalità di " -"costruzione 'Segmenti'." +"costruzione \"Segmenti\"." #: scene/2d/collision_shape_2d.cpp msgid "" @@ -13093,23 +13108,23 @@ msgstr "" #: scene/animation/animation_blend_tree.cpp msgid "On BlendTree node '%s', animation not found: '%s'" -msgstr "Sul nodo BlendTree '%s', animazione non trovata: '%s'" +msgstr "Sul nodo BlendTree \"%s\", animazione non trovata: \"%s\"" #: scene/animation/animation_blend_tree.cpp msgid "Animation not found: '%s'" -msgstr "Animazione non trovata: '%s'" +msgstr "Animazione non trovata: \"%s\"" #: scene/animation/animation_tree.cpp msgid "In node '%s', invalid animation: '%s'." -msgstr "Nel nodo '%s', animazione non valida: '%s'." +msgstr "Nel nodo \"%s\", animazione non valida: \"%s\"." #: scene/animation/animation_tree.cpp msgid "Invalid animation: '%s'." -msgstr "Animazione non valida: '%s'." +msgstr "Animazione non valida: \"%s\"." #: scene/animation/animation_tree.cpp msgid "Nothing connected to input '%s' of node '%s'." -msgstr "Nulla collegato all'ingresso '%s' del nodo '%s'." +msgstr "Nulla collegato all'ingresso \"%s\" del nodo \"%s\"." #: scene/animation/animation_tree.cpp msgid "No root AnimationNode for the graph is set." @@ -13258,7 +13273,7 @@ msgid "" "'SamplerPort'." msgstr "" "La porta del sampler è connessa ma mai usata. Considera cambiare la sorgente " -"a 'SamplerPort'." +"a \"SamplerPort\"." #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 2d694989fc..3e03c04b72 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -36,7 +36,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-01 02:04+0000\n" +"PO-Revision-Date: 2021-05-10 15:32+0000\n" "Last-Translator: nitenook <admin@alterbaum.net>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" @@ -45,7 +45,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2562,9 +2562,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "パス '%s' ã‹ã‚‰ã‚¢ãƒ‰ã‚ªãƒ³ã‚¹ã‚¯ãƒªãƒ—トをèªè¾¼ã‚ã¾ã›ã‚“。" #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "パス '%s' ã‹ã‚‰ã‚¢ãƒ‰ã‚ªãƒ³ã‚¹ã‚¯ãƒªãƒ—トをèªã¿è¾¼ã‚ã¾ã›ã‚“。コードã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚‹å¯èƒ½æ€§" "ãŒã‚りã¾ã™ã€‚構文を確èªã—ã¦ãã ã•ã„。" @@ -3011,6 +3013,10 @@ msgid "About" msgstr "概è¦" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’実行。" @@ -3695,6 +3701,8 @@ msgstr "" msgid "" "Importing has been disabled for this file, so it can't be opened for editing." msgstr "" +"ã“ã®ãƒ•ァイルã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã‚‹ãŸã‚ã€ç·¨é›†ã®ãŸã‚ã«é–‹ãã“ã¨ã¯ã§ãã¾" +"ã›ã‚“。" #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." @@ -4101,7 +4109,7 @@ msgstr "デフォルトをèªè¾¼ã‚€" #: editor/import_dock.cpp msgid "Keep File (No Import)" -msgstr "" +msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ä¿æŒ (インãƒãƒ¼ãƒˆã—ãªã„)" #: editor/import_dock.cpp msgid "%d Files" @@ -5235,6 +5243,7 @@ msgstr "" "ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index 1894b0e156..fd1f34ae59 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -2561,8 +2561,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2974,6 +2975,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/km.po b/editor/translations/km.po index 9e167dfe2c..3d0c4b2f9d 100644 --- a/editor/translations/km.po +++ b/editor/translations/km.po @@ -2440,8 +2440,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2846,6 +2847,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 9770daf14a..604479435e 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -26,7 +26,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-11 22:02+0000\n" +"PO-Revision-Date: 2021-05-18 10:00+0000\n" "Last-Translator: Myeongjin Lee <aranet100@gmail.com>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" @@ -35,7 +35,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2545,11 +2545,13 @@ msgstr "ë‹¤ìŒ ê²½ë¡œì—서 ì• ë“œì˜¨ 스í¬ë¦½íŠ¸ë¥¼ 불러올 수 ì—†ìŒ: '%s' #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"ë‹¤ìŒ ê²½ë¡œì—서 ì• ë“œì˜¨ 스í¬ë¦½íŠ¸ë¥¼ 불러올 수 ì—†ìŒ: '%s' ì½”ë“œì— ì˜¤ë¥˜ê°€ 있는 것 ê°™" -"습니다. ë¬¸ë²•ì„ í™•ì¸í•´ë³´ì„¸ìš”." +"ë‹¤ìŒ ê²½ë¡œì—서 ì• ë“œì˜¨ 스í¬ë¦½íŠ¸ë¥¼ 불러올 수 ì—†ìŒ: '%s' 해당 스í¬ë¦½íŠ¸ì˜ ì½”ë“œì— " +"오류가 있는 것 같습니다.\n" +"추가 오류를 ë°©ì§€í•˜ë ¤ë©´ '%s'ì—서 ì• ë“œì˜¨ì„ ë¹„í™œì„±í™”í•˜ì„¸ìš”." #: editor/editor_node.cpp msgid "" @@ -2794,7 +2796,7 @@ msgstr "내보내기..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "안드로ì´ë“œ 빌드 템플릿 설치..." +msgstr "Android 빌드 템플릿 설치..." #: editor/editor_node.cpp msgid "Open Project Data Folder" @@ -2989,6 +2991,10 @@ msgid "About" msgstr "ì •ë³´" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "프로ì 트를 실행합니다." @@ -3071,7 +3077,7 @@ msgstr "ì €ìž¥í•˜ì§€ 않ìŒ" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "안드로ì´ë“œ 빌드 í…œí”Œë¦¿ì´ ì—†ìŠµë‹ˆë‹¤, ê´€ë ¨ í…œí”Œë¦¿ì„ ì„¤ì¹˜í•´ì£¼ì„¸ìš”." +msgstr "Android 빌드 í…œí”Œë¦¿ì´ ì—†ìŠµë‹ˆë‹¤, ê´€ë ¨ í…œí”Œë¦¿ì„ ì„¤ì¹˜í•´ì£¼ì„¸ìš”." #: editor/editor_node.cpp msgid "Manage Templates" @@ -3087,12 +3093,12 @@ msgid "" "the \"Use Custom Build\" option should be enabled in the Android export " "preset." msgstr "" -"\"res://android/build\"ì— ì†ŒìŠ¤ í…œí”Œë¦¿ì„ ì„¤ì¹˜í•´ì„œ, 프로ì 트를 맞춤 안드로ì´ë“œ " -"ë¹Œë“œì— ë§žê²Œ ì„¤ì •í• ê²ƒìž…ë‹ˆë‹¤.\n" +"\"res://android/build\"ì— ì†ŒìŠ¤ í…œí”Œë¦¿ì„ ì„¤ì¹˜í•´ì„œ, 프로ì 트를 맞춤 Android 빌" +"ë“œì— ë§žê²Œ ì„¤ì •í• ê²ƒìž…ë‹ˆë‹¤.\n" "그런 ë‹¤ìŒ ìˆ˜ì • 사í•ì„ ì ìš©í•˜ê³ ë§žì¶¤ APK를 만들어 내보낼 수 있습니다 (모듈 ì¶”" "ê°€, AndroidManifest.xml 바꾸기 등).\n" -"미리 ë¹Œë“œëœ APK를 사용하는 ëŒ€ì‹ ë§žì¶¤ 빌드를 ë§Œë“¤ë ¤ë©´, 안드로ì´ë“œ 내보내기 프" -"리셋ì—서 \"맞춤 빌드 사용\" ì„¤ì •ì„ ì¼œ 놓아야 합니다." +"미리 ë¹Œë“œëœ APK를 사용하는 ëŒ€ì‹ ë§žì¶¤ 빌드를 ë§Œë“¤ë ¤ë©´, Android 내보내기 프리셋" +"ì—서 \"맞춤 빌드 사용\" ì„¤ì •ì„ ì¼œ 놓아야 합니다." #: editor/editor_node.cpp msgid "" @@ -3101,7 +3107,7 @@ msgid "" "Remove the \"res://android/build\" directory manually before attempting this " "operation again." msgstr "" -"안드로ì´ë“œ 빌드 í…œí”Œë¦¿ì´ ì´ë¯¸ ì´ í”„ë¡œì íŠ¸ì— ì„¤ì¹˜í–ˆê³ , ë®ì–´ 쓸 수 없습니다.\n" +"Android 빌드 í…œí”Œë¦¿ì´ ì´ë¯¸ ì´ í”„ë¡œì íŠ¸ì— ì„¤ì¹˜í–ˆê³ , ë®ì–´ 쓸 수 없습니다.\n" "ì´ ëª…ë ¹ì„ ë‹¤ì‹œ 실행 ì „ì— \"res://android/build\" ë””ë ‰í† ë¦¬ë¥¼ ì‚ì œí•˜ì„¸ìš”." #: editor/editor_node.cpp @@ -3616,7 +3622,7 @@ msgstr "SSL 핸드셰ì´í¬ 오류" #: editor/export_template_manager.cpp msgid "Uncompressing Android Build Sources" -msgstr "안드로ì´ë“œ 빌드 소스 ì••ì¶• 푸는 중" +msgstr "Android 빌드 소스 ì••ì¶• 푸는 중" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -5201,11 +5207,12 @@ msgstr "" "ì–´ 있는지 확ì¸í•´ì£¼ì„¸ìš”." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" -"Godot 편집기가 ë ˆì´ íŠ¸ë ˆì´ì‹± ì§€ì› ì—†ì´ ë¹Œë“œë˜ì–´ 있어, ë¼ì´íŠ¸ë§µì´ êµ¬ì›Œì§ˆ 수 ì—†" -"습니다." +"Godot 편집기는 ë ˆì´ íŠ¸ë ˆì´ì‹± ì§€ì› ì—†ì´ ë¹Œë“œë˜ì—ˆìœ¼ë©° ë¼ì´íŠ¸ë§µì€ êµ¬ìš¸ 수 없습니" +"다." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" @@ -7515,7 +7522,7 @@ msgstr "ë·° íšŒì „ ìž ê¹€" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" -msgstr "" +msgstr "ë”ìš± í™•ëŒ€í•˜ë ¤ë©´, ì¹´ë©”ë¼ì˜ í´ë¦½í•‘ í‰ë©´ì„ 변경하세요 (보기 -> ì„¤ì •...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -10863,6 +10870,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"ì„ íƒë˜ì–´ 있다면, ì›ê²© 씬 트리 ë…ì€ ê·¸ê²ƒì´ ì—…ë°ì´íЏë 때마다 프로ì 트가 ëŠê¸°" +"는 ì›ì¸ì´ ë©ë‹ˆë‹¤.\n" +"ì„±ëŠ¥ì„ í–¥ìƒì‹œí‚¤ë ¤ë©´ 로컬 씬 트리 ë…으로 다시 ì „í™˜í•˜ì„¸ìš”." #: editor/scene_tree_dock.cpp msgid "Local" @@ -12075,8 +12085,7 @@ msgstr "패키지 세그먼트는 길ì´ê°€ 0ì´ ì•„ë‹ˆì–´ì•¼ 합니다." #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." -msgstr "" -"ë¬¸ìž '%s'ì€(는) 안드로ì´ë“œ ì• í”Œë¦¬ì¼€ì´ì…˜ 패키지 ì´ë¦„으로 쓸 수 없습니다." +msgstr "ë¬¸ìž '%s'ì€(는) Android ì• í”Œë¦¬ì¼€ì´ì…˜ 패키지 ì´ë¦„으로 쓸 수 없습니다." #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." @@ -13043,6 +13052,19 @@ msgid "Constants cannot be modified." msgstr "ìƒìˆ˜ëŠ” ìˆ˜ì •í• ìˆ˜ 없습니다." #~ msgid "" +#~ "Godot editor was built without ray tracing support; lightmaps can't be " +#~ "baked.\n" +#~ "If you are using an Apple Silicon-based Mac, try forcing Rosetta " +#~ "emulation on Godot.app in the application settings\n" +#~ "then restart the editor." +#~ msgstr "" +#~ "Godot 편집기는 ë ˆì´ íŠ¸ë ˆì´ì‹± ì§€ì› ì—†ì´ ë¹Œë“œë˜ì—ˆìœ¼ë©° ë¼ì´íŠ¸ë§µì€ êµ¬ìš¸ 수 ì—†" +#~ "습니다.\n" +#~ "Apple Silicon ê¸°ë°˜ì˜ Macì„ ì‚¬ìš© ì¤‘ì¸ ê²½ìš°, ì• í”Œë¦¬ì¼€ì´ì…˜ ì„¤ì •ì—서 Godot.app" +#~ "ì˜ Rosetta ì—ë®¬ë ˆì´ì…˜ ê°•ì œë¡œ\n" +#~ "시ë„í•˜ê³ ë‚˜ì„œ 편집기를 다시 시작하세요." + +#~ msgid "" #~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0." #~ msgstr "" #~ "InterpolatedCamera는 ë” ì´ìƒ 사용ë˜ì§€ 않으며 Godot 4.0ì—서 ì œê±°ë©ë‹ˆë‹¤." diff --git a/editor/translations/lt.po b/editor/translations/lt.po index e5ca1dd50c..6dad903aac 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -2513,8 +2513,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2926,6 +2927,10 @@ msgid "About" msgstr "Apie" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 606c690a55..3333b65210 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -2486,8 +2486,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2892,6 +2893,10 @@ msgid "About" msgstr "Par" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 1259cbeed4..780599c2da 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -2432,8 +2432,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2838,6 +2839,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/mk.po b/editor/translations/mk.po index 25f0c1bedd..01dbc3ed02 100644 --- a/editor/translations/mk.po +++ b/editor/translations/mk.po @@ -2439,8 +2439,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2845,6 +2846,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 2ffb3793b7..b03638aded 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -2444,8 +2444,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2850,6 +2851,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index 119e1ce931..d7a76e3f10 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -2439,8 +2439,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2845,6 +2846,10 @@ msgid "About" msgstr "आमचà¥à¤¯à¤¾ बदà¥à¤¦à¤²" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index 127e06c898..3798405050 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-01-12 13:32+0000\n" +"PO-Revision-Date: 2021-05-10 15:32+0000\n" "Last-Translator: Keviindran Ramachandran <keviinx@yahoo.com>\n" "Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/" "ms/>\n" @@ -22,7 +22,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1607,22 +1607,20 @@ msgstr "" "Fallback Enabled'." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" -"Platform sasaran memerlukan pemampatan tekstur 'ETC' untuk GLES2. Aktifkan " -"'Import Etc' dalam Tetapan Projek." +"Platform sasaran memerlukan pemampatan tekstur 'PVRTC' untuk GLES2. Aktifkan " +"'Import Pvrtc' dalam Tetapan Projek." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. " "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" -"Platform sasaran memerlukan pemampatan tekstur 'ETC2' untuk GLES3. Aktifkan " -"'Import Etc 2' dalam Tetapan Projek." +"Platform sasaran memerlukan pemampatan tekstur 'ETC2' atau 'PVRTC' untuk " +"GLES3. Aktifkan 'Import Etc 2' atau 'Import Pvrtc' dalam Tetapan Projek." #: editor/editor_export.cpp #, fuzzy @@ -1679,9 +1677,8 @@ msgid "Node Dock" msgstr "Dok nod" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "FileSystem Dock" -msgstr "Sistem Fail dan Dok Import" +msgstr "Dok FileSystem" #: editor/editor_feature_profile.cpp msgid "Import Dock" @@ -1768,7 +1765,7 @@ msgstr "Baru" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "Import" +msgstr "import" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -2000,7 +1997,7 @@ msgstr "Tutorial Dalam Talian" #: editor/editor_help.cpp msgid "Properties" -msgstr "Sifat" +msgstr "Sifat-sifat" #: editor/editor_help.cpp msgid "override:" @@ -2396,7 +2393,7 @@ msgstr "Tiada adegan yang didefinisikan untuk dijalankan." #: editor/editor_node.cpp msgid "Save scene before running..." -msgstr "" +msgstr "Simpan adegan sebelum menjalankan..." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -2552,9 +2549,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Tidak dapat memuatkan skrip addon dari laluan: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Tidak dapat memuat skrip addon dari laluan: '%s' Nampaknya terdapat ralat " "dalam kod, sila periksa sintaksnya." @@ -2593,9 +2592,8 @@ msgid "Scene '%s' has broken dependencies:" msgstr "Adegan '%s' mengandungi kebergantungan yang pecah:" #: editor/editor_node.cpp -#, fuzzy msgid "Clear Recent Scenes" -msgstr "Kosongkan Adegan Terbaru" +msgstr "Kosongkan Adegan-adegan Terbaru" #: editor/editor_node.cpp msgid "" @@ -2608,7 +2606,6 @@ msgstr "" "'aplikasi'." #: editor/editor_node.cpp -#, fuzzy msgid "" "Selected scene '%s' does not exist, select a valid one?\n" "You can change it later in \"Project Settings\" under the 'application' " @@ -2647,81 +2644,66 @@ msgid "Show in FileSystem" msgstr "Tunjukkan dalam FileSystem" #: editor/editor_node.cpp -#, fuzzy msgid "Play This Scene" msgstr "Mainkan Adegan Ini" #: editor/editor_node.cpp -#, fuzzy msgid "Close Tab" msgstr "Tutup Tab" #: editor/editor_node.cpp -#, fuzzy msgid "Undo Close Tab" msgstr "Buat Asal Tutup Tab" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Close Other Tabs" -msgstr "Tutup Tab Lain" +msgstr "Tutup Tab-tab Lain" #: editor/editor_node.cpp msgid "Close Tabs to the Right" msgstr "Tutup Tab-tab ke Kanan" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" msgstr "Tutup Semua Tab" #: editor/editor_node.cpp -#, fuzzy msgid "Switch Scene Tab" msgstr "Tukar Tab Adegan" #: editor/editor_node.cpp -#, fuzzy msgid "%d more files or folders" -msgstr "%d lebih banyak fail atau folder" +msgstr "%d lebih banyak fail-fail atau folder-folder" #: editor/editor_node.cpp -#, fuzzy msgid "%d more folders" -msgstr "%d lebih banyak folder" +msgstr "%d lebih banyak folder-folder" #: editor/editor_node.cpp -#, fuzzy msgid "%d more files" -msgstr "%d lebih banyak fail" +msgstr "%d lebih banyak fail-fail" #: editor/editor_node.cpp -#, fuzzy msgid "Dock Position" msgstr "Kedudukan Dok" #: editor/editor_node.cpp -#, fuzzy msgid "Distraction Free Mode" msgstr "Mod Bebas Gangguan" #: editor/editor_node.cpp -#, fuzzy msgid "Toggle distraction-free mode." msgstr "Togol mod bebas gangguan." #: editor/editor_node.cpp -#, fuzzy msgid "Add a new scene." msgstr "Tambah adegan baru." #: editor/editor_node.cpp -#, fuzzy msgid "Scene" msgstr "Adegan" #: editor/editor_node.cpp -#, fuzzy msgid "Go to previously opened scene." msgstr "Pergi ke adegan yang dibuka sebelum ini." @@ -2731,14 +2713,12 @@ msgid "Copy Text" msgstr "Semua Pilihan" #: editor/editor_node.cpp -#, fuzzy msgid "Next tab" msgstr "Tab seterusnya" #: editor/editor_node.cpp -#, fuzzy msgid "Previous tab" -msgstr "Tab terdahulu" +msgstr "Tab sebelumnya" #: editor/editor_node.cpp msgid "Filter Files..." @@ -2749,12 +2729,10 @@ msgid "Operations with scene files." msgstr "Operasi dengan fail adegan." #: editor/editor_node.cpp -#, fuzzy msgid "New Scene" msgstr "Adegan Baru" #: editor/editor_node.cpp -#, fuzzy msgid "New Inherited Scene..." msgstr "Adegan Baru Diwarisi..." @@ -3052,6 +3030,10 @@ msgid "About" msgstr "Tentang" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp #, fuzzy msgid "Play the project." msgstr "Main projek." @@ -3205,21 +3187,24 @@ msgid "Open & Run a Script" msgstr "Buka & Jalankan Skrip" #: editor/editor_node.cpp -#, fuzzy msgid "" "The following files are newer on disk.\n" "What action should be taken?" -msgstr "Fail berikut gagal diekstrak dari pakej:" +msgstr "" +"Fail berikut lebih baru pada cakera.\n" +"Apakah tindakan yang harus diambil?" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp +#, fuzzy msgid "Reload" -msgstr "" +msgstr "Muatkan Semula" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp +#, fuzzy msgid "Resave" -msgstr "" +msgstr "Simpan semula" #: editor/editor_node.cpp #, fuzzy @@ -3703,152 +3688,165 @@ msgstr "Muat turun Selesai." #: editor/export_template_manager.cpp msgid "Cannot remove temporary file:" -msgstr "" +msgstr "Tidak dapat membuang fail sementara:" #: editor/export_template_manager.cpp msgid "" "Templates installation failed.\n" "The problematic templates archives can be found at '%s'." msgstr "" +"Pemasangan templat gagal.\n" +"Arkib templat yang bermasalah boleh didapati di '%s'." #: editor/export_template_manager.cpp +#, fuzzy msgid "Error requesting URL:" -msgstr "" +msgstr "Ralat semasa meminta URL:" #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." -msgstr "" +msgstr "Menyambung ke Cermin..." #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "" +msgstr "Sambungan terputus" #: editor/export_template_manager.cpp +#, fuzzy msgid "Resolving" -msgstr "" +msgstr "Menyelesaikan" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "Tidak Dapat Menyelesaikan" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connecting..." -msgstr "" +msgstr "Menyambung..." #: editor/export_template_manager.cpp msgid "Can't Connect" -msgstr "" +msgstr "Tidak Dapat Menyambung" #: editor/export_template_manager.cpp msgid "Connected" -msgstr "" +msgstr "Disambungkan" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Requesting..." -msgstr "" +msgstr "Meminta..." #: editor/export_template_manager.cpp msgid "Downloading" -msgstr "" +msgstr "Memuat turun" #: editor/export_template_manager.cpp msgid "Connection Error" -msgstr "" +msgstr "Ralat Sambungan" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "" +msgstr "Ralat Jabat Tangan SSL" #: editor/export_template_manager.cpp msgid "Uncompressing Android Build Sources" -msgstr "" +msgstr "Nyahmemampatkan Sumber Binaan Android" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "" +msgstr "Versi Terkini:" #: editor/export_template_manager.cpp +#, fuzzy msgid "Installed Versions:" -msgstr "" +msgstr "Versi Yang Dipasang:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "" +msgstr "Pasang Dari Fail" #: editor/export_template_manager.cpp msgid "Remove Template" -msgstr "" +msgstr "Alih Keluar Templat" #: editor/export_template_manager.cpp msgid "Select Template File" -msgstr "" +msgstr "Pilih Fail Templat" #: editor/export_template_manager.cpp msgid "Godot Export Templates" -msgstr "" +msgstr "Templat Eksport Godot" #: editor/export_template_manager.cpp msgid "Export Template Manager" -msgstr "" +msgstr "Pengurus Templat Eksport" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "" +msgstr "Muat Turun Templat-templat" #: editor/export_template_manager.cpp +#, fuzzy msgid "Select mirror from list: (Shift+Click: Open in Browser)" -msgstr "" +msgstr "Pilih cermin daripada senarai: (Shift+Click: Buka dalam Pelayar)" #: editor/filesystem_dock.cpp +#, fuzzy msgid "Favorites" -msgstr "" +msgstr "Kegemaran" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." msgstr "" +"Status: Import fail gagal. Sila betulkan fail dan import semula secara " +"manual." #: editor/filesystem_dock.cpp +#, fuzzy msgid "" "Importing has been disabled for this file, so it can't be opened for editing." msgstr "" +"Pengimportan telah dilumpuhkan untuk fail ini, jadi tidak dapat dibuka untuk " +"diedit." #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "Tidak dapat memindahkan/menamakan semula akar sumber." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "Tidak dapat memindahkan folder ke dalamnya sendiri." #: editor/filesystem_dock.cpp msgid "Error moving:" -msgstr "" +msgstr "Ralat semasa memindahkan:" #: editor/filesystem_dock.cpp msgid "Error duplicating:" -msgstr "" +msgstr "Ralat penduaan:" #: editor/filesystem_dock.cpp msgid "Unable to update dependencies:" -msgstr "" +msgstr "Tidak dapat mengemaskini kebergantungan:" #: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp msgid "No name provided." -msgstr "" +msgstr "Tidak ada nama yang diberikan." #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters." -msgstr "" +msgstr "Nama yang diberikan mengandungi aksara yang tidak sah." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "Fail atau folder dengan nama ini sudah wujud." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "Nama mengandungi aksara yang tidak sah." #: editor/filesystem_dock.cpp msgid "" @@ -3859,84 +3857,90 @@ msgid "" "\n" "Do you wish to overwrite them?" msgstr "" +"Fail atau folder berikut bercanggah dengan barang-barang dalam lokasi " +"sasaran '%s':\n" +"\n" +"%s\n" +"\n" +"Adakah anda ingin menulis ganti mereka?" #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "" +msgstr "Menamakan semula fail:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "" +msgstr "Menamakan semula folder:" #: editor/filesystem_dock.cpp msgid "Duplicating file:" -msgstr "" +msgstr "Menduakan fail:" #: editor/filesystem_dock.cpp msgid "Duplicating folder:" -msgstr "" +msgstr "Menduakan folder:" #: editor/filesystem_dock.cpp msgid "New Inherited Scene" -msgstr "" +msgstr "Adegan Baru Yang Diwarisi" #: editor/filesystem_dock.cpp msgid "Set As Main Scene" -msgstr "" +msgstr "Tetapkan Sebagai Adegan Utama" #: editor/filesystem_dock.cpp msgid "Open Scenes" -msgstr "" +msgstr "Buka Adegan-adegan" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "Contoh" #: editor/filesystem_dock.cpp msgid "Add to Favorites" -msgstr "" +msgstr "Tambah ke Kegemaran" #: editor/filesystem_dock.cpp msgid "Remove from Favorites" -msgstr "" +msgstr "Alih keluar dari Kegemaran" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." -msgstr "" +msgstr "Sunting Kebergantungan..." #: editor/filesystem_dock.cpp msgid "View Owners..." -msgstr "" +msgstr "Lihat Pemilik..." #: editor/filesystem_dock.cpp msgid "Move To..." -msgstr "" +msgstr "Pindah Ke..." #: editor/filesystem_dock.cpp msgid "New Scene..." -msgstr "" +msgstr "Adegan Baru..." #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "New Script..." -msgstr "" +msgstr "Skrip Baru..." #: editor/filesystem_dock.cpp msgid "New Resource..." -msgstr "" +msgstr "Sumber Baru..." #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp msgid "Expand All" -msgstr "" +msgstr "Kembangkan Semua" #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp msgid "Collapse All" -msgstr "" +msgstr "Runtuhkan Semua" #: editor/filesystem_dock.cpp msgid "Duplicate..." -msgstr "" +msgstr "Penduakan..." #: editor/filesystem_dock.cpp #, fuzzy @@ -3945,107 +3949,116 @@ msgstr "Pindah Autoload" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." -msgstr "" +msgstr "Namakan semula..." #: editor/filesystem_dock.cpp +#, fuzzy msgid "Previous Folder/File" -msgstr "" +msgstr "Folder/Fail Terdahulu" #: editor/filesystem_dock.cpp msgid "Next Folder/File" -msgstr "" +msgstr "Folder/Fail Seterusnya" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "" +msgstr "Imbas Semula Sistem Fail" #: editor/filesystem_dock.cpp msgid "Toggle Split Mode" -msgstr "" +msgstr "Togol Mod Berpisah" #: editor/filesystem_dock.cpp msgid "Search files" -msgstr "" +msgstr "Cari fail" #: editor/filesystem_dock.cpp msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" +"Mengimbas Fail,\n" +"Sila Tunggu..." #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "Pindah" #: editor/filesystem_dock.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp #: editor/project_manager.cpp editor/rename_dialog.cpp #: editor/scene_tree_dock.cpp +#, fuzzy msgid "Rename" -msgstr "" +msgstr "Namakan semula" #: editor/filesystem_dock.cpp +#, fuzzy msgid "Overwrite" -msgstr "" +msgstr "Tulis ganti" #: editor/filesystem_dock.cpp +#, fuzzy msgid "Create Scene" -msgstr "" +msgstr "Cipta Adegan" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "" +msgstr "Cipta Skrip" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp msgid "Find in Files" -msgstr "" +msgstr "Cari dalam Fail-fail" #: editor/find_in_files.cpp msgid "Find:" -msgstr "" +msgstr "Cari:" #: editor/find_in_files.cpp msgid "Folder:" -msgstr "" +msgstr "Folder:" #: editor/find_in_files.cpp msgid "Filters:" -msgstr "" +msgstr "Penapis:" #: editor/find_in_files.cpp msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Sertakan fail-fail dengan sambungan berikut. Tambah atau keluar mereka dalam " +"ProjectSettings." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find..." -msgstr "" +msgstr "Cari..." #: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp msgid "Replace..." -msgstr "" +msgstr "Ganti..." #: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" -msgstr "" +msgstr "Batal" #: editor/find_in_files.cpp msgid "Find: " -msgstr "" +msgstr "Cari: " #: editor/find_in_files.cpp msgid "Replace: " -msgstr "" +msgstr "Ganti: " #: editor/find_in_files.cpp msgid "Replace all (no undo)" -msgstr "" +msgstr "Ganti semua (tiada buat asal)" #: editor/find_in_files.cpp +#, fuzzy msgid "Searching..." -msgstr "" +msgstr "Mencari..." #: editor/find_in_files.cpp #, fuzzy @@ -4064,23 +4077,23 @@ msgstr "%d padan." #: editor/groups_editor.cpp msgid "Add to Group" -msgstr "" +msgstr "Tambah ke Kumpulan" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "" +msgstr "Alih keluar dari Kumpulan" #: editor/groups_editor.cpp msgid "Group name already exists." -msgstr "" +msgstr "Nama kumpulan sudah wujud." #: editor/groups_editor.cpp msgid "Invalid group name." -msgstr "" +msgstr "Nama kumpulan tidak sah." #: editor/groups_editor.cpp msgid "Rename Group" -msgstr "" +msgstr "Namakan semula Kumpulan" #: editor/groups_editor.cpp #, fuzzy @@ -4089,113 +4102,117 @@ msgstr "Semua Pilihan" #: editor/groups_editor.cpp editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "Kumpulan" #: editor/groups_editor.cpp msgid "Nodes Not in Group" -msgstr "" +msgstr "Nod-nod Tidak dalam Kumpulan" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp #: editor/scene_tree_editor.cpp msgid "Filter nodes" -msgstr "" +msgstr "Tapis nod-nod" #: editor/groups_editor.cpp msgid "Nodes in Group" -msgstr "" +msgstr "Nod-nod dalam Kumpulan" #: editor/groups_editor.cpp +#, fuzzy msgid "Empty groups will be automatically removed." -msgstr "" +msgstr "Kumpulan kosong akan dikeluarkan secara automatik." #: editor/groups_editor.cpp msgid "Group Editor" -msgstr "" +msgstr "Editor Kumpulan" #: editor/groups_editor.cpp msgid "Manage Groups" -msgstr "" +msgstr "Urus Kumpulan-kumpulan" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "" +msgstr "Import sebagai Satu Adegan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "" +msgstr "Import dengan Animasi Berasingan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "" +msgstr "Import dengan Bahan Berasingan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "" +msgstr "Import dengan Objek Berasingan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "" +msgstr "Import dengan Objek+Bahan Berasingan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "" +msgstr "Import dengan Objek+Animasi Berasingan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "" +msgstr "Import dengan Bahan+Animasi Berasingan" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "" +msgstr "Import dengan Objek+Bahan+Animasi Berasingan" #: editor/import/resource_importer_scene.cpp +#, fuzzy msgid "Import as Multiple Scenes" -msgstr "" +msgstr "Import sebagai Pelbagai Adegan" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "Import sebagai Pelbagai Adegan +Bahan" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "Import Adegan" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "" +msgstr "Mengimport Adegan..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" -msgstr "" +msgstr "Menjana Peta Cahaya" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "Menjana untuk Mesh: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." -msgstr "" +msgstr "Menjalankan Skrip Tersuai..." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "Tidak dapat memuatkan skrip pasca-import:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" -msgstr "" +msgstr "Skrip tidak sah/rosak untuk pasca-import (periksa konsol):" #: editor/import/resource_importer_scene.cpp msgid "Error running post-import script:" -msgstr "" +msgstr "Ralat semasa menjalankan skrip pasca-import:" #: editor/import/resource_importer_scene.cpp msgid "Did you return a Node-derived object in the `post_import()` method?" msgstr "" +"Adakah anda mengembalikan objek yang diperolehi dari Nod dalam kaedah " +"'post_import()'?" #: editor/import/resource_importer_scene.cpp msgid "Saving..." -msgstr "" +msgstr "Menyimpan..." #: editor/import_defaults_editor.cpp #, fuzzy @@ -4203,9 +4220,8 @@ msgid "Select Importer" msgstr "Pilih Nod(Nod-nod) untuk Diimport" #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Importer:" -msgstr "Import" +msgstr "Pengimport:" #: editor/import_defaults_editor.cpp #, fuzzy @@ -4214,168 +4230,171 @@ msgstr "Muatkan Lalai" #: editor/import_dock.cpp msgid "Keep File (No Import)" -msgstr "" +msgstr "Simpan Fail (Tiada Import)" #: editor/import_dock.cpp msgid "%d Files" -msgstr "" +msgstr "%d Fail-fail" #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "" +msgstr "Tetapkan sebagai Lalai untuk '%s'" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "Kosongkan Lalai untuk '%s'" #: editor/import_dock.cpp msgid "Import As:" -msgstr "" +msgstr "Import Sebagai:" #: editor/import_dock.cpp msgid "Preset" -msgstr "" +msgstr "Pratetap" #: editor/import_dock.cpp msgid "Reimport" -msgstr "" +msgstr "Import semula" #: editor/import_dock.cpp msgid "Save Scenes, Re-Import, and Restart" -msgstr "" +msgstr "Simpan Adegan, Import semula, dan Mula Semula" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." -msgstr "" +msgstr "Mengubah jenis fail yang diimport memerlukan editor dimulakan semula." #: editor/import_dock.cpp msgid "" "WARNING: Assets exist that use this resource, they may stop loading properly." msgstr "" +"AMARAN: Terdapat aset-aset yang menggunakan sumber ini, mereka mungkin " +"berhenti memuat dengan betul." #: editor/inspector_dock.cpp msgid "Failed to load resource." -msgstr "" +msgstr "Gagal untuk memuatkan sumber." #: editor/inspector_dock.cpp msgid "Expand All Properties" -msgstr "" +msgstr "Kembangkan Semua Sifat-sifat" #: editor/inspector_dock.cpp msgid "Collapse All Properties" -msgstr "" +msgstr "Tutup Semua Sifat-sifat" #: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Save As..." -msgstr "" +msgstr "Simpan Sebagai..." #: editor/inspector_dock.cpp msgid "Copy Params" -msgstr "" +msgstr "Salin Parameter-parameter" #: editor/inspector_dock.cpp msgid "Edit Resource Clipboard" -msgstr "" +msgstr "Sunting Papan Klip Sumber" #: editor/inspector_dock.cpp msgid "Copy Resource" -msgstr "" +msgstr "Salin Sumber" #: editor/inspector_dock.cpp msgid "Make Built-In" -msgstr "" +msgstr "Buat Terbina Dalaman" #: editor/inspector_dock.cpp msgid "Make Sub-Resources Unique" -msgstr "" +msgstr "Buat Sub-Sumber Unik" #: editor/inspector_dock.cpp msgid "Open in Help" -msgstr "" +msgstr "Buka dalam Bantuan" #: editor/inspector_dock.cpp msgid "Create a new resource in memory and edit it." -msgstr "" +msgstr "Cipta sumber baru dalam ingatan dan suntingnya." #: editor/inspector_dock.cpp msgid "Load an existing resource from disk and edit it." -msgstr "" +msgstr "Muatkan sumber sedia ada dari cakera dan suntingnya." #: editor/inspector_dock.cpp msgid "Save the currently edited resource." -msgstr "" +msgstr "Simpan sumber yang sedang disunting." #: editor/inspector_dock.cpp msgid "Go to the previous edited object in history." -msgstr "" +msgstr "Pergi ke objek yang disunting sebelumnya dalam sejarah." #: editor/inspector_dock.cpp msgid "Go to the next edited object in history." -msgstr "" +msgstr "Pergi ke objek yang disunting seterusnya dalam sejarah." #: editor/inspector_dock.cpp msgid "History of recently edited objects." -msgstr "" +msgstr "Sejarah objek-objek yang baru disunting." #: editor/inspector_dock.cpp msgid "Object properties." -msgstr "" +msgstr "Sifat-sifat objek." #: editor/inspector_dock.cpp msgid "Filter properties" -msgstr "" +msgstr "Tapis sifat-sifat" #: editor/inspector_dock.cpp msgid "Changes may be lost!" -msgstr "" +msgstr "Perubahan mungkin akan hilang!" #: editor/multi_node_edit.cpp msgid "MultiNode Set" -msgstr "" +msgstr "Tetap MultiNode" #: editor/node_dock.cpp msgid "Select a single node to edit its signals and groups." -msgstr "" +msgstr "Pilih satu nod untuk menyunting isyarat dan kumpulan-kumpulannya." #: editor/plugin_config_dialog.cpp msgid "Edit a Plugin" -msgstr "" +msgstr "Sunting satu Plugin" #: editor/plugin_config_dialog.cpp msgid "Create a Plugin" -msgstr "" +msgstr "Cipta satu Plugin" #: editor/plugin_config_dialog.cpp +#, fuzzy msgid "Plugin Name:" -msgstr "" +msgstr "Nama Plugin:" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" -msgstr "" +msgstr "Subfolder:" #: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp msgid "Language:" -msgstr "" +msgstr "Bahasa:" #: editor/plugin_config_dialog.cpp msgid "Script Name:" -msgstr "" +msgstr "Nama Skrip:" #: editor/plugin_config_dialog.cpp msgid "Activate now?" -msgstr "" +msgstr "Aktifkan sekarang?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Polygon" -msgstr "" +msgstr "Buat Poligon" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Create points." -msgstr "" +msgstr "Cipta titik-titik." #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -4383,15 +4402,18 @@ msgid "" "LMB: Move Point\n" "RMB: Erase Point" msgstr "" +"Sunting titik-titik.\n" +"LMB: Pindah Titik\n" +"RMB: Padam Titik" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp msgid "Erase points." -msgstr "" +msgstr "Padam titik-titik." #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Edit Polygon" -msgstr "" +msgstr "Sunting Poligon" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" @@ -7143,7 +7165,7 @@ msgstr "" #: editor/plugins/script_text_editor.cpp msgid "Go to Function" -msgstr "" +msgstr "Pergi ke Fungsi" #: editor/plugins/script_text_editor.cpp msgid "Only resources from filesystem can be dropped." @@ -7243,9 +7265,8 @@ msgid "Complete Symbol" msgstr "" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Evaluate Selection" -msgstr "Semua Pilihan" +msgstr "Menilai Pemilihan" #: editor/plugins/script_text_editor.cpp msgid "Trim Trailing Whitespace" @@ -7419,9 +7440,8 @@ msgid "Yaw" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Size" -msgstr "Saiz: " +msgstr "Saiz" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" @@ -7680,7 +7700,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" -msgstr "" +msgstr "Masukkan Kunci Animasi" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Origin" @@ -8233,9 +8253,8 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cut Selection" -msgstr "Semua Pilihan" +msgstr "Potong Pilihan" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" @@ -8318,9 +8337,8 @@ msgid "Flip Vertically" msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" -msgstr "Anim Ubah Penukaran" +msgstr "Kosongkan Transformasi" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -8818,7 +8836,7 @@ msgstr "Anim Menduakan Kunci" #: editor/plugins/visual_shader_editor_plugin.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Paste Nodes" -msgstr "" +msgstr "Tampal Nod" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9608,7 +9626,7 @@ msgstr "" #: editor/project_export.cpp msgid "Export all resources in the project" -msgstr "" +msgstr "Eksport semua sumber dalam projek" #: editor/project_export.cpp msgid "Export selected scenes (and dependencies)" @@ -10392,9 +10410,8 @@ msgid "Select Method" msgstr "" #: editor/rename_dialog.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Batch Rename" -msgstr "Ubah Nama Trek Anim" +msgstr "Namakan Semula Kumpulan" #: editor/rename_dialog.cpp msgid "Replace:" @@ -11923,15 +11940,15 @@ msgstr "" #: modules/visual_script/visual_script_editor.cpp msgid "Copy Nodes" -msgstr "" +msgstr "Salin Nod" #: modules/visual_script/visual_script_editor.cpp msgid "Cut Nodes" -msgstr "" +msgstr "Potong Nod" #: modules/visual_script/visual_script_editor.cpp msgid "Make Function" -msgstr "" +msgstr "Buat Fungsi" #: modules/visual_script/visual_script_editor.cpp msgid "Refresh Graph" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 398330b3e9..39f45f5ae5 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2640,8 +2640,9 @@ msgstr "Kan ikke laste addon-skript fra bane: '%s'." #: editor/editor_node.cpp #, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Kunne ikke laste tillegsskript fra sti: '%s' Script er ikke i verktøymodus." @@ -3102,6 +3103,10 @@ msgid "About" msgstr "Om" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Spill prosjektet." diff --git a/editor/translations/nl.po b/editor/translations/nl.po index e12d8c9324..32b3ff9117 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -2587,9 +2587,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Volgend script kon niet geladen worden: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Script kon niet geladen worden van het pad: '%s'. Er lijkt een fout in de " "code te zijn, controleer de syntax." @@ -3037,6 +3039,10 @@ msgid "About" msgstr "Over" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Speel het project." diff --git a/editor/translations/or.po b/editor/translations/or.po index 77e9075f6a..8e40eb4b04 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -2438,8 +2438,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2844,6 +2845,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 122c89f2b6..483d572041 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -52,7 +52,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-19 22:33+0000\n" +"PO-Revision-Date: 2021-04-22 14:39+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -2572,9 +2572,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Nie można zaÅ‚adować skryptu dodatku z Å›cieżki: \"%s\"." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Nie można zaÅ‚adować skryptu dodatku ze Å›cieżki: \"%s\" W kodzie znajduje siÄ™ " "błąd, sprawdź skÅ‚adniÄ™." @@ -3020,6 +3022,10 @@ msgid "About" msgstr "O silniku" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Uruchom projekt." @@ -5251,6 +5257,7 @@ msgstr "" "mieszczÄ… siÄ™ w kwadratowym obszarze [0.0, 1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7580,6 +7587,8 @@ msgstr "Obroty widoku zablokowane" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"By przybliżyć bardziej, zmieÅ„ pÅ‚aszczyzny odciÄ™cia kamery (Widok -> " +"Ustawienia...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -10971,6 +10980,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Kiedy wybrany, dok zdalnego drzewa sceny bÄ™dzie powodowaÅ‚ przestoje za " +"każdym razem, gdy siÄ™ aktualizuje.\n" +"ZmieÅ„ z powrotem na drzewo lokalne, by zwiÄ™kszyć wydajność." #: editor/scene_tree_dock.cpp msgid "Local" diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 24e2c7146a..a0a9719128 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -2519,8 +2519,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2936,6 +2937,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/pt.po b/editor/translations/pt.po index 26c28d5a19..99f9934e1c 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -13,7 +13,7 @@ # Rueben Stevens <supercell03@gmail.com>, 2017. # SARDON <fabio3_Santos@hotmail.com>, 2017. # Vinicius Gonçalves <viniciusgoncalves21@gmail.com>, 2017. -# ssantos <ssantos@web.de>, 2018, 2019, 2020. +# ssantos <ssantos@web.de>, 2018, 2019, 2020, 2021. # Gonçalo Dinis Guerreiro João <goncalojoao205@gmail.com>, 2019. # Manuela Silva <mmsrs@sky.com>, 2020. # Murilo Gama <murilovsky2030@gmail.com>, 2020. @@ -22,8 +22,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-20 22:25+0000\n" -"Last-Translator: João Lopes <linux-man@hotmail.com>\n" +"PO-Revision-Date: 2021-05-10 15:32+0000\n" +"Last-Translator: ssantos <ssantos@web.de>\n" "Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/" "godot/pt/>\n" "Language: pt\n" @@ -2550,9 +2550,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Incapaz de carregar script addon do caminho: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Incapaz de carregar script addon do caminho: '%s' Parece haver um erro no " "código, reveja a sintaxe." @@ -2684,7 +2686,7 @@ msgstr "%d mais Ficheiros" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "Posição do Painel" +msgstr "Posição da Doca" #: editor/editor_node.cpp msgid "Distraction Free Mode" @@ -2843,7 +2845,7 @@ msgstr "" "irá tentar ligar-se ao endereço IP deste computador, para que o projeto " "possa ser depurado.\n" "Esta opção foi criada para ser usada pela depuração remota (tipicamente com " -"um dispositivo móvel).\n" +"um aparelho móvel).\n" "Não é necessário ativá-la para usar o depurador de GDScript localmente." #: editor/editor_node.cpp @@ -2902,8 +2904,8 @@ msgid "" msgstr "" "Quando esta opção está ativada, quaisquer alterações feitas a uma cena no " "editor serão propagadas no projeto em execução.\n" -"Quando é usada remotamente num dispositivo, é mais eficiente quando a opção " -"do sistema de ficheiros em rede está ativa." +"Quando é usada remotamente num aparelho, é mais eficiente quando a opção do " +"sistema de ficheiros em rede está ativa." #: editor/editor_node.cpp msgid "Synchronize Script Changes" @@ -3000,6 +3002,10 @@ msgid "About" msgstr "Sobre" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Executa o projeto." @@ -3476,7 +3482,7 @@ msgstr "(Instalado)" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download" -msgstr "Download" +msgstr "Descarrega" #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." @@ -3572,7 +3578,7 @@ msgstr "Falhou:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "Download Completo." +msgstr "Descarrega completa." #: editor/export_template_manager.cpp msgid "Cannot remove temporary file:" @@ -5229,6 +5235,7 @@ msgstr "" "contidos na região quadrada [0.0,1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -5454,8 +5461,8 @@ msgid "" "Game Camera Override\n" "Overrides game camera with editor viewport camera." msgstr "" -"Sobreposição de Câmera de Jogo\n" -"Sobrepõe câmara de jogo com câmera viewport do editor." +"Sobreposição de Câmara de Jogo\n" +"Sobrepõe câmara de jogo com câmara viewport do editor." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5463,7 +5470,7 @@ msgid "" "Game Camera Override\n" "No game instance running." msgstr "" -"Sobreposição de Câmera de Jogo\n" +"Sobreposição de Câmara de Jogo\n" "Nenhuma instância de jogo em execução." #: editor/plugins/canvas_item_editor_plugin.cpp @@ -7551,6 +7558,8 @@ msgstr "Rotação da Vista Bloqueada" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Para aumentar o zoom, mude os planos de corte da câmara (Ver -> " +"Configurações...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -9490,7 +9499,7 @@ msgid "" "direction of camera (pass associated inputs to it)." msgstr "" "Devolve queda baseada no produto escalar da normal à superfÃcie e da direção " -"da câmera (passa entradas associadas)." +"da câmara (passa entradas associadas)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -10936,6 +10945,9 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Se selecionada, a doca de árvore da cena Remota vai travar o projeto cada " +"vez que atualiza.\n" +"Volte para a doca de árvore da cena Local para melhorar o desempenho." #: editor/scene_tree_dock.cpp msgid "Local" @@ -11347,11 +11359,11 @@ msgstr "Mudar ângulo de emissão de AudioStreamPlayer3D" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" -msgstr "Mudar FOV da Câmera" +msgstr "Mudar FOV da Câmara" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera Size" -msgstr "Mudar tamanho da Câmera" +msgstr "Mudar tamanho da Câmara" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -12956,7 +12968,7 @@ msgid "" "This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set " "this environment's Background Mode to Canvas (for 2D scenes)." msgstr "" -"Este WorldEnvironment é ignorado. Pode adicionar uma Câmera (para cenas 3D) " +"Este WorldEnvironment é ignorado. Pode adicionar uma Câmara (para cenas 3D) " "ou definir o Modo Background deste ambiente como Canvas (para cenas 2D)." #: scene/animation/animation_blend_tree.cpp diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 3509d790d8..25cdec4f49 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -2650,9 +2650,11 @@ msgstr "" "'%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Não foi possÃvel localizar a área do script para o complemento do plugin em: " "'%s'." @@ -3100,6 +3102,10 @@ msgid "About" msgstr "Sobre" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Roda o projeto." @@ -5339,6 +5345,7 @@ msgstr "" "contidos na região quadrada [0.0,1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 5761aadd1d..d2ecad4c74 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -2557,9 +2557,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Nu a putut fi încărcat scriptul add-on din calea: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Imposibil de încărcat scriptul addon din cale: '%s' Se pare că există o " "eroare în cod, verificaÈ›i sintaxa." @@ -3009,6 +3011,10 @@ msgid "About" msgstr "Despre" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Rulează proiectul." diff --git a/editor/translations/ru.po b/editor/translations/ru.po index b12e95793a..dfda002c17 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -93,11 +93,12 @@ # Dmytro Meleshko <dmytro.meleshko@gmail.com>, 2021. # narrnika <narr13niki@gmail.com>, 2021. # nec-trou <darya.bilyalova@gmail.com>, 2021. +# IindinAndEdresia <kapitan_pol@inbox.ru>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-19 22:33+0000\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" "Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -2624,9 +2625,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Ðе удалоÑÑŒ загрузить Ñкрипт из иÑточника: «%s»." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Ðевозможно загрузить Ñкрипт аддона из иÑточника: «%s». Ð’ коде еÑть ошибка, " "пожалуйÑта, проверьте ÑинтакÑиÑ." @@ -3072,6 +3075,10 @@ msgid "About" msgstr "О Godot Engine" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "ЗапуÑтить проект." @@ -5301,6 +5308,7 @@ msgstr "" "находÑÑ‚ÑÑ Ð² квадратной облаÑти [0.0,1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7627,6 +7635,8 @@ msgstr "Блокировать вращение камеры" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Чтобы увеличить маÑштаб дальше, измените плоÑкоÑти отÑÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹ (Вид -> " +"ÐаÑтройки...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -11018,6 +11028,10 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"ЕÑли выбрано, панель удалённого дерева Ñцены будет вызывать задержки при " +"каждом обновлении.\n" +"Ð”Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти переключитеÑÑŒ обратно в панель локального " +"дерева Ñцены." #: editor/scene_tree_dock.cpp msgid "Local" diff --git a/editor/translations/si.po b/editor/translations/si.po index 20b9001362..7bc9066904 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -2464,8 +2464,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2870,6 +2871,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 95b0fc7136..3bb1bce542 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -2531,9 +2531,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Nepodarilo sa naÄÃtaÅ¥ addon script z cesty: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Nepodarilo sa nájsÅ¥ addon script z cesty: '%s' Vyzerá to tak že by mohol byÅ¥ " "problém v kóde, prosÃm skontrolujte syntax." @@ -2978,6 +2980,10 @@ msgid "About" msgstr "O nás" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "SpustiÅ¥ projekt." diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 500b8b1e54..fd38959e1d 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -2646,8 +2646,9 @@ msgstr "Ni mogoÄe naložiti dodatno skripto iz poti: '%s'." #: editor/editor_node.cpp #, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Ni mogoÄe naložiti dodatno skripto iz poti: '%s' Skripta ni v naÄinu orodje." @@ -3113,6 +3114,10 @@ msgid "About" msgstr "O Programu" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Zaženi projekt." diff --git a/editor/translations/sq.po b/editor/translations/sq.po index 7b2fee263a..abf3243545 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -2586,9 +2586,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "I paaftë të ngarkojë shkrimin e shtojcës nga rruga: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "I paaftë të ngarkojë shkrimin e shtojcës nga rruga: '%s' Me sa duket është " "një gabim në kod, ju lutem kontrolloni sintaksën." @@ -3050,6 +3052,10 @@ msgid "About" msgstr "Rreth" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Luaj projektin." diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index cb28a6b876..6518f9b2bd 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -2763,8 +2763,9 @@ msgstr "ÐеуÑпех при учитавању Ñкриптице додатк #: editor/editor_node.cpp #, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "ÐеуÑпех при учитавању Ñкриптице додатка Ñа путем „%s“. Скриптица није у " "режиму алатке." @@ -3241,6 +3242,10 @@ msgid "About" msgstr "О" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Покрени пројекат." diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index 86ce05a7f2..b646003e1a 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -2477,8 +2477,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2885,6 +2886,10 @@ msgid "About" msgstr "O nama / O Godou" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index 2b3c17e07e..7253693a74 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -26,8 +26,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-24 23:44+0000\n" -"Last-Translator: Jonas Robertsson <jonas.robertsson@posteo.net>\n" +"PO-Revision-Date: 2021-05-03 21:29+0000\n" +"Last-Translator: Alex25820 <Alexander_sjogren@hotmail.se>\n" "Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/" "godot/sv/>\n" "Language: sv\n" @@ -35,7 +35,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5.2-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2599,8 +2599,9 @@ msgstr "Kunde inte ladda addon script frÃ¥n sökväg: '%s'." #: editor/editor_node.cpp #, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "Kunde inte ladda addon script frÃ¥n sökväg: '%s' Skript är inte i " "verktygsläge." @@ -2814,7 +2815,6 @@ msgid "MeshLibrary..." msgstr "MeshBibliotek..." #: editor/editor_node.cpp -#, fuzzy msgid "TileSet..." msgstr "TileSet..." @@ -2830,7 +2830,7 @@ msgstr "Ã…terställ" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "" +msgstr "Diverse projekt eller scenövergripande-verktyg." #: editor/editor_node.cpp editor/project_manager.cpp #: editor/script_create_dialog.cpp @@ -2859,7 +2859,7 @@ msgstr "Exportera..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "Installera Android Build Template..." #: editor/editor_node.cpp msgid "Open Project Data Folder" @@ -3025,7 +3025,7 @@ msgstr "Importera om" #: editor/editor_node.cpp msgid "Send Docs Feedback" -msgstr "" +msgstr "Skicka Dokumentations Feedback" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3036,6 +3036,10 @@ msgid "About" msgstr "Om" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Spela projektet." @@ -3114,7 +3118,7 @@ msgstr "Expandera alla" #: editor/editor_node.cpp msgid "Output" -msgstr "" +msgstr "Utdata" #: editor/editor_node.cpp msgid "Don't Save" @@ -3275,7 +3279,7 @@ msgstr "Redigera:" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "Mät:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" @@ -3287,11 +3291,11 @@ msgstr "Genomsnittlig Tid (sek)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "" +msgstr "Bildruta %" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "" +msgstr "Fysik Bildruta %" #: editor/editor_profiler.cpp msgid "Inclusive" @@ -3303,7 +3307,7 @@ msgstr "Själv" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "" +msgstr "Bildruta #:" #: editor/editor_profiler.cpp msgid "Time" @@ -3323,7 +3327,7 @@ msgstr "PÃ¥" #: editor/editor_properties.cpp msgid "Layer" -msgstr "" +msgstr "Lager" #: editor/editor_properties.cpp msgid "Bit %d, value %d" @@ -3331,7 +3335,7 @@ msgstr "" #: editor/editor_properties.cpp msgid "[Empty]" -msgstr "" +msgstr "[Tom]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp msgid "Assign..." @@ -3377,11 +3381,11 @@ msgstr "Öppna Skript" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" -msgstr "" +msgstr "Ny %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" -msgstr "" +msgstr "Gör Unik" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3407,11 +3411,11 @@ msgstr "" #: editor/editor_properties_array_dict.cpp msgid "Size: " -msgstr "" +msgstr "Storlek: " #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "Sida: " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -3441,7 +3445,7 @@ msgstr "" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "" +msgstr "Skriv din logik i _run() metoden." #: editor/editor_run_script.cpp msgid "There is an edited scene already." @@ -3461,7 +3465,7 @@ msgstr "Kunde inte köra Skript:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "" +msgstr "Glömde du '_run' metoden?" #: editor/editor_spin_slider.cpp msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes." @@ -3558,6 +3562,8 @@ msgid "" "No download links found for this version. Direct download is only available " "for official releases." msgstr "" +"Ingen nedladdningslänk hittades för denna version. Direkt nedladdning finns " +"endast tillgängligt för officiella utgÃ¥vor." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3576,16 +3582,16 @@ msgstr "Inget svar." #: editor/export_template_manager.cpp msgid "Request Failed." -msgstr "" +msgstr "FörfrÃ¥gning Misslyckades." #: editor/export_template_manager.cpp msgid "Redirect Loop." -msgstr "" +msgstr "Omdirigera Loop." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" +msgstr "Misslyckades:" #: editor/export_template_manager.cpp msgid "Download Complete." @@ -3617,11 +3623,11 @@ msgstr "FrÃ¥nkopplad" #: editor/export_template_manager.cpp msgid "Resolving" -msgstr "" +msgstr "Löser" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "Kan inte lösa" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3641,7 +3647,7 @@ msgstr "Ansluten" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Requesting..." -msgstr "" +msgstr "Begär..." #: editor/export_template_manager.cpp msgid "Downloading" @@ -3653,7 +3659,7 @@ msgstr "Anslutningsfel" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "" +msgstr "Fel vid SSL-handskakning" #: editor/export_template_manager.cpp #, fuzzy @@ -3717,7 +3723,7 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "Det gÃ¥r inte att flytta en mapp in i sig själv." #: editor/filesystem_dock.cpp #, fuzzy @@ -3736,11 +3742,11 @@ msgstr "Scen '%s' har trasiga beroenden:" #: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp msgid "No name provided." -msgstr "" +msgstr "Inget namn har angetts." #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters." -msgstr "" +msgstr "Angivet namn innehÃ¥ller ogiltiga tecken." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." @@ -3748,7 +3754,7 @@ msgstr "En fil eller mapp med detta namn finns redan." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "Namnet innehÃ¥ller ogiltiga tecken." #: editor/filesystem_dock.cpp msgid "" @@ -3886,6 +3892,8 @@ msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" +"Skannar Filer,\n" +"Snälla Vänta..." #: editor/filesystem_dock.cpp msgid "Move" @@ -3900,7 +3908,7 @@ msgstr "Byt namn" #: editor/filesystem_dock.cpp msgid "Overwrite" -msgstr "" +msgstr "Skriv över" #: editor/filesystem_dock.cpp #, fuzzy @@ -4030,7 +4038,7 @@ msgstr "Lägg till i Grupp" #: editor/groups_editor.cpp msgid "Empty groups will be automatically removed." -msgstr "" +msgstr "Tomma grupper tas automatiskt bort." #: editor/groups_editor.cpp #, fuzzy @@ -4282,11 +4290,11 @@ msgstr "Skapa Prenumeration" #: editor/plugin_config_dialog.cpp msgid "Plugin Name:" -msgstr "" +msgstr "Plugin Namn:" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" -msgstr "" +msgstr "Undermapp:" #: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp msgid "Language:" @@ -4298,7 +4306,7 @@ msgstr "Skript Namn:" #: editor/plugin_config_dialog.cpp msgid "Activate now?" -msgstr "" +msgstr "Aktivera nu?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -4751,9 +4759,8 @@ msgid "Onion Skinning Options" msgstr "Alternativ" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Directions" -msgstr "Sektioner:" +msgstr "Riktningar" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -5386,9 +5393,8 @@ msgid "Rotate %d CanvasItems" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Rotate CanvasItem \"%s\" to %d degrees" -msgstr "Roterar %s grader." +msgstr "Rotera CanvasItem \"%s\" till %d grader" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move CanvasItem \"%s\" Anchor" @@ -5840,9 +5846,8 @@ msgid "Auto Insert Key" msgstr "Anim Infoga Nyckel" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Animation Key and Pose Options" -msgstr "Animation längd (i sekunder)." +msgstr "Animations Nyckel och Pose Inställningar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" @@ -8361,9 +8366,8 @@ msgid "Enable Priority" msgstr "Redigera Filter" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Filter tiles" -msgstr "Filtrera Filer..." +msgstr "Filtrera tiles" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Give a TileSet resource to this TileMap to use its tiles." @@ -8616,9 +8620,8 @@ msgid "" msgstr "" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete selected Rect." -msgstr "Ta bort valda filer?" +msgstr "Ta bort vald Rect." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -9834,9 +9837,8 @@ msgid "Export Project" msgstr "Exportera Projekt" #: editor/project_export.cpp -#, fuzzy msgid "Export mode?" -msgstr "Exportera Projekt" +msgstr "Export läge?" #: editor/project_export.cpp #, fuzzy diff --git a/editor/translations/ta.po b/editor/translations/ta.po index 9b57af9595..9107c43f7c 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -2468,8 +2468,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2876,6 +2877,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/te.po b/editor/translations/te.po index a3c48112a6..c983fbe90e 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -2441,8 +2441,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2847,6 +2848,10 @@ msgid "About" msgstr "à°—à±à°°à°¿à°‚à°šà°¿" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index d865b04b16..24b007b891 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -8,12 +8,15 @@ # Anonymous <noreply@weblate.org>, 2020. # Lon3r <mptube.p@gmail.com>, 2020. # Kongfa Warorot <gongpha@hotmail.com>, 2020, 2021. +# Kongfa Waroros <gongpha@hotmail.com>, 2021. +# Atirut Wattanamongkol <artjang301@gmail.com>, 2021. +# PT 07 <porton555@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-05 14:28+0000\n" -"Last-Translator: Thanachart Monpassorn <nunf_2539@hotmail.com>\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" +"Last-Translator: Kongfa Waroros <gongpha@hotmail.com>\n" "Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/" "th/>\n" "Language: th\n" @@ -21,50 +24,53 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." -msgstr "ชนิดตัวà¹à¸›à¸£à¹ƒà¸™ convert() ผิดพลาด ใช้ค่าคงที่ TYPE_* เท่านั้น" +msgstr "ชนิดตัวà¹à¸›à¸£à¹ƒà¸™ convert() ผิด ใช้ค่าคงที่ TYPE_* เท่านั้น" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "พบ String ที่มีความยาวเท่าà¸à¸±à¸š 1 (ตัวà¸à¸±à¸à¸©à¸£)" +msgstr "String นี้ต้à¸à¸‡à¸¡à¸µà¸„วามยาวเท่าà¸à¸±à¸š 1 ตัวà¸à¸±à¸à¸©à¸£" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "ไบต์ไม่ครบหรืà¸à¸œà¸´à¸”รูปà¹à¸šà¸š ไม่สามารถà¹à¸›à¸¥à¸‡à¸„่าได้" +msgstr "ไบต์ไม่เพียงพà¸à¸«à¸£à¸·à¸à¸£à¸¹à¸›à¹à¸šà¸šà¹„ม่ถูà¸à¸•้à¸à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸–à¸à¸”รหัสไบต์" #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "ค่าà¸à¸´à¸™à¸žà¸¸à¸•ผิดพลาด %i (ไม่ผ่าน)" +msgstr "à¸à¸´à¸™à¸žà¸¸à¸• %i ใน expression ไม่ถูà¸à¸•้à¸à¸‡ (ไม่ผ่าน)" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "self ไม่สามารถใช้ได้เนื่à¸à¸‡à¸ˆà¸²à¸ instance ว่าง (ไม่ผ่าน)" +msgstr "ไม่สามารถใช้ self ได้เนื่à¸à¸‡à¸ˆà¸²à¸à¸à¸´à¸™à¸ªà¹à¸•นซ์เป็น null (ไม่ผ่าน)" #: core/math/expression.cpp +#, fuzzy msgid "Invalid operands to operator %s, %s and %s." -msgstr "ดำเนินà¸à¸²à¸£à¸œà¸´à¸”พลาดที่ตัวดำเนินà¸à¸²à¸£ %s, %s à¹à¸¥à¸° %s" +msgstr "ตัวดำเนินà¸à¸²à¸£à¸ªà¸³à¸«à¸£à¸±à¸šà¹‚à¸à¹€à¸›à¸à¹€à¸£à¹€à¸•à¸à¸£à¹Œ %s, %s à¹à¸¥à¸° %s ไม่ถูà¸à¸•้à¸à¸‡" #: core/math/expression.cpp +#, fuzzy msgid "Invalid index of type %s for base type %s" -msgstr "ดัชนีขà¸à¸‡à¸Šà¸™à¸´à¸” '%s' ผิดพลาด ในชนิดà¸à¸²à¸™ %s" +msgstr "ดัชนีขà¸à¸‡à¸Šà¸™à¸´à¸” '%s' ไม่ถูà¸à¸•้à¸à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¸Šà¸™à¸´à¸”à¸à¸²à¸™ %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "ชื่à¸à¸”ัชนีขà¸à¸‡ '%s' ผิดพลาด สำหรับà¸à¸²à¸™ %s" +msgstr "ชื่à¸à¸”ัชนีขà¸à¸‡ '%s' ผิดพลาดสำหรับà¸à¸²à¸™ %s" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" msgstr "à¸à¸²à¸£à¹Œà¸à¸´à¸§à¹€à¸¡à¸™à¸•์ขà¸à¸‡à¸„à¸à¸™à¸ªà¸•รัค '%s' ผิดพลาด" #: core/math/expression.cpp +#, fuzzy msgid "On call to '%s':" -msgstr "เรียภ'%s':" +msgstr "ขณะเรียภ'%s':" #: core/ustring.cpp msgid "B" @@ -99,12 +105,14 @@ msgid "Free" msgstr "à¸à¸´à¸ªà¸£à¸°" #: editor/animation_bezier_editor.cpp +#, fuzzy msgid "Balanced" -msgstr "ความสมดุล" +msgstr "สมดุล" #: editor/animation_bezier_editor.cpp +#, fuzzy msgid "Mirror" -msgstr "à¸à¸£à¸°à¸ˆà¸" +msgstr "สะท้à¸à¸™" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" @@ -115,12 +123,13 @@ msgid "Value:" msgstr "ค่า:" #: editor/animation_bezier_editor.cpp +#, fuzzy msgid "Insert Key Here" -msgstr "เพิ่มปุ่มที่นี่" +msgstr "เพิ่มคีย์ที่นี่" #: editor/animation_bezier_editor.cpp msgid "Duplicate Selected Key(s)" -msgstr "ทำซ้ำคีย์ที่เลืà¸à¸" +msgstr "คัดลà¸à¸à¸„ีย์ที่เลืà¸à¸" #: editor/animation_bezier_editor.cpp msgid "Delete Selected Key(s)" @@ -135,8 +144,9 @@ msgid "Move Bezier Points" msgstr "ย้ายจุดเบซิเยร์" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Duplicate Keys" -msgstr "ทำซ้ำคีย์à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "คีย์à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸‹à¹‰à¸³à¸à¸±à¸™" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Delete Keys" @@ -147,10 +157,12 @@ msgid "Anim Change Keyframe Time" msgstr "à¹à¸à¹‰à¹„ขเวลาคีย์เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Change Transition" -msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เปลี่ยนทรานสิชันขà¸à¸‡à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Change Transform" msgstr "เคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" @@ -171,8 +183,9 @@ msgid "Anim Multi Change Transition" msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Multi Change Transform" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" +msgstr "à¹à¸à¹‰à¹„ขตำà¹à¸«à¸™à¹ˆà¸‡à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Value" @@ -189,11 +202,11 @@ msgstr "à¹à¸à¹‰à¹„ขความยาวà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation Loop" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¸‚à¸à¸‡à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp msgid "Property Track" -msgstr "คุณสมบัติà¹à¸—ร็à¸" +msgstr "à¹à¸—ร็à¸à¸„ุณสมบัติ" #: editor/animation_track_editor.cpp msgid "3D Transform Track" @@ -250,7 +263,7 @@ msgstr "เปลี่ยนที่à¸à¸¢à¸¹à¹ˆà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." -msgstr "เปิด/ปิดà¸à¸²à¸£à¸•ิดตามà¹à¸—ร็à¸à¸™à¸µà¹‰" +msgstr "เปิด/ปิดà¹à¸—ร็à¸à¸™à¸µà¹‰" #: editor/animation_track_editor.cpp msgid "Update Mode (How this property is set)" @@ -261,8 +274,9 @@ msgid "Interpolation Mode" msgstr "โหมดà¸à¸²à¸£à¹à¸à¹‰à¹„ข" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "โหมดลูปวาร์ป (à¹à¸à¹‰à¹„ขจุดสิ้นสุดด้วยจุดเริ่มตต้นบนลูป)" +msgstr "โหมดวนลูป (Interpolate จุดสิ้นสุดด้วยจุดเริ่มตต้นบนลูป)" #: editor/animation_track_editor.cpp msgid "Remove this track." @@ -348,7 +362,7 @@ msgstr "เพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆà¸ªà¸³à¸«à¸£à¸±à¸š %s à¹à¸¥à¸ #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "เพิ่ม %d à¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆà¹à¸¥à¸°à¹€à¸žà¸´à¹ˆà¸¡à¸„ีย์?" +msgstr "เพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆ %d à¹à¸—ร็à¸à¹à¸¥à¸°à¹€à¸žà¸´à¹ˆà¸¡à¸„ีย์?" #: editor/animation_track_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp @@ -391,17 +405,19 @@ msgid "Rearrange Tracks" msgstr "จัดเรียงà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Transform tracks only apply to Spatial-based nodes." -msgstr "à¹à¸›à¸¥à¸‡à¹à¸—ร็à¸à¹€à¸‰à¸žà¸²à¸°à¸—ี่ Spatial-based nodes" +msgstr "à¹à¸—ร็ภTransform ส่งผลต่à¸à¹‚นดประเภท Spatial-based เท่านั้น" #: editor/animation_track_editor.cpp +#, fuzzy msgid "" "Audio tracks can only point to nodes of type:\n" "-AudioStreamPlayer\n" "-AudioStreamPlayer2D\n" "-AudioStreamPlayer3D" msgstr "" -"à¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡à¸ªà¸²à¸¡à¸²à¸£à¸–ติดไว้บนโหนดชนิดเหล่านี้เท่านั้น:\n" +"à¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡à¸ªà¸²à¸¡à¸²à¸£à¸–ชี้ไปยังโนดชนิดเหล่านี้ได้เท่านั้น:\n" "-AudioStreamPlayer\n" "-AudioStreamPlayer2D\n" "-AudioStreamPlayer3D" @@ -505,7 +521,7 @@ msgstr "เลืà¸à¸à¹‚หนด AnimationPlayer เพื่à¸à¸ªà¸£à¹‰à¸²à #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." -msgstr "โชว์à¹à¸—ร็à¸à¸ˆà¸²à¸à¹‚หนดที่เลืà¸à¸à¹ƒà¸™à¸œà¸±à¸‡à¹€à¸—่านั้น" +msgstr "à¹à¸ªà¸”งà¹à¸—ร็à¸à¸ˆà¸²à¸à¹‚หนดที่เลืà¸à¸à¹ƒà¸™à¸œà¸±à¸‡à¹€à¸—่านั้น" #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." @@ -1634,11 +1650,11 @@ msgstr "à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸à¹à¸šà¸š 32 bit PCK à¹à¸šà¸šà¸à¸±à¸‡à¸•ั #: editor/editor_feature_profile.cpp msgid "3D Editor" -msgstr "เà¸à¸”ิเตà¸à¸£à¹Œ 3D" +msgstr "ตัวà¹à¸à¹‰à¹„ข 3D" #: editor/editor_feature_profile.cpp msgid "Script Editor" -msgstr "เà¸à¸”ิเตà¸à¸£à¹Œà¸ªà¸„ริปต์" +msgstr "ตัวà¹à¸à¹‰à¹„ขสคริปต์" #: editor/editor_feature_profile.cpp msgid "Asset Library" @@ -1674,7 +1690,7 @@ msgstr "มีโปรไฟล์ที่มีชื่à¸à¸™à¸µà¹‰à¸à¸¢à¸¹ #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "(เà¸à¸”ิเตà¸à¸£à¹Œà¸–ูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™, คุณสมบัติถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)" +msgstr "(ตัวà¹à¸à¹‰à¹„ขถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™, คุณสมบัติถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)" #: editor/editor_feature_profile.cpp msgid "(Properties Disabled)" @@ -1682,7 +1698,7 @@ msgstr "(ปิดà¸à¸²à¸£à¸—ำงานคุณสมบัติ)" #: editor/editor_feature_profile.cpp msgid "(Editor Disabled)" -msgstr "(เà¸à¸”ิเตà¸à¸£à¹Œà¸–ูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)" +msgstr "(ตัวà¹à¸à¹‰à¹„ขถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)" #: editor/editor_feature_profile.cpp msgid "Class Options:" @@ -1690,7 +1706,7 @@ msgstr "ตั้งค่าคลาส:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" -msgstr "เปิดà¸à¸²à¸£à¸—ำงานเà¸à¸”ิเตà¸à¸£à¹Œà¸•ามบริบท" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานตัวà¹à¸à¹‰à¹„ขตามบริบท" #: editor/editor_feature_profile.cpp msgid "Enabled Properties:" @@ -1775,7 +1791,7 @@ msgstr "ส่งà¸à¸à¸à¹‚ปรไฟล์" #: editor/editor_feature_profile.cpp msgid "Manage Editor Feature Profiles" -msgstr "จัดà¸à¸²à¸£à¸£à¸²à¸¢à¸¥à¸°à¹€à¸à¸µà¸¢à¸”คุณสมบัติเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "จัดà¸à¸²à¸£à¸£à¸²à¸¢à¸¥à¸°à¹€à¸à¸µà¸¢à¸”คุณสมบัติตัวà¹à¸à¹‰à¹„ข" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1981,7 +1997,7 @@ msgstr "ค่าเริ่มต้น:" #: editor/editor_help.cpp msgid "Methods" -msgstr "เมท็à¸à¸”" +msgstr "เมธà¸à¸”" #: editor/editor_help.cpp msgid "Theme Properties" @@ -2278,8 +2294,8 @@ msgid "" "An error occurred while trying to save the editor layout.\n" "Make sure the editor's user data path is writable." msgstr "" -"เà¸à¸´à¸”ข้à¸à¸œà¸´à¸”พลาดขณะà¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึà¸à¹€à¸¥à¹€à¸à¸²à¸•์ขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ\n" -"ตรวจสà¸à¸šà¹ƒà¸«à¹‰à¹à¸™à¹ˆà¹ƒà¸ˆà¸§à¹ˆà¸²à¸—ี่à¸à¸¢à¸¹à¹ˆà¸‚้à¸à¸¡à¸¹à¸¥à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹€à¸à¸”ิเตà¸à¸£à¹Œà¸ªà¸²à¸¡à¸²à¸£à¸–à¹à¸à¹‰à¹„ขได้" +"เà¸à¸´à¸”ข้à¸à¸œà¸´à¸”พลาดขณะà¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึà¸à¹€à¸¥à¹€à¸à¸²à¸•์ขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข\n" +"ตรวจสà¸à¸šà¹ƒà¸«à¹‰à¹à¸™à¹ˆà¹ƒà¸ˆà¸§à¹ˆà¸²à¸—ี่à¸à¸¢à¸¹à¹ˆà¸‚้à¸à¸¡à¸¹à¸¥à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸•ัวà¹à¸à¹‰à¹„ขสามารถà¹à¸à¹‰à¹„ขได้" #: editor/editor_node.cpp msgid "" @@ -2287,8 +2303,9 @@ msgid "" "To restore the Default layout to its base settings, use the Delete Layout " "option and delete the Default layout." msgstr "" -"เลเà¸à¸²à¸•์เà¸à¸”ิเตà¸à¸£à¹Œà¸”ั้งเดิมถูà¸à¹€à¸‚ียนทับ\n" -"เพื่à¸à¸—ี่จะà¸à¸¹à¹‰à¸„ืนเลเà¸à¸²à¸•์ดั้งเดิมไปยังà¸à¸²à¸£à¸•ั้งค่าพื้นà¸à¸²à¸™ ใช้à¸à¸²à¸£à¸•ั้งค่า Delete Layout à¹à¸¥à¸°à¸¥à¸šà¹€à¸¥à¹€à¸à¸²à¸•์ตั้งเดิม" +"à¸à¸²à¸£à¸ˆà¸±à¸”เค้าโครงตัวà¹à¸à¹‰à¹„ขดั้งเดิมถูà¸à¹€à¸‚ียนทับ\n" +"เพื่à¸à¸—ี่จะà¸à¸¹à¹‰à¸„ืนเค้าโครงดั้งเดิมไปยังà¸à¸²à¸£à¸•ั้งค่าพื้นà¸à¸²à¸™ ใช้à¸à¸²à¸£à¸•ั้งค่า Delete Layout " +"à¹à¸¥à¸°à¸¥à¸šà¹€à¸„้าโครงตั้งเดิม" #: editor/editor_node.cpp msgid "Layout name not found!" @@ -2497,9 +2514,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "ไม่สามารถโหลดสคริปต์จาà¸: '%s'" #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "ไม่สามารถโหลดสคริปต์ส่วนเสริมจาà¸: '%s' เหมืà¸à¸™à¸§à¹ˆà¸²à¸ˆà¸°à¹€à¸à¸´à¸”ข้à¸à¸œà¸´à¸”พลาดขึ้นในโค้ด " "à¸à¸£à¸¸à¸“าเช็ตรูปà¹à¸šà¸šà¸à¸²à¸£à¹€à¸‚ียนโค้ด" @@ -2799,7 +2818,7 @@ msgid "" msgstr "" "ถ้าเปิดตัวเลืà¸à¸à¸™à¸µà¹‰ à¸à¸²à¸£à¹ƒà¸Šà¹‰ deploy สำหรับà¹à¸à¸™à¸”รà¸à¸¢à¸”์จะส่งà¸à¸à¸à¹€à¸‰à¸žà¸²à¸°à¹„ฟล์ปà¸à¸´à¸šà¸±à¸•ิà¸à¸²à¸£ " "ไม่มีข้à¸à¸¡à¸¹à¸¥à¹‚ปรเจà¸à¸•์\n" -"ระบบไฟล์จะถูà¸à¸ˆà¸±à¸”เตรียมจาà¸à¹‚ปรเจ็à¸à¸•์โดยเà¸à¸”ิเตà¸à¸£à¹Œà¸šà¸™à¹€à¸„รืà¸à¸‚่าย\n" +"ระบบไฟล์จะถูà¸à¸ˆà¸±à¸”เตรียมจาà¸à¹‚ปรเจ็à¸à¸•์โดยตัวà¹à¸à¹‰à¹„ขบนเครืà¸à¸‚่าย\n" "บน Android จะ deploy โดยใช้สาย USB เพื่à¸à¸›à¸£à¸°à¸ªà¸´à¸—ธิภาพที่ดี " "ตัวเลืà¸à¸à¸™à¸µà¹‰à¸ˆà¸°à¸Šà¹ˆà¸§à¸¢à¹ƒà¸«à¹‰à¸à¸²à¸£à¸—ดสà¸à¸šà¹€à¸à¸¡à¹€à¸£à¹‡à¸§à¸‚ึ้น สำหรับโปรเจà¸à¸•์ขนาดใหà¸à¹ˆ" @@ -2837,7 +2856,7 @@ msgid "" "filesystem option is enabled." msgstr "" "เมื่à¸à¹€à¸›à¸´à¸”ใช้งานตัวเลืà¸à¸à¸™à¸µà¹‰ à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹ƒà¸” ๆ " -"ที่เà¸à¸´à¸”ขึ้นà¸à¸±à¸šà¸‰à¸²à¸à¹ƒà¸™à¹€à¸à¸”ิเตà¸à¸£à¹Œà¸ˆà¸°à¸›à¸£à¸²à¸à¸à¹ƒà¸™à¹‚ปรเจ็à¸à¸•์ที่à¸à¸³à¸¥à¸±à¸‡à¸—ำงานà¸à¸¢à¸¹à¹ˆ\n" +"ที่เà¸à¸´à¸”ขึ้นà¸à¸±à¸šà¸‰à¸²à¸à¹ƒà¸™à¸•ัวà¹à¸à¹‰à¹„ขจะปราà¸à¸à¹ƒà¸™à¹‚ปรเจ็à¸à¸•์ที่à¸à¸³à¸¥à¸±à¸‡à¸—ำงานà¸à¸¢à¸¹à¹ˆ\n" "เมื่à¸à¸£à¸µà¹‚มตผ่านà¸à¸¸à¸›à¸à¸£à¸“์ นี่จะมีประสิทธิภาพมาà¸à¸‚ึ้นเมื่à¸à¹€à¸›à¸´à¸”ใช้งานตัวเลืà¸à¸à¸£à¸°à¸šà¸šà¹„ฟล์เครืà¸à¸‚่าย" #: editor/editor_node.cpp @@ -2856,15 +2875,15 @@ msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "เà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "ตัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Editor Settings..." -msgstr "ตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "ตั้งค่าตัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "เลย์เà¸à¸²à¸•์เà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "เค้าโครงตัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Take Screenshot" @@ -2872,7 +2891,7 @@ msgstr "ถ่ายภาพหน้าจà¸" #: editor/editor_node.cpp msgid "Screenshots are stored in the Editor Data/Settings Folder." -msgstr "ภาพหน้าจà¸à¸ˆà¸°à¸–ูà¸à¹€à¸à¹‡à¸šà¹„ว้ในโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/à¸à¸²à¸£à¸•ั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "ภาพหน้าจà¸à¸ˆà¸°à¸–ูà¸à¹€à¸à¹‡à¸šà¹„ว้ในโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/à¸à¸²à¸£à¸•ั้งค่าขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Toggle Fullscreen" @@ -2884,19 +2903,19 @@ msgstr "เปิด/ปิด คà¸à¸™à¹‚ซลระบบ" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/ตั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/ตั้งค่าขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚à¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚à¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Open Editor Settings Folder" -msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸à¸²à¸£à¸•ั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸à¸²à¸£à¸•ั้งค่าขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข" #: editor/editor_node.cpp msgid "Manage Editor Features..." -msgstr "จัดà¸à¸²à¸£à¸Ÿà¸µà¹€à¸ˆà¸à¸£à¹Œà¸‚à¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ..." +msgstr "จัดà¸à¸²à¸£à¸¥à¸±à¸à¸©à¸“ะเฉพาะขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข..." #: editor/editor_node.cpp msgid "Manage Export Templates..." @@ -2932,6 +2951,10 @@ msgid "About" msgstr "เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸š" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "เล่นโปรเจà¸à¸•์" @@ -2969,7 +2992,7 @@ msgstr "เลืà¸à¸à¹€à¸¥à¹ˆà¸™à¸‰à¸²à¸" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹„ดรเวà¸à¸£à¹Œà¸à¸²à¸£à¹Œà¸”จà¸à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¹€à¸à¸”ิเตà¸à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆ" +msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹„ดรเวà¸à¸£à¹Œà¸à¸²à¸£à¹Œà¸”จà¸à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¸•ัวà¹à¸à¹‰à¹„ขใหม่" #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp @@ -3099,15 +3122,15 @@ msgstr "เลืà¸à¸" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ 2D" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ข 2D" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ 3D" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ข 3D" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œà¸ªà¸„ริปต์" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" @@ -3115,11 +3138,11 @@ msgstr "เปิดà¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œà¸–ัดไป" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ขà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" #: editor/editor_node.h msgid "Warning!" @@ -4036,7 +4059,7 @@ msgstr "บันทึà¸à¸‰à¸²à¸, นำเข้าà¹à¸¥à¸°à¹€à¸£à¸´à¹ˆà¸¡à #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." -msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸Šà¸™à¸´à¸”ขà¸à¸‡à¹„ฟล์ที่นำเข้า จำเป็นต้à¸à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¹€à¸à¸”ิเตà¸à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆ" +msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸Šà¸™à¸´à¸”ขà¸à¸‡à¹„ฟล์ที่นำเข้า จำเป็นต้à¸à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¸•ัวà¹à¸à¹‰à¹„ขใหม่" #: editor/import_dock.cpp msgid "" @@ -4285,7 +4308,7 @@ msgstr "จุด" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Open Editor" -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ข" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -5122,11 +5145,11 @@ msgid "" msgstr "mesh บางส่วนไม่ถูà¸à¸•้à¸à¸‡ ตรวจสà¸à¸šà¹ƒà¸«à¹‰à¹à¸™à¹ˆà¹ƒà¸ˆà¸§à¹ˆà¸²à¸„่า UV2 à¸à¸¢à¸¹à¹ˆà¹ƒà¸™à¸žà¸·à¹‰à¸™à¸—ี่สี่เหลี่ยม [0.0,1.0]" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" -"เà¸à¸”ิเตà¸à¸£à¹Œ Godot ถูà¸à¸ªà¸£à¹‰à¸²à¸‡à¹‚ดยไม่ได้สนับสนุน ray tracing ดังนั้นจึงไม่สามารถ bake lightmaps " -"ได้" +"ตัวà¹à¸à¹‰à¹„ข Godot ถูà¸à¸ªà¸£à¹‰à¸²à¸‡à¹‚ดยไม่ได้สนับสนุน Ray Tracing ดังนั้นจึงไม่สามารถปั้น Lightmap ได้" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" @@ -5344,7 +5367,7 @@ msgid "" "Overrides game camera with editor viewport camera." msgstr "" "เขียนทับà¸à¸¥à¹‰à¸à¸‡à¸‚à¸à¸‡à¹€à¸à¸¡à¸ªà¹Œ\n" -"เขียนทับà¸à¸¥à¹‰à¸à¸‡à¸‚à¸à¸‡à¹€à¸à¸¡à¸ªà¹Œà¸”้วยเà¸à¸”ิเตà¸à¸£à¹Œà¸‚à¸à¸‡à¸§à¸´à¸§à¸žà¸à¸£à¹Œà¸•ขà¸à¸‡à¸à¸¥à¹‰à¸à¸‡" +"เขียนทับà¸à¸¥à¹‰à¸à¸‡à¸‚à¸à¸‡à¹€à¸à¸¡à¸ªà¹Œà¸”้วยตัวà¹à¸à¹‰à¹„ขขà¸à¸‡à¸§à¸´à¸§à¸žà¸à¸£à¹Œà¸•ขà¸à¸‡à¸à¸¥à¹‰à¸à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6475,11 +6498,11 @@ msgstr "เติมน้ำหนัà¸à¹‚ครง" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Open Polygon 2D UV editor." -msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ Polygon 2D UV" +msgstr "เปิดตัวà¹à¸à¹‰à¹„ข Polygon 2D UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon 2D UV Editor" -msgstr "เà¸à¸”ิเตà¸à¸£à¹Œ Polygon 2D UV" +msgstr "ตัวà¹à¸à¹‰à¹„ข Polygon 2D UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV" @@ -6734,7 +6757,8 @@ msgstr "สคริปต์ไม่ได้à¸à¸¢à¸¹à¹ˆà¹ƒà¸™à¹‚หมดเ #: editor/plugins/script_editor_plugin.cpp msgid "" "To run this script, it must inherit EditorScript and be set to tool mode." -msgstr "เพื่à¸à¸—ี่จะเริ่มสคริปต์ จำเป็นต้à¸à¸‡à¸ªà¸·à¸šà¸—à¸à¸”สคริปต์เà¸à¸”ิเตà¸à¸£à¹Œ à¹à¸¥à¸°à¸•ั้งโหมดเป็นโหมดเครื่à¸à¸‡à¸¡à¸·à¸" +msgstr "" +"หาà¸à¸•้à¸à¸‡à¸à¸²à¸£à¸—ี่จะเริ่มสคริปต์ มันจำเป็นต้à¸à¸‡à¸ªà¸·à¸šà¸—à¸à¸”จาภEditorScript à¹à¸¥à¸°à¸•ั้งโหมดเป็นโหมดเครื่à¸à¸‡à¸¡à¸·à¸" #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" @@ -6894,7 +6918,7 @@ msgstr "เปิดตัวดีบัà¸à¸„้างไว้" #: editor/plugins/script_editor_plugin.cpp msgid "Debug with External Editor" -msgstr "ดีบัà¸à¸”้วยเà¸à¸”ิเตà¸à¸£à¹Œà¸à¸·à¹ˆà¸™" +msgstr "ดีบัà¸à¸”้วยตัวà¹à¸à¹‰à¹„ขภายนà¸à¸" #: editor/plugins/script_editor_plugin.cpp msgid "Open Godot online documentation." @@ -7426,14 +7450,14 @@ msgstr "ล็à¸à¸„à¸à¸²à¸£à¸«à¸¡à¸¸à¸™à¸§à¸´à¸§à¹à¸¥à¹‰à¸§" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" -msgstr "" +msgstr "หาà¸à¸•้à¸à¸‡à¸à¸²à¸£à¸—ี่จะขยายให้ไà¸à¸¥à¸à¸à¸à¹„ป ให้เปลี่ยนระนà¸à¸šà¸à¸²à¸£à¸•ัดขà¸à¸‡à¸à¸¥à¹‰à¸à¸‡ (มุมมà¸à¸‡ -> ตั้งค่า...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" -"หมายเหตุ: ค่า FPS ที่à¹à¸ªà¸”งเป็นà¸à¸±à¸•ราเฟรมขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ\n" +"หมายเหตุ: ค่า FPS ที่à¹à¸ªà¸”งเป็นà¸à¸±à¸•ราเฟรมขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ข\n" "ไม่สามารถใช้เป็นตัวบ่งชี้ประสิทธิภาพในเà¸à¸¡à¸—ี่à¹à¸—้จริงได้" #: editor/plugins/spatial_editor_plugin.cpp @@ -7933,7 +7957,7 @@ msgstr "สร้างเทมเพลตเปล่า" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Editor Template" -msgstr "สร้างเทมเพลตเปล่าสำหรับเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "สร้างà¹à¸¡à¹ˆà¹à¸šà¸šà¹€à¸›à¸¥à¹ˆà¸²à¸ªà¸³à¸«à¸£à¸±à¸šà¸•ัวà¹à¸à¹‰à¹„ข" #: editor/plugins/theme_editor_plugin.cpp msgid "Create From Current Editor Theme" @@ -9861,8 +9885,8 @@ msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" -"เปลี่ยนภาษาà¹à¸¥à¹‰à¸§\n" -"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¸¡à¸µà¸œà¸¥à¹€à¸¡à¸·à¹ˆà¸à¹€à¸›à¸´à¸”เà¸à¸”ิเตà¸à¸£à¹Œà¸«à¸£à¸·à¸à¸•ัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์ใหม่" +"ภาษาได้ถูà¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸¥à¹‰à¸§\n" +"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¸¡à¸µà¸œà¸¥à¹€à¸¡à¸·à¹ˆà¸à¹€à¸›à¸´à¸”ตัวà¹à¸à¹‰à¹„ขหรืà¸à¸•ัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์ใหม่" #: editor/project_manager.cpp msgid "" @@ -10168,7 +10192,7 @@ msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "The editor must be restarted for changes to take effect." -msgstr "ต้à¸à¸‡à¹€à¸›à¸´à¸”เà¸à¸”ิเตà¸à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆà¹€à¸žà¸·à¹ˆà¸à¹ƒà¸«à¹‰à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸¡à¸µà¸œà¸¥" +msgstr "ต้à¸à¸‡à¹€à¸›à¸´à¸”ตัวà¹à¸à¹‰à¹„ขใหม่เพื่à¸à¹ƒà¸«à¹‰à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸¡à¸µà¸œà¸¥" #: editor/project_settings_editor.cpp msgid "Input Map" @@ -10685,8 +10709,8 @@ msgid "" "This is probably because this editor was built with all language modules " "disabled." msgstr "" -"ไม่สามารถà¹à¸™à¸šà¸ªà¸„ริปต์: ไม่มีภาษาโปรà¹à¸à¸£à¸¡à¸—ี่เปิดใช้\n" -"à¸à¸²à¸ˆà¹€à¸›à¹‡à¸™à¹€à¸žà¸£à¸²à¸°à¹€à¸à¸”ิเตà¸à¸£à¹Œà¸™à¸µà¹‰à¸ªà¸£à¹‰à¸²à¸‡à¸‚ึ้นโดยปิดใช้งานโมดูลภาษาโปรà¹à¸à¸£à¸¡à¸—ั้งหมด" +"ไม่สามารถà¹à¸™à¸šà¸ªà¸„ริปต์: ไม่มีภาษาที่เปิดใช้\n" +"à¸à¸²à¸ˆà¹€à¸›à¹‡à¸™à¹€à¸žà¸£à¸²à¸°à¸•ัวà¹à¸à¹‰à¹„ขนี้สร้างขึ้นโดยปิดใช้งานโมดูลภาษาทั้งหมด" #: editor/scene_tree_dock.cpp msgid "Add Child Node" @@ -10752,6 +10776,8 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"หาà¸à¹€à¸¥à¸·à¸à¸à¹„ว้ à¹à¸œà¸‡à¸œà¸±à¸‡à¸‰à¸²à¸à¸ˆà¸²à¸à¸£à¸°à¸¢à¸°à¹„à¸à¸¥à¸ˆà¸°à¸—ำให้โปรเจà¸à¸•์เà¸à¸´à¸”à¸à¸²à¸£à¸à¸£à¸°à¸•ุà¸à¸—ุà¸à¸„รั้งที่à¸à¸±à¸›à¹€à¸”ต\n" +"สลับà¸à¸¥à¸±à¸šà¹„ปยัง à¹à¸œà¸‡à¸œà¸±à¸‡à¸‰à¸²à¸à¸ˆà¸²à¸à¸£à¸°à¸¢à¸°à¹ƒà¸à¸¥à¹‰à¹€à¸žà¸·à¹ˆà¸à¹€à¸žà¸´à¹ˆà¸¡à¸›à¸£à¸°à¸ªà¸´à¸—ธิภาพในà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™" #: editor/scene_tree_dock.cpp msgid "Local" @@ -10961,7 +10987,7 @@ msgstr "ไฟล์สคริปต์มีà¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" msgid "" "Note: Built-in scripts have some limitations and can't be edited using an " "external editor." -msgstr "หมายเหตุ: บิวท์à¸à¸´à¸™à¸ªà¸„ริปต์มีข้à¸à¸ˆà¸³à¸à¸±à¸” ไม่สามารถà¹à¸à¹‰à¹„ขได้โดยใช้เà¸à¸”ิเตà¸à¸£à¹Œà¸ ายนà¸à¸" +msgstr "หมายเหตุ: สคริปต์ในตัวมีข้à¸à¸ˆà¸³à¸à¸±à¸” ไม่สามารถà¹à¸à¹‰à¹„ขได้โดยใช้ตัวà¹à¸à¹‰à¹„ขภายนà¸à¸" #: editor/script_create_dialog.cpp msgid "Class Name:" @@ -11141,7 +11167,7 @@ msgstr "à¹à¸à¹‰à¹„ขทางลัด" #: editor/settings_config_dialog.cpp msgid "Editor Settings" -msgstr "ตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "à¸à¸²à¸£à¸•ั้งค่าตัวà¹à¸à¹‰à¹„ข" #: editor/settings_config_dialog.cpp msgid "Shortcuts" @@ -11980,7 +12006,7 @@ msgstr "เทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸à¸™ #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." -msgstr "Debug keystore ไม่ได้ถูà¸à¸•ั้งไว้ในตั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œà¸«à¸£à¸·à¸à¹ƒà¸™à¸žà¸£à¸µà¹€à¸‹à¹‡à¸•" +msgstr "ดีบัภKeystore ไม่ได้ถูà¸à¸•ั้งไว้ในตั้งค่าขà¸à¸‡à¸•ัวà¹à¸à¹‰à¹„ขหรืà¸à¹ƒà¸™à¸žà¸£à¸µà¹€à¸‹à¹‡à¸•" #: platform/android/export/export.cpp msgid "Release keystore incorrectly configured in the export preset." @@ -11988,11 +12014,11 @@ msgstr "Release keystore à¸à¸³à¸«à¸™à¸”ค่าไว้à¸à¸¢à¹ˆà¸²à¸‡à¹„มà #: platform/android/export/export.cpp msgid "A valid Android SDK path is required in Editor Settings." -msgstr "ต้à¸à¸‡à¸à¸²à¸£à¸—ี่à¸à¸¢à¸¹à¹ˆà¸‚à¸à¸‡ Android SDK ที่ถูà¸à¸•้à¸à¸‡ ในà¸à¸²à¸£à¸•ั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "ต้à¸à¸‡à¸à¸²à¸£à¸—ี่à¸à¸¢à¸¹à¹ˆà¸‚à¸à¸‡ Android SDK ที่ถูà¸à¸•้à¸à¸‡ ในà¸à¸²à¸£à¸•ั้งค่าตัวà¹à¸à¹‰à¹„ข" #: platform/android/export/export.cpp msgid "Invalid Android SDK path in Editor Settings." -msgstr "ที่à¸à¸¢à¸¹à¹ˆ Android SDK ไม่ถูà¸à¸•้à¸à¸‡à¹ƒà¸™à¸•ั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "ที่à¸à¸¢à¸¹à¹ˆ Android SDK ไม่ถูà¸à¸•้à¸à¸‡à¹ƒà¸™à¸à¸²à¸£à¸•ั้งค่าตัวà¹à¸à¹‰à¹„ข" #: platform/android/export/export.cpp msgid "Missing 'platform-tools' directory!" @@ -12004,7 +12030,7 @@ msgstr "ไม่พบคำสั่ง adb ขà¸à¸‡ Android SDK platform-too #: platform/android/export/export.cpp msgid "Please check in the Android SDK directory specified in Editor Settings." -msgstr "โปรดตรวจสà¸à¸šà¹ƒà¸™à¹„ดเร็à¸à¸—à¸à¸£à¸µ Android SDK ที่ระบุใตัวตั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "à¸à¸£à¸¸à¸“าตรวจสà¸à¸šà¹ƒà¸™à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸‚à¸à¸‡ Android SDK ที่ระบุไว้ในà¸à¸²à¸£à¸•ั้งค่าตัวà¹à¸à¹‰à¹„ข" #: platform/android/export/export.cpp msgid "Missing 'build-tools' directory!" @@ -12737,7 +12763,7 @@ msgstr "" #: scene/gui/color_picker.cpp msgid "Pick a color from the editor window." -msgstr "เลืà¸à¸à¸ªà¸µà¸ˆà¸²à¸à¸«à¸™à¹‰à¸²à¸•่างเà¸à¸”ิเตà¸à¸£à¹Œ" +msgstr "เลืà¸à¸à¸ªà¸µà¸ˆà¸²à¸à¸«à¸™à¹‰à¸²à¸•่างตัวà¹à¸à¹‰à¹„ข" #: scene/gui/color_picker.cpp msgid "HSV" @@ -12762,7 +12788,7 @@ msgid "" "If you don't intend to add a script, use a plain Control node instead." msgstr "" "ตัวคà¸à¸™à¹€à¸—นเนà¸à¸£à¹Œà¹€à¸à¸‡à¹„ม่มีบทบาทเว้นà¹à¸•่คุณจะตั้งค่าลัà¸à¸©à¸“ะà¸à¸²à¸£à¸—ำงานขà¸à¸‡à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸à¸‡à¹ƒà¸™à¸ªà¸„ริปต์\n" -"หาà¸à¸„ุณไม่ต้à¸à¸‡à¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¸ªà¸„ริปต์ให้ใช้โหนด \"ควบคุม\" ปà¸à¸•ิà¹à¸—น" +"หาà¸à¸„ุณไม่ต้à¸à¸‡à¸à¸²à¸£à¹€à¸žà¸´à¹ˆà¸¡à¸ªà¸„ริปต์ให้ใช้โหนด Control ปà¸à¸•ิà¹à¸—น" #: scene/gui/control.cpp msgid "" @@ -12795,7 +12821,7 @@ msgid "" "running." msgstr "" "ป๊à¸à¸›à¸à¸±à¸›à¸ˆà¸°à¸–ูà¸à¸‹à¹ˆà¸à¸™à¸•ามค่าเริ่มต้นยà¸à¹€à¸§à¹‰à¸™à¹à¸•่คุณจะเรียà¸à¹ƒà¸Šà¹‰ popup() หรืà¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™ popup*() ใด ๆ " -"à¸à¸²à¸£à¸—ำให้มà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้สำหรับà¸à¸²à¸£à¹à¸à¹‰à¹„ขเป็นเรื่à¸à¸‡à¸›à¸à¸•ิ à¹à¸•่จะซ่à¸à¸™à¹€à¸¡à¸·à¹ˆà¸à¸—ำงาน" +"คุณสามารถทำให้มันมà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้เมื่à¸à¹à¸à¹‰à¹„ข à¹à¸•่มันจะถูà¸à¸‹à¹ˆà¸à¸™à¹€à¸¡à¸·à¹ˆà¸à¸—ำงานจริง" #: scene/gui/range.cpp msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 47ac3ea764..43c8aa9e52 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -57,12 +57,13 @@ # Suleyman Poyraz <zaryob.dev@gmail.com>, 2020. # ÇaÄŸlar KOPARIR <ckoparir@gmail.com>, 2021. # Cem Eren Fukara <cefukara@hotmail.com>, 2021. +# Jafar Tarverdiyev <cefertarverdiyevv@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-31 03:53+0000\n" -"Last-Translator: OÄŸuz Ersen <oguzersen@protonmail.com>\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" +"Last-Translator: Jafar Tarverdiyev <cefertarverdiyevv@gmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -70,7 +71,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2587,9 +2588,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "Yoldaki eklenti betiÄŸi yüklenemedi: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" "'%s' adresindeki eklenti betik yüklenemiyor. Kodun içinde bir hata var gibi " "görünüyor, lütfen sözdizimini kontrol edin." @@ -3035,6 +3038,10 @@ msgid "About" msgstr "Hakkında" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Projeti oynat." @@ -5266,6 +5273,7 @@ msgstr "" "içerdiÄŸinden emin olun." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7589,6 +7597,8 @@ msgstr "Dönme Kilitli Görünüm" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Daha fazla yakınlaÅŸtırmak için, kameranın kırpma düzlemlerini deÄŸiÅŸtirin " +"(Görünüm -> Ayarlar ...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po index d13e2e5705..a28dce76f9 100644 --- a/editor/translations/tzm.po +++ b/editor/translations/tzm.po @@ -2439,8 +2439,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2845,6 +2846,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index 1eed824645..251c85a8ba 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-31 03:53+0000\n" +"PO-Revision-Date: 2021-05-14 20:34+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -30,7 +30,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -2557,11 +2557,13 @@ msgstr "Ðеможливо завантажити Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÑкриР#: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"Ðеможливо завантажити Ñкрипт Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð· шлÑху «%s». ЗдаєтьÑÑ, у коді Ñ” " -"помилка, будь лаÑка, перевірте ÑинтакÑиÑ." +"Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ додатковий Ñкрипт з такою адреÑою: «%s». Причиною " +"може бути помилка у коді цього Ñкрипту.\n" +"Вимикаємо додаток у «%s», щоб запобігти подальшим помилкам." #: editor/editor_node.cpp msgid "" @@ -3008,6 +3010,10 @@ msgid "About" msgstr "Про" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "ЗапуÑтити проєкт." @@ -5245,6 +5251,7 @@ msgstr "" "потраплÑють до квадратної облаÑті [0.0,1.0]." #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" @@ -7576,6 +7583,8 @@ msgstr "ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду заблоковано" msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" msgstr "" +"Ð”Ð»Ñ Ð¿Ð¾Ð´Ð°Ð»ÑŒÑˆÐ¾Ð³Ð¾ маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½Ñ–Ñ‚ÑŒ площини Ð¾Ð±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ ÐºÐ°Ð¼ÐµÑ€Ð¸ (ПереглÑд -> " +"Параметри...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -10974,6 +10983,10 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"Якщо позначено, бічна панель ієрархії віддаленої Ñцени призупинÑтиме роботу " +"проєкту під Ñ‡Ð°Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ Ñвого оновленнÑ.\n" +"ПеремкнітьÑÑ Ð½Ð°Ð·Ð°Ð´ на бічну панель ієрархії локальної Ñцени, щоб пришвидшити " +"роботу." #: editor/scene_tree_dock.cpp msgid "Local" @@ -13217,6 +13230,19 @@ msgid "Constants cannot be modified." msgstr "Сталі не можна змінювати." #~ msgid "" +#~ "Godot editor was built without ray tracing support; lightmaps can't be " +#~ "baked.\n" +#~ "If you are using an Apple Silicon-based Mac, try forcing Rosetta " +#~ "emulation on Godot.app in the application settings\n" +#~ "then restart the editor." +#~ msgstr "" +#~ "Редактор Godot було зібрано без підтримки траÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ–Ð²; мапи " +#~ "оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñтворити не вдаÑтьÑÑ.\n" +#~ "Якщо ви кориÑтуєтеÑÑ Mac на оÑнові Apple Silicon, Ñпробуйте примуÑово " +#~ "вÑтановити емулÑцію Rosetta Ð´Ð»Ñ Godot.app у параметрах програми,\n" +#~ "а потім перезапуÑтіть редактор." + +#~ msgid "" #~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0." #~ msgstr "" #~ "InterpolatedCamera вважаєтьÑÑ Ð·Ð°Ñтарілою, Ñ—Ñ— буде вилучено у Godot 4.0." diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 697cc3e5a4..32a88830cb 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -2489,8 +2489,9 @@ msgstr "" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -2899,6 +2900,10 @@ msgid "About" msgstr "" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 74d8666e35..3939ac7a4d 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -18,11 +18,13 @@ # LetterC67 <hoangdeptoong@gmail.com>, 2020, 2021. # Rev <revolnoom7801@gmail.com>, 2021. # SyliawDeV <thanhlongstranger@gmail.com>, 2021. +# IoeCmcomc <hopdaigia2004@gmail.com>, 2021. +# Hung <hungthitkhia@gmail.com>, 2021. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-04-19 22:33+0000\n" +"PO-Revision-Date: 2021-05-14 11:20+0000\n" "Last-Translator: Rev <revolnoom7801@gmail.com>\n" "Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/" "godot/vi/>\n" @@ -904,7 +906,7 @@ msgstr "Bạn muốn xoá tất cả kết nối từ tÃn hiệu \"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" -msgstr "TÃn hiệu (Signal)" +msgstr "TÃn hiệu" #: editor/connections_dialog.cpp msgid "Filter signals" @@ -936,7 +938,7 @@ msgstr "Äổi" #: editor/create_dialog.cpp msgid "Create New %s" -msgstr "Tạo %s Má»›i" +msgstr "Tạo %s má»›i" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -1316,7 +1318,7 @@ msgstr "Tắt tiếng" #: editor/editor_audio_buses.cpp msgid "Bypass" -msgstr "" +msgstr "Bá» qua" #: editor/editor_audio_buses.cpp msgid "Bus options" @@ -1381,7 +1383,7 @@ msgstr "Không có tệp tin '%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "Bố trÃ" +msgstr "Bố cục" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -1467,7 +1469,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" -msgstr "" +msgstr "Di chuyển Tá»± nạp" #: editor/editor_autoload_settings.cpp msgid "Remove Autoload" @@ -1620,16 +1622,15 @@ msgstr "" "ETC2' hoặc 'Nháºp Pvrtc' trong Cà i đặt Dá»± án." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'PVRTC' texture compression for the driver fallback " "to GLES2.\n" "Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"Ná»n tảng yêu cầu kiểu nén 'ETC' cho trình Ä‘iá»u khiển dá»± phòng GLES2.\n" -"Chá»n kÃch hoạt 'Nháºp ETC' trong Cà i đặt Dá»± án, hoặc chá»n tắt 'KÃch hoạt " -"Trình Ä‘iá»u khiển Dá»± phòng'." +"Ná»n tảng yêu cầu kiểu nén 'PVRTC' cho driver tương thÃch ngược GLES2.\n" +"Chá»n kÃch hoạt 'Nháºp PVRTC' trong Cà i đặt Dá»± án, hoặc tắt 'KÃch hoạt Driver " +"Tương thÃch Ngược'." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1649,7 +1650,7 @@ msgstr "Không tìm thấy tệp tin mẫu:" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." -msgstr "" +msgstr "Ở các bản xuất 32-bit thì PCK được nhúng và o không thể lá»›n hÆ¡n 4 GiB." #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -1781,9 +1782,8 @@ msgid "Erase Profile" msgstr "Xoá hồ sÆ¡" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Godot Feature Profile" -msgstr "Quản lý trình tÃnh năng" +msgstr "Quản lý TÃnh năng Godot" #: editor/editor_feature_profile.cpp msgid "Import Profile(s)" @@ -1892,7 +1892,7 @@ msgstr "Báºt tắt Chức năng" #: editor/editor_file_dialog.cpp msgid "Focus Path" -msgstr "Táºp trung ÄÆ°á»ng dẫn" +msgstr "ÄÆ°á»ng dẫn Táºp trung" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" @@ -1983,7 +1983,7 @@ msgstr "ÄÆ°á»£c thừa kế bởi:" #: editor/editor_help.cpp msgid "Description" -msgstr "Mô tả" +msgstr "Ná»™i dung" #: editor/editor_help.cpp msgid "Online Tutorials" @@ -2007,11 +2007,11 @@ msgstr "Hà m" #: editor/editor_help.cpp msgid "Theme Properties" -msgstr "Cà i đặt Tông mà u" +msgstr "Thuá»™c tÃnh Chá»§ Ä‘á»" #: editor/editor_help.cpp msgid "Enumerations" -msgstr "" +msgstr "Liệt kê" #: editor/editor_help.cpp msgid "Constants" @@ -2019,7 +2019,7 @@ msgstr "Hằng số" #: editor/editor_help.cpp msgid "Property Descriptions" -msgstr "Mô tả thuá»™c tÃnh" +msgstr "Ná»™i dung Thuá»™c tÃnh" #: editor/editor_help.cpp msgid "(value)" @@ -2035,7 +2035,7 @@ msgstr "" #: editor/editor_help.cpp msgid "Method Descriptions" -msgstr "Mô tả hà m" +msgstr "Ná»™i dung Hà m" #: editor/editor_help.cpp msgid "" @@ -2318,7 +2318,7 @@ msgid "" "option and delete the Default layout." msgstr "" "Bố cục mặc định cá»§a trình chỉnh sá»a đã bị ghi đè.\n" -"Äể hồi lại bố cục mặc định vá» cà i đặt gốc, sá» dụng tùy chá»n \"Xóa bố cục\" " +"Äể khôi phục bố cục mặc định vá» cà i đặt gốc, sá» dụng tùy chá»n \"Xóa bố cục\" " "rồi xóa bố cục \"Mặc định\"." #: editor/editor_node.cpp @@ -2480,7 +2480,7 @@ msgstr "Có" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "Thoát trình biên táºp?" +msgstr "Thoát trình chỉnh sá»a?" #: editor/editor_node.cpp msgid "Open Project Manager?" @@ -2521,33 +2521,38 @@ msgstr "Mở lại Cảnh đã đóng" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" +"Không thể kÃch hoạt plugin addon tại: '%s' phân tÃch thiết láºp thất bại." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: '%s'." -msgstr "" +msgstr "Không thể tìm trưá»ng táºp lệnh cá»§a plugin addon tại: '%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "Không thể nạp tệp lệnh bổ trợ từ đưá»ng dẫn: '%s'." +msgstr "Không thể tải tệp addon từ đưá»ng dẫn: '%s'." #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" -"Không thể nạp tệp lệnh bổ trợ từ đưá»ng dẫn: '%s' Có vẻ có lá»—i trong mã " -"nguồn, hãy kiểm tra lại cú pháp." +"Không thể nạp tệp lệnh bổ trợ từ đưá»ng dẫn: '%s' Có vẻ có lá»—i trong mã, hãy " +"kiểm tra lại cú pháp." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" -"Không thể tải script addon từ đưá»ng dẫn: '%s' Kiểu gốc không phải " +"Không thể tải táºp lệnh addon từ đưá»ng dẫn: '%s' Kiểu gốc không phải " "EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" +"Không thể tải script addon từ đưá»ng dẫn: '%s' Script không ở trong \"trạng " +"thái công cụ\"." #: editor/editor_node.cpp msgid "" @@ -2790,9 +2795,8 @@ msgid "Tools" msgstr "Công cụ" #: editor/editor_node.cpp -#, fuzzy msgid "Orphan Resource Explorer..." -msgstr "Lưu tà i nguyên thà nh ..." +msgstr "Tìm kiếm tà i nguyên mất gốc..." #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2819,10 +2823,9 @@ msgstr "" #: editor/editor_node.cpp msgid "Small Deploy with Network Filesystem" -msgstr "" +msgstr "Triển khai nhá» vá»›i hệ thống tệp mạng" #: editor/editor_node.cpp -#, fuzzy msgid "" "When this option is enabled, using one-click deploy for Android will only " "export an executable without the project data.\n" @@ -2831,9 +2834,9 @@ msgid "" "On Android, deploying will use the USB cable for faster performance. This " "option speeds up testing for projects with large assets." msgstr "" -"Khi tuỳ chá»n nà y được báºt, lúc xuất hoặc triển khai sẽ tạo má»™t tệp thá»±c thi " -"tối giản nhất.\n" -"Hệ thống tệp tin sẽ được cung cấp từ dá»± án bởi trình soạn thảo qua mạng.\n" +"Khi tuỳ chá»n nà y được báºt, lúc xuất hoặc triển khai ra Android sẽ chỉ tạo " +"má»™t tệp thá»±c thi tối giản nhất.\n" +"Hệ thống tệp tin sẽ được cung cấp từ dá»± án bởi trình chỉnh sá»a qua mạng.\n" "Trên ná»n tảng Android, triển khai sẽ sá» dụng cáp USB để có hiệu suất nhanh " "hÆ¡n. Tuỳ chá»n nà y tăng tốc độ khi thá» nghiệm cho các trò chÆ¡i nặng." @@ -2872,6 +2875,10 @@ msgid "" "When used remotely on a device, this is more efficient when the network " "filesystem option is enabled." msgstr "" +"Khi tuỳ chá»n nà y được báºt, bất cứ thay đổi nà o được tạo ra lên cảnh trong " +"trình chỉnh sá»a sẽ được sao lại trong dá»± án Ä‘ang chạy.\n" +"Khi được dùng từ xa trên má»™t thiết bị, là m như váºy sẽ hiệu quả hÆ¡n khi tuỳ " +"chá»n hệ thống tệp mạng được báºt." #: editor/editor_node.cpp msgid "Synchronize Script Changes" @@ -2887,11 +2894,11 @@ msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "Editor (trình biên táºp)" +msgstr "Trình chỉnh sá»a" #: editor/editor_node.cpp msgid "Editor Settings..." -msgstr "Cà i đặt Trình biên táºp..." +msgstr "Cà i đặt trình chỉnh sá»a..." #: editor/editor_node.cpp msgid "Editor Layout" @@ -2904,32 +2911,31 @@ msgstr "Chụp mà n hình" #: editor/editor_node.cpp msgid "Screenshots are stored in the Editor Data/Settings Folder." msgstr "" -"Ảnh chụp mà n hình được lưu ở thư mục Dữ liệu/Cà i đặt cá»§a trình biên táºp." +"Ảnh chụp mà n hình được lưu ở thư mục Dữ liệu/Cà i đặt cá»§a trình chỉnh sá»a." #: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Chế độ Toà n mà n hình" #: editor/editor_node.cpp -#, fuzzy msgid "Toggle System Console" -msgstr "Chế độ Phân chia" +msgstr "KÃch hoạt Console Hệ thống" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "Mở thư mục dữ liệu Trình biên táºp" +msgstr "Mở thư mục dữ liệu cá»§a trình chỉnh sá»a" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "Mở thư mục dữ liệu Trình biên táºp" +msgstr "Mở thư mục dữ liệu cá»§a trình chỉnh sá»a" #: editor/editor_node.cpp msgid "Open Editor Settings Folder" -msgstr "Mở thư mục Thiết láºp Trình biên táºp" +msgstr "Mở thư mục Thiết láºp trình chỉnh sá»a" #: editor/editor_node.cpp msgid "Manage Editor Features..." -msgstr "Quản lý tÃnh năng Trình biên táºp..." +msgstr "Quản lý tÃnh năng trình chỉnh sá»a..." #: editor/editor_node.cpp msgid "Manage Export Templates..." @@ -2965,6 +2971,10 @@ msgid "About" msgstr "Vá» chúng tôi" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "Chạy dá»± án." @@ -3002,7 +3012,8 @@ msgstr "Chạy Cảnh Tuỳ Chá»n" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "Thay đổi trình Ä‘iá»u khiển Video cần phải khởi động lại Trình biên táºp." +msgstr "" +"Thay đổi trình Ä‘iá»u khiển Video cần phải khởi động lại trình chỉnh sá»a." #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp @@ -3011,7 +3022,7 @@ msgstr "Lưu & Khởi động lại" #: editor/editor_node.cpp msgid "Spins when the editor window redraws." -msgstr "Xoay khi cá»a sổ trình biên soạn được vẽ lại." +msgstr "Xoay khi cá»a sổ trình chỉnh sá»a được vẽ lại." #: editor/editor_node.cpp msgid "Update Continuously" @@ -3134,15 +3145,15 @@ msgstr "Chá»n" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "Mở Trình biên táºp 2D" +msgstr "Mở trình chỉnh sá»a 2D" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "Mở Trình biên táºp 3D" +msgstr "Mở trình chỉnh sá»a 3D" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "Mở Trình biên soạn Mã lệnh" +msgstr "Mở trình chỉnh sá»a táºp lệnh" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" @@ -3150,11 +3161,11 @@ msgstr "Mở Thư viện Nguyên liệu" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "Mở Trình biên soạn tiếp theo" +msgstr "Mở trình chỉnh sá»a tiếp theo" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "Mở Trình biên soạn trước đó" +msgstr "Mở trình chỉnh sá»a trước đó" #: editor/editor_node.h msgid "Warning!" @@ -3231,7 +3242,7 @@ msgstr "Bao gồm" #: editor/editor_profiler.cpp msgid "Self" -msgstr "" +msgstr "ChÃnh nó" #: editor/editor_profiler.cpp msgid "Frame #:" @@ -3243,7 +3254,7 @@ msgstr "Thá»i gian" #: editor/editor_profiler.cpp msgid "Calls" -msgstr "" +msgstr "Lượt gá»i" #: editor/editor_properties.cpp msgid "Edit Text:" @@ -3305,13 +3316,12 @@ msgid "New Script" msgstr "Mã lệnh má»›i" #: editor/editor_properties.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Extend Script" -msgstr "Tạo Script" +msgstr "Mở rá»™ng Script" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" -msgstr "Má»›i %s" +msgstr "%s má»›i" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" @@ -3416,9 +3426,8 @@ msgid "Import From Node:" msgstr "Nháºp từ Nút:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Redownload" -msgstr "Tải lại" +msgstr "Tải lại xuống" #: editor/export_template_manager.cpp msgid "Uninstall" @@ -3446,9 +3455,8 @@ msgid "(Current)" msgstr "(Hiện tại)" #: editor/export_template_manager.cpp -#, fuzzy msgid "Retrieving mirrors, please wait..." -msgstr "Äang tìm các trang mirror, đợi xÃu..." +msgstr "Äang tìm các trang dá»± phòng, đợi xÃu..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" @@ -3483,9 +3491,9 @@ msgid "Error getting the list of mirrors." msgstr "Có lá»—i khi lấy các trang mirror." #: editor/export_template_manager.cpp -#, fuzzy msgid "Error parsing JSON of mirror list. Please report this issue!" -msgstr "Có lá»—i khi phân tÃch JSON cá»§a danh sách trang mirror. Hãy báo cáo lá»—i!" +msgstr "" +"Có lá»—i khi phân tÃch JSON cá»§a danh sách trang dá»± phòng. Hãy báo cáo lá»—i!" #: editor/export_template_manager.cpp msgid "" @@ -3528,9 +3536,8 @@ msgid "Download Complete." msgstr "Tải xuống xong." #: editor/export_template_manager.cpp -#, fuzzy msgid "Cannot remove temporary file:" -msgstr "Không thể gỡ bá»:" +msgstr "Không thể gỡ bá» tệp tạm thá»i:" #: editor/export_template_manager.cpp msgid "" @@ -3611,9 +3618,8 @@ msgid "Remove Template" msgstr "Xóa Template" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Chá»n file template" +msgstr "Chá»n tệp bản mẫu" #: editor/export_template_manager.cpp msgid "Godot Export Templates" @@ -3628,9 +3634,9 @@ msgid "Download Templates" msgstr "Tải Xuống Các Mẫu Xuất Bản" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select mirror from list: (Shift+Click: Open in Browser)" -msgstr "Chá»n trang mirror từ danh sách: (Shift+Nhấp: Mở trong trình duyệt)" +msgstr "" +"Chá»n trang dá»± phòng từ danh sách: (Shift + Chuá»™t trái: Mở trong trình duyệt)" #: editor/filesystem_dock.cpp msgid "Favorites" @@ -3718,9 +3724,8 @@ msgid "New Inherited Scene" msgstr "Tạo Cảnh kế thừa má»›i" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Set As Main Scene" -msgstr "Chá»n má»™t Scene chÃnh" +msgstr "Chá»n là m Scene chÃnh" #: editor/filesystem_dock.cpp msgid "Open Scenes" @@ -3777,9 +3782,8 @@ msgid "Duplicate..." msgstr "Nhân đôi..." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Move to Trash" -msgstr "Di chuyển Nút" +msgstr "Di chuyển và o Thùng rác" #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." @@ -3829,9 +3833,8 @@ msgid "Overwrite" msgstr "Ghi đè" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Create Scene" -msgstr "Tạo từ Scene" +msgstr "Tạo Scene" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" @@ -3891,19 +3894,16 @@ msgid "Searching..." msgstr "Äang tìm kiếm ..." #: editor/find_in_files.cpp -#, fuzzy msgid "%d match in %d file." -msgstr "Tìm thấy %d khá»›p." +msgstr "Tìm thấy %d Ä‘iểm khá»›p trong %d tệp." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d file." -msgstr "Tìm thấy %d khá»›p." +msgstr "Tìm thấy %d Ä‘iểm khá»›p trong %d tệp." #: editor/find_in_files.cpp -#, fuzzy msgid "%d matches in %d files." -msgstr "Tìm thấy %d khá»›p." +msgstr "Tìm thấy %d Ä‘iểm khá»›p trong %d tệp." #: editor/groups_editor.cpp msgid "Add to Group" @@ -3922,14 +3922,12 @@ msgid "Invalid group name." msgstr "Tên nhóm không hợp lệ." #: editor/groups_editor.cpp -#, fuzzy msgid "Rename Group" -msgstr "Quản lý Nhóm" +msgstr "Äổi tên Nhóm" #: editor/groups_editor.cpp -#, fuzzy msgid "Delete Group" -msgstr "Xoá bố cục" +msgstr "Xoá Nhóm" #: editor/groups_editor.cpp editor/node_dock.cpp msgid "Groups" @@ -3953,9 +3951,8 @@ msgid "Empty groups will be automatically removed." msgstr "Các nhóm trống sẽ tá»± động bị xóa." #: editor/groups_editor.cpp -#, fuzzy msgid "Group Editor" -msgstr "Trình viết mã lệnh" +msgstr "Trình chỉnh sá»a Nhóm" #: editor/groups_editor.cpp msgid "Manage Groups" @@ -3999,7 +3996,7 @@ msgstr "Nháºp và o Nhiá»u cảnh" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "Nháºp nhiá»u Scene + Váºt liệu" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp @@ -4044,18 +4041,16 @@ msgid "Saving..." msgstr "Äang lưu ..." #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Select Importer" -msgstr "Chế độ chá»n" +msgstr "Chá»n bá»™ nháºp" #: editor/import_defaults_editor.cpp msgid "Importer:" msgstr "Công cụ nháºp:" #: editor/import_defaults_editor.cpp -#, fuzzy msgid "Reset to Defaults" -msgstr "Nạp mặc định" +msgstr "Äặt lại thà nh mặc định" #: editor/import_dock.cpp msgid "Keep File (No Import)" @@ -4091,7 +4086,7 @@ msgstr "Lưu các cảnh, nháºp lại, rồi tái khởi động" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." -msgstr "Sá»a kiểu cá»§a tệp đã nháºp yêu cầu khởi động lại trình biên soạn." +msgstr "Sá»a kiểu cá»§a tệp đã nháºp yêu cầu khởi động lại trình chỉnh sá»a." #: editor/import_dock.cpp msgid "" @@ -4340,7 +4335,7 @@ msgstr "Äiểm" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Open Editor" -msgstr "Mở Trình biên soạn" +msgstr "Mở trình chỉnh sá»a" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4358,23 +4353,20 @@ msgid "Add Triangle" msgstr "Thêm Tam giác" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Change BlendSpace2D Limits" -msgstr "Äổi Thá»i gian Chuyển Animation" +msgstr "Äổi các giá»›i hạn BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Change BlendSpace2D Labels" -msgstr "Äổi Thá»i gian Chuyển Animation" +msgstr "Äổi các nhãn BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Remove BlendSpace2D Point" msgstr "Xóa Ä‘iểm BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Remove BlendSpace2D Triangle" -msgstr "Xoá Variable" +msgstr "Bá» các tam giác BlendSpace2D" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "BlendSpace2D does not belong to an AnimationTree node." @@ -4749,11 +4741,11 @@ msgstr "Äồng bá»™ hoá" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" -msgstr "" +msgstr "Ở cuối" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "Di chuyển" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." @@ -4839,11 +4831,11 @@ msgstr "Giảm dần (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend" -msgstr "" +msgstr "Hoà " #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Mix" -msgstr "" +msgstr "Trá»™n" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Auto Restart:" @@ -4978,7 +4970,7 @@ msgstr "Không có phản hồi từ host:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve hostname:" -msgstr "" +msgstr "Không thể phân giải tên máy lưu trữ:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, return code:" @@ -5001,7 +4993,6 @@ msgid "Request failed, too many redirects" msgstr "Yêu cầu thất bại, chuyển hướng quá nhiá»u" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Redirect loop." msgstr "Chuyển hướng vòng lặp." @@ -5224,7 +5215,7 @@ msgstr "bước" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" -msgstr "" +msgstr "Äá»™ lệch xoay:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Step:" @@ -5336,43 +5327,40 @@ msgid "Bottom Left" msgstr "Góc dưới trái" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Left" -msgstr "Trung tâm Bên trái" +msgstr "Giữa bên trái" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Top" -msgstr "" +msgstr "Trên giữa" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Right" -msgstr "" +msgstr "Phải giữa" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Bottom" -msgstr "" +msgstr "Dưới giữa" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center" -msgstr "" +msgstr "Giữa" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Left Wide" -msgstr "Tịnh tuyến" +msgstr "Rá»™ng bên trái" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Top Wide" -msgstr "" +msgstr "Rá»™ng bên trên" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Right Wide" -msgstr "Tịnh tuyến" +msgstr "Rá»™ng bên phải" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Bottom Wide" -msgstr "" +msgstr "Rá»™ng bên dưới" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "VCenter Wide" @@ -5408,6 +5396,8 @@ msgid "" "Game Camera Override\n" "Overrides game camera with editor viewport camera." msgstr "" +"Ghi đè máy quay trò chÆ¡i\n" +"Ghi đè máy quay trò chÆ¡i bằng máy quay cổng xem cá»§a trình chỉnh sá»a." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5415,6 +5405,8 @@ msgid "" "Game Camera Override\n" "No game instance running." msgstr "" +"Ghi đè máy quay trò chÆ¡i\n" +"Không có thá»±c thể trò chÆ¡i nà y Ä‘ang chạy." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5438,7 +5430,7 @@ msgstr "Bá» nhóm đã chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" -msgstr "" +msgstr "Dán tư thé" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Guides" @@ -5528,9 +5520,8 @@ msgid "Pan Mode" msgstr "Chế độ Xoay" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Ruler Mode" -msgstr "Chế độ Tỉ lệ" +msgstr "Chế độ thước" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Toggle smart snapping." @@ -5635,7 +5626,7 @@ msgstr "Tạo xương tuỳ chá»n từ các nút" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Custom Bones" -msgstr "" +msgstr "Xoá sạch các xương tuỳ chỉnh" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5643,9 +5634,8 @@ msgid "View" msgstr "Hiện thị" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Always Show Grid" -msgstr "Hiện lưới" +msgstr "Luôn hiện lưới" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" @@ -5673,7 +5663,7 @@ msgstr "Hiện biểu tượng Nhóm và Khóa" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" -msgstr "" +msgstr "Căn giữa phần được chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" @@ -5681,7 +5671,7 @@ msgstr "Lá»±a chá»n khung hình" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Xem trước tỉ lệ bức vẽ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5696,9 +5686,8 @@ msgid "Scale mask for inserting keys." msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Insert keys (based on mask)." -msgstr "Chèn Khóa (dá»±a trên mask)." +msgstr "Chèn khóa (dá»±a trên mặt nạ)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5709,9 +5698,8 @@ msgid "" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Auto Insert Key" -msgstr "Chèn Key Anim" +msgstr "Tá»± chèn khoá" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5728,7 +5716,7 @@ msgstr "Sao chép Tư thế" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Pose" -msgstr "" +msgstr "Xoá sạch tư thế" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Multiply grid step by 2" @@ -5740,7 +5728,7 @@ msgstr "Chia đôi bước lưới" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Pan View" -msgstr "" +msgstr "Di chuyển tầm nhìn" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5837,9 +5825,8 @@ msgstr "Äiểm ảnh viá»n" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Directed Border Pixels" -msgstr "Các Thư mục và Tệp tin:" +msgstr "Pixel ở Viá»n cạnh Có hướng" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5853,7 +5840,7 @@ msgstr "" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" -msgstr "" +msgstr "CPUParticles" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp @@ -5907,14 +5894,12 @@ msgid "Remove Point" msgstr "Xoá Ä‘iểm" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "Tịnh tuyến" +msgstr "Tịnh tuyến trái" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Tịnh tuyến" +msgstr "Tịnh tuyến phải" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Preset" @@ -5954,7 +5939,7 @@ msgstr "Mục" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item List Editor" -msgstr "" +msgstr "Trình chỉnh sá»a ItemList" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" @@ -6225,7 +6210,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Target Surface:" -msgstr "" +msgstr "Bá» mặt mục tiêu:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" @@ -6261,7 +6246,7 @@ msgstr "Thu phóng ngẫu nhiên:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate" -msgstr "" +msgstr "Äiá»n" #: editor/plugins/navigation_polygon_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp @@ -6325,7 +6310,7 @@ msgstr "" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points" -msgstr "" +msgstr "Các Ä‘iểm bá» mặt" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points+Normal (Directed)" @@ -6337,7 +6322,7 @@ msgstr "Âm lượng" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Source: " -msgstr "" +msgstr "Nguồn phát ra: " #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -6345,7 +6330,7 @@ msgstr "" #: editor/plugins/particles_editor_plugin.cpp msgid "Generating AABB" -msgstr "" +msgstr "Äang sinh AABB" #: editor/plugins/particles_editor_plugin.cpp msgid "Generate Visibility AABB" @@ -6392,7 +6377,7 @@ msgstr "Chá»n Points" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Shift+Drag: Select Control Points" -msgstr "" +msgstr "Shift+Kéo: Chá»n các Ä‘iểm Ä‘iá»u khiển" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -6467,7 +6452,7 @@ msgstr "Tách đưá»ng" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Path Point" -msgstr "" +msgstr "Loại bá» Ä‘iểm đưá»ng dẫn" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Out-Control Point" @@ -6499,22 +6484,24 @@ msgid "" "No texture in this polygon.\n" "Set a texture to be able to edit UV." msgstr "" +"Không có hình kết cấu nà o trong Ä‘a giác nà y.\n" +"Äặt má»™ hình kết cấu để có thể chỉnh sá»a UV." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" -msgstr "" +msgstr "Tạo bản đồ UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "" "Polygon 2D has internal vertices, so it can no longer be edited in the " "viewport." msgstr "" -"Äa giác 2D có đỉnh nằm trong, vì váºy không thể chỉnh sá»a trong cổng xem." +"Äa giác 2D có đỉnh nằm trong, vì váºy nó không thể được chỉnh sá»a trong cổng " +"xem." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Polygon & UV" -msgstr "" +msgstr "Tạo Ä‘a giác & UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Internal Vertex" @@ -6558,7 +6545,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV" -msgstr "" +msgstr "UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Points" @@ -6715,7 +6702,7 @@ msgstr "Dán tà i nguyên" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_editor.cpp msgid "Instance:" -msgstr "" +msgstr "Thế:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp @@ -6948,7 +6935,7 @@ msgstr "Tìm kiếm" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "" +msgstr "Bước và o" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" @@ -6956,7 +6943,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" -msgstr "" +msgstr "Thoát" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp @@ -7263,11 +7250,11 @@ msgstr "Chạy IK" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" -msgstr "" +msgstr "Vuông góc" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective" -msgstr "" +msgstr "Phối cảnh" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Aborted." @@ -7355,7 +7342,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom" -msgstr "" +msgstr "Dưới" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View." @@ -7363,7 +7350,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left" -msgstr "" +msgstr "Trái" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right View." @@ -7371,7 +7358,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right" -msgstr "" +msgstr "Phải" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View." @@ -7379,7 +7366,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front" -msgstr "" +msgstr "Trước" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear View." @@ -7760,7 +7747,7 @@ msgstr "" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." -msgstr "" +msgstr "Hình không hợp lệ, không thể thay thế bằng lưới." #: editor/plugins/sprite_editor_plugin.cpp msgid "Convert to Mesh2D" @@ -7768,7 +7755,7 @@ msgstr "Chuyển thà nh Mesh2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." -msgstr "" +msgstr "Hình không hợp lệ, không thể tạo Ä‘a giác." #: editor/plugins/sprite_editor_plugin.cpp msgid "Convert to Polygon2D" @@ -7776,20 +7763,19 @@ msgstr "Chuyển thà nh Polygon2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "" +msgstr "Hình há»c không hợp lệ, không thể tạo Ä‘a giác va chạm." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create CollisionPolygon2D Sibling" -msgstr "Tạo" +msgstr "Tạo CollisionPolygon2D cùng báºc" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create light occluder." -msgstr "" +msgstr "Hình há»c không rõ, không thể tạo bá»™ tá»a ánh sáng." #: editor/plugins/sprite_editor_plugin.cpp msgid "Create LightOccluder2D Sibling" -msgstr "" +msgstr "Tạo LightOccluder2D cùng báºc" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" @@ -7805,7 +7791,7 @@ msgstr "Thu nhá» (Äiểm ảnh): " #: editor/plugins/sprite_editor_plugin.cpp msgid "Grow (Pixels): " -msgstr "" +msgstr "Phóng to (Äiểm ảnh): " #: editor/plugins/sprite_editor_plugin.cpp msgid "Update Preview" @@ -8101,7 +8087,7 @@ msgstr "Cây con" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" -msgstr "" +msgstr "Có, Nhiá»u, Tùy Chá»n" #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" @@ -8114,7 +8100,7 @@ msgstr "Biểu tượng" #: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp msgid "Style" -msgstr "" +msgstr "Kiểu" #: editor/plugins/theme_editor_plugin.cpp msgid "Font" @@ -8298,7 +8284,7 @@ msgstr "Ưu tiên" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Z Index" -msgstr "" +msgstr "Chỉ số Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Region Mode" @@ -8382,6 +8368,8 @@ msgstr "Hiển thị tên ô (Giữ phÃm Alt)" msgid "" "Add or select a texture on the left panel to edit the tiles bound to it." msgstr "" +"Thêm hoặc chá»n má»™t há»a tiết ở bảng bên trái để chỉnh sá»a các ô bị nó giá»›i " +"hạn." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove selected texture? This will remove all tiles which use it." @@ -8429,12 +8417,17 @@ msgid "Delete polygon." msgstr "Xóa Ä‘a giác." #: editor/plugins/tile_set_editor_plugin.cpp +#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" "Shift+LMB: Set wildcard bit.\n" "Click on another Tile to edit it." msgstr "" +"Chuá»™t trái: Báºt bit.\n" +"Chuá»™t phải: Tắt bit.\n" +"Shift + Chuá»™t trái: Äặt bit biến hóa.\n" +"Bấm chuá»™t và o ô khác để chỉnh sá»a nó." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -8559,7 +8552,7 @@ msgstr "Lá»—i" #: editor/plugins/version_control_editor_plugin.cpp msgid "No files added to stage" -msgstr "" +msgstr "Không có tệp nà o trong giai Ä‘oạn chá»" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -8568,7 +8561,7 @@ msgstr "Cá»™ng đồng" #: editor/plugins/version_control_editor_plugin.cpp msgid "VCS Addon is not initialized" -msgstr "" +msgstr "Trình kiểm soát phiên bản chưa được khởi tạo" #: editor/plugins/version_control_editor_plugin.cpp msgid "Version Control System" @@ -8580,7 +8573,7 @@ msgstr "Khởi tạo" #: editor/plugins/version_control_editor_plugin.cpp msgid "Staging area" -msgstr "" +msgstr "Vùng chá»" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" @@ -8629,7 +8622,7 @@ msgstr "Trạng thái" #: editor/plugins/version_control_editor_plugin.cpp msgid "View file diffs before committing them to the latest version" -msgstr "" +msgstr "Kiểm tra các khác biệt trước khi xác nháºn và o phiên bản má»›i nhất" #: editor/plugins/version_control_editor_plugin.cpp msgid "No file diff is active" @@ -8696,9 +8689,8 @@ msgid "Remove output port" msgstr "Xóa Cổng ra" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Phiên bản hiện tại:" +msgstr "Äặt phép diá»…n đạt" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Resize VisualShader node" @@ -8778,11 +8770,11 @@ msgstr "Tạo Function" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "Chuyển đổi vector HSV sang RGB tương đương." +msgstr "Chuyển vector mà u HSV sang RGB tương ứng." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "Chuyển đổi vector RGB sang HSV tương đương." +msgstr "Chuyển vector mà u RGB sang HSV tương ứng." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sepia function." @@ -8954,7 +8946,7 @@ msgstr "Chá»n Scale" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Scalar operator." -msgstr "" +msgstr "Toán tá» vô hướng." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." @@ -8994,56 +8986,56 @@ msgstr "Trả vá» giá trị tuyệt đối cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "Trả vá» arc-cosine cá»§a tham số." +msgstr "Trả vá» côsin nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "Trả vá» côsin hyperbolic nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "Trả vá» arc-sin cá»§a tham số." +msgstr "Trả vá» sin nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "Trả vá» sin hyperbolic nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "Trả vá» arc-tan cá»§a tham số." +msgstr "Trả vá» tan nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "Trả vá» arc-tan cá»§a các tham số." +msgstr "Trả vá» tan nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "Trả vá» tan hyperbolic nghịch đảo cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "Tìm số nguyên gần nhất lá»›n hÆ¡n hoặc bằng tham số." +msgstr "Trả vá» số nguyên nhá» nhất lá»›n hÆ¡n hoặc bằng tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Kẹp má»™t giá trị giữa hai biên." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "Trả vá» cosine cá»§a tham số." +msgstr "Trả vá» côsin cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "Trả vá» côsin hyperbolic cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "Äổi radian vỠđộ." +msgstr "Chuyển đổi đơn vị radian sang độ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "LÅ©y thừa cÆ¡ số e." +msgstr "LÅ©y thừa cÆ¡ số e (hằng số Euler)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." @@ -9051,23 +9043,23 @@ msgstr "LÅ©y thừa cÆ¡ số 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "Tìm số nguyên gần nhất nhá» hÆ¡n hoặc bằng tham số." +msgstr "Tìm số nguyên lá»›n nhất nhá» hÆ¡n hoặc bằng tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "TÃnh phần phân số cá»§a tham số." +msgstr "TÃnh phần tháºp phân cá»§a phép chia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Trả vá» nghịch đảo căn báºc hai cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "Logarit tá»± nhiên." +msgstr "Lôgarit tá»± nhiên." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "Logarit cÆ¡ số 2." +msgstr "Lôgarit cÆ¡ số 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." @@ -9096,7 +9088,7 @@ msgstr "Trả vá» lÅ©y thừa cÆ¡ số tham số đầu tiên có số mÅ© tham #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "Äổi từ độ vá» radian." +msgstr "Chuyển đơn vị độ thà nh radian." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" @@ -9124,7 +9116,7 @@ msgstr "Trả vá» sin cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic sine of the parameter." -msgstr "Trả vá» sin hyperbolic cá»§a tham số." +msgstr "Trả vá» sin hyperbol cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." @@ -9152,7 +9144,7 @@ msgstr "Trả vá» tan cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic tangent of the parameter." -msgstr "Trả vá» tan hyperbolic cá»§a tham số." +msgstr "Trả vá» tan hyperbol cá»§a tham số." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the truncated value of the parameter." @@ -9284,7 +9276,7 @@ msgstr "Tách vector thà nh ba giá trị vô hướng." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "TÃnh tÃch chéo cá»§a hai vector." +msgstr "TÃnh tÃch có hướng cá»§a hai vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." @@ -9376,7 +9368,7 @@ msgstr "Cá»™ng vector vá»›i vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "Chia vector cho vector." +msgstr "Chia hai vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." @@ -10005,7 +9997,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Key " -msgstr "" +msgstr "Khoá " #: editor/project_settings_editor.cpp msgid "Joy Button" @@ -10170,7 +10162,7 @@ msgstr "Tên hà nh động không thể trống hoặc chứa '/', ':', '=', '\\ #: editor/project_settings_editor.cpp msgid "Add Input Action" -msgstr "" +msgstr "Thêm hà nh động đầu và o" #: editor/project_settings_editor.cpp msgid "Error saving settings." @@ -10242,7 +10234,7 @@ msgstr "Thay đổi sẽ được áp dụng sau khi Trình biên táºp khởi Ä #: editor/project_settings_editor.cpp msgid "Input Map" -msgstr "" +msgstr "Ãnh xạ đầu và o" #: editor/project_settings_editor.cpp msgid "Action:" @@ -10263,19 +10255,19 @@ msgstr "Thiết bị:" #: editor/project_settings_editor.cpp msgid "Index:" -msgstr "" +msgstr "Chỉ mục:" #: editor/project_settings_editor.cpp msgid "Localization" -msgstr "" +msgstr "Bản địa hoá" #: editor/project_settings_editor.cpp msgid "Translations" -msgstr "" +msgstr "Bản dịch" #: editor/project_settings_editor.cpp msgid "Translations:" -msgstr "" +msgstr "Bản dịch:" #: editor/project_settings_editor.cpp msgid "Remaps" @@ -10291,7 +10283,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Locale" -msgstr "" +msgstr "Vùng vị trÃ" #: editor/project_settings_editor.cpp msgid "Locales Filter" @@ -10316,7 +10308,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "AutoLoad" -msgstr "" +msgstr "Tá»± nạp" #: editor/project_settings_editor.cpp msgid "Plugins" @@ -10333,7 +10325,7 @@ msgstr "Cà i sẵn ..." #: editor/property_editor.cpp msgid "Zero" -msgstr "" +msgstr "Không" #: editor/property_editor.cpp msgid "Easing In-Out" @@ -10528,7 +10520,7 @@ msgstr "" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent" -msgstr "" +msgstr "Äổi nút cha" #: editor/run_settings_dialog.cpp msgid "Run Mode:" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index e5826da638..3b528525e1 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -82,7 +82,7 @@ msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2021-04-19 22:33+0000\n" +"PO-Revision-Date: 2021-05-16 03:32+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" @@ -2565,9 +2565,12 @@ msgstr "æ— æ³•ä»Žè·¯å¾„ “%s†ä¸åŠ è½½åŠ è½½é¡¹è„šæœ¬ã€‚" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." -msgstr "æ— æ³•ä»Žè·¯å¾„ “%sâ€ åŠ è½½åŠ è½½é¡¹è„šæœ¬ï¼šè„šæœ¬ä¼¼ä¹Žæœ‰ä»£ç é”™è¯¯ï¼Œè¯·æ£€æŸ¥å…¶è¯æ³•。" +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." +msgstr "" +"æ— æ³•ä»Žè·¯å¾„â€œ%sâ€åŠ è½½åŠ è½½é¡¹è„šæœ¬ï¼šè¯¥è„šæœ¬å¯èƒ½æœ‰ä»£ç 错误。\n" +"ç¦ç”¨åŠ è½½é¡¹â€œ%sâ€å¯é˜»æ¢å…¶è¿›ä¸€æ¥æŠ¥é”™ã€‚" #: editor/editor_node.cpp msgid "" @@ -2993,6 +2996,10 @@ msgid "About" msgstr "关于" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "è¿è¡Œæ¤é¡¹ç›®ã€‚" @@ -5182,9 +5189,10 @@ msgid "" msgstr "æŸäº›ç½‘æ ¼æ— æ•ˆã€‚ç¡®ä¿UV2通é“值包å«åœ¨[0.0,1.0]平方区域内。" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." -msgstr "Godot编辑器是在没有光线跟踪支æŒçš„æƒ…å†µä¸‹æž„å»ºçš„ï¼Œå…‰ç…§è´´å›¾æ— æ³•çƒ˜ç„™ã€‚" +msgstr "Godot 编辑器是在没有光线跟踪支æŒçš„æƒ…å†µä¸‹æž„å»ºçš„ï¼›æ— æ³•çƒ˜ç„™å…‰ç…§è´´å›¾ã€‚" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" @@ -7477,12 +7485,12 @@ msgstr "缓慢自由视图速度" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Rotation Locked" -msgstr "é”定视角旋转" +msgstr "å·²é”定视角旋转" #: editor/plugins/spatial_editor_plugin.cpp msgid "" "To zoom further, change the camera's clipping planes (View -> Settings...)" -msgstr "" +msgstr "修改相机的è£å‰ªå¹³é¢åŽæ‰èƒ½è¿›ä¸€æ¥ç¼©æ”¾ï¼ˆè§†å›¾ -> 设置...)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -7595,27 +7603,27 @@ msgstr "å˜æ¢å¯¹è¯æ¡†..." #: editor/plugins/spatial_editor_plugin.cpp msgid "1 Viewport" -msgstr "1 个视å£" +msgstr "1 个视窗" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports" -msgstr "2 个视å£" +msgstr "2 个视窗" #: editor/plugins/spatial_editor_plugin.cpp msgid "2 Viewports (Alt)" -msgstr "2 个视å£ï¼ˆå¤‡é€‰ï¼‰" +msgstr "2 个视窗(备选)" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports" -msgstr "3 个视å£" +msgstr "3 个视窗" #: editor/plugins/spatial_editor_plugin.cpp msgid "3 Viewports (Alt)" -msgstr "3 个视å£ï¼ˆå¤‡é€‰ï¼‰" +msgstr "3 个视窗(备选)" #: editor/plugins/spatial_editor_plugin.cpp msgid "4 Viewports" -msgstr "4 个视å£" +msgstr "4 个视窗" #: editor/plugins/spatial_editor_plugin.cpp msgid "Gizmos" @@ -10798,6 +10806,8 @@ msgid "" "every time it updates.\n" "Switch back to the Local scene tree dock to improve performance." msgstr "" +"选ä¸åŽï¼Œè¿œç¨‹åœºæ™¯æ ‘颿¿åœ¨æ›´æ–°æ—¶ä¼šé€ æˆé¡¹ç›®çš„å¡é¡¿ã€‚\n" +"åˆ‡å›žæœ¬åœ°åœºæ™¯æ ‘é¢æ¿å¯ä»¥æå‡æ€§èƒ½ã€‚" #: editor/scene_tree_dock.cpp msgid "Local" @@ -12921,6 +12931,18 @@ msgid "Constants cannot be modified." msgstr "ä¸å…许修改常é‡ã€‚" #~ msgid "" +#~ "Godot editor was built without ray tracing support; lightmaps can't be " +#~ "baked.\n" +#~ "If you are using an Apple Silicon-based Mac, try forcing Rosetta " +#~ "emulation on Godot.app in the application settings\n" +#~ "then restart the editor." +#~ msgstr "" +#~ "Godot 编辑器是在没有光线跟踪支æŒçš„æƒ…å†µä¸‹æž„å»ºçš„ï¼›æ— æ³•çƒ˜ç„™å…‰ç…§è´´å›¾ã€‚\n" +#~ "å¦‚æžœä½ ä½¿ç”¨çš„æ˜¯åŸºäºŽ Apple Silicon çš„ Mac,å¯ä»¥å°è¯•在应用设置ä¸è®© Godot.app " +#~ "强制使用 Rosetta 模拟\n" +#~ "å¹¶é‡å¯ç¼–辑器。" + +#~ msgid "" #~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0." #~ msgstr "InterpolatedCamera 已废弃,将在 Godot 4.0 ä¸åˆ 除。" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index 37e8f6ab61..2350817f1f 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -2609,8 +2609,9 @@ msgstr "載入å—形出ç¾éŒ¯èª¤" #: editor/editor_node.cpp msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "" #: editor/editor_node.cpp @@ -3058,6 +3059,10 @@ msgid "About" msgstr "關於" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "é‹è¡Œå°ˆæ¡ˆ" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 50b323130e..a24b8831d2 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -2513,9 +2513,11 @@ msgid "Unable to load addon script from path: '%s'." msgstr "無法自路徑「%sã€è¼‰å…¥æ“´å……腳本。" #: editor/editor_node.cpp +#, fuzzy msgid "" -"Unable to load addon script from path: '%s' There seems to be an error in " -"the code, please check the syntax." +"Unable to load addon script from path: '%s'. This might be due to a code " +"error in that script.\n" +"Disabling the addon at '%s' to prevent further errors." msgstr "無法自路徑「%sã€è¼‰å…¥æ“´å……腳本。å¯èƒ½ç‚ºç¨‹å¼ç¢¼ä¸æœ‰éŒ¯èª¤ï¼Œè«‹æª¢æŸ¥èªžæ³•。" #: editor/editor_node.cpp @@ -2942,6 +2944,10 @@ msgid "About" msgstr "關於" #: editor/editor_node.cpp +msgid "Support Godot Development" +msgstr "" + +#: editor/editor_node.cpp msgid "Play the project." msgstr "執行該專案。" @@ -5131,6 +5137,7 @@ msgid "" msgstr "éƒ¨åˆ†ç¶²æ ¼ç„¡æ•ˆã€‚è«‹ç¢ºä¿ UV2 通é“çš„å€¼ä½æ–¼ [0.0,1.0] 矩形內。" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Godot editor was built without ray tracing support, lightmaps can't be baked." msgstr "" diff --git a/main/main.cpp b/main/main.cpp index 67d8d93728..d67761db55 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1327,23 +1327,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } { - String orientation = GLOBAL_DEF("display/window/handheld/orientation", "landscape"); - - if (orientation == "portrait") { - window_orientation = DisplayServer::SCREEN_PORTRAIT; - } else if (orientation == "reverse_landscape") { - window_orientation = DisplayServer::SCREEN_REVERSE_LANDSCAPE; - } else if (orientation == "reverse_portrait") { - window_orientation = DisplayServer::SCREEN_REVERSE_PORTRAIT; - } else if (orientation == "sensor_landscape") { - window_orientation = DisplayServer::SCREEN_SENSOR_LANDSCAPE; - } else if (orientation == "sensor_portrait") { - window_orientation = DisplayServer::SCREEN_SENSOR_PORTRAIT; - } else if (orientation == "sensor") { - window_orientation = DisplayServer::SCREEN_SENSOR; - } else { - window_orientation = DisplayServer::SCREEN_LANDSCAPE; - } + window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_LANDSCAPE))); } Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF_BASIC("physics/common/physics_fps", 60)); @@ -1461,6 +1445,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } #endif +#ifdef TOOLS_ENABLED + if (editor || project_manager) { + EditorNode::register_editor_paths(project_manager); + } +#endif + /* Determine text driver */ if (text_driver == "") { diff --git a/misc/dist/html/service-worker.js b/misc/dist/html/service-worker.js index f8dee8cd5b..063e40a6cb 100644 --- a/misc/dist/html/service-worker.js +++ b/misc/dist/html/service-worker.js @@ -1,6 +1,6 @@ // This service worker is required to expose an exported Godot project as a // Progressive Web App. It provides an offline fallback page telling the user -// that they need an Internet conneciton to run the project if desired. +// that they need an Internet connection to run the project if desired. // Incrementing CACHE_VERSION will kick off the install event and force // previously cached resources to be updated from the network. const CACHE_VERSION = "@GODOT_VERSION@"; diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index b9ad431e6e..fd69725a21 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -255,7 +255,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; OTHER_LDFLAGS = "$linker_flags"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "$targeted_device_family"; }; name = Debug; }; @@ -294,7 +294,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; OTHER_LDFLAGS = "$linker_flags"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "$targeted_device_family"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -323,7 +323,7 @@ PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "$provisioning_profile_uuid_debug"; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "$targeted_device_family"; VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64"; WRAPPER_EXTENSION = app; }; @@ -353,7 +353,7 @@ PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "$provisioning_profile_uuid_release"; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "$targeted_device_family"; VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64"; WRAPPER_EXTENSION = app; }; diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme b/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme index b6beeb012f..d61a53d5c2 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme @@ -23,7 +23,7 @@ </BuildActionEntries> </BuildAction> <TestAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> @@ -42,7 +42,7 @@ </AdditionalOptions> </TestAction> <LaunchAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle = "0" @@ -67,7 +67,7 @@ </AdditionalOptions> </LaunchAction> <ProfileAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" shouldUseLaunchSchemeArgsEnv = "YES" savedToolIdentifier = "" useCustomWorkingDirectory = "NO" @@ -84,10 +84,10 @@ </BuildableProductRunnable> </ProfileAction> <AnalyzeAction - buildConfiguration = "Debug"> + buildConfiguration = "$default_build_config"> </AnalyzeAction> <ArchiveAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" revealArchiveInOrganizer = "YES"> </ArchiveAction> </Scheme> diff --git a/misc/dist/osx/editor.entitlements b/misc/dist/osx/editor.entitlements new file mode 100644 index 0000000000..5496f65dcc --- /dev/null +++ b/misc/dist/osx/editor.entitlements @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.apple.security.device.audio-input</key> + <true/> + <key>com.apple.security.device.camera</key> + <true/> + <key>com.apple.security.cs.disable-library-validation</key> + <true/> +</dict> +</plist> diff --git a/misc/dist/osx/editor_mono.entitlements b/misc/dist/osx/editor_mono.entitlements new file mode 100644 index 0000000000..c61c287652 --- /dev/null +++ b/misc/dist/osx/editor_mono.entitlements @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.apple.security.cs.allow-dyld-environment-variables</key> + <true/> + <key>com.apple.security.cs.allow-jit</key> + <true/> + <key>com.apple.security.cs.allow-unsigned-executable-memory</key> + <true/> + <key>com.apple.security.cs.disable-library-validation</key> + <true/> + <key>com.apple.security.device.audio-input</key> + <true/> + <key>com.apple.security.device.camera</key> + <true/> +</dict> +</plist> diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index 7c6e5fcb42..2dac8e9a55 100755 --- a/misc/hooks/pre-commit-clang-format +++ b/misc/hooks/pre-commit-clang-format @@ -99,8 +99,12 @@ if [ ! -x "$CLANG_FORMAT" ] ; then exit 1 fi -CLANG_FORMAT_VERSION="$(clang-format --version | cut -d' ' -f3)" -CLANG_FORMAT_MAJOR="$(echo "$CLANG_FORMAT_VERSION" | cut -d'.' -f1)" +# The returned string can be inconsistent depending on where clang-format comes from. +# Example output strings reported by `clang-format --version`: +# - Ubuntu: "Ubuntu clang-format version 11.0.0-2" +# - Fedora: "clang-format version 11.0.0 (Fedora 11.0.0-2.fc33)" +CLANG_FORMAT_VERSION="$(clang-format --version | sed "s/[^0-9\.]*\([0-9\.]*\).*/\1/")" +CLANG_FORMAT_MAJOR="$(echo "$CLANG_FORMAT_VERSION" | cut -d. -f1)" if [ "$CLANG_FORMAT_MAJOR" != "$RECOMMENDED_CLANG_FORMAT_MAJOR" ]; then echo "Warning: Your clang-format binary is the wrong version ($CLANG_FORMAT_VERSION, expected $RECOMMENDED_CLANG_FORMAT_MAJOR.x.x)." diff --git a/misc/scripts/check_ci_log.py b/misc/scripts/check_ci_log.py index f2cdf95c7b..56c32b154c 100755 --- a/misc/scripts/check_ci_log.py +++ b/misc/scripts/check_ci_log.py @@ -53,11 +53,11 @@ if file_contents.find("ObjectDB instances leaked at exit") != -1: # execution of project if file_contents.find("Assertion failed") != -1: - print("ERROR: Assertion failed in project, check exectution log for more info") + print("ERROR: Assertion failed in project, check execution log for more info") sys.exit(1) # For now Godot leaks a lot of rendering stuff so for now we just show info -# about it and this needs to be reenabled after fixing this memory leaks. +# about it and this needs to be re-enabled after fixing this memory leaks. if file_contents.find("were leaked") != -1 or file_contents.find("were never freed") != -1: print("WARNING: Memory leak was found") diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub index 351628a0e3..1f9fde966d 100644 --- a/modules/basis_universal/SCsub +++ b/modules/basis_universal/SCsub @@ -11,40 +11,45 @@ thirdparty_obj = [] # Not unbundled so far since not widespread as shared library thirdparty_dir = "#thirdparty/basis_universal/" -tool_sources = [ +# Sync list with upstream CMakeLists.txt +encoder_sources = [ + "apg_bmp.c", "basisu_astc_decomp.cpp", "basisu_backend.cpp", "basisu_basis_file.cpp", + "basisu_bc7enc.cpp", "basisu_comp.cpp", "basisu_enc.cpp", "basisu_etc.cpp", "basisu_frontend.cpp", "basisu_global_selector_palette_helpers.cpp", "basisu_gpu_texture.cpp", + "basisu_kernels_sse.cpp", "basisu_pvrtc1_4.cpp", - "basisu_resample_filters.cpp", "basisu_resampler.cpp", + "basisu_resample_filters.cpp", "basisu_ssim.cpp", + "basisu_uastc_enc.cpp", + "jpgd.cpp", "lodepng.cpp", ] -tool_sources = [thirdparty_dir + file for file in tool_sources] +encoder_sources = [thirdparty_dir + "encoder/" + file for file in encoder_sources] transcoder_sources = [thirdparty_dir + "transcoder/basisu_transcoder.cpp"] # Treat Basis headers as system headers to avoid raising warnings. Not supported on MSVC. if not env.msvc: - env_basisu.Append( - CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir(thirdparty_dir + "transcoder").path] - ) + env_basisu.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) else: - env_basisu.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "transcoder"]) + env_basisu.Prepend(CPPPATH=[thirdparty_dir]) if env["target"] == "debug": - env_basisu.Append(CPPFLAGS=["-DBASISU_DEVEL_MESSAGES=1", "-DBASISD_ENABLE_DEBUG_FLAGS=1"]) + env_basisu.Append(CPPDEFINES=[("BASISU_DEVEL_MESSAGES", 1), ("BASISD_ENABLE_DEBUG_FLAGS", 1)]) env_thirdparty = env_basisu.Clone() env_thirdparty.disable_warnings() if env["tools"]: - env_thirdparty.add_source_files(thirdparty_obj, tool_sources) + env_thirdparty.Append(CPPDEFINES=["BASISU_NO_IMG_LOADERS"]) + env_thirdparty.add_source_files(thirdparty_obj, encoder_sources) env_thirdparty.add_source_files(thirdparty_obj, transcoder_sources) env.modules_sources += thirdparty_obj diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp index cf5581265b..772ac87dbf 100644 --- a/modules/basis_universal/register_types.cpp +++ b/modules/basis_universal/register_types.cpp @@ -35,7 +35,7 @@ #include "texture_basisu.h" #ifdef TOOLS_ENABLED -#include <basisu_comp.h> +#include <encoder/basisu_comp.h> #endif #include <transcoder/basisu_transcoder.h> @@ -233,7 +233,7 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) { basist::basisu_image_info info; tr.get_image_info(ptr, size, info, 0); - int block_size = basist::basis_get_bytes_per_block(format); + int block_size = basist::basis_get_bytes_per_block_or_pixel(format); Vector<uint8_t> gpudata; gpudata.resize(info.m_total_blocks * block_size); diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp index 92882a1cc8..6a5f6313c4 100644 --- a/modules/basis_universal/texture_basisu.cpp +++ b/modules/basis_universal/texture_basisu.cpp @@ -33,7 +33,7 @@ #include "core/os/os.h" #ifdef TOOLS_ENABLED -#include <basisu_comp.h> +#include <encoder/basisu_comp.h> #endif #include <transcoder/basisu_transcoder.h> diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h index 282a0dfc8a..3316035404 100644 --- a/modules/basis_universal/texture_basisu.h +++ b/modules/basis_universal/texture_basisu.h @@ -34,7 +34,7 @@ #include "scene/resources/texture.h" #ifdef TOOLS_ENABLED -#include <basisu_comp.h> +#include <encoder/basisu_comp.h> #endif #include <transcoder/basisu_transcoder.h> diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index f22e74cafb..27b49a6609 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -205,7 +205,7 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, // A valid bmp file should always at least have a // file header and a minimal info header - if (f->get_len() > BITMAP_FILE_HEADER_SIZE + BITMAP_INFO_HEADER_MIN_SIZE) { + if (f->get_length() > BITMAP_FILE_HEADER_SIZE + BITMAP_INFO_HEADER_MIN_SIZE) { // File Header bmp_header.bmp_file_header.bmp_signature = f->get_16(); if (bmp_header.bmp_file_header.bmp_signature == BITMAP_SIGNATURE) { diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 541b7036ac..67dfdfb5eb 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -923,45 +923,43 @@ CSGBrush *CSGSphere3D::_build_brush() { Ref<Material> *materialsw = materials.ptrw(); bool *invertw = invert.ptrw(); + const double lat_step = 1.0 / rings; + const double lon_step = 1.0 / radial_segments; int face = 0; - const double lat_step = Math_TAU / rings; - const double lon_step = Math_TAU / radial_segments; - for (int i = 1; i <= rings; i++) { - double lat0 = lat_step * (i - 1) - Math_TAU / 4; - double z0 = Math::sin(lat0); - double zr0 = Math::cos(lat0); - double u0 = double(i - 1) / rings; - - double lat1 = lat_step * i - Math_TAU / 4; - double z1 = Math::sin(lat1); - double zr1 = Math::cos(lat1); - double u1 = double(i) / rings; - - for (int j = radial_segments; j >= 1; j--) { - double lng0 = lon_step * (j - 1); + double lat0 = Math_PI * (0.5 - (i - 1) * lat_step); + double c0 = Math::cos(lat0); + double s0 = Math::sin(lat0); + double v0 = double(i - 1) / rings; + + double lat1 = Math_PI * (0.5 - i * lat_step); + double c1 = Math::cos(lat1); + double s1 = Math::sin(lat1); + double v1 = double(i) / rings; + + for (int j = 1; j <= radial_segments; j++) { + double lng0 = Math_TAU * (0.5 - (j - 1) * lon_step); double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); - double v0 = double(i - 1) / radial_segments; + double u0 = double(j - 1) / radial_segments; - double lng1 = lon_step * j; + double lng1 = Math_TAU * (0.5 - j * lon_step); double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); - double v1 = double(i) / radial_segments; + double u1 = double(j) / radial_segments; Vector3 v[4] = { - Vector3(x1 * zr0, z0, y1 * zr0) * radius, - Vector3(x1 * zr1, z1, y1 * zr1) * radius, - Vector3(x0 * zr1, z1, y0 * zr1) * radius, - Vector3(x0 * zr0, z0, y0 * zr0) * radius + Vector3(x0 * c0, s0, y0 * c0) * radius, + Vector3(x1 * c0, s0, y1 * c0) * radius, + Vector3(x1 * c1, s1, y1 * c1) * radius, + Vector3(x0 * c1, s1, y0 * c1) * radius, }; Vector2 u[4] = { - Vector2(v1, u0), - Vector2(v1, u1), - Vector2(v0, u1), - Vector2(v0, u0), - + Vector2(u0, v0), + Vector2(u1, v0), + Vector2(u1, v1), + Vector2(u0, v1), }; if (i < rings) { diff --git a/modules/csg/icons/CSGBox3D.svg b/modules/csg/icons/CSGBox3D.svg index ceef9196a7..2740cc2f8c 100644 --- a/modules/csg/icons/CSGBox3D.svg +++ b/modules/csg/icons/CSGBox3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/><path d="m8 .94531-7 3.5v7.2227l7 3.5.29492-.14844c-.18282-.30101-.29492-.64737-.29492-1.0195v-2c0-.72651.40824-1.3664 1-1.7168v-1.6699l4-2v1.3867h1c.36419 0 .70336.10754 1 .2832v-3.8379zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002z" fill="#fc9c9c" stroke-width="1.0667"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/><path d="m8 .94531-7 3.5v7.2227l7 3.5.29492-.14844c-.18282-.30101-.29492-.64737-.29492-1.0195v-2c0-.72651.40824-1.3664 1-1.7168v-1.6699l4-2v1.3867h1c.36419 0 .70336.10754 1 .2832v-3.8379zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002z" fill="#fc7f7f" stroke-width="1.0667"/></svg> diff --git a/modules/csg/icons/CSGCapsule3D.svg b/modules/csg/icons/CSGCapsule3D.svg index 14e582ee84..db4f71864b 100644 --- a/modules/csg/icons/CSGCapsule3D.svg +++ b/modules/csg/icons/CSGCapsule3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.7527 0-5 2.2418-5 4.9902v4.0176c0 2.7484 2.2473 4.9922 5 4.9922.092943 0 .18367-.008623.27539-.013672-.17055-.29341-.27539-.62792-.27539-.98633v-2c0-.72887.41095-1.3691 1.0059-1.7188v-.28125c.34771-.034464.68259-.10691 1.0156-.19922.10394-.99856.95603-1.8008 1.9785-1.8008h1v-2.0098c0-2.7484-2.2473-4.9902-5-4.9902zm-1.0059 2.127v4.8574c-.66556-.1047-1.2974-.37231-1.9941-.66211v-1.3223c0-1.3474.79841-2.4642 1.9941-2.873zm2.0117 0c1.1957.4088 1.9941 1.5256 1.9941 2.873v1.3457c-.68406.3054-1.3142.57292-1.9941.66602v-4.8848zm-4.0059 6.334c.67836.2231 1.3126.44599 1.9941.52539v2.8848c-1.1957-.4092-1.9941-1.5237-1.9941-2.8711v-.53906z" fill="#fc9c9c"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.7527 0-5 2.2418-5 4.9902v4.0176c0 2.7484 2.2473 4.9922 5 4.9922.092943 0 .18367-.008623.27539-.013672-.17055-.29341-.27539-.62792-.27539-.98633v-2c0-.72887.41095-1.3691 1.0059-1.7188v-.28125c.34771-.034464.68259-.10691 1.0156-.19922.10394-.99856.95603-1.8008 1.9785-1.8008h1v-2.0098c0-2.7484-2.2473-4.9902-5-4.9902zm-1.0059 2.127v4.8574c-.66556-.1047-1.2974-.37231-1.9941-.66211v-1.3223c0-1.3474.79841-2.4642 1.9941-2.873zm2.0117 0c1.1957.4088 1.9941 1.5256 1.9941 2.873v1.3457c-.68406.3054-1.3142.57292-1.9941.66602v-4.8848zm-4.0059 6.334c.67836.2231 1.3126.44599 1.9941.52539v2.8848c-1.1957-.4092-1.9941-1.5237-1.9941-2.8711v-.53906z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg> diff --git a/modules/csg/icons/CSGCombiner3D.svg b/modules/csg/icons/CSGCombiner3D.svg index 50ce4179d9..692ba54cb8 100644 --- a/modules/csg/icons/CSGCombiner3D.svg +++ b/modules/csg/icons/CSGCombiner3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/><path d="m3 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm0 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2z" fill="#fc9c9c"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/><path d="m3 1c-1.1046 0-2 .89543-2 2h2zm2 0v2h2v-2zm4 0v2h2v-2zm4 0v2h2c0-1.1046-.89543-2-2-2zm-12 4v2h2v-2zm12 0v2h2v-2zm-12 4v2h2v-2zm0 4c0 1.1046.89543 2 2 2v-2zm4 0v2h2v-2z" fill="#fc7f7f"/></svg> diff --git a/modules/csg/icons/CSGCylinder3D.svg b/modules/csg/icons/CSGCylinder3D.svg index c84594928a..4bc2427887 100644 --- a/modules/csg/icons/CSGCylinder3D.svg +++ b/modules/csg/icons/CSGCylinder3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-1.7469 0-3.328.22648-4.5586.63672-.61528.20512-1.1471.45187-1.5898.80078-.44272.34891-.85156.88101-.85156 1.5625v8c0 .68149.40884 1.2155.85156 1.5645.44272.34891.97457.59577 1.5898.80078 1.2306.41024 2.8117.63477 4.5586.63477.095648 0 .18467-.008426.2793-.009766-.1722-.29446-.2793-.62995-.2793-.99023v-1c-1.5668 0-2.9867-.2195-3.9277-.5332-.46329-.15435-.90474-.33752-1.0723-.4668v-5.8125c.1468.058667.2835.12515.44141.17773 1.2306.41024 2.8117.63477 4.5586.63477s3.328-.22453 4.5586-.63477c.15791-.052267.29461-.11864.44141-.17773v1.8125h1c.36396 0 .70348.10774 1 .2832v-4.2832c0-.68149-.40884-1.2136-.85156-1.5625-.44272-.34891-.97457-.59566-1.5898-.80078-1.2306-.41024-2.8117-.63672-4.5586-.63672zm0 2c1.5668 0 2.9867.22145 3.9277.53516.46368.15456.80138.33741.96875.4668-.16752.12928-.50546.3105-.96875.46484-.94102.31371-2.361.5332-3.9277.5332s-2.9867-.2195-3.9277-.5332c-.46329-.15435-.80123-.33556-.96875-.46484.16737-.12939.50507-.31224.96875-.4668.94102-.31371 2.361-.53516 3.9277-.53516z" fill="#fc9c9c" stroke-width="1.0667" transform="scale(.9375)"/><path d="m11.25 8.4375c-.51938 0-.9375.41812-.9375.9375v.9375h1.875v1.875h.9375c.51938 0 .9375-.41812.9375-.9375v-1.875c0-.51938-.41812-.9375-.9375-.9375zm.9375 3.75h-1.875v-1.875h-.9375c-.51938 0-.9375.41812-.9375.9375v1.875c0 .51938.41812.9375.9375.9375h1.875c.51938 0 .9375-.41812.9375-.9375z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-1.7469 0-3.328.22648-4.5586.63672-.61528.20512-1.1471.45187-1.5898.80078-.44272.34891-.85156.88101-.85156 1.5625v8c0 .68149.40884 1.2155.85156 1.5645.44272.34891.97457.59577 1.5898.80078 1.2306.41024 2.8117.63477 4.5586.63477.095648 0 .18467-.008426.2793-.009766-.1722-.29446-.2793-.62995-.2793-.99023v-1c-1.5668 0-2.9867-.2195-3.9277-.5332-.46329-.15435-.90474-.33752-1.0723-.4668v-5.8125c.1468.058667.2835.12515.44141.17773 1.2306.41024 2.8117.63477 4.5586.63477s3.328-.22453 4.5586-.63477c.15791-.052267.29461-.11864.44141-.17773v1.8125h1c.36396 0 .70348.10774 1 .2832v-4.2832c0-.68149-.40884-1.2136-.85156-1.5625-.44272-.34891-.97457-.59566-1.5898-.80078-1.2306-.41024-2.8117-.63672-4.5586-.63672zm0 2c1.5668 0 2.9867.22145 3.9277.53516.46368.15456.80138.33741.96875.4668-.16752.12928-.50546.3105-.96875.46484-.94102.31371-2.361.5332-3.9277.5332s-2.9867-.2195-3.9277-.5332c-.46329-.15435-.80123-.33556-.96875-.46484.16737-.12939.50507-.31224.96875-.4668.94102-.31371 2.361-.53516 3.9277-.53516z" fill="#fc7f7f" stroke-width="1.0667" transform="scale(.9375)"/><path d="m11.25 8.4375c-.51938 0-.9375.41812-.9375.9375v.9375h1.875v1.875h.9375c.51938 0 .9375-.41812.9375-.9375v-1.875c0-.51938-.41812-.9375-.9375-.9375zm.9375 3.75h-1.875v-1.875h-.9375c-.51938 0-.9375.41812-.9375.9375v1.875c0 .51938.41812.9375.9375.9375h1.875c.51938 0 .9375-.41812.9375-.9375z" fill="#5fb2ff"/></svg> diff --git a/modules/csg/icons/CSGMesh3D.svg b/modules/csg/icons/CSGMesh3D.svg index 962e71f6ae..8f4a1736fb 100644 --- a/modules/csg/icons/CSGMesh3D.svg +++ b/modules/csg/icons/CSGMesh3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h3.2695v-2h-3.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l4.916 4.916c.31428-.20669.68609-.33008 1.084-.33008 0-.3979.12338-.76971.33008-1.084l-4.916-4.916h5.8574c.17478.30301.42598.55488.72852.73047v3.2695h2v-3.2715c.61771-.35663.99874-1.0152 1-1.7285 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1z" fill="#fc9c9c"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2 .0005649.71397.38169 1.3735 1 1.7305v6.541c-.61771.35663-.99874 1.0152-1 1.7285 0 1.1046.89543 2 2 2 .71397-.000565 1.3735-.38169 1.7305-1h3.2695v-2h-3.2715c-.17478-.30301-.42598-.55488-.72852-.73047v-5.8555l4.916 4.916c.31428-.20669.68609-.33008 1.084-.33008 0-.3979.12338-.76971.33008-1.084l-4.916-4.916h5.8574c.17478.30301.42598.55488.72852.73047v3.2695h2v-3.2715c.61771-.35663.99874-1.0152 1-1.7285 0-1.1046-.89543-2-2-2-.71397.0005648-1.3735.38169-1.7305 1h-6.541c-.35663-.61771-1.0152-.99874-1.7285-1z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg> diff --git a/modules/csg/icons/CSGPolygon3D.svg b/modules/csg/icons/CSGPolygon3D.svg index 1d496e5fd9..971f3577bb 100644 --- a/modules/csg/icons/CSGPolygon3D.svg +++ b/modules/csg/icons/CSGPolygon3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002c-.14254.00487-.28238.04016-.41016.10352l-6 3c-.33878.16944-.55276.51574-.55273.89453v5.832c-.105.61631.37487 1.1768 1 1.168h5v2c.0000216.67546.64487 1.1297 1.2617.95898-.16118-.28721-.26172-.61135-.26172-.95898v-2c0-.72673.40794-1.3664 1-1.7168v-1.666l4-2v1.3828h1c.36397 0 .70348.10774 1 .2832v-3.2773c.000006-.00195.000006-.0039094 0-.0058594.000026-.37879-.21395-.72509-.55273-.89453l-6-3c-.15022-.074574-.31679-.11017-.48438-.10352zm.037109 2.1172 3.7637 1.8809-2.7637 1.3809v-1.3809c-.0000552-.55226-.44774-.99994-1-1h-1.7617l1.7617-.88086zm-5 2.8809h4v4h-4z" fill="#fc9c9c"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002c-.14254.00487-.28238.04016-.41016.10352l-6 3c-.33878.16944-.55276.51574-.55273.89453v5.832c-.105.61631.37487 1.1768 1 1.168h5v2c.0000216.67546.64487 1.1297 1.2617.95898-.16118-.28721-.26172-.61135-.26172-.95898v-2c0-.72673.40794-1.3664 1-1.7168v-1.666l4-2v1.3828h1c.36397 0 .70348.10774 1 .2832v-3.2773c.000006-.00195.000006-.0039094 0-.0058594.000026-.37879-.21395-.72509-.55273-.89453l-6-3c-.15022-.074574-.31679-.11017-.48438-.10352zm.037109 2.1172 3.7637 1.8809-2.7637 1.3809v-1.3809c-.0000552-.55226-.44774-.99994-1-1h-1.7617l1.7617-.88086zm-5 2.8809h4v4h-4z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg> diff --git a/modules/csg/icons/CSGSphere3D.svg b/modules/csg/icons/CSGSphere3D.svg index 639e38f49f..770af80632 100644 --- a/modules/csg/icons/CSGSphere3D.svg +++ b/modules/csg/icons/CSGSphere3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 .093042 0 .18321-.01004.27539-.013672-.17055-.29341-.27539-.62792-.27539-.98633v-2c0-.72673.40794-1.3664 1-1.7168v-.33398c.34074-.019259.67728-.069097 1.0156-.10547.083091-1.0187.94713-1.8438 1.9844-1.8438h2c.35841 0 .69292.10484.98633.27539.003633-.092184.013672-.18235.013672-.27539 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-.071342-2.6061-.29819-3.9434-.69141.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549.41253 3.637 2.0767 3.9414 4.1699-1.3046.36677-2.6158.60259-3.9414.6875zm-5.7793 6.2988c1.2733.31892 2.5337.50215 3.7793.5625v2.9414c-1.8291-.36719-3.266-1.7339-3.7793-3.5039z" fill="#fc9c9c"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 .093042 0 .18321-.01004.27539-.013672-.17055-.29341-.27539-.62792-.27539-.98633v-2c0-.72673.40794-1.3664 1-1.7168v-.33398c.34074-.019259.67728-.069097 1.0156-.10547.083091-1.0187.94713-1.8438 1.9844-1.8438h2c.35841 0 .69292.10484.98633.27539.003633-.092184.013672-.18235.013672-.27539 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-.071342-2.6061-.29819-3.9434-.69141.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549.41253 3.637 2.0767 3.9414 4.1699-1.3046.36677-2.6158.60259-3.9414.6875zm-5.7793 6.2988c1.2733.31892 2.5337.50215 3.7793.5625v2.9414c-1.8291-.36719-3.266-1.7339-3.7793-3.5039z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg> diff --git a/modules/csg/icons/CSGTorus3D.svg b/modules/csg/icons/CSGTorus3D.svg index eb8c0f37cb..ece9c68d28 100644 --- a/modules/csg/icons/CSGTorus3D.svg +++ b/modules/csg/icons/CSGTorus3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3c-1.8145 0-3.4691.41721-4.7461 1.1621-1.277.745-2.2539 1.9082-2.2539 3.3379 0 1.4298.9769 2.5949 2.2539 3.3398s2.9316 1.1602 4.7461 1.1602c0-1.0907.90931-2 2-2 0-.080836.013744-.15778.023438-.23633-.61769.14673-1.3008.23633-2.0234.23633-1.4992 0-2.8437-.36687-3.7383-.88867-.89456-.5219-1.2617-1.108-1.2617-1.6113 0-.5032.36716-1.0876 1.2617-1.6094.89456-.5219 2.2391-.89062 3.7383-.89062s2.8437.36872 3.7383.89062c.89456.5218 1.2617 1.1062 1.2617 1.6094 0 .15978-.053679.32822-.13281.5h1.1328c.32481 0 .62893.088408.90234.23047.057552-.23582.097656-.47718.097656-.73047 0-1.4297-.9769-2.5929-2.2539-3.3379-1.277-.7449-2.9316-1.1621-4.7461-1.1621z" fill="#fc9c9c"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#84c2ff"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3c-1.8145 0-3.4691.41721-4.7461 1.1621-1.277.745-2.2539 1.9082-2.2539 3.3379 0 1.4298.9769 2.5949 2.2539 3.3398s2.9316 1.1602 4.7461 1.1602c0-1.0907.90931-2 2-2 0-.080836.013744-.15778.023438-.23633-.61769.14673-1.3008.23633-2.0234.23633-1.4992 0-2.8437-.36687-3.7383-.88867-.89456-.5219-1.2617-1.108-1.2617-1.6113 0-.5032.36716-1.0876 1.2617-1.6094.89456-.5219 2.2391-.89062 3.7383-.89062s2.8437.36872 3.7383.89062c.89456.5218 1.2617 1.1062 1.2617 1.6094 0 .15978-.053679.32822-.13281.5h1.1328c.32481 0 .62893.088408.90234.23047.057552-.23582.097656-.47718.097656-.73047 0-1.4297-.9769-2.5929-2.2539-3.3379-1.277-.7449-2.9316-1.1621-4.7461-1.1621z" fill="#fc7f7f"/><path d="m12 9c-.55401 0-1 .44599-1 1v1h2v2h1c.55401 0 1-.44599 1-1v-2c0-.55401-.44599-1-1-1zm1 4h-2v-2h-1c-.55401 0-1 .44599-1 1v2c0 .55401.44599 1 1 1h2c.55401 0 1-.44599 1-1z" fill="#5fb2ff"/></svg> diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index f22ff29349..271cb03c9f 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -144,7 +144,7 @@ </argument> <description> Sets the timeout parameters for a peer. The timeout parameters control how and when a peer will timeout from a failure to acknowledge reliable traffic. Timeout values are expressed in milliseconds. - The [code]timeout_limit[/code] is a factor that, multiplied by a value based on the avarage round trip time, will determine the timeout limit for a reliable packet. When that limit is reached, the timeout will be doubled, and the peer will be disconnected if that limit has reached [code]timeout_min[/code]. The [code]timeout_max[/code] parameter, on the other hand, defines a fixed timeout for which any packet must be acknowledged or the peer will be dropped. + The [code]timeout_limit[/code] is a factor that, multiplied by a value based on the average round trip time, will determine the timeout limit for a reliable packet. When that limit is reached, the timeout will be doubled, and the peer will be disconnected if that limit has reached [code]timeout_min[/code]. The [code]timeout_max[/code] parameter, on the other hand, defines a fixed timeout for which any packet must be acknowledged or the peer will be dropped. </description> </method> </methods> diff --git a/modules/fbx/README.md b/modules/fbx/README.md index 2a2f186463..69a50d4bea 100644 --- a/modules/fbx/README.md +++ b/modules/fbx/README.md @@ -15,7 +15,7 @@ functionality. If anything we should give this parser back to assimp at some poi # Updating assimp fbx parser -Don't. it's not possible the code is rewritten in many areas to remove thirdparty deps and various bugs are fixed. +Don't. It's not possible the code is rewritten in many areas to remove thirdparty deps and various bugs are fixed. Many days were put into rewriting the parser to use safe code and safe memory accessors. diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp index 304d1598f6..349bcaeeaa 100644 --- a/modules/fbx/data/fbx_mesh_data.cpp +++ b/modules/fbx/data/fbx_mesh_data.cpp @@ -945,7 +945,7 @@ void FBXMeshData::triangulate_polygon(SurfaceData *surface, const Vector<int> &p for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) { TPPLPoly &tp = I->get(); - ERR_FAIL_COND_MSG(tp.GetNumPoints() != 3, "The triangulator retuned more points, how this is possible?"); + ERR_FAIL_COND_MSG(tp.GetNumPoints() != 3, "The triangulator returned more points, how this is possible?"); // Find Index for (int i = 2; i >= 0; i -= 1) { const Vector2 vertex = tp.GetPoint(i); diff --git a/modules/fbx/data/fbx_mesh_data.h b/modules/fbx/data/fbx_mesh_data.h index 575f833584..c4eaa7d170 100644 --- a/modules/fbx/data/fbx_mesh_data.h +++ b/modules/fbx/data/fbx_mesh_data.h @@ -156,7 +156,7 @@ private: /// [0, 2, 1, 3, 4] /// The negative values are computed using this formula: `(-value) - 1` /// - /// Returns the vertex index from the poligon vertex. + /// Returns the vertex index from the polygon vertex. /// Returns -1 if `p_index` is invalid. int get_vertex_from_polygon_vertex(const std::vector<int> &p_face_indices, int p_index) const; diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index ccbea21541..f60277f60a 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -102,7 +102,7 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl FBXDocParser::TokenList tokens; bool is_binary = false; - data.resize(f->get_len()); + data.resize(f->get_length()); ERR_FAIL_COND_V(data.size() < 64, nullptr); @@ -1056,7 +1056,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( //print_verbose("[doc] node animation path: " + node_path); } } else { - // note: this could actually be unsafe this means we should be careful about continuing here, if we see bizzare effects later we should disable this. + // note: this could actually be unsafe this means we should be careful about continuing here, if we see bizarre effects later we should disable this. // I am not sure if this is unsafe or not, testing will tell us this. print_error("[doc] invalid fbx target detected for this track"); continue; diff --git a/modules/fbx/fbx_parser/FBXDocument.cpp b/modules/fbx/fbx_parser/FBXDocument.cpp index bb85d6ff7c..89c69d2ee8 100644 --- a/modules/fbx/fbx_parser/FBXDocument.cpp +++ b/modules/fbx/fbx_parser/FBXDocument.cpp @@ -487,7 +487,7 @@ const std::vector<const AnimationStack *> &Document::AnimationStacks() const { const AnimationStack *stack = lazy->Get<AnimationStack>(); ERR_CONTINUE_MSG(!stack, "invalid ptr to AnimationStack - conversion failure"); - // We push back the weak reference :) to keep things simple, as ownership is on the parser side so it wont be cleaned up. + // We push back the weak reference :) to keep things simple, as ownership is on the parser side so it won't be cleaned up. animationStacksResolved.push_back(stack); } diff --git a/modules/fbx/fbx_parser/FBXDocument.h b/modules/fbx/fbx_parser/FBXDocument.h index 9664cd763a..e01e0471aa 100644 --- a/modules/fbx/fbx_parser/FBXDocument.h +++ b/modules/fbx/fbx_parser/FBXDocument.h @@ -699,7 +699,7 @@ private: typedef std::vector<int64_t> KeyTimeList; typedef std::vector<float> KeyValueList; -/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */ +/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */ class AnimationCurve : public Object { public: AnimationCurve(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc); diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp index a28e7565c6..2cc25a0690 100644 --- a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp +++ b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp @@ -125,7 +125,7 @@ MeshGeometry::MeshGeometry(uint64_t id, const ElementPtr element, const std::str ScopePtr sc = element->Compound(); ERR_FAIL_COND_MSG(sc == nullptr, "failed to read geometry, prevented crash"); - ERR_FAIL_COND_MSG(!HasElement(sc, "Vertices"), "Detected mesh with no vertexes, didn't populate the mesh"); + ERR_FAIL_COND_MSG(!HasElement(sc, "Vertices"), "Detected mesh with no vertices, didn't populate the mesh"); // must have Mesh elements: const ElementPtr Vertices = GetRequiredElement(sc, "Vertices", element); @@ -140,7 +140,7 @@ MeshGeometry::MeshGeometry(uint64_t id, const ElementPtr element, const std::str ParseVectorDataArray(m_vertices, Vertices); ParseVectorDataArray(m_face_indices, PolygonVertexIndex); - ERR_FAIL_COND_MSG(m_vertices.empty(), "mesh with no vertexes in FBX file, did you mean to delete it?"); + ERR_FAIL_COND_MSG(m_vertices.empty(), "mesh with no vertices in FBX file, did you mean to delete it?"); ERR_FAIL_COND_MSG(m_face_indices.empty(), "mesh has no faces, was this intended?"); // Retrieve layer elements, for all of the mesh @@ -278,7 +278,7 @@ MeshGeometry::MeshGeometry(uint64_t id, const ElementPtr element, const std::str } } // As the algorithm above, this check is useless. Because the first - // ever vertex is always considered the begining of a polygon. + // ever vertex is always considered the beginning of a polygon. ERR_FAIL_COND_MSG(found_it == false, "Was not possible to find the first vertex of this polygon. FBX file is corrupted."); } else { @@ -418,7 +418,7 @@ MeshGeometry::MappingData<T> MeshGeometry::resolve_vertex_data_array( // parse data into array ParseVectorDataArray(tempData.data, GetRequiredElement(source, dataElementName)); - // index array wont always exist + // index array won't always exist const ElementPtr element = GetOptionalElement(source, indexDataElementName); if (element) { ParseVectorDataArray(tempData.index, element); diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.h b/modules/fbx/fbx_parser/FBXMeshGeometry.h index 05493c4aec..c9b25f008d 100644 --- a/modules/fbx/fbx_parser/FBXMeshGeometry.h +++ b/modules/fbx/fbx_parser/FBXMeshGeometry.h @@ -122,7 +122,7 @@ typedef std::vector<int> MatIndexArray; /// ## Map Type: /// * None The mapping is undetermined. /// * ByVertex There will be one mapping coordinate for each surface control point/vertex (ControlPoint is a vertex). -/// * If you have direct reference type verticies[x] +/// * If you have direct reference type vertices[x] /// * If you have IndexToDirect reference type the UV /// * ByPolygonVertex There will be one mapping coordinate for each vertex, for every polygon of which it is a part. This means that a vertex will have as many mapping coordinates as polygons of which it is a part. (Sorted by polygon, referencing vertex) /// * ByPolygon There can be only one mapping coordinate for the whole polygon. @@ -186,7 +186,7 @@ public: /// Returns -1 if the vertices doesn't form an edge. Vertex order, doesn't // matter. static int get_edge_id(const std::vector<Edge> &p_map, int p_vertex_a, int p_vertex_b); - // Retuns the edge point bu that ID, or the edge with -1 vertices if the + // Returns the edge point bu that ID, or the edge with -1 vertices if the // id is not valid. static Edge get_edge(const std::vector<Edge> &p_map, int p_id); diff --git a/modules/fbx/tools/import_utils.cpp b/modules/fbx/tools/import_utils.cpp index c87dd1fd3a..368aa09a75 100644 --- a/modules/fbx/tools/import_utils.cpp +++ b/modules/fbx/tools/import_utils.cpp @@ -128,7 +128,7 @@ Transform get_unscaled_transform(const Transform &p_initial, real_t p_scale) { } Vector3 get_poly_normal(const std::vector<Vector3> &p_vertices) { - ERR_FAIL_COND_V_MSG(p_vertices.size() < 3, Vector3(0, 0, 0), "At least 3 vertices are necesary"); + ERR_FAIL_COND_V_MSG(p_vertices.size() < 3, Vector3(0, 0, 0), "At least 3 vertices are necessary"); // Using long double to make sure that normal is computed for even really tiny objects. typedef long double ldouble; ldouble x = 0.0; diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 0de6b27d27..7c3b76e4d7 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/core_constants.h" #include "core/io/file_access_encrypted.h" +#include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" @@ -335,9 +336,18 @@ bool GDNative::initialize() { // On OSX the exported libraries are located under the Frameworks directory. // So we need to replace the library path. String path = ProjectSettings::get_singleton()->globalize_path(lib_path); - if (!FileAccess::exists(path)) { + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + if (!da->file_exists(path) && !da->dir_exists(path)) { path = OS::get_singleton()->get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(lib_path.get_file()); } + + if (da->dir_exists(path)) { // Target library is a ".framework", add library base name to the path. + path = path.plus_file(path.get_file().get_basename()); + } + + memdelete(da); + #else String path = ProjectSettings::get_singleton()->globalize_path(lib_path); #endif diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp index dfb26c13e3..b4ac0d886e 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.cpp +++ b/modules/gdnative/gdnative_library_editor_plugin.cpp @@ -131,7 +131,7 @@ void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) { EditorFileDialog::FileMode mode = EditorFileDialog::FILE_MODE_OPEN_FILE; if (id == BUTTON_SELECT_DEPENDENCES) { mode = EditorFileDialog::FILE_MODE_OPEN_FILES; - } else if (treeItem->get_text(0) == "iOS") { + } else if (treeItem->get_text(0) == "iOS" || treeItem->get_text(0) == "macOS") { mode = EditorFileDialog::FILE_MODE_OPEN_ANY; } @@ -278,11 +278,10 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() { platforms["X11"] = platform_linux; NativePlatformConfig platform_osx; - platform_osx.name = "Mac OSX"; + platform_osx.name = "macOS"; platform_osx.entries.push_back("64"); - platform_osx.entries.push_back("32"); - platform_osx.library_extension = "*.dylib"; - platforms["OSX"] = platform_osx; + platform_osx.library_extension = "*.framework; Framework, *.dylib; Dynamic Library"; + platforms["macOS"] = platform_osx; NativePlatformConfig platform_haiku; platform_haiku.name = "Haiku"; diff --git a/modules/gdnative/include/gdnative/callable.h b/modules/gdnative/include/gdnative/callable.h index b84b0c1f1f..1d52ca7a68 100644 --- a/modules/gdnative/include/gdnative/callable.h +++ b/modules/gdnative/include/gdnative/callable.h @@ -37,6 +37,7 @@ extern "C" { #include <stdint.h> +// Alignment hardcoded in `core/variant/callable.h`. #define GODOT_CALLABLE_SIZE (16) #ifndef GODOT_CORE_API_GODOT_CALLABLE_TYPE_DEFINED diff --git a/modules/gdnative/include/gdnative/signal.h b/modules/gdnative/include/gdnative/signal.h index f4dc17e089..41a76d0510 100644 --- a/modules/gdnative/include/gdnative/signal.h +++ b/modules/gdnative/include/gdnative/signal.h @@ -37,6 +37,7 @@ extern "C" { #include <stdint.h> +// Alignment hardcoded in `core/variant/callable.h`. #define GODOT_SIGNAL_SIZE (16) #ifndef GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index 31e6a81975..a48245814f 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -212,6 +212,8 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) { } bool PluginScript::instance_has(const Object *p_this) const { + ERR_FAIL_COND_V(!_language, false); + _language->lock(); bool hasit = _instances.has((Object *)p_this); _language->unlock(); @@ -441,10 +443,10 @@ Error PluginScript::load_source_code(const String &p_path) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + p_path + "'."); - int len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); - int r = f->get_buffer(w, len); + uint64_t r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index f2fb0a2fdc..8b0434c7dd 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -47,11 +47,7 @@ godot_int GDAPI godot_videodecoder_file_read(void *ptr, uint8_t *buf, int buf_si // if file exists if (file) { - long bytes_read = file->get_buffer(buf, buf_size); - // No bytes to read => EOF - if (bytes_read == 0) { - return 0; - } + int64_t bytes_read = file->get_buffer(buf, buf_size); return bytes_read; } return -1; @@ -62,41 +58,35 @@ int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) { FileAccess *file = reinterpret_cast<FileAccess *>(ptr); if (file) { - size_t len = file->get_len(); + int64_t len = file->get_length(); switch (whence) { case SEEK_SET: { - // Just for explicitness - size_t new_pos = static_cast<size_t>(pos); - if (new_pos > len) { + if (pos > len) { return -1; } - file->seek(new_pos); - pos = static_cast<int64_t>(file->get_position()); - return pos; + file->seek(pos); + return file->get_position(); } break; case SEEK_CUR: { // Just in case it doesn't exist - if (pos < 0 && (size_t)-pos > file->get_position()) { + if (pos < 0 && -pos > (int64_t)file->get_position()) { return -1; } - pos = pos + static_cast<int>(file->get_position()); - file->seek(pos); - pos = static_cast<int64_t>(file->get_position()); - return pos; + file->seek(file->get_position() + pos); + return file->get_position(); } break; case SEEK_END: { // Just in case something goes wrong - if ((size_t)-pos > len) { + if (-pos > len) { return -1; } file->seek_end(pos); - pos = static_cast<int64_t>(file->get_position()); - return pos; + return file->get_position(); } break; default: { // Only 4 possible options, hence default = AVSEEK_SIZE // Asks to return the length of file - return static_cast<int64_t>(len); + return len; } break; } } diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp index 2513c62b6a..41306f0687 100644 --- a/modules/gdnavigation/nav_map.cpp +++ b/modules/gdnavigation/nav_map.cpp @@ -112,7 +112,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p } } - // Check for trival cases + // Check for trivial cases if (!begin_poly || !end_poly) { return Vector<Vector3>(); } diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp index a7d4e79148..7d30ce0f44 100644 --- a/modules/gdnavigation/navigation_mesh_generator.cpp +++ b/modules/gdnavigation/navigation_mesh_generator.cpp @@ -32,7 +32,7 @@ #include "navigation_mesh_generator.h" -#include "core/math/quick_hull.h" +#include "core/math/convex_hull.h" #include "core/os/thread.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/mesh_instance_3d.h" @@ -220,7 +220,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Vector<Vector3> varr = Variant(convex_polygon->get_points()); Geometry3D::MeshData md; - Error err = QuickHull::build(varr, md); + Error err = ConvexHullComputer::convex_hull(varr, md); if (err == OK) { PackedVector3Array faces; diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index ca646dff15..d34cccb3af 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -546,7 +546,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { } const String text_edit_color_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); - const bool default_theme = text_edit_color_theme == "Default"; + const bool default_theme = text_edit_color_theme == "Godot 2"; if (default_theme || EditorSettings::get_singleton()->is_dark_theme()) { function_definition_color = Color(0.4, 0.9, 1.0); @@ -558,7 +558,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { EDITOR_DEF("text_editor/highlighting/gdscript/function_definition_color", function_definition_color); EDITOR_DEF("text_editor/highlighting/gdscript/node_path_color", node_path_color); - if (text_edit_color_theme == "Adaptive" || default_theme) { + if (text_edit_color_theme == "Default" || default_theme) { EditorSettings::get_singleton()->set_initial_value( "text_editor/highlighting/gdscript/function_definition_color", function_definition_color, diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 859c1acde9..d7814e85b0 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -481,7 +481,7 @@ void GDScript::_update_doc() { methods[i].return_val.class_name = _get_gdscript_reference_class_name(Object::cast_to<GDScript>(return_type.script_type)); } - // Change class name if argumetn is script reference. + // Change class name if argument is script reference. for (int j = 0; j < fn->get_argument_count(); j++) { GDScriptDataType arg_type = fn->get_argument_type(j); if (arg_type.kind == GDScriptDataType::GDSCRIPT) { @@ -1045,10 +1045,10 @@ Error GDScript::load_source_code(const String &p_path) { ERR_FAIL_COND_V(err, err); } - int len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); - int r = f->get_buffer(w, len); + uint64_t r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 17ae52f3ab..d8d60b35c6 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -543,6 +543,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas } else { // TODO: Add warning. mark_node_unsafe(member.variable->initializer); + member.variable->use_conversion_assign = true; } } else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { #ifdef DEBUG_ENABLED @@ -552,6 +553,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas if (member.variable->initializer->get_datatype().is_variant()) { // TODO: Warn unsafe assign. mark_node_unsafe(member.variable->initializer); + member.variable->use_conversion_assign = true; } } } else if (member.variable->infer_datatype) { @@ -1145,6 +1147,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable } else { // TODO: Add warning. mark_node_unsafe(p_variable->initializer); + p_variable->use_conversion_assign = true; } #ifdef DEBUG_ENABLED } else if (type.builtin_type == Variant::INT && p_variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { @@ -1154,6 +1157,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable if (p_variable->initializer->get_datatype().is_variant()) { // TODO: Warn unsafe assign. mark_node_unsafe(p_variable->initializer); + p_variable->use_conversion_assign = true; } } } else if (p_variable->infer_datatype) { @@ -1608,10 +1612,12 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig } else { // TODO: Add warning. mark_node_unsafe(p_assignment); + p_assignment->use_conversion_assign = true; } } else { // TODO: Warning in this case. mark_node_unsafe(p_assignment); + p_assignment->use_conversion_assign = true; } } } else { @@ -1621,6 +1627,9 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig if (assignee_type.has_no_type() || assigned_value_type.is_variant()) { mark_node_unsafe(p_assignment); + if (assignee_type.is_hard_type()) { + p_assignment->use_conversion_assign = true; + } } if (p_assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) { @@ -2059,9 +2068,11 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa if (p_call->is_super) { base_type = parser->current_class->base_type; + base_type.is_meta_type = false; is_self = true; } else if (callee_type == GDScriptParser::Node::IDENTIFIER) { base_type = parser->current_class->get_datatype(); + base_type.is_meta_type = false; is_self = true; } else if (callee_type == GDScriptParser::Node::SUBSCRIPT) { GDScriptParser::SubscriptNode *subscript = static_cast<GDScriptParser::SubscriptNode *>(p_call->callee); @@ -2078,9 +2089,23 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa mark_node_unsafe(p_call); return; } - reduce_expression(subscript->base); + if (subscript->attribute == nullptr) { + // Invalid call. Error already sent in parser. + p_call->set_datatype(call_type); + mark_node_unsafe(p_call); + return; + } - base_type = subscript->base->get_datatype(); + GDScriptParser::IdentifierNode *base_id = nullptr; + if (subscript->base->type == GDScriptParser::Node::IDENTIFIER) { + base_id = static_cast<GDScriptParser::IdentifierNode *>(subscript->base); + } + if (base_id && GDScriptParser::get_builtin_type(base_id->name) < Variant::VARIANT_MAX) { + base_type = make_builtin_meta_type(GDScriptParser::get_builtin_type(base_id->name)); + } else { + reduce_expression(subscript->base); + base_type = subscript->base->get_datatype(); + } } else { // Invalid call. Error already sent in parser. // TODO: Could check if Callable here too. diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 0da99ccee3..77a972ef12 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -129,12 +129,6 @@ uint32_t GDScriptByteCodeGenerator::add_temporary(const GDScriptDataType &p_type int idx = temporaries.size(); pool.push_back(idx); temporaries.push_back(new_temp); - - // First time using this, so adjust to the proper type. - if (temp_type != Variant::NIL) { - Address addr(Address::TEMPORARY, idx, p_type); - write_type_adjust(addr, temp_type); - } } int slot = pool.front()->get(); pool.pop_front(); @@ -189,8 +183,12 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { append(GDScriptFunction::OPCODE_END, 0); for (int i = 0; i < temporaries.size(); i++) { + int stack_index = i + max_locals + RESERVED_STACK; for (int j = 0; j < temporaries[i].bytecode_indices.size(); j++) { - opcodes.write[temporaries[i].bytecode_indices[j]] = (i + max_locals + RESERVED_STACK) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + opcodes.write[temporaries[i].bytecode_indices[j]] = stack_index | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + } + if (temporaries[i].type != Variant::NIL) { + function->temporary_slots[stack_index] = temporaries[i].type; } } @@ -781,63 +779,43 @@ void GDScriptByteCodeGenerator::write_get_member(const Address &p_target, const append(p_name); } -void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) { - if (p_target.type.has_type && !p_source.type.has_type) { - // Typed assignment. - switch (p_target.type.kind) { - case GDScriptDataType::BUILTIN: { - if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); - append(p_target); - append(p_source); - } else { - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); - append(p_target); - append(p_source); - append(p_target.type.builtin_type); - } - } break; - case GDScriptDataType::NATIVE: { - int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type]; - Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx]; - class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3); - append(p_target); - append(p_source); - append(class_idx); - } break; - case GDScriptDataType::SCRIPT: - case GDScriptDataType::GDSCRIPT: { - Variant script = p_target.type.script_type; - int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); - - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3); +void GDScriptByteCodeGenerator::write_assign_with_conversion(const Address &p_target, const Address &p_source) { + switch (p_target.type.kind) { + case GDScriptDataType::BUILTIN: { + if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); append(p_target); append(p_source); - append(idx); - } break; - default: { - ERR_PRINT("Compiler bug: unresolved assign."); - - // Shouldn't get here, but fail-safe to a regular assignment - append(GDScriptFunction::OPCODE_ASSIGN, 2); + } else { + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); append(p_target); append(p_source); + append(p_target.type.builtin_type); } - } - } else { - if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); + } break; + case GDScriptDataType::NATIVE: { + int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type]; + Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx]; + class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3); append(p_target); append(p_source); - } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) { - // Need conversion.. - append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); + append(class_idx); + } break; + case GDScriptDataType::SCRIPT: + case GDScriptDataType::GDSCRIPT: { + Variant script = p_target.type.script_type; + int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); + + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3); append(p_target); append(p_source); - append(p_target.type.builtin_type); - } else { - // Either untyped assignment or already type-checked by the parser + append(idx); + } break; + default: { + ERR_PRINT("Compiler bug: unresolved assign."); + + // Shouldn't get here, but fail-safe to a regular assignment append(GDScriptFunction::OPCODE_ASSIGN, 2); append(p_target); append(p_source); @@ -845,6 +823,24 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr } } +void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) { + if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) { + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2); + append(p_target); + append(p_source); + } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) { + // Need conversion. + append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2); + append(p_target); + append(p_source); + append(p_target.type.builtin_type); + } else { + append(GDScriptFunction::OPCODE_ASSIGN, 2); + append(p_target); + append(p_source); + } +} + void GDScriptByteCodeGenerator::write_assign_true(const Address &p_target) { append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1); append(p_target); @@ -1017,6 +1013,56 @@ void GDScriptByteCodeGenerator::write_call_builtin_type(const Address &p_target, append(Variant::get_validated_builtin_method(p_type, p_method)); } +void GDScriptByteCodeGenerator::write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) { + bool is_validated = false; + + // Check if all types are correct. + if (Variant::is_builtin_method_vararg(p_type, p_method)) { + is_validated = true; // Vararg works fine with any argument, since they can be any type. + } else if (p_arguments.size() == Variant::get_builtin_method_argument_count(p_type, p_method)) { + bool all_types_exact = true; + for (int i = 0; i < p_arguments.size(); i++) { + if (!IS_BUILTIN_TYPE(p_arguments[i], Variant::get_builtin_method_argument_type(p_type, p_method, i))) { + all_types_exact = false; + break; + } + } + + is_validated = all_types_exact; + } + + if (!is_validated) { + // Perform regular call. + append(GDScriptFunction::OPCODE_CALL_BUILTIN_STATIC, p_arguments.size() + 1); + for (int i = 0; i < p_arguments.size(); i++) { + append(p_arguments[i]); + } + append(p_target); + append(p_type); + append(p_method); + append(p_arguments.size()); + return; + } + + if (p_target.mode == Address::TEMPORARY) { + Variant::Type result_type = Variant::get_builtin_method_return_type(p_type, p_method); + Variant::Type temp_type = temporaries[p_target.address].type; + if (result_type != temp_type) { + write_type_adjust(p_target, result_type); + } + } + + append(GDScriptFunction::OPCODE_CALL_BUILTIN_TYPE_VALIDATED, 2 + p_arguments.size()); + + for (int i = 0; i < p_arguments.size(); i++) { + append(p_arguments[i]); + } + append(Address()); // No base since it's static. + append(p_target); + append(p_arguments.size()); + append(Variant::get_validated_builtin_method(p_type, p_method)); +} + void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) { append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL_METHOD_BIND : GDScriptFunction::OPCODE_CALL_METHOD_BIND_RET, 2 + p_arguments.size()); for (int i = 0; i < p_arguments.size(); i++) { diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index c060476f39..b1f3cd5fb3 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -450,6 +450,7 @@ public: virtual void write_set_member(const Address &p_value, const StringName &p_name) override; virtual void write_get_member(const Address &p_target, const StringName &p_name) override; virtual void write_assign(const Address &p_target, const Address &p_source) override; + virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) override; virtual void write_assign_true(const Address &p_target) override; virtual void write_assign_false(const Address &p_target) override; virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override; @@ -461,6 +462,7 @@ public: virtual void write_call_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &p_arguments) override; virtual void write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector<Address> &p_arguments) override; virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override; + virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override; virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override; virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override; virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override; diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 113d36be98..601cdb4080 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -153,9 +153,9 @@ String GDScriptCache::get_source_code(const String &p_path) { ERR_FAIL_COND_V(err, ""); } - int len = f->get_len(); + uint64_t len = f->get_length(); source_file.resize(len + 1); - int r = f->get_buffer(source_file.ptrw(), len); + uint64_t r = f->get_buffer(source_file.ptrw(), len); f->close(); ERR_FAIL_COND_V(r != len, ""); source_file.write[len] = 0; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index ae9a8ede5e..cac6544f03 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -111,6 +111,7 @@ public: virtual void write_set_member(const Address &p_value, const StringName &p_name) = 0; virtual void write_get_member(const Address &p_target, const StringName &p_name) = 0; virtual void write_assign(const Address &p_target, const Address &p_source) = 0; + virtual void write_assign_with_conversion(const Address &p_target, const Address &p_source) = 0; virtual void write_assign_true(const Address &p_target) = 0; virtual void write_assign_false(const Address &p_target) = 0; virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0; @@ -122,6 +123,7 @@ public: virtual void write_call_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &p_arguments) = 0; virtual void write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector<Address> &p_arguments) = 0; virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0; + virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0; virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0; virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0; virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 37ce8ae2cb..c7ca9449c2 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -537,39 +537,44 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee); if (subscript->is_attribute) { - GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base); - if (r_error) { - return GDScriptCodeGenerator::Address(); - } - if (within_await) { - gen->write_call_async(result, base, call->function_name, arguments); - } else if (base.type.has_type && base.type.kind != GDScriptDataType::BUILTIN) { - // Native method, use faster path. - StringName class_name; - if (base.type.kind == GDScriptDataType::NATIVE) { - class_name = base.type.native_type; - } else { - class_name = base.type.native_type == StringName() ? base.type.script_type->get_instance_base_type() : base.type.native_type; + // May be static built-in method call. + if (!call->is_super && subscript->base->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name) < Variant::VARIANT_MAX) { + gen->write_call_builtin_type_static(result, GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name), subscript->attribute->name, arguments); + } else { + GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base); + if (r_error) { + return GDScriptCodeGenerator::Address(); } - if (ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) { - MethodBind *method = ClassDB::get_method(class_name, call->function_name); - if (_have_exact_arguments(method, arguments)) { - // Exact arguments, use ptrcall. - gen->write_call_ptrcall(result, base, method, arguments); + if (within_await) { + gen->write_call_async(result, base, call->function_name, arguments); + } else if (base.type.has_type && base.type.kind != GDScriptDataType::BUILTIN) { + // Native method, use faster path. + StringName class_name; + if (base.type.kind == GDScriptDataType::NATIVE) { + class_name = base.type.native_type; } else { - // Not exact arguments, but still can use method bind call. - gen->write_call_method_bind(result, base, method, arguments); + class_name = base.type.native_type == StringName() ? base.type.script_type->get_instance_base_type() : base.type.native_type; } + if (ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) { + MethodBind *method = ClassDB::get_method(class_name, call->function_name); + if (_have_exact_arguments(method, arguments)) { + // Exact arguments, use ptrcall. + gen->write_call_ptrcall(result, base, method, arguments); + } else { + // Not exact arguments, but still can use method bind call. + gen->write_call_method_bind(result, base, method, arguments); + } + } else { + gen->write_call(result, base, call->function_name, arguments); + } + } else if (base.type.has_type && base.type.kind == GDScriptDataType::BUILTIN) { + gen->write_call_builtin_type(result, base, base.type.builtin_type, call->function_name, arguments); } else { gen->write_call(result, base, call->function_name, arguments); } - } else if (base.type.has_type && base.type.kind == GDScriptDataType::BUILTIN) { - gen->write_call_builtin_type(result, base, base.type.builtin_type, call->function_name, arguments); - } else { - gen->write_call(result, base, call->function_name, arguments); - } - if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); + } } } else { _set_error("Cannot call something that isn't a function.", call->callee); @@ -966,6 +971,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } else { gen->write_set(prev_base, key, assigned); } + if (key.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); + } if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); } @@ -1076,7 +1084,11 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), setter_function, args); } else { // Just assign. - gen->write_assign(target, op_result); + if (assignment->use_conversion_assign) { + gen->write_assign_with_conversion(target, op_result); + } else { + gen->write_assign(target, op_result); + } } if (op_result.mode == GDScriptCodeGenerator::Address::TEMPORARY) { @@ -1784,7 +1796,11 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui if (error) { return error; } - gen->write_assign(local, src_address); + if (lv->use_conversion_assign) { + gen->write_assign_with_conversion(local, src_address); + } else { + gen->write_assign(local, src_address); + } if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) { codegen.generator->pop_temporary(); } @@ -1922,7 +1938,11 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ return nullptr; } - codegen.generator->write_assign(dst_address, src_address); + if (field->use_conversion_assign) { + codegen.generator->write_assign_with_conversion(dst_address, src_address); + } else { + codegen.generator->write_assign(dst_address, src_address); + } if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) { codegen.generator->pop_temporary(); } @@ -2203,7 +2223,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar if (err) { return err; } - if (base.is_null() && !base->is_valid()) { + if (base.is_null() || !base->is_valid()) { return ERR_COMPILATION_FAILED; } } diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index 789af57b4c..eee713aa45 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -397,7 +397,7 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { text += DADDR(1 + argc); text += " = "; - text += "<unkown type>("; + text += "<unknown type>("; for (int i = 0; i < argc; i++) { if (i > 0) { text += ", "; @@ -542,6 +542,28 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { incr = 5 + argc; } break; + case OPCODE_CALL_BUILTIN_STATIC: { + Variant::Type type = (Variant::Type)_code_ptr[ip + 1 + instr_var_args]; + int argc = _code_ptr[ip + 3 + instr_var_args]; + + text += "call built-in method static "; + text += DADDR(1 + argc); + text += " = "; + text += Variant::get_type_name(type); + text += "."; + text += _global_names_ptr[_code_ptr[ip + 2 + instr_var_args]].operator String(); + text += "("; + + for (int i = 0; i < argc; i++) { + if (i > 0) { + text += ", "; + } + text += DADDR(1 + i); + } + text += ")"; + + incr += 5 + argc; + } break; case OPCODE_CALL_PTRCALL_NO_RETURN: { text += "call-ptrcall (no return) "; @@ -666,7 +688,7 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { int argc = _code_ptr[ip + 1 + instr_var_args]; text += DADDR(1 + argc) + " = "; - text += "<unkown function>"; + text += "<unknown function>"; text += "("; for (int i = 0; i < argc; i++) { diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 6ae825d2bd..504c7414f6 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -741,6 +741,7 @@ static void _find_identifiers_in_suite(const GDScriptParser::SuiteNode *p_suite, ScriptCodeCompletionOption option; if (p_suite->locals[i].type == GDScriptParser::SuiteNode::Local::CONSTANT) { option = ScriptCodeCompletionOption(p_suite->locals[i].name, ScriptCodeCompletionOption::KIND_CONSTANT); + option.default_value = p_suite->locals[i].constant->initializer->reduced_value; } else { option = ScriptCodeCompletionOption(p_suite->locals[i].name, ScriptCodeCompletionOption::KIND_VARIABLE); } @@ -2872,7 +2873,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co StringName parent = ClassDB::get_parent_class(class_name); if (parent != StringName()) { if (String(parent).begins_with("_")) { - base_type.native_type = String(parent).right(1); + base_type.native_type = String(parent).substr(1); } else { base_type.native_type = parent; } @@ -3066,7 +3067,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol // proxy class remove the underscore. if (r_result.class_name.begins_with("_")) { - r_result.class_name = r_result.class_name.right(1); + r_result.class_name = r_result.class_name.substr(1); } return OK; } diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 70b62ced6d..26b8809337 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -263,6 +263,7 @@ public: OPCODE_CALL_SELF_BASE, OPCODE_CALL_METHOD_BIND, OPCODE_CALL_METHOD_BIND_RET, + OPCODE_CALL_BUILTIN_STATIC, // ptrcall have one instruction per return type. OPCODE_CALL_PTRCALL_NO_RETURN, OPCODE_CALL_PTRCALL_BOOL, @@ -496,6 +497,8 @@ private: Vector<GDScriptDataType> argument_types; GDScriptDataType return_type; + Map<int, Variant::Type> temporary_slots; + #ifdef TOOLS_ENABLED Vector<StringName> arg_names; Vector<Variant> default_arg_values; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index f9027c3a87..b61b469fbc 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1173,7 +1173,7 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() { consume(GDScriptTokenizer::Token::BRACE_CLOSE, R"(Expected closing "}" for enum.)"); #ifdef TOOLS_ENABLED - // Enum values documentaion. + // Enum values documentation. for (int i = 0; i < enum_node->values.size(); i++) { if (i == enum_node->values.size() - 1) { // If close bracket is same line as last value. diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index b1b29a7bd1..ee5e411cad 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -370,6 +370,7 @@ public: Variant::Operator variant_op = Variant::OP_MAX; ExpressionNode *assignee = nullptr; ExpressionNode *assigned_value = nullptr; + bool use_conversion_assign = false; AssignmentNode() { type = ASSIGNMENT; @@ -1119,6 +1120,7 @@ public: MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; int assignments = 0; int usages = 0; + bool use_conversion_assign = false; #ifdef TOOLS_ENABLED String doc_description; #endif // TOOLS_ENABLED diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 4757ec6ca9..56b0f6db83 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -152,6 +152,44 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const return err_text; } +void (*type_init_function_table[])(Variant *) = { + nullptr, // NIL (shouldn't be called). + &VariantInitializer<bool>::init, // BOOL. + &VariantInitializer<int64_t>::init, // INT. + &VariantInitializer<double>::init, // FLOAT. + &VariantInitializer<String>::init, // STRING. + &VariantInitializer<Vector2>::init, // VECTOR2. + &VariantInitializer<Vector2i>::init, // VECTOR2I. + &VariantInitializer<Rect2>::init, // RECT2. + &VariantInitializer<Rect2i>::init, // RECT2I. + &VariantInitializer<Vector3>::init, // VECTOR3. + &VariantInitializer<Vector3i>::init, // VECTOR3I. + &VariantInitializer<Transform2D>::init, // TRANSFORM2D. + &VariantInitializer<Plane>::init, // PLANE. + &VariantInitializer<Quat>::init, // QUAT. + &VariantInitializer<AABB>::init, // AABB. + &VariantInitializer<Basis>::init, // BASIS. + &VariantInitializer<Transform>::init, // TRANSFORM. + &VariantInitializer<Color>::init, // COLOR. + &VariantInitializer<StringName>::init, // STRING_NAME. + &VariantInitializer<NodePath>::init, // NODE_PATH. + &VariantInitializer<RID>::init, // RID. + &VariantTypeAdjust<Object *>::adjust, // OBJECT. + &VariantInitializer<Callable>::init, // CALLABLE. + &VariantInitializer<Signal>::init, // SIGNAL. + &VariantInitializer<Dictionary>::init, // DICTIONARY. + &VariantInitializer<Array>::init, // ARRAY. + &VariantInitializer<PackedByteArray>::init, // PACKED_BYTE_ARRAY. + &VariantInitializer<PackedInt32Array>::init, // PACKED_INT32_ARRAY. + &VariantInitializer<PackedInt64Array>::init, // PACKED_INT64_ARRAY. + &VariantInitializer<PackedFloat32Array>::init, // PACKED_FLOAT32_ARRAY. + &VariantInitializer<PackedFloat64Array>::init, // PACKED_FLOAT64_ARRAY. + &VariantInitializer<PackedStringArray>::init, // PACKED_STRING_ARRAY. + &VariantInitializer<PackedVector2Array>::init, // PACKED_VECTOR2_ARRAY. + &VariantInitializer<PackedVector3Array>::init, // PACKED_VECTOR3_ARRAY. + &VariantInitializer<PackedColorArray>::init, // PACKED_COLOR_ARRAY. +}; + #if defined(__GNUC__) #define OPCODES_TABLE \ static const void *switch_table_ops[] = { \ @@ -196,6 +234,7 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const &&OPCODE_CALL_SELF_BASE, \ &&OPCODE_CALL_METHOD_BIND, \ &&OPCODE_CALL_METHOD_BIND_RET, \ + &&OPCODE_CALL_BUILTIN_STATIC, \ &&OPCODE_CALL_PTRCALL_NO_RETURN, \ &&OPCODE_CALL_PTRCALL_BOOL, \ &&OPCODE_CALL_PTRCALL_INT, \ @@ -491,6 +530,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a memnew_placement(&stack[ADDR_STACK_CLASS], Variant(script)); + for (const Map<int, Variant::Type>::Element *E = temporary_slots.front(); E; E = E->next()) { + type_init_function_table[E->get()](&stack[E->key()]); + } + String err_text; #ifdef DEBUG_ENABLED @@ -1573,6 +1616,51 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } DISPATCH_OPCODE; + OPCODE(OPCODE_CALL_BUILTIN_STATIC) { + CHECK_SPACE(4 + instr_arg_count); + + ip += instr_arg_count; + + GD_ERR_BREAK(_code_ptr[ip + 1] < 0 || _code_ptr[ip + 1] >= Variant::VARIANT_MAX); + Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 1]; + + int methodname_idx = _code_ptr[ip + 2]; + GD_ERR_BREAK(methodname_idx < 0 || methodname_idx >= _global_names_count); + const StringName *methodname = &_global_names_ptr[methodname_idx]; + + int argc = _code_ptr[ip + 3]; + GD_ERR_BREAK(argc < 0); + + GET_INSTRUCTION_ARG(ret, argc); + + const Variant **argptrs = const_cast<const Variant **>(instruction_args); + +#ifdef DEBUG_ENABLED + uint64_t call_time = 0; + + if (GDScriptLanguage::get_singleton()->profiling) { + call_time = OS::get_singleton()->get_ticks_usec(); + } +#endif + + Callable::CallError err; + Variant::call_static(builtin_type, *methodname, argptrs, argc, *ret, err); + +#ifdef DEBUG_ENABLED + if (GDScriptLanguage::get_singleton()->profiling) { + function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; + } + + if (err.error != Callable::CallError::CALL_OK) { + err_text = _get_call_error(err, "static function '" + methodname->operator String() + "' in type '" + Variant::get_type_name(builtin_type) + "'", argptrs); + OPCODE_BREAK; + } +#endif + + ip += 4; + } + DISPATCH_OPCODE; + #ifdef DEBUG_ENABLED #define OPCODE_CALL_PTR(m_type) \ OPCODE(OPCODE_CALL_PTRCALL_##m_type) { \ @@ -1882,7 +1970,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { // TODO: Add this information in debug. - String methodstr = "<unkown function>"; + String methodstr = "<unknown function>"; if (dst->get_type() == Variant::STRING) { // Call provided error string. err_text = "Error calling GDScript utility function '" + methodstr + "': " + String(*dst); diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index 76ae43e792..e20e427597 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -257,6 +257,7 @@ bool GDScriptTestRunner::make_tests() { ERR_FAIL_COND_V_MSG(err != OK, false, "Could not open specified test directory."); + source_dir = dir->get_current_dir() + "/"; // Make it absolute path. return make_tests_for_dir(dir->get_current_dir()); } @@ -361,11 +362,9 @@ void GDScriptTest::error_handler(void *p_this, const char *p_function, const cha break; } - builder.append("\n>> "); - builder.append(p_function); - builder.append("\n>> "); + builder.append("\n>> on function: "); builder.append(p_function); - builder.append("\n>> "); + builder.append("()\n>> "); builder.append(String(p_file).trim_prefix(self->base_dir)); builder.append("\n>> "); builder.append(itos(p_line)); diff --git a/modules/gdscript/tests/gdscript_test_runner_suite.h b/modules/gdscript/tests/gdscript_test_runner_suite.h index 136907b316..8fd77239cd 100644 --- a/modules/gdscript/tests/gdscript_test_runner_suite.h +++ b/modules/gdscript/tests/gdscript_test_runner_suite.h @@ -48,6 +48,27 @@ TEST_SUITE("[Modules][GDScript]") { } } +TEST_CASE("[Modules][GDScript] Load source code dynamically and run it") { + Ref<GDScript> gdscript = memnew(GDScript); + gdscript->set_source_code(R"( +extends Reference + +func _init(): + set_meta("result", 42) +)"); + // A spurious `Condition "err" is true` message is printed (despite parsing being successful and returning `OK`). + // Silence it. + ERR_PRINT_OFF; + const Error error = gdscript->reload(); + ERR_PRINT_ON; + CHECK_MESSAGE(error == OK, "The script should parse successfully."); + + // Run the script by assigning it to a reference-counted object. + Ref<Reference> reference = memnew(Reference); + reference->set_script(gdscript); + CHECK_MESSAGE(int(reference->get_meta("result")) == 42, "The script should assign object metadata successfully."); +} + } // namespace GDScriptTests #endif // GDSCRIPT_TEST_RUNNER_SUITE_H diff --git a/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd new file mode 100644 index 0000000000..d21d8bce96 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.gd @@ -0,0 +1,9 @@ +extends Node + +func test(): + set_name("TestNodeName") + if get_name() == &"TestNodeName": + print("Name is equal") + else: + print("Name is not equal") + print(get_name() is StringName) diff --git a/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out new file mode 100644 index 0000000000..dc4348d9c3 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/call_self_get_name.out @@ -0,0 +1,3 @@ +GDTEST_OK +Name is equal +True diff --git a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd new file mode 100644 index 0000000000..10780b5379 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd @@ -0,0 +1,5 @@ +func test(): + var node := Node.new() + var inside_tree = node.is_inside_tree + node.free() + inside_tree.call() diff --git a/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out new file mode 100644 index 0000000000..e585c374e2 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out @@ -0,0 +1,6 @@ +GDTEST_RUNTIME_ERROR +>> SCRIPT ERROR +>> on function: test() +>> runtime/errors/callable_call_after_free_object.gd +>> 5 +>> Attempt to call function 'null::is_inside_tree (Callable)' on a null instance. diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 36da64bbaa..fc73b5bb72 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -215,8 +215,8 @@ void test(TestType p_type) { init_language(fa->get_path_absolute().get_base_dir()); Vector<uint8_t> buf; - int flen = fa->get_len(); - buf.resize(fa->get_len() + 1); + uint64_t flen = fa->get_length(); + buf.resize(flen + 1); fa->get_buffer(buf.ptrw(), flen); buf.write[flen] = 0; diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index 4331daadfc..8979eabfc3 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -179,11 +179,18 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage return ret; } +static String _get_cache_key_function_glsl(const RenderingDevice::Capabilities *p_capabilities) { + String version; + version = "SpirVGen=" + itos(glslang::GetSpirvGeneratorVersion()) + ", major=" + itos(p_capabilities->version_major) + ", minor=" + itos(p_capabilities->version_minor) + " , subgroup_size=" + itos(p_capabilities->subgroup_operations) + " , subgroup_ops=" + itos(p_capabilities->subgroup_operations) + " , subgroup_in_shaders=" + itos(p_capabilities->subgroup_in_shaders); + return version; +} + void preregister_glslang_types() { // initialize in case it's not initialized. This is done once per thread // and it's safe to call multiple times glslang::InitializeProcess(); RenderingDevice::shader_set_compile_function(_compile_shader_glsl); + RenderingDevice::shader_set_get_cache_key_function(_get_cache_key_function_glsl); } void register_glslang_types() { diff --git a/modules/gltf/doc_classes/GLTFNode.xml b/modules/gltf/doc_classes/GLTFNode.xml index 5b7d4fadec..af7be55e4b 100644 --- a/modules/gltf/doc_classes/GLTFNode.xml +++ b/modules/gltf/doc_classes/GLTFNode.xml @@ -13,8 +13,6 @@ </member> <member name="children" type="PackedInt32Array" setter="set_children" getter="get_children" default="PackedInt32Array( )"> </member> - <member name="fake_joint_parent" type="int" setter="set_fake_joint_parent" getter="get_fake_joint_parent" default="-1"> - </member> <member name="height" type="int" setter="set_height" getter="get_height" default="-1"> </member> <member name="joint" type="bool" setter="set_joint" getter="get_joint" default="false"> diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index e67e29f7b4..abac0a2e17 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -233,7 +233,7 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { } Vector<uint8_t> array; - array.resize(f->get_len()); + array.resize(f->get_length()); f->get_buffer(array.ptrw(), array.size()); String text; text.parse_utf8((const char *)array.ptr(), array.size()); @@ -664,7 +664,7 @@ static Vector<uint8_t> _parse_base64_uri(const String &uri) { int start = uri.find(","); ERR_FAIL_COND_V(start == -1, Vector<uint8_t>()); - CharString substr = uri.right(start + 1).ascii(); + CharString substr = uri.substr(start + 1).ascii(); int strlen = substr.length(); @@ -2821,8 +2821,8 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) { } blend_weights.write[j] = weights[j]; } - mesh->set_blend_weights(blend_weights); } + mesh->set_blend_weights(blend_weights); mesh->set_mesh(import_mesh); state->meshes.push_back(mesh); @@ -3031,8 +3031,11 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat } } - ERR_FAIL_COND_V_MSG(img.is_null(), ERR_FILE_CORRUPT, - vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype)); + if (img.is_null()) { + ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype)); + state->images.push_back(Ref<Texture2D>()); + continue; + } Ref<ImageTexture> t; t.instance(); @@ -4105,81 +4108,10 @@ Error GLTFDocument::_reparent_non_joint_skeleton_subtrees(Ref<GLTFState> state, subtree_set.get_members(subtree_nodes, subtree_root); for (int subtree_i = 0; subtree_i < subtree_nodes.size(); ++subtree_i) { - ERR_FAIL_COND_V(_reparent_to_fake_joint(state, skeleton, subtree_nodes[subtree_i]), FAILED); - - // We modified the tree, recompute all the heights - _compute_node_heights(state); - } - } - - return OK; -} - -Error GLTFDocument::_reparent_to_fake_joint(Ref<GLTFState> state, Ref<GLTFSkeleton> skeleton, const GLTFNodeIndex node_index) { - Ref<GLTFNode> node = state->nodes[node_index]; - - // Can we just "steal" this joint if it is just a spatial node? - if (node->skin < 0 && node->mesh < 0 && node->camera < 0) { - node->joint = true; - // Add the joint to the skeletons joints - skeleton->joints.push_back(node_index); - return OK; - } - - GLTFNode *fake_joint = memnew(GLTFNode); - const GLTFNodeIndex fake_joint_index = state->nodes.size(); - state->nodes.push_back(fake_joint); - - // We better not be a joint, or we messed up in our logic - if (node->joint) { - return FAILED; - } - - fake_joint->translation = node->translation; - fake_joint->rotation = node->rotation; - fake_joint->scale = node->scale; - fake_joint->xform = node->xform; - fake_joint->joint = true; - - // We can use the exact same name here, because the joint will be inside a skeleton and not the scene - fake_joint->set_name(node->get_name()); - - // Clear the nodes transforms, since it will be parented to the fake joint - node->translation = Vector3(0, 0, 0); - node->rotation = Quat(); - node->scale = Vector3(1, 1, 1); - node->xform = Transform(); - - // Transfer the node children to the fake joint - for (int child_i = 0; child_i < node->children.size(); ++child_i) { - Ref<GLTFNode> child = state->nodes[node->children[child_i]]; - child->parent = fake_joint_index; - } - - fake_joint->children = node->children; - node->children.clear(); - - // add the fake joint to the parent and remove the original joint - if (node->parent >= 0) { - Ref<GLTFNode> parent = state->nodes[node->parent]; - parent->children.erase(node_index); - parent->children.push_back(fake_joint_index); - fake_joint->parent = node->parent; - } - - // Add the node to the fake joint - fake_joint->children.push_back(node_index); - node->parent = fake_joint_index; - node->fake_joint_parent = fake_joint_index; - - // Add the fake joint to the skeletons joints - skeleton->joints.push_back(fake_joint_index); - - // Replace skin_skeletons with fake joints if we must. - for (GLTFSkinIndex skin_i = 0; skin_i < state->skins.size(); ++skin_i) { - Ref<GLTFSkin> skin = state->skins.write[skin_i]; - if (skin->skin_root == node_index) { - skin->skin_root = fake_joint_index; + Ref<GLTFNode> node = state->nodes[subtree_nodes[subtree_i]]; + node->joint = true; + // Add the joint to the skeletons joints + skeleton->joints.push_back(subtree_nodes[subtree_i]); } } @@ -4387,6 +4319,9 @@ bool GLTFDocument::_skins_are_same(const Ref<Skin> skin_a, const Ref<Skin> skin_ if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) { return false; } + if (skin_a->get_bind_name(i) != skin_b->get_bind_name(i)) { + return false; + } Transform a_xform = skin_a->get_bind_pose(i); Transform b_xform = skin_b->get_bind_pose(i); @@ -4914,10 +4849,9 @@ void GLTFDocument::_assign_scene_names(Ref<GLTFState> state) { } } -BoneAttachment3D *GLTFDocument::_generate_bone_attachment(Ref<GLTFState> state, Skeleton3D *skeleton, const GLTFNodeIndex node_index) { +BoneAttachment3D *GLTFDocument::_generate_bone_attachment(Ref<GLTFState> state, Skeleton3D *skeleton, const GLTFNodeIndex node_index, const GLTFNodeIndex bone_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; - Ref<GLTFNode> bone_node = state->nodes[gltf_node->parent]; - + Ref<GLTFNode> bone_node = state->nodes[bone_index]; BoneAttachment3D *bone_attachment = memnew(BoneAttachment3D); print_verbose("glTF: Creating bone attachment for: " + gltf_node->get_name()); @@ -5002,7 +4936,7 @@ EditorSceneImporterMeshNode3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFSta return mi; } -Light3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { +Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; ERR_FAIL_INDEX_V(gltf_node->light, state->lights.size(), nullptr); @@ -5051,7 +4985,7 @@ Light3D *GLTFDocument::_generate_light(Ref<GLTFState> state, Node *scene_parent, light->set_param(SpotLight3D::PARAM_SPOT_ATTENUATION, angle_attenuation); return light; } - return nullptr; + return memnew(Node3D); } Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index) { @@ -5423,31 +5357,22 @@ void GLTFDocument::_convert_mesh_to_gltf(Node *p_scene_parent, Ref<GLTFState> st void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index) { Ref<GLTFNode> gltf_node = state->nodes[node_index]; + if (gltf_node->skeleton >= 0) { + _generate_skeleton_bone_node(state, scene_parent, scene_root, node_index); + return; + } + Node3D *current_node = nullptr; // Is our parent a skeleton Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(scene_parent); - if (gltf_node->skeleton >= 0) { - Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton; + const bool non_bone_parented_to_skeleton = active_skeleton; - if (active_skeleton != skeleton) { - ERR_FAIL_COND_MSG(active_skeleton != nullptr, "glTF: Generating scene detected direct parented Skeletons"); - - // Add it to the scene if it has not already been added - if (skeleton->get_parent() == nullptr) { - scene_parent->add_child(skeleton); - skeleton->set_owner(scene_root); - } - } - - active_skeleton = skeleton; - current_node = skeleton; - } - - // If we have an active skeleton, and the node is node skinned, we need to create a bone attachment - if (current_node == nullptr && active_skeleton != nullptr && gltf_node->skin < 0) { - BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index); + // skinned meshes must not be placed in a bone attachment. + if (non_bone_parented_to_skeleton && gltf_node->skin < 0) { + // Bone Attachment - Parent Case + BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index, gltf_node->parent); scene_parent->add_child(bone_attachment); bone_attachment->set_owner(scene_root); @@ -5461,7 +5386,86 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent } // We still have not managed to make a node - if (current_node == nullptr) { + if (gltf_node->mesh >= 0) { + current_node = _generate_mesh_instance(state, scene_parent, node_index); + } else if (gltf_node->camera >= 0) { + current_node = _generate_camera(state, scene_parent, node_index); + } else if (gltf_node->light >= 0) { + current_node = _generate_light(state, scene_parent, node_index); + } else { + current_node = _generate_spatial(state, scene_parent, node_index); + } + + scene_parent->add_child(current_node); + if (current_node != scene_root) { + current_node->set_owner(scene_root); + } + current_node->set_transform(gltf_node->xform); + current_node->set_name(gltf_node->get_name()); + + state->scene_nodes.insert(node_index, current_node); + + for (int i = 0; i < gltf_node->children.size(); ++i) { + _generate_scene_node(state, current_node, scene_root, gltf_node->children[i]); + } +} + +void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index) { + Ref<GLTFNode> gltf_node = state->nodes[node_index]; + + Node3D *current_node = nullptr; + + Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton; + // In this case, this node is already a bone in skeleton. + const bool is_skinned_mesh = (gltf_node->skin >= 0 && gltf_node->mesh >= 0); + const bool requires_extra_node = (gltf_node->mesh >= 0 || gltf_node->camera >= 0 || gltf_node->light >= 0); + + Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(scene_parent); + if (active_skeleton != skeleton) { + if (active_skeleton) { + // Bone Attachment - Direct Parented Skeleton Case + BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index, gltf_node->parent); + + scene_parent->add_child(bone_attachment); + bone_attachment->set_owner(scene_root); + + // There is no gltf_node that represent this, so just directly create a unique name + bone_attachment->set_name(_gen_unique_name(state, "BoneAttachment3D")); + + // We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node + // and attach it to the bone_attachment + scene_parent = bone_attachment; + WARN_PRINT(vformat("glTF: Generating scene detected direct parented Skeletons at node %d", node_index)); + } + + // Add it to the scene if it has not already been added + if (skeleton->get_parent() == nullptr) { + scene_parent->add_child(skeleton); + skeleton->set_owner(scene_root); + } + } + + active_skeleton = skeleton; + current_node = skeleton; + + if (requires_extra_node) { + // skinned meshes must not be placed in a bone attachment. + if (!is_skinned_mesh) { + // Bone Attachment - Same Node Case + BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index, node_index); + + scene_parent->add_child(bone_attachment); + bone_attachment->set_owner(scene_root); + + // There is no gltf_node that represent this, so just directly create a unique name + bone_attachment->set_name(_gen_unique_name(state, "BoneAttachment3D")); + + // We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node + // and attach it to the bone_attachment + scene_parent = bone_attachment; + } + + // We still have not managed to make a node if (gltf_node->mesh >= 0) { current_node = _generate_mesh_instance(state, scene_parent, node_index); } else if (gltf_node->camera >= 0) { @@ -5470,22 +5474,18 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> state, Node *scene_parent current_node = _generate_light(state, scene_parent, node_index); } - if (!current_node) { - current_node = _generate_spatial(state, scene_parent, node_index); - } - scene_parent->add_child(current_node); if (current_node != scene_root) { current_node->set_owner(scene_root); } - current_node->set_transform(gltf_node->xform); + // Do not set transform here. Transform is already applied to our bone. current_node->set_name(gltf_node->get_name()); } state->scene_nodes.insert(node_index, current_node); for (int i = 0; i < gltf_node->children.size(); ++i) { - _generate_scene_node(state, current_node, scene_root, gltf_node->children[i]); + _generate_scene_node(state, active_skeleton, scene_root, gltf_node->children[i]); } } @@ -5626,28 +5626,30 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, for (Map<int, GLTFAnimation::Track>::Element *track_i = anim->get_tracks().front(); track_i; track_i = track_i->next()) { const GLTFAnimation::Track &track = track_i->get(); - //need to find the path + //need to find the path: for skeletons, weight tracks will affect the mesh NodePath node_path; + //for skeletons, transform tracks always affect bones + NodePath transform_node_path; GLTFNodeIndex node_index = track_i->key(); - if (state->nodes[node_index]->fake_joint_parent >= 0) { - // Should be same as parent - node_index = state->nodes[node_index]->fake_joint_parent; - } const Ref<GLTFNode> gltf_node = state->nodes[track_i->key()]; + Node *root = ap->get_parent(); + ERR_FAIL_COND(root == nullptr); + Map<GLTFNodeIndex, Node *>::Element *node_element = state->scene_nodes.find(node_index); + ERR_CONTINUE_MSG(node_element == nullptr, vformat("Unable to find node %d for animation", node_index)); + node_path = root->get_path_to(node_element->get()); + if (gltf_node->skeleton >= 0) { - const Skeleton3D *sk = Object::cast_to<Skeleton3D>(state->scene_nodes.find(node_index)->get()); + const Skeleton3D *sk = state->skeletons[gltf_node->skeleton]->godot_skeleton; ERR_FAIL_COND(sk == nullptr); const String path = ap->get_parent()->get_path_to(sk); const String bone = gltf_node->get_name(); - node_path = path + ":" + bone; + transform_node_path = path + ":" + bone; } else { - Node *root = ap->get_parent(); - Node *godot_node = state->scene_nodes.find(node_index)->get(); - node_path = root->get_path_to(godot_node); + transform_node_path = node_path; } for (int i = 0; i < track.rotation_track.times.size(); i++) { @@ -5666,11 +5668,13 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, } } - if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) { + // Animated TRS properties will not affect a skinned mesh. + const bool transform_affects_skinned_mesh_instance = gltf_node->skeleton < 0 && gltf_node->skin >= 0; + if ((track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) && !transform_affects_skinned_mesh_instance) { //make transform track int track_idx = animation->get_track_count(); animation->add_track(Animation::TYPE_TRANSFORM); - animation->track_set_path(track_idx, node_path); + animation->track_set_path(track_idx, transform_node_path); //first determine animation length const double increment = 1.0 / bake_fps; @@ -5975,13 +5979,15 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> state, Node *scene_roo const GLTFSkinIndex skin_i = node->skin; Map<GLTFNodeIndex, Node *>::Element *mi_element = state->scene_nodes.find(node_i); + ERR_CONTINUE_MSG(mi_element == nullptr, vformat("Unable to find node %d", node_i)); + EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(mi_element->get()); - ERR_FAIL_COND(mi == nullptr); + ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to EditorSceneImporterMeshNode3D", node_i, mi_element->get()->get_class_name())); const GLTFSkeletonIndex skel_i = state->skins.write[node->skin]->skeleton; Ref<GLTFSkeleton> gltf_skeleton = state->skeletons.write[skel_i]; Skeleton3D *skeleton = gltf_skeleton->godot_skeleton; - ERR_FAIL_COND(skeleton == nullptr); + ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i)); mi->get_parent()->remove_child(mi); skeleton->add_child(mi); diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index bda1ce87d6..900c367010 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -260,11 +260,12 @@ private: Error _serialize_animations(Ref<GLTFState> state); BoneAttachment3D *_generate_bone_attachment(Ref<GLTFState> state, Skeleton3D *skeleton, - const GLTFNodeIndex node_index); + const GLTFNodeIndex node_index, + const GLTFNodeIndex bone_index); EditorSceneImporterMeshNode3D *_generate_mesh_instance(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index); Camera3D *_generate_camera(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index); - Light3D *_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index); + Node3D *_generate_light(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index); Node3D *_generate_spatial(Ref<GLTFState> state, Node *scene_parent, const GLTFNodeIndex node_index); void _assign_scene_names(Ref<GLTFState> state); @@ -365,6 +366,7 @@ public: void _generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index); + void _generate_skeleton_bone_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index); void _import_animation(Ref<GLTFState> state, AnimationPlayer *ap, const GLTFAnimationIndex index, const int bake_fps); GLTFMeshIndex _convert_mesh_instance(Ref<GLTFState> state, diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/gltf_node.cpp index 777c6fbd9a..f6f33ef009 100644 --- a/modules/gltf/gltf_node.cpp +++ b/modules/gltf/gltf_node.cpp @@ -55,8 +55,6 @@ void GLTFNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_scale", "scale"), &GLTFNode::set_scale); ClassDB::bind_method(D_METHOD("get_children"), &GLTFNode::get_children); ClassDB::bind_method(D_METHOD("set_children", "children"), &GLTFNode::set_children); - ClassDB::bind_method(D_METHOD("get_fake_joint_parent"), &GLTFNode::get_fake_joint_parent); - ClassDB::bind_method(D_METHOD("set_fake_joint_parent", "fake_joint_parent"), &GLTFNode::set_fake_joint_parent); ClassDB::bind_method(D_METHOD("get_light"), &GLTFNode::get_light); ClassDB::bind_method(D_METHOD("set_light", "light"), &GLTFNode::set_light); @@ -72,7 +70,6 @@ void GLTFNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::QUAT, "rotation"), "set_rotation", "get_rotation"); // Quat ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale"), "set_scale", "get_scale"); // Vector3 ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "children"), "set_children", "get_children"); // Vector<int> - ADD_PROPERTY(PropertyInfo(Variant::INT, "fake_joint_parent"), "set_fake_joint_parent", "get_fake_joint_parent"); // GLTFNodeIndex ADD_PROPERTY(PropertyInfo(Variant::INT, "light"), "set_light", "get_light"); // GLTFLightIndex } @@ -172,14 +169,6 @@ void GLTFNode::set_children(Vector<int> p_children) { children = p_children; } -GLTFNodeIndex GLTFNode::get_fake_joint_parent() { - return fake_joint_parent; -} - -void GLTFNode::set_fake_joint_parent(GLTFNodeIndex p_fake_joint_parent) { - fake_joint_parent = p_fake_joint_parent; -} - GLTFLightIndex GLTFNode::get_light() { return light; } diff --git a/modules/gltf/gltf_node.h b/modules/gltf/gltf_node.h index ce8aff8944..3a5689d004 100644 --- a/modules/gltf/gltf_node.h +++ b/modules/gltf/gltf_node.h @@ -53,7 +53,6 @@ private: Quat rotation; Vector3 scale = Vector3(1, 1, 1); Vector<int> children; - GLTFNodeIndex fake_joint_parent = -1; GLTFLightIndex light = -1; protected: @@ -96,9 +95,6 @@ public: Vector<int> get_children(); void set_children(Vector<int> p_children); - GLTFNodeIndex get_fake_joint_parent(); - void set_fake_joint_parent(GLTFNodeIndex p_fake_joint_parent); - GLTFLightIndex get_light(); void set_light(GLTFLightIndex p_light); }; diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 74ae45a46e..813b4b9689 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -615,13 +615,13 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && (mb->get_command() || mb->get_shift())) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && (mb->is_command_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() + mb->get_factor()); } return true; // Eaten. - } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && (mb->get_command() || mb->get_shift())) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() - mb->get_factor()); } @@ -630,7 +630,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In if (mb->is_pressed()) { Node3DEditorViewport::NavigationScheme nav_scheme = (Node3DEditorViewport::NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); - if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->get_alt()) { + if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->is_alt_pressed()) { input_action = INPUT_NONE; } else if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { bool can_edit = (node && node->get_mesh_library().is_valid()); @@ -638,10 +638,10 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In _do_paste(); input_action = INPUT_NONE; _update_paste_indicator(); - } else if (mb->get_shift() && can_edit) { + } else if (mb->is_shift_pressed() && can_edit) { input_action = INPUT_SELECT; last_selection = selection; - } else if (mb->get_command() && can_edit) { + } else if (mb->is_command_pressed() && can_edit) { input_action = INPUT_PICK; } else { input_action = INPUT_PAINT; @@ -732,7 +732,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In } } - if (k->get_shift() && selection.active && input_action != INPUT_PASTE) { + if (k->is_shift_pressed() && selection.active && input_action != INPUT_PASTE) { if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) { selection.click[edit_axis]--; _validate_selection(); @@ -749,7 +749,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { - if (pan_gesture->get_alt() && (pan_gesture->get_command() || pan_gesture->get_shift())) { + if (pan_gesture->is_alt_pressed() && (pan_gesture->is_command_pressed() || pan_gesture->is_shift_pressed())) { const real_t delta = pan_gesture->get_delta().y * 0.5; accumulated_floor_delta += delta; int step = 0; @@ -810,7 +810,7 @@ void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) { const Ref<InputEventMouseButton> mb = p_ie; // Zoom in/out using Ctrl + mouse wheel - if (mb.is_valid() && mb->is_pressed() && mb->get_command()) { + if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed()) { if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { size_slider->set_value(size_slider->get_value() + 0.2); } diff --git a/modules/gridmap/icons/GridMap.svg b/modules/gridmap/icons/GridMap.svg index 7a36fd888c..e208257855 100644 --- a/modules/gridmap/icons/GridMap.svg +++ b/modules/gridmap/icons/GridMap.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1-6 3v8l6 3 6-3v-2l-2-1-4 2-2-1v-4l2-1v-2l2-1zm4 2-2 1v2l2 1 2-1v-2z" fill="#fc9c9c" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1-6 3v8l6 3 6-3v-2l-2-1-4 2-2-1v-4l2-1v-2l2-1zm4 2-2 1v2l2 1 2-1v-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index 7daf6a3a57..d237544d66 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -105,7 +105,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - int src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index 987306af2a..c389609984 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -58,7 +58,7 @@ Error CryptoKeyMbedTLS::load(String p_path, bool p_public_only) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_INVALID_PARAMETER, "Cannot open CryptoKeyMbedTLS file '" + p_path + "'."); - int flen = f->get_len(); + uint64_t flen = f->get_length(); out.resize(flen + 1); f->get_buffer(out.ptrw(), flen); out.write[flen] = 0; // string terminator @@ -146,7 +146,7 @@ Error X509CertificateMbedTLS::load(String p_path) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_INVALID_PARAMETER, "Cannot open X509CertificateMbedTLS file '" + p_path + "'."); - int flen = f->get_len(); + uint64_t flen = f->get_length(); out.resize(flen + 1); f->get_buffer(out.ptrw(), flen); out.write[flen] = 0; // string terminator diff --git a/modules/meshoptimizer/register_types.cpp b/modules/meshoptimizer/register_types.cpp index a03310f518..77cc82a4e2 100644 --- a/modules/meshoptimizer/register_types.cpp +++ b/modules/meshoptimizer/register_types.cpp @@ -35,6 +35,7 @@ void register_meshoptimizer_types() { SurfaceTool::optimize_vertex_cache_func = meshopt_optimizeVertexCache; SurfaceTool::simplify_func = meshopt_simplify; + SurfaceTool::simplify_with_attrib_func = meshopt_simplifyWithAttributes; SurfaceTool::simplify_scale_func = meshopt_simplifyScale; SurfaceTool::simplify_sloppy_func = meshopt_simplifySloppy; } diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index afd26fb79e..f5137965da 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -79,7 +79,7 @@ Error ResourceImporterMP3::import(const String &p_source_file, const String &p_s ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); - size_t len = f->get_len(); + uint64_t len = f->get_length(); Vector<uint8_t> data; data.resize(len); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index ffb04bfd37..b6a7a7579c 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -368,7 +368,7 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin "}\n"; // Replaces all spaces in p_class_name with underscores to prevent - // erronous C# Script templates from being generated when the object name + // invalid C# Script templates from being generated when the object name // has spaces in it. String class_name_no_spaces = p_class_name.replace(" ", "_"); String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 6279ea1ace..ebfe70aa82 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -519,7 +519,7 @@ namespace Godot /// compared to the original, with the same length. /// </summary> /// <returns>The perpendicular vector.</returns> - public Vector2 Perpendicular() + public Vector2 Orthogonal() { return new Vector2(y, -x); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs index 8dd9ab2f0d..f605ba8fd0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -248,13 +248,13 @@ namespace Godot } /// <summary> - /// Returns a vector rotated 90 degrees counter-clockwise + /// Returns a perpendicular vector rotated 90 degrees counter-clockwise /// compared to the original, with the same length. /// </summary> /// <returns>The perpendicular vector.</returns> - public Vector2 Perpendicular() + public Vector2i Orthogonal() { - return new Vector2(y, -x); + return new Vector2i(y, -x); } // Constants diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 020a40575c..68134b9b20 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -63,8 +63,8 @@ String _get_expected_build_config() { String _get_mono_user_dir() { #ifdef TOOLS_ENABLED - if (EditorSettings::get_singleton()) { - return EditorSettings::get_singleton()->get_data_dir().plus_file("mono"); + if (EditorPaths::get_singleton()) { + return EditorPaths::get_singleton()->get_data_dir().plus_file("mono"); } else { String settings_path; diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp index 43de77005e..ee68458268 100644 --- a/modules/mono/utils/string_utils.cpp +++ b/modules/mono/utils/string_utils.cpp @@ -170,10 +170,10 @@ Error read_all_file_utf8(const String &p_path, String &r_content) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); - int len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); - int r = f->get_buffer(w, len); + uint64_t r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml index 38c5138482..a12412a9cd 100644 --- a/modules/opensimplex/doc_classes/NoiseTexture.xml +++ b/modules/opensimplex/doc_classes/NoiseTexture.xml @@ -31,6 +31,9 @@ <member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise"> The [OpenSimplexNoise] instance used to generate the noise. </member> + <member name="noise_offset" type="Vector2" setter="set_noise_offset" getter="get_noise_offset" default="Vector2( 0, 0 )"> + An offset used to specify the noise space coordinate of the top left corner of the generated noise. This value is ignored if [member seamless] is enabled. + </member> <member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false"> Whether the texture can be tiled without visible seams or not. Seamless textures take longer to generate. [b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise. diff --git a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml index ad82f87213..2fdbd61ee7 100644 --- a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml +++ b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml @@ -31,8 +31,10 @@ </argument> <argument index="1" name="height" type="int"> </argument> + <argument index="2" name="noise_offset" type="Vector2" default="Vector2( 0, 0 )"> + </argument> <description> - Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. + Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters. If [code]noise_offset[/code] is specified, then the offset value is used as the coordinates of the top-left corner of the generated noise. </description> </method> <method name="get_noise_1d" qualifiers="const"> diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index 7272d32fac..9e0155da94 100644 --- a/modules/opensimplex/noise_texture.cpp +++ b/modules/opensimplex/noise_texture.cpp @@ -52,6 +52,9 @@ void NoiseTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise); ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise); + ClassDB::bind_method(D_METHOD("set_noise_offset", "noise_offset"), &NoiseTexture::set_noise_offset); + ClassDB::bind_method(D_METHOD("get_noise_offset"), &NoiseTexture::get_noise_offset); + ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless); ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless); @@ -71,6 +74,7 @@ void NoiseTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normal_map"), "set_as_normal_map", "is_normal_map"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "noise_offset"), "set_noise_offset", "get_noise_offset"); } void NoiseTexture::_validate_property(PropertyInfo &property) const { @@ -130,7 +134,7 @@ Ref<Image> NoiseTexture::_generate_texture() { if (seamless) { image = ref_noise->get_seamless_image(size.x); } else { - image = ref_noise->get_image(size.x, size.y); + image = ref_noise->get_image(size.x, size.y, noise_offset); } if (as_normal_map) { @@ -198,6 +202,14 @@ void NoiseTexture::set_height(int p_height) { _queue_update(); } +void NoiseTexture::set_noise_offset(Vector2 p_noise_offset) { + if (noise_offset == p_noise_offset) { + return; + } + noise_offset = p_noise_offset; + _queue_update(); +} + void NoiseTexture::set_seamless(bool p_seamless) { if (p_seamless == seamless) { return; @@ -245,6 +257,10 @@ int NoiseTexture::get_height() const { return size.y; } +Vector2 NoiseTexture::get_noise_offset() const { + return noise_offset; +} + RID NoiseTexture::get_rid() const { if (!texture.is_valid()) { texture = RS::get_singleton()->texture_2d_placeholder_create(); diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 6983ae18fe..20a53bb58b 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -56,6 +56,7 @@ private: Ref<OpenSimplexNoise> noise; Vector2i size = Vector2i(512, 512); + Vector2 noise_offset; bool seamless = false; bool as_normal_map = false; float bump_strength = 8.0; @@ -79,6 +80,9 @@ public: void set_width(int p_width); void set_height(int p_height); + void set_noise_offset(Vector2 p_noise_offset); + Vector2 get_noise_offset() const; + void set_seamless(bool p_seamless); bool get_seamless(); diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp index 3773946112..f0a8867284 100644 --- a/modules/opensimplex/open_simplex_noise.cpp +++ b/modules/opensimplex/open_simplex_noise.cpp @@ -96,7 +96,7 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) { emit_changed(); } -Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const { +Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height, const Vector2 &p_noise_offset) const { Vector<uint8_t> data; data.resize(p_width * p_height); @@ -104,7 +104,7 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const { for (int i = 0; i < p_height; i++) { for (int j = 0; j < p_width; j++) { - float v = get_noise_2d(j, i); + float v = get_noise_2d(float(j) + p_noise_offset.x, float(i) + p_noise_offset.y); v = v * 0.5 + 0.5; // Normalize [0..1] wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255)); } @@ -161,7 +161,7 @@ void OpenSimplexNoise::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &OpenSimplexNoise::set_lacunarity); ClassDB::bind_method(D_METHOD("get_lacunarity"), &OpenSimplexNoise::get_lacunarity); - ClassDB::bind_method(D_METHOD("get_image", "width", "height"), &OpenSimplexNoise::get_image); + ClassDB::bind_method(D_METHOD("get_image", "width", "height", "noise_offset"), &OpenSimplexNoise::get_image, DEFVAL(Vector2())); ClassDB::bind_method(D_METHOD("get_seamless_image", "size"), &OpenSimplexNoise::get_seamless_image); ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &OpenSimplexNoise::get_noise_1d); diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h index 847c157409..bb50c523d2 100644 --- a/modules/opensimplex/open_simplex_noise.h +++ b/modules/opensimplex/open_simplex_noise.h @@ -75,7 +75,7 @@ public: void set_lacunarity(float p_lacunarity); float get_lacunarity() const { return lacunarity; } - Ref<Image> get_image(int p_width, int p_height) const; + Ref<Image> get_image(int p_width, int p_height, const Vector2 &p_noise_offset = Vector2()) const; Ref<Image> get_seamless_image(int p_size) const; float get_noise_1d(float x) const; diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub index 57120bff26..6e7b3e7b8d 100644 --- a/modules/raycast/SCsub +++ b/modules/raycast/SCsub @@ -10,7 +10,7 @@ env_raycast = env_modules.Clone() thirdparty_obj = [] if env["builtin_embree"]: - thirdparty_dir = "#thirdparty/embree-aarch64/" + thirdparty_dir = "#thirdparty/embree/" embree_src = [ "common/sys/sysinfo.cpp", @@ -28,16 +28,6 @@ if env["builtin_embree"]: "common/lexers/stringstream.cpp", "common/lexers/tokenstream.cpp", "common/tasking/taskschedulerinternal.cpp", - "common/algorithms/parallel_for.cpp", - "common/algorithms/parallel_reduce.cpp", - "common/algorithms/parallel_prefix_sum.cpp", - "common/algorithms/parallel_for_for.cpp", - "common/algorithms/parallel_for_for_prefix_sum.cpp", - "common/algorithms/parallel_partition.cpp", - "common/algorithms/parallel_sort.cpp", - "common/algorithms/parallel_set.cpp", - "common/algorithms/parallel_map.cpp", - "common/algorithms/parallel_filter.cpp", "kernels/common/device.cpp", "kernels/common/stat.cpp", "kernels/common/acceln.cpp", @@ -82,13 +72,17 @@ if env["builtin_embree"]: if env["platform"] == "windows": if env.msvc: env.Append(LINKFLAGS=["psapi.lib"]) - env_raycast.Append(CPPDEFINES=["__SSE2__", "__SSE__"]) else: env.Append(LIBS=["psapi"]) env_thirdparty = env_raycast.Clone() env_thirdparty.disable_warnings() env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) + + if not env["arch"] in ["x86", "x86_64"] or env.msvc: + # Embree needs those, it will automatically use SSE2NEON in ARM + env_thirdparty.Append(CPPDEFINES=["__SSE2__", "__SSE__"]) + env.modules_sources += thirdparty_obj diff --git a/modules/raycast/config.py b/modules/raycast/config.py index 26493da41b..5de36c5322 100644 --- a/modules/raycast/config.py +++ b/modules/raycast/config.py @@ -1,10 +1,15 @@ def can_build(env, platform): + # Depends on Embree library, which only supports x86_64 and aarch64. + if platform == "android": - return env["android_arch"] in ["arm64v8", "x86", "x86_64"] + return env["android_arch"] in ["arm64v8", "x86_64"] if platform == "javascript": return False # No SIMD support yet + if env["bits"] == "32": + return False + return True diff --git a/modules/raycast/godot_update_embree.py b/modules/raycast/godot_update_embree.py index db4fa95c21..31a25a318f 100644 --- a/modules/raycast/godot_update_embree.py +++ b/modules/raycast/godot_update_embree.py @@ -11,6 +11,7 @@ include_dirs = [ "common/algorithms", "common/lexers", "common/simd", + "common/simd/arm", "include/embree3", "kernels/subdiv", "kernels/geometry", @@ -32,16 +33,6 @@ cpp_files = [ "common/lexers/stringstream.cpp", "common/lexers/tokenstream.cpp", "common/tasking/taskschedulerinternal.cpp", - "common/algorithms/parallel_for.cpp", - "common/algorithms/parallel_reduce.cpp", - "common/algorithms/parallel_prefix_sum.cpp", - "common/algorithms/parallel_for_for.cpp", - "common/algorithms/parallel_for_for_prefix_sum.cpp", - "common/algorithms/parallel_partition.cpp", - "common/algorithms/parallel_sort.cpp", - "common/algorithms/parallel_set.cpp", - "common/algorithms/parallel_map.cpp", - "common/algorithms/parallel_filter.cpp", "kernels/common/device.cpp", "kernels/common/stat.cpp", "kernels/common/acceln.cpp", @@ -74,11 +65,11 @@ cpp_files = [ os.chdir("../../thirdparty") -dir_name = "embree-aarch64" +dir_name = "embree" if os.path.exists(dir_name): shutil.rmtree(dir_name) -subprocess.run(["git", "clone", "https://github.com/lighttransport/embree-aarch64.git", "embree-tmp"]) +subprocess.run(["git", "clone", "https://github.com/embree/embree.git", "embree-tmp"]) os.chdir("embree-tmp") commit_hash = str(subprocess.check_output(["git", "rev-parse", "HEAD"], universal_newlines=True)).strip() @@ -197,7 +188,7 @@ with open("CMakeLists.txt", "r") as cmake_file: with open(os.path.join(dest_dir, "include/embree3/rtcore_config.h"), "w") as config_file: config_file.write( f""" -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster.cpp index 56bdb5900b..0583acc119 100644 --- a/modules/raycast/lightmap_raycaster.cpp +++ b/modules/raycast/lightmap_raycaster.cpp @@ -32,7 +32,9 @@ #include "lightmap_raycaster.h" +#ifdef __SSE2__ #include <pmmintrin.h> +#endif LightmapRaycaster *LightmapRaycasterEmbree::create_embree_raycaster() { return memnew(LightmapRaycasterEmbree); @@ -171,8 +173,10 @@ void embree_error_handler(void *p_user_data, RTCError p_code, const char *p_str) } LightmapRaycasterEmbree::LightmapRaycasterEmbree() { +#ifdef __SSE2__ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); +#endif embree_device = rtcNewDevice(nullptr); rtcSetDeviceErrorFunction(embree_device, &embree_error_handler, nullptr); @@ -180,8 +184,10 @@ LightmapRaycasterEmbree::LightmapRaycasterEmbree() { } LightmapRaycasterEmbree::~LightmapRaycasterEmbree() { +#ifdef __SSE2__ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_OFF); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF); +#endif if (embree_scene != nullptr) { rtcReleaseScene(embree_scene); diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp index ec1c30783a..e3aa630cef 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp @@ -79,7 +79,7 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open file '" + p_source_file + "'."); - size_t len = f->get_len(); + uint64_t len = f->get_length(); Vector<uint8_t> data; data.resize(len); diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 6ce3e4b4b3..4911346b96 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -140,7 +140,7 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p } Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { - uint32_t size = f->get_len(); + uint64_t size = f->get_length(); Vector<uint8_t> src_image; src_image.resize(size + 1); uint8_t *src_w = src_image.ptrw(); diff --git a/modules/text_server_adv/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp index 326af7f0ee..c29aac05bb 100644 --- a/modules/text_server_adv/dynamic_font_adv.cpp +++ b/modules/text_server_adv/dynamic_font_adv.cpp @@ -66,7 +66,7 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size( ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'."); } - size_t len = f->get_len(); + uint64_t len = f->get_length(); font_mem_cache.resize(len); f->get_buffer(font_mem_cache.ptrw(), len); font_mem = font_mem_cache.ptr(); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 8b8b6b7cd3..7eff3f8dee 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -181,7 +181,7 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) { UErrorCode err = U_ZERO_ERROR; // ICU data found. - size_t len = f->get_len(); + uint64_t len = f->get_length(); icu_data = (uint8_t *)memalloc(len); f->get_buffer(icu_data, len); f->close(); diff --git a/modules/text_server_fb/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp index dec1d6f83f..a261ba8f37 100644 --- a/modules/text_server_fb/dynamic_font_fb.cpp +++ b/modules/text_server_fb/dynamic_font_fb.cpp @@ -65,7 +65,7 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size( ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'."); } - size_t len = f->get_len(); + uint64_t len = f->get_length(); font_mem_cache.resize(len); f->get_buffer(font_mem_cache.ptrw(), len); font_mem = font_mem_cache.ptr(); diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index ef53661557..3cfd4ff36a 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -226,9 +226,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - int src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); - ERR_FAIL_COND_V(src_image_len < (int)sizeof(tga_header_s), ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(src_image_len < (int64_t)sizeof(tga_header_s), ERR_FILE_CORRUPT); src_image.resize(src_image_len); Error err = OK; diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 54f5b3f424..7b421bdc16 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -58,7 +58,7 @@ int VideoStreamPlaybackTheora::buffer_data() { #else - int bytes = file->get_buffer((uint8_t *)buffer, 4096); + uint64_t bytes = file->get_buffer((uint8_t *)buffer, 4096); ogg_sync_wrote(&oy, bytes); return (bytes); @@ -176,7 +176,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { thread_eof = false; //pre-fill buffer int to_read = ring_buffer.space_left(); - int read = file->get_buffer(read_buffer.ptr(), to_read); + uint64_t read = file->get_buffer(read_buffer.ptr(), to_read); ring_buffer.write(read_buffer.ptr(), read); thread.start(_streaming_thread, this); @@ -632,8 +632,8 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) { //just fill back the buffer if (!vs->thread_eof) { int to_read = vs->ring_buffer.space_left(); - if (to_read) { - int read = vs->file->get_buffer(vs->read_buffer.ptr(), to_read); + if (to_read > 0) { + uint64_t read = vs->file->get_buffer(vs->read_buffer.ptr(), to_read); vs->ring_buffer.write(vs->read_buffer.ptr(), read); vs->thread_eof = vs->file->eof_reached(); } diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 47214e6974..eb7a8597e6 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -37,7 +37,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - int src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 3b24de433c..df34ec22ce 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -132,6 +132,7 @@ bool VisualScriptBuiltinFunc::has_input_sequence_port() const { case TEXT_PRINT: case TEXT_PRINTERR: case TEXT_PRINTRAW: + case MATH_SEED: return true; default: return false; diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index dc400982e8..7432440603 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1168,11 +1168,11 @@ void VisualScriptEditor::_member_selected() { selected = ti->get_metadata(0); - if (ti->get_parent() == members->get_root()->get_children()) { + if (ti->get_parent() == members->get_root()->get_first_child()) { #ifdef OSX_ENABLED bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CTRL); #endif if (held_ctrl) { ERR_FAIL_COND(!script->has_function(selected)); @@ -1214,7 +1214,7 @@ void VisualScriptEditor::_member_edited() { TreeItem *root = members->get_root(); - if (ti->get_parent() == root->get_children()) { + if (ti->get_parent() == root->get_first_child()) { selected = new_name; int node_id = script->get_function_node_id(name); @@ -1255,7 +1255,7 @@ void VisualScriptEditor::_member_edited() { return; // Or crash because it will become invalid. } - if (ti->get_parent() == root->get_children()->get_next()) { + if (ti->get_parent() == root->get_first_child()->get_next()) { selected = new_name; undo_redo->create_action(TTR("Rename Variable")); undo_redo->add_do_method(script.ptr(), "rename_variable", name, new_name); @@ -1271,7 +1271,7 @@ void VisualScriptEditor::_member_edited() { return; // Or crash because it will become invalid. } - if (ti->get_parent() == root->get_children()->get_next()->get_next()) { + if (ti->get_parent() == root->get_first_child()->get_next()->get_next()) { selected = new_name; undo_redo->create_action(TTR("Rename Signal")); undo_redo->add_do_method(script.ptr(), "rename_custom_signal", name, new_name); @@ -1405,7 +1405,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt if (ti->get_parent() == root) { //main buttons - if (ti == root->get_children()) { + if (ti == root->get_first_child()) { // Add function, this one uses menu. if (p_button == 1) { @@ -1442,7 +1442,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt return; // Or crash because it will become invalid. } - if (ti == root->get_children()->get_next()) { + if (ti == root->get_first_child()->get_next()) { // Add variable. String name = _validate_name("new_variable"); selected = name; @@ -1458,7 +1458,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt return; // Or crash because it will become invalid. } - if (ti == root->get_children()->get_next()->get_next()) { + if (ti == root->get_first_child()->get_next()->get_next()) { // Add variable. String name = _validate_name("new_signal"); selected = name; @@ -1473,7 +1473,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt undo_redo->commit_action(); return; // Or crash because it will become invalid. } - } else if (ti->get_parent() == root->get_children()) { + } else if (ti->get_parent() == root->get_first_child()) { selected = ti->get_text(0); function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10)); function_name_edit->popup(); @@ -1841,13 +1841,13 @@ void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) { TreeItem *ti = members->get_selected(); if (ti) { TreeItem *root = members->get_root(); - if (ti->get_parent() == root->get_children()) { + if (ti->get_parent() == root->get_first_child()) { member_type = MEMBER_FUNCTION; } - if (ti->get_parent() == root->get_children()->get_next()) { + if (ti->get_parent() == root->get_first_child()->get_next()) { member_type = MEMBER_VARIABLE; } - if (ti->get_parent() == root->get_children()->get_next()->get_next()) { + if (ti->get_parent() == root->get_first_child()->get_next()->get_next()) { member_type = MEMBER_SIGNAL; } member_name = ti->get_text(0); @@ -1864,7 +1864,7 @@ void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> btn = p_event; if (btn.is_valid() && btn->is_double_click()) { TreeItem *ti = members->get_selected(); - if (ti && ti->get_parent() == members->get_root()->get_children()) { // to check if it's a function + if (ti && ti->get_parent() == members->get_root()->get_first_child()) { // to check if it's a function _center_on_node(script->get_function_node_id(ti->get_metadata(0))); } } @@ -1946,13 +1946,13 @@ Variant VisualScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f Dictionary dd; TreeItem *root = members->get_root(); - if (it->get_parent() == root->get_children()) { + if (it->get_parent() == root->get_first_child()) { dd["type"] = "visual_script_function_drag"; dd["function"] = type; - } else if (it->get_parent() == root->get_children()->get_next()) { + } else if (it->get_parent() == root->get_first_child()->get_next()) { dd["type"] = "visual_script_variable_drag"; dd["variable"] = type; - } else if (it->get_parent() == root->get_children()->get_next()->get_next()) { + } else if (it->get_parent() == root->get_first_child()->get_next()->get_next()) { dd["type"] = "visual_script_signal_drag"; dd["signal"] = type; @@ -2070,7 +2070,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da #ifdef OSX_ENABLED bool use_set = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool use_set = Input::get_singleton()->is_key_pressed(KEY_CTRL); #endif Vector2 ofs = graph->get_scroll_ofs() + p_point; if (graph->is_using_snap()) { @@ -2258,7 +2258,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da #ifdef OSX_ENABLED bool use_node = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool use_node = Input::get_singleton()->is_key_pressed(KEY_CTRL); #endif Array nodes = d["nodes"]; @@ -2341,7 +2341,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da #ifdef OSX_ENABLED bool use_get = Input::get_singleton()->is_key_pressed(KEY_META); #else - bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL); + bool use_get = Input::get_singleton()->is_key_pressed(KEY_CTRL); #endif if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { @@ -2710,6 +2710,10 @@ void VisualScriptEditor::set_debugger_active(bool p_active) { } } +Control *VisualScriptEditor::get_base_editor() const { + return graph; +} + void VisualScriptEditor::set_tooltip_request_func(String p_method, Object *p_obj) { } @@ -4111,7 +4115,7 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { Ref<Texture2D> edit_icon = Control::get_theme_icon("Edit", "EditorIcons"); - if (ti->get_parent() == root->get_children()) { + if (ti->get_parent() == root->get_first_child()) { member_type = MEMBER_FUNCTION; member_name = ti->get_text(0); member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); @@ -4121,7 +4125,7 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { return; } - if (ti->get_parent() == root->get_children()->get_next()) { + if (ti->get_parent() == root->get_first_child()->get_next()) { member_type = MEMBER_VARIABLE; member_name = ti->get_text(0); member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); @@ -4131,7 +4135,7 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { return; } - if (ti->get_parent() == root->get_children()->get_next()->get_next()) { + if (ti->get_parent() == root->get_first_child()->get_next()->get_next()) { member_type = MEMBER_SIGNAL; member_name = ti->get_text(0); member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index fc9a2df60f..ef3a5d11c0 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -320,6 +320,8 @@ public: virtual bool can_lose_focus_on_node_selection() override { return false; } virtual void validate() override; + virtual Control *get_base_editor() const override; + static void register_editor(); static void free_clipboard(); diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 862cac5c67..93e14f60d0 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -59,7 +59,7 @@ void VisualScriptPropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) { search_box->accept_event(); TreeItem *root = search_options->get_root(); - if (!root->get_children()) { + if (!root->get_first_child()) { break; } @@ -265,7 +265,7 @@ void VisualScriptPropertySelector::_update_search() { item->set_metadata(2, connecting); } - if (category && category->get_children() == nullptr) { + if (category && category->get_first_child() == nullptr) { memdelete(category); //old category was unused } } @@ -310,7 +310,7 @@ void VisualScriptPropertySelector::_update_search() { found = true; } - get_ok_button()->set_disabled(root->get_children() == nullptr); + get_ok_button()->set_disabled(root->get_first_child() == nullptr); } void VisualScriptPropertySelector::create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text) { diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index a6b64b342e..34addb5c9f 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -62,10 +62,10 @@ public: virtual int Read(long long pos, long len, unsigned char *buf) { if (file) { - if (file->get_position() != (size_t)pos) { + if (file->get_position() != (uint64_t)pos) { file->seek(pos); } - if (file->get_buffer(buf, len) == len) { + if (file->get_buffer(buf, len) == (uint64_t)len) { return 0; } } @@ -74,7 +74,7 @@ public: virtual int Length(long long *total, long long *available) { if (file) { - const size_t len = file->get_len(); + const uint64_t len = file->get_length(); if (total) { *total = len; } diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index 6e62840a3e..1f2a456619 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -147,7 +147,7 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) { Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - int src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml index e21dee8eff..3b53892a3d 100644 --- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml +++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml @@ -48,7 +48,7 @@ Valid [code]options[/code] are: [codeblock] { - "negotiated": true, # When set to true (default off), means the channel is negotiated out of band. "id" must be set too. data_channel_received will not be called. + "negotiated": true, # When set to true (default off), means the channel is negotiated out of band. "id" must be set too. "data_channel_received" will not be called. "id": 1, # When "negotiated" is true this value must also be set to the same value on both peer. # Only one of maxRetransmits and maxPacketLifeTime can be specified, not both. They make the channel unreliable (but also better at real time). diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml index 2407d44496..9b3a063ef5 100644 --- a/modules/webxr/doc_classes/WebXRInterface.xml +++ b/modules/webxr/doc_classes/WebXRInterface.xml @@ -7,7 +7,7 @@ WebXR is an open standard that allows creating VR and AR applications that run in the web browser. As such, this interface is only available when running in an HTML5 export. WebXR supports a wide range of devices, from the very capable (like Valve Index, HTC Vive, Oculus Rift and Quest) down to the much less capable (like Google Cardboard, Oculus Go, GearVR, or plain smartphones). - Since WebXR is based on Javascript, it makes extensive use of callbacks, which means that [WebXRInterface] is forced to use signals, where other AR/VR interfaces would instead use functions that return a result immediately. This makes [WebXRInterface] quite a bit more complicated to intialize than other AR/VR interfaces. + Since WebXR is based on Javascript, it makes extensive use of callbacks, which means that [WebXRInterface] is forced to use signals, where other AR/VR interfaces would instead use functions that return a result immediately. This makes [WebXRInterface] quite a bit more complicated to initialize than other AR/VR interfaces. Here's the minimum code required to start an immersive VR session: [codeblock] extends Node3D diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h index e0ee2888c0..6d25a366a4 100644 --- a/platform/android/android_keys_utils.h +++ b/platform/android/android_keys_utils.h @@ -127,8 +127,8 @@ static _WinTranslatePair _ak_to_keycode[] = { { KEY_BACKSLASH, AKEYCODE_BACKSLASH }, { KEY_BRACKETLEFT, AKEYCODE_LEFT_BRACKET }, { KEY_BRACKETRIGHT, AKEYCODE_RIGHT_BRACKET }, - { KEY_CONTROL, AKEYCODE_CTRL_LEFT }, - { KEY_CONTROL, AKEYCODE_CTRL_RIGHT }, + { KEY_CTRL, AKEYCODE_CTRL_LEFT }, + { KEY_CTRL, AKEYCODE_CTRL_RIGHT }, { KEY_UNKNOWN, 0 } }; /* diff --git a/platform/android/detect.py b/platform/android/detect.py index 2a80a3c45b..1b6af8662e 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -250,7 +250,7 @@ def configure(env): env["RANLIB"] = tools_path + "/ranlib" env["AS"] = tools_path + "/as" - common_opts = ["-fno-integrated-as", "-gcc-toolchain", gcc_toolchain_path] + common_opts = ["-gcc-toolchain", gcc_toolchain_path] # Compile flags @@ -285,6 +285,9 @@ def configure(env): ) env.Append(CPPDEFINES=["NO_STATVFS", "GLES_ENABLED"]) + if get_platform(env["ndk_platform"]) >= 24: + env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)]) + env["neon_enabled"] = False if env["android_arch"] == "x86": target_opts = ["-target", "i686-none-linux-android"] diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index f8ac29c738..0bae090702 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -201,8 +201,7 @@ String DirAccessJAndroid::get_filesystem_type() const { return "APK"; } -//FileType get_file_type() const; -size_t DirAccessJAndroid::get_space_left() { +uint64_t DirAccessJAndroid::get_space_left() { return 0; } diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index fed468d051..7b9cbeea47 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -74,10 +74,13 @@ public: virtual Error rename(String p_from, String p_to); virtual Error remove(String p_name); + virtual bool is_link(String p_file) { return false; } + virtual String read_link(String p_file) { return p_file; } + virtual Error create_link(String p_source, String p_target) { return FAILED; } + virtual String get_filesystem_type() const; - //virtual FileType get_file_type() const; - size_t get_space_left(); + uint64_t get_space_left(); static void setup(jobject p_io); diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 7a32184139..ff61eeaee1 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -36,8 +36,6 @@ #include "java_godot_wrapper.h" #include "os_android.h" -#include <android/input.h> - #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/android/vulkan/vulkan_context_android.h" @@ -51,7 +49,7 @@ DisplayServerAndroid *DisplayServerAndroid::get_singleton() { bool DisplayServerAndroid::has_feature(Feature p_feature) const { switch (p_feature) { //case FEATURE_CONSOLE_WINDOW: - //case FEATURE_CURSOR_SHAPE: + case FEATURE_CURSOR_SHAPE: //case FEATURE_CUSTOM_CURSOR_SHAPE: //case FEATURE_GLOBAL_MENU: //case FEATURE_HIDPI: @@ -198,7 +196,7 @@ void DisplayServerAndroid::window_set_input_text_callback(const Callable &p_call } void DisplayServerAndroid::window_set_rect_changed_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { - // Not supported on Android. + rect_changed_callback = p_callable; } void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { @@ -391,6 +389,19 @@ void DisplayServerAndroid::reset_window() { #endif } +void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) { + if (rect_changed_callback.is_null()) { + return; + } + + const Variant size = Rect2i(0, 0, p_width, p_height); + const Variant *sizep = &size; + Variant ret; + Callable::CallError ce; + + rect_changed_callback.call(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce); +} + DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { rendering_driver = p_rendering_driver; @@ -490,10 +501,10 @@ void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p } void DisplayServerAndroid::_set_key_modifier_state(Ref<InputEventWithModifiers> ev) { - ev->set_shift(shift_mem); - ev->set_alt(alt_mem); - ev->set_metakey(meta_mem); - ev->set_control(control_mem); + ev->set_shift_pressed(shift_mem); + ev->set_alt_pressed(alt_mem); + ev->set_meta_pressed(meta_mem); + ev->set_ctrl_pressed(control_mem); } void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) { @@ -528,7 +539,7 @@ void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int if (keycode == KEY_ALT) { alt_mem = p_pressed; } - if (keycode == KEY_CONTROL) { + if (keycode == KEY_CTRL) { control_mem = p_pressed; } if (keycode == KEY_META) { @@ -829,6 +840,12 @@ void DisplayServerAndroid::mouse_set_mode(MouseMode p_mode) { return; } + if (p_mode == MouseMode::MOUSE_MODE_HIDDEN) { + OS_Android::get_singleton()->get_godot_java()->get_godot_view()->set_pointer_icon(CURSOR_TYPE_NULL); + } else { + cursor_set_shape(cursor_shape); + } + if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) { OS_Android::get_singleton()->get_godot_java()->get_godot_view()->request_pointer_capture(); } else { @@ -870,3 +887,19 @@ int DisplayServerAndroid::_android_button_mask_to_godot_button_mask(int android_ return godot_button_mask; } + +void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) { + if (cursor_shape == p_shape) { + return; + } + + cursor_shape = p_shape; + + if (mouse_mode == MouseMode::MOUSE_MODE_VISIBLE || mouse_mode == MouseMode::MOUSE_MODE_CONFINED) { + OS_Android::get_singleton()->get_godot_java()->get_godot_view()->set_pointer_icon(android_cursors[cursor_shape]); + } +} + +DisplayServer::CursorShape DisplayServerAndroid::cursor_get_shape() const { + return cursor_shape; +} diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index b9d1641656..1379baf154 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -70,6 +70,28 @@ private: int buttons_state; + // https://developer.android.com/reference/android/view/PointerIcon + // mapping between Godot's cursor shape to Android's' + int android_cursors[CURSOR_MAX] = { + 1000, //CURSOR_ARROW + 1008, //CURSOR_IBEAM + 1002, //CURSOR_POINTIN + 1007, //CURSOR_CROSS + 1004, //CURSOR_WAIT + 1004, //CURSOR_BUSY + 1021, //CURSOR_DRAG + 1021, //CURSOR_CAN_DRO + 1000, //CURSOR_FORBIDD (no corresponding icon in Android's icon so fallback to default) + 1015, //CURSOR_VSIZE + 1014, //CURSOR_HSIZE + 1017, //CURSOR_BDIAGSI + 1016, //CURSOR_FDIAGSI + 1020, //CURSOR_MOVE + 1015, //CURSOR_VSPLIT + 1014, //CURSOR_HSPLIT + 1003, //CURSOR_HELP + }; + const int CURSOR_TYPE_NULL = 0; MouseMode mouse_mode; bool keep_screen_on; @@ -78,6 +100,8 @@ private: Point2 hover_prev_pos; // needed to calculate the relative position on hover events Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events + CursorShape cursor_shape = CursorShape::CURSOR_ARROW; + #if defined(VULKAN_ENABLED) VulkanContextAndroid *context_vulkan; RenderingDeviceVulkan *rendering_device_vulkan; @@ -88,6 +112,7 @@ private: Callable window_event_callback; Callable input_event_callback; Callable input_text_callback; + Callable rect_changed_callback; void _window_callback(const Callable &p_callable, const Variant &p_arg) const; @@ -180,6 +205,9 @@ public: void process_joy_event(JoypadEvent p_event); void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed); + virtual void cursor_set_shape(CursorShape p_shape); + virtual CursorShape cursor_get_shape() const; + void mouse_set_mode(MouseMode p_mode); MouseMode mouse_get_mode() const; @@ -188,6 +216,7 @@ public: static void register_android_driver(); void reset_window(); + void notify_surface_changed(int p_width, int p_height); virtual Point2i mouse_get_position() const; virtual int mouse_get_button_state() const; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index cd3f00f935..1338b31a64 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -847,7 +847,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int version_code = p_preset->get("version/code"); String package_name = p_preset->get("package/unique_name"); - const int screen_orientation = _get_android_orientation_value(_get_screen_orientation()); + const int screen_orientation = + _get_android_orientation_value(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); bool screen_support_small = p_preset->get("screen/support_small"); bool screen_support_normal = p_preset->get("screen/support_normal"); @@ -856,6 +857,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int xr_mode_index = p_preset->get("xr_features/xr_mode"); + bool backup_allowed = p_preset->get("user_data_backup/allow"); + Vector<String> perms; // Write permissions into the perms variable. _get_permissions(p_preset, p_give_internet, perms); @@ -948,6 +951,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } } + if (tname == "application" && attrname == "allowBackup") { + encode_uint32(backup_allowed, &p_manifest.write[iofs + 16]); + } + if (tname == "instrumentation" && attrname == "targetPackage") { string_table.write[attr_value] = get_package_name(package_name); } @@ -1683,6 +1690,8 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data_backup/allow"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false)); @@ -1784,7 +1793,7 @@ public: p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST; } - String tmp_export_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport." + uitos(OS::get_singleton()->get_unix_time()) + ".apk"); + String tmp_export_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpexport." + uitos(OS::get_singleton()->get_unix_time()) + ".apk"); #define CLEANUP_AND_RETURN(m_err) \ { \ @@ -2642,7 +2651,7 @@ public: FileAccess *dst_f = nullptr; io2.opaque = &dst_f; - String tmp_unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned." + uitos(OS::get_singleton()->get_unix_time()) + ".apk"); + String tmp_unaligned_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned." + uitos(OS::get_singleton()->get_unix_time()) + ".apk"); #define CLEANUP_AND_RETURN(m_err) \ { \ diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index bbbb526af9..0bb94dcc97 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -44,28 +44,6 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut </resources> )"; -DisplayServer::ScreenOrientation _get_screen_orientation() { - String orientation_settings = ProjectSettings::get_singleton()->get("display/window/handheld/orientation"); - DisplayServer::ScreenOrientation screen_orientation; - if (orientation_settings == "portrait") { - screen_orientation = DisplayServer::SCREEN_PORTRAIT; - } else if (orientation_settings == "reverse_landscape") { - screen_orientation = DisplayServer::SCREEN_REVERSE_LANDSCAPE; - } else if (orientation_settings == "reverse_portrait") { - screen_orientation = DisplayServer::SCREEN_REVERSE_PORTRAIT; - } else if (orientation_settings == "sensor_landscape") { - screen_orientation = DisplayServer::SCREEN_SENSOR_LANDSCAPE; - } else if (orientation_settings == "sensor_portrait") { - screen_orientation = DisplayServer::SCREEN_SENSOR_PORTRAIT; - } else if (orientation_settings == "sensor") { - screen_orientation = DisplayServer::SCREEN_SENSOR; - } else { - screen_orientation = DisplayServer::SCREEN_LANDSCAPE; - } - - return screen_orientation; -} - int _get_android_orientation_value(DisplayServer::ScreenOrientation screen_orientation) { switch (screen_orientation) { case DisplayServer::SCREEN_PORTRAIT: @@ -266,7 +244,7 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) { String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; - String orientation = _get_android_orientation_label(_get_screen_orientation()); + String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); String manifest_activity_text = vformat( " <activity android:name=\"com.godot.game.GodotApp\" " "tools:replace=\"android:screenOrientation\" " @@ -280,10 +258,11 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { } String _get_application_tag(const Ref<EditorExportPreset> &p_preset) { - String manifest_application_text = + String manifest_application_text = vformat( " <application android:label=\"@string/godot_project_name_string\"\n" - " android:allowBackup=\"false\" tools:ignore=\"GoogleAppIndexingWarning\"\n" - " android:icon=\"@mipmap/icon\">\n\n"; + " android:allowBackup=\"%s\" tools:ignore=\"GoogleAppIndexingWarning\"\n" + " android:icon=\"@mipmap/icon\">\n\n", + bool_to_string(p_preset->get("user_data_backup/allow"))); manifest_application_text += _get_activity_tag(p_preset); manifest_application_text += " </application>\n"; diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index 705891713f..90370878b7 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -71,8 +71,9 @@ bool FileAccessAndroid::is_open() const { return a != nullptr; } -void FileAccessAndroid::seek(size_t p_position) { +void FileAccessAndroid::seek(uint64_t p_position) { ERR_FAIL_COND(!a); + AAsset_seek(a, p_position, SEEK_SET); pos = p_position; if (pos > len) { @@ -89,11 +90,11 @@ void FileAccessAndroid::seek_end(int64_t p_position) { pos = len + p_position; } -size_t FileAccessAndroid::get_position() const { +uint64_t FileAccessAndroid::get_position() const { return pos; } -size_t FileAccessAndroid::get_len() const { +uint64_t FileAccessAndroid::get_length() const { return len; } @@ -113,11 +114,10 @@ uint8_t FileAccessAndroid::get_8() const { return byte; } -int FileAccessAndroid::get_buffer(uint8_t *p_dst, int p_length) const { +uint64_t FileAccessAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const { ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); - ERR_FAIL_COND_V(p_length < 0, -1); - off_t r = AAsset_read(a, p_dst, p_length); + int r = AAsset_read(a, p_dst, p_length); if (pos + p_length > len) { eof = true; diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index 56010c918a..8890e0f645 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -40,8 +40,8 @@ class FileAccessAndroid : public FileAccess { static FileAccess *create_android(); mutable AAsset *a = nullptr; - mutable size_t len = 0; - mutable size_t pos = 0; + mutable uint64_t len = 0; + mutable uint64_t pos = 0; mutable bool eof = false; public: @@ -51,15 +51,15 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open - virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file - virtual size_t get_position() const; ///< get position in the file - virtual size_t get_len() const; ///< get size of the file + virtual uint64_t get_position() const; ///< get position in the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF virtual uint8_t get_8() const; ///< get a byte - virtual int get_buffer(uint8_t *p_dst, int p_length) const; + virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; virtual Error get_error() const; ///< get last error diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index 63c91561ff..b3ee55ea64 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -44,11 +44,15 @@ import android.annotation.SuppressLint; import android.content.Context; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; +import android.os.Build; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.PointerIcon; import android.view.SurfaceView; +import androidx.annotation.Keep; + /** * A simple GLSurfaceView sub-class that demonstrate how to perform * OpenGL ES 2.0 rendering into a GL Surface. Note the following important @@ -72,6 +76,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView private final GodotInputHandler inputHandler; private final GestureDetector detector; private final GodotRenderer godotRenderer; + private PointerIcon pointerIcon; public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) { @@ -83,6 +88,9 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView this.inputHandler = new GodotInputHandler(this); this.detector = new GestureDetector(context, new GodotGestureHandler(this)); this.godotRenderer = new GodotRenderer(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + pointerIcon = PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_DEFAULT); + } init(xrMode, false, 16, 0); } @@ -149,6 +157,21 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView return inputHandler.onGenericMotionEvent(event); } + /** + * called from JNI to change pointer icon + */ + @Keep + public void setPointerIcon(int pointerType) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + pointerIcon = PointerIcon.getSystemIcon(getContext(), pointerType); + } + } + + @Override + public PointerIcon onResolvePointerIcon(MotionEvent me, int pointerIndex) { + return pointerIcon; + } + private void init(XRMode xrMode, boolean translucent, int depth, int stencil) { setPreserveEGLContextOnPause(true); setFocusableInTouchMode(true); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java index 2047c88070..ac333dd827 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java @@ -47,4 +47,6 @@ public interface GodotRenderView { abstract public void onBackPressed(); abstract public GodotInputHandler getInputHandler(); + + abstract public void setPointerIcon(int pointerType); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java index 2e59dbc0d0..169c6cf770 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -37,17 +37,22 @@ import org.godotengine.godot.vulkan.VkSurfaceView; import android.annotation.SuppressLint; import android.content.Context; +import android.os.Build; import android.view.GestureDetector; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.PointerIcon; import android.view.SurfaceView; +import androidx.annotation.Keep; + public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView { private final Godot godot; private final GodotInputHandler mInputHandler; private final GestureDetector mGestureDetector; private final VkRenderer mRenderer; + private PointerIcon pointerIcon; public GodotVulkanRenderView(Context context, Godot godot) { super(context); @@ -56,7 +61,9 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV mInputHandler = new GodotInputHandler(this); mGestureDetector = new GestureDetector(context, new GodotGestureHandler(this)); mRenderer = new VkRenderer(); - + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + pointerIcon = PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_DEFAULT); + } setFocusableInTouchMode(true); startRenderer(mRenderer); } @@ -124,6 +131,21 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV return mInputHandler.onGenericMotionEvent(event); } + /** + * called from JNI to change pointer icon + */ + @Keep + public void setPointerIcon(int pointerType) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + pointerIcon = PointerIcon.getSystemIcon(getContext(), pointerType); + } + } + + @Override + public PointerIcon onResolvePointerIcon(MotionEvent me, int pointerIndex) { + return pointerIcon; + } + @Override public void onResume() { super.onResume(); diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt index b967fd5f24..6e59268076 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt @@ -61,6 +61,7 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk private var rendererInitialized = false private var rendererResumed = false private var resumed = false + private var surfaceChanged = false private var hasSurface = false private var width = 0 private var height = 0 @@ -141,8 +142,10 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk fun onSurfaceChanged(width: Int, height: Int) { lock.withLock { hasSurface = true + surfaceChanged = true; this.width = width this.height = height + lockCondition.signalAll() } } @@ -188,8 +191,11 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk rendererInitialized = true vkRenderer.onVkSurfaceCreated(vkSurfaceView.holder.surface) } + } + if (surfaceChanged) { vkRenderer.onVkSurfaceChanged(vkSurfaceView.holder.surface, width, height) + surfaceChanged = false } // Break out of the loop so drawing can occur without holding onto the lock. diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 0c342dc280..c7ff6cb2c0 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -173,6 +173,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j os_android->set_native_window(native_window); DisplayServerAndroid::get_singleton()->reset_window(); + DisplayServerAndroid::get_singleton()->notify_surface_changed(p_width, p_height); } } } diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp index 6b5e44f371..837d2aeced 100644 --- a/platform/android/java_godot_view_wrapper.cpp +++ b/platform/android/java_godot_view_wrapper.cpp @@ -43,6 +43,7 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) { if (android_get_device_api_level() >= __ANDROID_API_O__) { _request_pointer_capture = env->GetMethodID(_cls, "requestPointerCapture", "()V"); _release_pointer_capture = env->GetMethodID(_cls, "releasePointerCapture", "()V"); + _set_pointer_icon = env->GetMethodID(_cls, "setPointerIcon", "(I)V"); } } @@ -64,6 +65,15 @@ void GodotJavaViewWrapper::release_pointer_capture() { } } +void GodotJavaViewWrapper::set_pointer_icon(int pointer_type) { + if (_set_pointer_icon != 0) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_COND(env == nullptr); + + env->CallVoidMethod(_godot_view, _set_pointer_icon, pointer_type); + } +} + GodotJavaViewWrapper::~GodotJavaViewWrapper() { JNIEnv *env = get_jni_env(); ERR_FAIL_COND(env == nullptr); diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h index bfb4369fb8..da547d8118 100644 --- a/platform/android/java_godot_view_wrapper.h +++ b/platform/android/java_godot_view_wrapper.h @@ -45,12 +45,14 @@ private: jmethodID _request_pointer_capture = 0; jmethodID _release_pointer_capture = 0; + jmethodID _set_pointer_icon = 0; public: GodotJavaViewWrapper(jobject godot_view); void request_pointer_capture(); void release_pointer_capture(); + void set_pointer_icon(int pointer_type); ~GodotJavaViewWrapper(); }; diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index c585c2afbe..73723b98a0 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -353,6 +353,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/targeted_device_family", PROPERTY_HINT_ENUM, "iPhone,iPad,iPhone & iPad"), 2)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/bundle_identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), "")); @@ -378,11 +380,6 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_left"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_right"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait_upside_down"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "icons/generate_missing"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone/iPod Touch with retina display @@ -453,6 +450,8 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n"; } else if (lines[i].find("$team_id") != -1) { strnew += lines[i].replace("$team_id", p_preset->get("application/app_store_team_id")) + "\n"; + } else if (lines[i].find("$default_build_config") != -1) { + strnew += lines[i].replace("$default_build_config", p_debug ? "Debug" : "Release") + "\n"; } else if (lines[i].find("$export_method") != -1) { int export_method = p_preset->get(p_debug ? "application/export_method_debug" : "application/export_method_release"); strnew += lines[i].replace("$export_method", export_method_string[export_method]) + "\n"; @@ -473,6 +472,20 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$godot_archs", p_config.architectures) + "\n"; } else if (lines[i].find("$linker_flags") != -1) { strnew += lines[i].replace("$linker_flags", p_config.linker_flags) + "\n"; + } else if (lines[i].find("$targeted_device_family") != -1) { + String xcode_value; + switch ((int)p_preset->get("application/targeted_device_family")) { + case 0: // iPhone + xcode_value = "1"; + break; + case 1: // iPad + xcode_value = "2"; + break; + case 2: // iPhone & iPad + xcode_value = "1,2"; + break; + } + strnew += lines[i].replace("$targeted_device_family", xcode_value) + "\n"; } else if (lines[i].find("$cpp_code") != -1) { strnew += lines[i].replace("$cpp_code", p_config.cpp_code) + "\n"; } else if (lines[i].find("$docs_in_place") != -1) { @@ -501,18 +514,39 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$required_device_capabilities", capabilities); } else if (lines[i].find("$interface_orientations") != -1) { String orientations; + const DisplayServer::ScreenOrientation screen_orientation = + DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation"))); - if ((bool)p_preset->get("orientation/portrait")) { - orientations += "<string>UIInterfaceOrientationPortrait</string>\n"; - } - if ((bool)p_preset->get("orientation/landscape_left")) { - orientations += "<string>UIInterfaceOrientationLandscapeLeft</string>\n"; - } - if ((bool)p_preset->get("orientation/landscape_right")) { - orientations += "<string>UIInterfaceOrientationLandscapeRight</string>\n"; - } - if ((bool)p_preset->get("orientation/portrait_upside_down")) { - orientations += "<string>UIInterfaceOrientationPortraitUpsideDown</string>\n"; + switch (screen_orientation) { + case DisplayServer::SCREEN_LANDSCAPE: + orientations += "<string>UIInterfaceOrientationLandscapeLeft</string>\n"; + break; + case DisplayServer::SCREEN_PORTRAIT: + orientations += "<string>UIInterfaceOrientationPortrait</string>\n"; + break; + case DisplayServer::SCREEN_REVERSE_LANDSCAPE: + orientations += "<string>UIInterfaceOrientationLandscapeRight</string>\n"; + break; + case DisplayServer::SCREEN_REVERSE_PORTRAIT: + orientations += "<string>UIInterfaceOrientationPortraitUpsideDown</string>\n"; + break; + case DisplayServer::SCREEN_SENSOR_LANDSCAPE: + // Allow both landscape orientations depending on sensor direction. + orientations += "<string>UIInterfaceOrientationLandscapeLeft</string>\n"; + orientations += "<string>UIInterfaceOrientationLandscapeRight</string>\n"; + break; + case DisplayServer::SCREEN_SENSOR_PORTRAIT: + // Allow both portrait orientations depending on sensor direction. + orientations += "<string>UIInterfaceOrientationPortrait</string>\n"; + orientations += "<string>UIInterfaceOrientationPortraitUpsideDown</string>\n"; + break; + case DisplayServer::SCREEN_SENSOR: + // Allow all screen orientations depending on sensor direction. + orientations += "<string>UIInterfaceOrientationLandscapeLeft</string>\n"; + orientations += "<string>UIInterfaceOrientationLandscapeRight</string>\n"; + orientations += "<string>UIInterfaceOrientationPortrait</string>\n"; + orientations += "<string>UIInterfaceOrientationPortraitUpsideDown</string>\n"; + break; } strnew += lines[i].replace("$interface_orientations", orientations); diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m index 3ce9bffc79..6c433c5c3c 100644 --- a/platform/iphone/godot_app_delegate.m +++ b/platform/iphone/godot_app_delegate.m @@ -56,7 +56,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil; [services addObject:service]; } -// UIApplicationDelegate documantation can be found here: https://developer.apple.com/documentation/uikit/uiapplicationdelegate +// UIApplicationDelegate documentation can be found here: https://developer.apple.com/documentation/uikit/uiapplicationdelegate // MARK: Window diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index a760e36982..62a8660ae4 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -6,7 +6,7 @@ javascript_files = [ "audio_driver_javascript.cpp", "display_server_javascript.cpp", "http_client_javascript.cpp", - "javascript_eval.cpp", + "javascript_singleton.cpp", "javascript_main.cpp", "os_javascript.cpp", "api/javascript_tools_editor_plugin.cpp", @@ -23,10 +23,8 @@ sys_env.AddJSLibraries( ] ) -if env["tools"]: - sys_env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"]) if env["javascript_eval"]: - sys_env.AddJSLibraries(["js/libs/library_godot_eval.js"]) + sys_env.AddJSLibraries(["js/libs/library_godot_javascript_singleton.js"]) for lib in sys_env["JS_LIBS"]: sys_env.Append(LINKFLAGS=["--js-library", lib]) @@ -47,6 +45,7 @@ if env["gdnative_enabled"]: sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"]) sys_env.Append(CCFLAGS=["-s", "EXPORT_ALL=1"]) sys_env.Append(LINKFLAGS=["-s", "EXPORT_ALL=1"]) + sys_env.Append(LINKFLAGS=["-s", "WARN_ON_UNDEFINED_SYMBOLS=0"]) # Force exporting the standard library (printf, malloc, etc.) sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi" # The main emscripten runtime, with exported standard libraries. diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp index 2f7bde065f..5ad2bf56cf 100644 --- a/platform/javascript/api/api.cpp +++ b/platform/javascript/api/api.cpp @@ -30,13 +30,14 @@ #include "api.h" #include "core/config/engine.h" -#include "javascript_eval.h" +#include "javascript_singleton.h" #include "javascript_tools_editor_plugin.h" static JavaScript *javascript_eval; void register_javascript_api() { JavaScriptToolsEditorPlugin::initialize(); + ClassDB::register_virtual_class<JavaScriptObject>(); ClassDB::register_virtual_class<JavaScript>(); javascript_eval = memnew(JavaScript); Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval)); @@ -61,10 +62,46 @@ JavaScript::~JavaScript() {} void JavaScript::_bind_methods() { ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_interface", "interface"), &JavaScript::get_interface); + ClassDB::bind_method(D_METHOD("create_callback", "callable"), &JavaScript::create_callback); + { + MethodInfo mi; + mi.name = "create_object"; + mi.arguments.push_back(PropertyInfo(Variant::STRING, "object")); + ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "create_object", &JavaScript::_create_object_bind, mi); + } + ClassDB::bind_method(D_METHOD("download_buffer", "buffer", "name", "mime"), &JavaScript::download_buffer, DEFVAL("application/octet-stream")); } #if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED) Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { return Variant(); } + +Ref<JavaScriptObject> JavaScript::get_interface(const String &p_interface) { + return Ref<JavaScriptObject>(); +} + +Ref<JavaScriptObject> JavaScript::create_callback(const Callable &p_callable) { + return Ref<JavaScriptObject>(); +} + +Variant JavaScript::_create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + if (p_argcount < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 0; + return Ref<JavaScriptObject>(); + } + if (p_args[0]->get_type() != Variant::STRING) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::STRING; + return Ref<JavaScriptObject>(); + } + return Ref<JavaScriptObject>(); +} +#endif +#if !defined(JAVASCRIPT_ENABLED) +void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { +} #endif diff --git a/platform/javascript/api/javascript_eval.h b/platform/javascript/api/javascript_singleton.h index 24f7648ed9..1615efa87e 100644 --- a/platform/javascript/api/javascript_eval.h +++ b/platform/javascript/api/javascript_singleton.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* javascript_eval.h */ +/* javascript_singleton.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,10 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef JAVASCRIPT_EVAL_H -#define JAVASCRIPT_EVAL_H +#ifndef JAVASCRIPT_SINGLETON_H +#define JAVASCRIPT_SINGLETON_H #include "core/object/class_db.h" +#include "core/object/reference.h" + +class JavaScriptObject : public Reference { +private: + GDCLASS(JavaScriptObject, Reference); + +protected: + virtual bool _set(const StringName &p_name, const Variant &p_value) { return false; } + virtual bool _get(const StringName &p_name, Variant &r_ret) const { return false; } + virtual void _get_property_list(List<PropertyInfo> *p_list) const {} +}; class JavaScript : public Object { private: @@ -44,10 +55,14 @@ protected: public: Variant eval(const String &p_code, bool p_use_global_exec_context = false); + Ref<JavaScriptObject> get_interface(const String &p_interface); + Ref<JavaScriptObject> create_callback(const Callable &p_callable); + Variant _create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + void download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime = "application/octet-stream"); static JavaScript *get_singleton(); JavaScript(); ~JavaScript(); }; -#endif // JAVASCRIPT_EVAL_H +#endif // JAVASCRIPT_SINGLETON_H diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp index 7a2c2b2335..b35ccd087f 100644 --- a/platform/javascript/api/javascript_tools_editor_plugin.cpp +++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp @@ -41,7 +41,7 @@ // JavaScript functions defined in library_godot_editor_tools.js extern "C" { -extern void godot_js_editor_download_file(const char *p_path, const char *p_name, const char *p_mime); +extern int godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime); } static void _javascript_editor_init_callback() { @@ -69,7 +69,12 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) { String base_path = resource_path.substr(0, resource_path.rfind("/")) + "/"; _zip_recursive(resource_path, base_path, zip); zipClose(zip, nullptr); - godot_js_editor_download_file("/tmp/project.zip", "project.zip", "application/zip"); + FileAccess *f = FileAccess::open("/tmp/project.zip", FileAccess::READ); + ERR_FAIL_COND_MSG(!f, "Unable to create zip file"); + Vector<uint8_t> buf; + buf.resize(f->get_length()); + f->get_buffer(buf.ptrw(), buf.size()); + godot_js_os_download_buffer(buf.ptr(), buf.size(), "project.zip", "application/zip"); } void JavaScriptToolsEditorPlugin::_zip_file(String p_path, String p_base_path, zipFile p_zip) { @@ -79,7 +84,7 @@ void JavaScriptToolsEditorPlugin::_zip_file(String p_path, String p_base_path, z return; } Vector<uint8_t> data; - int len = f->get_len(); + uint64_t len = f->get_length(); data.resize(len); f->get_buffer(data.ptrw(), len); f->close(); diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index 736a8a9a34..dae0b5f7e7 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -120,10 +120,10 @@ void DisplayServerJavaScript::request_quit_callback() { template <typename T> void DisplayServerJavaScript::dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) { - godot_event->set_shift(emscripten_event_ptr->shiftKey); - godot_event->set_alt(emscripten_event_ptr->altKey); - godot_event->set_control(emscripten_event_ptr->ctrlKey); - godot_event->set_metakey(emscripten_event_ptr->metaKey); + godot_event->set_shift_pressed(emscripten_event_ptr->shiftKey); + godot_event->set_alt_pressed(emscripten_event_ptr->altKey); + godot_event->set_ctrl_pressed(emscripten_event_ptr->ctrlKey); + godot_event->set_meta_pressed(emscripten_event_ptr->metaKey); } Ref<InputEventKey> DisplayServerJavaScript::setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) { @@ -455,10 +455,10 @@ EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const Emscript ev->set_position(input->get_mouse_position()); ev->set_global_position(ev->get_position()); - ev->set_shift(input->is_key_pressed(KEY_SHIFT)); - ev->set_alt(input->is_key_pressed(KEY_ALT)); - ev->set_control(input->is_key_pressed(KEY_CONTROL)); - ev->set_metakey(input->is_key_pressed(KEY_META)); + ev->set_shift_pressed(input->is_key_pressed(KEY_SHIFT)); + ev->set_alt_pressed(input->is_key_pressed(KEY_ALT)); + ev->set_ctrl_pressed(input->is_key_pressed(KEY_CTRL)); + ev->set_meta_pressed(input->is_key_pressed(KEY_META)); if (p_event->deltaY < 0) ev->set_button_index(MOUSE_BUTTON_WHEEL_UP); @@ -536,7 +536,7 @@ bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const { return godot_js_display_touchscreen_is_available(); } -// Virtual Keybaord +// Virtual Keyboard void DisplayServerJavaScript::vk_input_text_callback(const char *p_text, int p_cursor) { DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton(); if (!ds || ds->input_text_callback.is_null()) { diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc index 7902efafe0..69340ff58c 100644 --- a/platform/javascript/dom_keys.inc +++ b/platform/javascript/dom_keys.inc @@ -159,8 +159,8 @@ int dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], b DOM2GODOT("Backspace", BACKSPACE); DOM2GODOT("CapsLock", CAPSLOCK); DOM2GODOT("ContextMenu", MENU); - DOM2GODOT("ControlLeft", CONTROL); - DOM2GODOT("ControlRight", CONTROL); + DOM2GODOT("ControlLeft", CTRL); + DOM2GODOT("ControlRight", CTRL); DOM2GODOT("Enter", ENTER); DOM2GODOT("MetaLeft", SUPER_L); DOM2GODOT("MetaRight", SUPER_R); diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 951d86d09e..8ce294f31b 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -63,7 +63,7 @@ private: } void _set_internal_certs(Ref<Crypto> p_crypto) { - const String cache_path = EditorSettings::get_singleton()->get_cache_dir(); + const String cache_path = EditorPaths::get_singleton()->get_cache_dir(); const String key_path = cache_path.plus_file("html5_server.key"); const String crt_path = cache_path.plus_file("html5_server.crt"); bool regen = !FileAccess::exists(key_path) || !FileAccess::exists(crt_path); @@ -138,7 +138,7 @@ public: const String req_file = req[1].get_file(); const String req_ext = req[1].get_extension(); - const String cache_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("web"); + const String cache_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("web"); const String filepath = cache_path.plus_file(req_file); if (!mimes.has(req_ext) || !FileAccess::exists(filepath)) { @@ -170,8 +170,8 @@ public: while (true) { uint8_t bytes[4096]; - int read = f->get_buffer(bytes, 4096); - if (read < 1) { + uint64_t read = f->get_buffer(bytes, 4096); + if (read == 0) { break; } err = peer->put_data(bytes, read); @@ -547,7 +547,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> & EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + sw_path); return ERR_FILE_CANT_READ; } - sw.resize(f->get_len()); + sw.resize(f->get_length()); f->get_buffer(sw.ptrw(), sw.size()); memdelete(f); f = nullptr; @@ -651,7 +651,7 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/experimental_virtual_keyboard"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "progressive_web_app/enabled"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/offline_page", PROPERTY_HINT_FILE, "*.html"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/display", PROPERTY_HINT_ENUM, "Fullscreen,Standalone,Minimal Ui,Browser"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/display", PROPERTY_HINT_ENUM, "Fullscreen,Standalone,Minimal UI,Browser"), 1)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/orientation", PROPERTY_HINT_ENUM, "Any,Landscape,Portrait"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_144x144", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg,*.svgz"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_180x180", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg,*.svgz"), "")); @@ -781,13 +781,13 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese FileAccess *f = nullptr; f = FileAccess::open(pck_path, FileAccess::READ); if (f) { - file_sizes[pck_path.get_file()] = (uint64_t)f->get_len(); + file_sizes[pck_path.get_file()] = (uint64_t)f->get_length(); memdelete(f); f = nullptr; } f = FileAccess::open(base_path + ".wasm", FileAccess::READ); if (f) { - file_sizes[base_name + ".wasm"] = (uint64_t)f->get_len(); + file_sizes[base_name + ".wasm"] = (uint64_t)f->get_length(); memdelete(f); f = nullptr; } @@ -800,7 +800,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese EditorNode::get_singleton()->show_warning(TTR("Could not read HTML shell:") + "\n" + html_path); return ERR_FILE_CANT_READ; } - html.resize(f->get_len()); + html.resize(f->get_length()); f->get_buffer(html.ptrw(), html.size()); memdelete(f); f = nullptr; @@ -888,7 +888,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese return OK; } - const String dest = EditorSettings::get_singleton()->get_cache_dir().plus_file("web"); + const String dest = EditorPaths::get_singleton()->get_cache_dir().plus_file("web"); DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (!da->dir_exists(dest)) { Error err = da->make_dir_recursive(dest); diff --git a/platform/javascript/javascript_singleton.cpp b/platform/javascript/javascript_singleton.cpp new file mode 100644 index 0000000000..5ef67c0cdd --- /dev/null +++ b/platform/javascript/javascript_singleton.cpp @@ -0,0 +1,343 @@ +/*************************************************************************/ +/* javascript_singleton.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef JAVASCRIPT_EVAL_ENABLED + +#include "api/javascript_singleton.h" +#include "emscripten.h" + +extern "C" { +typedef union { + int64_t i; + double r; + void *p; +} godot_js_wrapper_ex; + +typedef int (*GodotJSWrapperVariant2JSCallback)(const void **p_args, int p_pos, godot_js_wrapper_ex *r_val, void **p_lock); +typedef void (*GodotJSWrapperFreeLockCallback)(void **p_lock, int p_type); +extern int godot_js_wrapper_interface_get(const char *p_name); +extern int godot_js_wrapper_object_call(int p_id, const char *p_method, void **p_args, int p_argc, GodotJSWrapperVariant2JSCallback p_variant2js_callback, godot_js_wrapper_ex *p_cb_rval, void **p_lock, GodotJSWrapperFreeLockCallback p_lock_callback); +extern int godot_js_wrapper_object_get(int p_id, godot_js_wrapper_ex *p_val, const char *p_prop); +extern int godot_js_wrapper_object_getvar(int p_id, int p_type, godot_js_wrapper_ex *p_val); +extern int godot_js_wrapper_object_setvar(int p_id, int p_key_type, godot_js_wrapper_ex *p_key_ex, int p_val_type, godot_js_wrapper_ex *p_val_ex); +extern void godot_js_wrapper_object_set(int p_id, const char *p_name, int p_type, godot_js_wrapper_ex *p_val); +extern void godot_js_wrapper_object_unref(int p_id); +extern int godot_js_wrapper_create_cb(void *p_ref, void (*p_callback)(void *p_ref, int p_arg_id, int p_argc)); +extern int godot_js_wrapper_create_object(const char *p_method, void **p_args, int p_argc, GodotJSWrapperVariant2JSCallback p_variant2js_callback, godot_js_wrapper_ex *p_cb_rval, void **p_lock, GodotJSWrapperFreeLockCallback p_lock_callback); +}; + +class JavaScriptObjectImpl : public JavaScriptObject { +private: + friend class JavaScript; + + int _js_id = 0; + Callable _callable; + + static int _variant2js(const void **p_args, int p_pos, godot_js_wrapper_ex *r_val, void **p_lock); + static void _free_lock(void **p_lock, int p_type); + static Variant _js2variant(int p_type, godot_js_wrapper_ex *p_val); + static void *_alloc_variants(int p_size); + static void _callback(void *p_ref, int p_arg_id, int p_argc); + +protected: + bool _set(const StringName &p_name, const Variant &p_value) override; + bool _get(const StringName &p_name, Variant &r_ret) const override; + void _get_property_list(List<PropertyInfo> *p_list) const override; + +public: + Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const override; + void setvar(const Variant &p_key, const Variant &p_value, bool *r_valid = nullptr) override; + Variant call(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) override; + JavaScriptObjectImpl() {} + JavaScriptObjectImpl(int p_id) { _js_id = p_id; } + ~JavaScriptObjectImpl() { + if (_js_id) { + godot_js_wrapper_object_unref(_js_id); + } + } +}; + +bool JavaScriptObjectImpl::_set(const StringName &p_name, const Variant &p_value) { + ERR_FAIL_COND_V_MSG(!_js_id, false, "Invalid JS instance"); + const String name = p_name; + godot_js_wrapper_ex exchange; + void *lock = nullptr; + const Variant *v = &p_value; + int type = _variant2js((const void **)&v, 0, &exchange, &lock); + godot_js_wrapper_object_set(_js_id, name.utf8().get_data(), type, &exchange); + if (lock) { + _free_lock(&lock, type); + } + return true; +} + +bool JavaScriptObjectImpl::_get(const StringName &p_name, Variant &r_ret) const { + ERR_FAIL_COND_V_MSG(!_js_id, false, "Invalid JS instance"); + const String name = p_name; + godot_js_wrapper_ex exchange; + int type = godot_js_wrapper_object_get(_js_id, &exchange, name.utf8().get_data()); + r_ret = _js2variant(type, &exchange); + return true; +} + +Variant JavaScriptObjectImpl::getvar(const Variant &p_key, bool *r_valid) const { + if (r_valid) { + *r_valid = false; + } + godot_js_wrapper_ex exchange; + void *lock = nullptr; + const Variant *v = &p_key; + int prop_type = _variant2js((const void **)&v, 0, &exchange, &lock); + int type = godot_js_wrapper_object_getvar(_js_id, prop_type, &exchange); + if (lock) { + _free_lock(&lock, prop_type); + } + if (type < 0) { + return Variant(); + } + if (r_valid) { + *r_valid = true; + } + return _js2variant(type, &exchange); +} + +void JavaScriptObjectImpl::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid) { + if (r_valid) { + *r_valid = false; + } + godot_js_wrapper_ex kex, vex; + void *klock = nullptr; + void *vlock = nullptr; + const Variant *kv = &p_key; + const Variant *vv = &p_value; + int ktype = _variant2js((const void **)&kv, 0, &kex, &klock); + int vtype = _variant2js((const void **)&vv, 0, &vex, &vlock); + int ret = godot_js_wrapper_object_setvar(_js_id, ktype, &kex, vtype, &vex); + if (klock) { + _free_lock(&klock, ktype); + } + if (vlock) { + _free_lock(&vlock, vtype); + } + if (ret == 0 && r_valid) { + *r_valid = true; + } +} + +void JavaScriptObjectImpl::_get_property_list(List<PropertyInfo> *p_list) const { +} + +void JavaScriptObjectImpl::_free_lock(void **p_lock, int p_type) { + ERR_FAIL_COND_MSG(*p_lock == nullptr, "No lock to free!"); + const Variant::Type type = (Variant::Type)p_type; + switch (type) { + case Variant::STRING: { + CharString *cs = (CharString *)(*p_lock); + memdelete(cs); + *p_lock = nullptr; + } break; + default: + ERR_FAIL_MSG("Unknown lock type to free. Likely a bug."); + } +} + +Variant JavaScriptObjectImpl::_js2variant(int p_type, godot_js_wrapper_ex *p_val) { + Variant::Type type = (Variant::Type)p_type; + switch (type) { + case Variant::BOOL: + return Variant((bool)p_val->i); + case Variant::INT: + return p_val->i; + case Variant::FLOAT: + return p_val->r; + case Variant::STRING: { + String out((const char *)p_val->p); + free(p_val->p); + return out; + } + case Variant::OBJECT: { + return memnew(JavaScriptObjectImpl(p_val->i)); + } + default: + return Variant(); + } +} + +int JavaScriptObjectImpl::_variant2js(const void **p_args, int p_pos, godot_js_wrapper_ex *r_val, void **p_lock) { + const Variant **args = (const Variant **)p_args; + const Variant *v = args[p_pos]; + Variant::Type type = v->get_type(); + switch (type) { + case Variant::BOOL: + r_val->i = v->operator bool() ? 1 : 0; + break; + case Variant::INT: { + const int64_t tmp = v->operator int64_t(); + if (tmp >= 1 << 31) { + r_val->r = (double)tmp; + return Variant::FLOAT; + } + r_val->i = v->operator int64_t(); + } break; + case Variant::FLOAT: + r_val->r = v->operator real_t(); + break; + case Variant::STRING: { + CharString *cs = memnew(CharString(v->operator String().utf8())); + r_val->p = (void *)cs->get_data(); + *p_lock = (void *)cs; + } break; + case Variant::OBJECT: { + JavaScriptObject *js_obj = Object::cast_to<JavaScriptObject>(v->operator Object *()); + r_val->i = js_obj != nullptr ? ((JavaScriptObjectImpl *)js_obj)->_js_id : 0; + } break; + default: + break; + } + return type; +} + +Variant JavaScriptObjectImpl::call(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) { + godot_js_wrapper_ex exchange; + const String method = p_method; + void *lock = nullptr; + const int type = godot_js_wrapper_object_call(_js_id, method.utf8().get_data(), (void **)p_args, p_argc, &_variant2js, &exchange, &lock, &_free_lock); + r_error.error = Callable::CallError::CALL_OK; + if (type < 0) { + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return Variant(); + } + return _js2variant(type, &exchange); +} + +void JavaScriptObjectImpl::_callback(void *p_ref, int p_args_id, int p_argc) { + const JavaScriptObjectImpl *obj = (JavaScriptObjectImpl *)p_ref; + ERR_FAIL_COND_MSG(obj->_callable.is_null(), "JavaScript callback failed."); + Vector<const Variant *> argp; + Array arg_arr; + for (int i = 0; i < p_argc; i++) { + godot_js_wrapper_ex exchange; + exchange.i = i; + int type = godot_js_wrapper_object_getvar(p_args_id, Variant::INT, &exchange); + arg_arr.push_back(_js2variant(type, &exchange)); + } + Variant arg = arg_arr; + const Variant *argv[1] = { &arg }; + Callable::CallError err; + Variant ret; + obj->_callable.call(argv, 1, ret, err); +} + +Ref<JavaScriptObject> JavaScript::create_callback(const Callable &p_callable) { + Ref<JavaScriptObjectImpl> out = memnew(JavaScriptObjectImpl); + out->_callable = p_callable; + out->_js_id = godot_js_wrapper_create_cb(out.ptr(), JavaScriptObjectImpl::_callback); + return out; +} + +Ref<JavaScriptObject> JavaScript::get_interface(const String &p_interface) { + int js_id = godot_js_wrapper_interface_get(p_interface.utf8().get_data()); + ERR_FAIL_COND_V_MSG(!js_id, Ref<JavaScriptObject>(), "No interface '" + p_interface + "' registered."); + return Ref<JavaScriptObject>(memnew(JavaScriptObjectImpl(js_id))); +} + +Variant JavaScript::_create_object_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + if (p_argcount < 1) { + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = 0; + return Ref<JavaScriptObject>(); + } + if (p_args[0]->get_type() != Variant::STRING) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::STRING; + return Ref<JavaScriptObject>(); + } + godot_js_wrapper_ex exchange; + const String object = *p_args[0]; + void *lock = nullptr; + const Variant **args = p_argcount > 1 ? &p_args[1] : nullptr; + const int type = godot_js_wrapper_create_object(object.utf8().get_data(), (void **)args, p_argcount - 1, &JavaScriptObjectImpl::_variant2js, &exchange, &lock, &JavaScriptObjectImpl::_free_lock); + r_error.error = Callable::CallError::CALL_OK; + if (type < 0) { + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return Ref<JavaScriptObject>(); + } + return JavaScriptObjectImpl::_js2variant(type, &exchange); +} + +extern "C" { +union js_eval_ret { + uint32_t b; + double d; + char *s; +}; + +extern int godot_js_eval(const char *p_js, int p_use_global_ctx, union js_eval_ret *p_union_ptr, void *p_byte_arr, void *p_byte_arr_write, void *(*p_callback)(void *p_ptr, void *p_ptr2, int p_len)); +extern int godot_js_os_download_buffer(const uint8_t *p_buf, int p_buf_size, const char *p_name, const char *p_mime); +} + +void *resize_PackedByteArray_and_open_write(void *p_arr, void *r_write, int p_len) { + PackedByteArray *arr = (PackedByteArray *)p_arr; + VectorWriteProxy<uint8_t> *write = (VectorWriteProxy<uint8_t> *)r_write; + arr->resize(p_len); + *write = arr->write; + return arr->ptrw(); +} + +Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { + union js_eval_ret js_data; + PackedByteArray arr; + VectorWriteProxy<uint8_t> arr_write; + + Variant::Type return_type = static_cast<Variant::Type>(godot_js_eval(p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write, resize_PackedByteArray_and_open_write)); + + switch (return_type) { + case Variant::BOOL: + return js_data.b; + case Variant::FLOAT: + return js_data.d; + case Variant::STRING: { + String str = String::utf8(js_data.s); + free(js_data.s); // Must free the string allocated in JS. + return str; + } + case Variant::PACKED_BYTE_ARRAY: + arr_write = VectorWriteProxy<uint8_t>(); + return arr; + default: + return Variant(); + } +} +#endif // JAVASCRIPT_EVAL_ENABLED + +void JavaScript::download_buffer(Vector<uint8_t> p_arr, const String &p_name, const String &p_mime) { + godot_js_os_download_buffer(p_arr.ptr(), p_arr.size(), p_name.utf8().get_data(), p_mime.utf8().get_data()); +} diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js index ac4055516c..45c3a3fe2e 100644 --- a/platform/javascript/js/libs/library_godot_audio.js +++ b/platform/javascript/js/libs/library_godot_audio.js @@ -59,7 +59,7 @@ const GodotAudio = { } onstatechange(state); }; - ctx.onstatechange(); // Immeditately notify state. + ctx.onstatechange(); // Immediately notify state. // Update computed latency GodotAudio.interval = setInterval(function () { let computed_latency = 0; diff --git a/platform/javascript/js/libs/library_godot_eval.js b/platform/javascript/js/libs/library_godot_eval.js deleted file mode 100644 index 9ab392b813..0000000000 --- a/platform/javascript/js/libs/library_godot_eval.js +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************/ -/* library_godot_eval.js */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -const GodotEval = { - godot_js_eval__deps: ['$GodotRuntime'], - godot_js_eval__sig: 'iiiiiii', - godot_js_eval: function (p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) { - const js_code = GodotRuntime.parseString(p_js); - let eval_ret = null; - try { - if (p_use_global_ctx) { - // indirect eval call grants global execution context - const global_eval = eval; // eslint-disable-line no-eval - eval_ret = global_eval(js_code); - } else { - eval_ret = eval(js_code); // eslint-disable-line no-eval - } - } catch (e) { - GodotRuntime.error(e); - } - - switch (typeof eval_ret) { - case 'boolean': - GodotRuntime.setHeapValue(p_union_ptr, eval_ret, 'i32'); - return 1; // BOOL - - case 'number': - GodotRuntime.setHeapValue(p_union_ptr, eval_ret, 'double'); - return 3; // REAL - - case 'string': - GodotRuntime.setHeapValue(p_union_ptr, GodotRuntime.allocString(eval_ret), '*'); - return 4; // STRING - - case 'object': - if (eval_ret === null) { - break; - } - - if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) { - eval_ret = new Uint8Array(eval_ret.buffer); - } else if (eval_ret instanceof ArrayBuffer) { - eval_ret = new Uint8Array(eval_ret); - } - if (eval_ret instanceof Uint8Array) { - const func = GodotRuntime.get_func(p_callback); - const bytes_ptr = func(p_byte_arr, p_byte_arr_write, eval_ret.length); - HEAPU8.set(eval_ret, bytes_ptr); - return 20; // POOL_BYTE_ARRAY - } - break; - - // no default - } - return 0; // NIL - }, -}; - -mergeInto(LibraryManager.library, GodotEval); diff --git a/platform/javascript/js/libs/library_godot_javascript_singleton.js b/platform/javascript/js/libs/library_godot_javascript_singleton.js new file mode 100644 index 0000000000..09ef4a1a5d --- /dev/null +++ b/platform/javascript/js/libs/library_godot_javascript_singleton.js @@ -0,0 +1,333 @@ +/*************************************************************************/ +/* library_godot_eval.js */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +const GodotJSWrapper = { + + $GodotJSWrapper__deps: ['$GodotRuntime', '$IDHandler'], + $GodotJSWrapper__postset: 'GodotJSWrapper.proxies = new Map();', + $GodotJSWrapper: { + proxies: null, + + MyProxy: function (val) { + const id = IDHandler.add(this); + GodotJSWrapper.proxies.set(val, id); + let refs = 1; + this.ref = function () { + refs++; + }; + this.unref = function () { + refs--; + if (refs === 0) { + IDHandler.remove(id); + GodotJSWrapper.proxies.delete(val); + } + }; + this.get_val = function () { + return val; + }; + this.get_id = function () { + return id; + }; + }, + + get_proxied: function (val) { + const id = GodotJSWrapper.proxies.get(val); + if (id === undefined) { + const proxy = new GodotJSWrapper.MyProxy(val); + return proxy.get_id(); + } + IDHandler.get(id).ref(); + return id; + }, + + get_proxied_value: function (id) { + const proxy = IDHandler.get(id); + if (proxy === undefined) { + return undefined; + } + return proxy.get_val(); + }, + + variant2js: function (type, val) { + switch (type) { + case 0: + return null; + case 1: + return !!GodotRuntime.getHeapValue(val, 'i64'); + case 2: + return GodotRuntime.getHeapValue(val, 'i64'); + case 3: + return GodotRuntime.getHeapValue(val, 'double'); + case 4: + return GodotRuntime.parseString(GodotRuntime.getHeapValue(val, '*')); + case 21: // OBJECT + return GodotJSWrapper.get_proxied_value(GodotRuntime.getHeapValue(val, 'i64')); + default: + return undefined; + } + }, + + js2variant: function (p_val, p_exchange) { + if (p_val === undefined || p_val === null) { + return 0; // NIL + } + const type = typeof (p_val); + if (type === 'boolean') { + GodotRuntime.setHeapValue(p_exchange, p_val, 'i64'); + return 1; // BOOL + } else if (type === 'number') { + if (Number.isInteger(p_val)) { + GodotRuntime.setHeapValue(p_exchange, p_val, 'i64'); + return 2; // INT + } + GodotRuntime.setHeapValue(p_exchange, p_val, 'double'); + return 3; // REAL + } else if (type === 'string') { + const c_str = GodotRuntime.allocString(p_val); + GodotRuntime.setHeapValue(p_exchange, c_str, '*'); + return 4; // STRING + } + const id = GodotJSWrapper.get_proxied(p_val); + GodotRuntime.setHeapValue(p_exchange, id, 'i64'); + return 21; + }, + }, + + godot_js_wrapper_interface_get__sig: 'ii', + godot_js_wrapper_interface_get: function (p_name) { + const name = GodotRuntime.parseString(p_name); + if (typeof (window[name]) !== 'undefined') { + return GodotJSWrapper.get_proxied(window[name]); + } + return 0; + }, + + godot_js_wrapper_object_get__sig: 'iiii', + godot_js_wrapper_object_get: function (p_id, p_exchange, p_prop) { + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return 0; + } + if (p_prop) { + const prop = GodotRuntime.parseString(p_prop); + try { + return GodotJSWrapper.js2variant(obj[prop], p_exchange); + } catch (e) { + GodotRuntime.error(`Error getting variable ${prop} on object`, obj); + return 0; // NIL + } + } + return GodotJSWrapper.js2variant(obj, p_exchange); + }, + + godot_js_wrapper_object_set__sig: 'viiii', + godot_js_wrapper_object_set: function (p_id, p_name, p_type, p_exchange) { + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return; + } + const name = GodotRuntime.parseString(p_name); + try { + obj[name] = GodotJSWrapper.variant2js(p_type, p_exchange); + } catch (e) { + GodotRuntime.error(`Error setting variable ${name} on object`, obj); + } + }, + + godot_js_wrapper_object_call__sig: 'iiiiiiiii', + godot_js_wrapper_object_call: function (p_id, p_method, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return -1; + } + const method = GodotRuntime.parseString(p_method); + const convert = GodotRuntime.get_func(p_convert_callback); + const freeLock = GodotRuntime.get_func(p_free_lock_callback); + const args = new Array(p_argc); + for (let i = 0; i < p_argc; i++) { + const type = convert(p_args, i, p_exchange, p_lock); + const lock = GodotRuntime.getHeapValue(p_lock, '*'); + args[i] = GodotJSWrapper.variant2js(type, p_exchange); + if (lock) { + freeLock(p_lock, type); + } + } + try { + const res = obj[method](...args); + return GodotJSWrapper.js2variant(res, p_exchange); + } catch (e) { + GodotRuntime.error(`Error calling method ${method} on:`, obj, 'error:', e); + return -1; + } + }, + + godot_js_wrapper_object_unref__sig: 'vi', + godot_js_wrapper_object_unref: function (p_id) { + const proxy = IDHandler.get(p_id); + if (proxy !== undefined) { + proxy.unref(); + } + }, + + godot_js_wrapper_create_cb__sig: 'vii', + godot_js_wrapper_create_cb: function (p_ref, p_func) { + const func = GodotRuntime.get_func(p_func); + let id = 0; + const cb = function () { + if (!GodotJSWrapper.get_proxied_value(id)) { + return; + } + const args = Array.from(arguments); + func(p_ref, GodotJSWrapper.get_proxied(args), args.length); + }; + id = GodotJSWrapper.get_proxied(cb); + return id; + }, + + godot_js_wrapper_object_getvar__sig: 'iiii', + godot_js_wrapper_object_getvar: function (p_id, p_type, p_exchange) { + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return -1; + } + const prop = GodotJSWrapper.variant2js(p_type, p_exchange); + if (prop === undefined || prop === null) { + return -1; + } + try { + return GodotJSWrapper.js2variant(obj[prop], p_exchange); + } catch (e) { + GodotRuntime.error(`Error getting variable ${prop} on object`, obj, e); + return -1; + } + }, + + godot_js_wrapper_object_setvar__sig: 'iiiiii', + godot_js_wrapper_object_setvar: function (p_id, p_key_type, p_key_ex, p_val_type, p_val_ex) { + const obj = GodotJSWrapper.get_proxied_value(p_id); + if (obj === undefined) { + return -1; + } + const key = GodotJSWrapper.variant2js(p_key_type, p_key_ex); + try { + obj[key] = GodotJSWrapper.variant2js(p_val_type, p_val_ex); + return 0; + } catch (e) { + GodotRuntime.error(`Error setting variable ${key} on object`, obj); + return -1; + } + }, + + godot_js_wrapper_create_object__sig: 'iiiiiiii', + godot_js_wrapper_create_object: function (p_object, p_args, p_argc, p_convert_callback, p_exchange, p_lock, p_free_lock_callback) { + const name = GodotRuntime.parseString(p_object); + if (typeof (window[name]) === 'undefined') { + return -1; + } + const convert = GodotRuntime.get_func(p_convert_callback); + const freeLock = GodotRuntime.get_func(p_free_lock_callback); + const args = new Array(p_argc); + for (let i = 0; i < p_argc; i++) { + const type = convert(p_args, i, p_exchange, p_lock); + const lock = GodotRuntime.getHeapValue(p_lock, '*'); + args[i] = GodotJSWrapper.variant2js(type, p_exchange); + if (lock) { + freeLock(p_lock, type); + } + } + try { + const res = new window[name](...args); + return GodotJSWrapper.js2variant(res, p_exchange); + } catch (e) { + GodotRuntime.error(`Error calling constructor ${name} with args:`, args, 'error:', e); + return -1; + } + }, +}; + +autoAddDeps(GodotJSWrapper, '$GodotJSWrapper'); +mergeInto(LibraryManager.library, GodotJSWrapper); + +const GodotEval = { + godot_js_eval__deps: ['$GodotRuntime'], + godot_js_eval__sig: 'iiiiiii', + godot_js_eval: function (p_js, p_use_global_ctx, p_union_ptr, p_byte_arr, p_byte_arr_write, p_callback) { + const js_code = GodotRuntime.parseString(p_js); + let eval_ret = null; + try { + if (p_use_global_ctx) { + // indirect eval call grants global execution context + const global_eval = eval; // eslint-disable-line no-eval + eval_ret = global_eval(js_code); + } else { + eval_ret = eval(js_code); // eslint-disable-line no-eval + } + } catch (e) { + GodotRuntime.error(e); + } + + switch (typeof eval_ret) { + case 'boolean': + GodotRuntime.setHeapValue(p_union_ptr, eval_ret, 'i32'); + return 1; // BOOL + + case 'number': + GodotRuntime.setHeapValue(p_union_ptr, eval_ret, 'double'); + return 3; // REAL + + case 'string': + GodotRuntime.setHeapValue(p_union_ptr, GodotRuntime.allocString(eval_ret), '*'); + return 4; // STRING + + case 'object': + if (eval_ret === null) { + break; + } + + if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) { + eval_ret = new Uint8Array(eval_ret.buffer); + } else if (eval_ret instanceof ArrayBuffer) { + eval_ret = new Uint8Array(eval_ret); + } + if (eval_ret instanceof Uint8Array) { + const func = GodotRuntime.get_func(p_callback); + const bytes_ptr = func(p_byte_arr, p_byte_arr_write, eval_ret.length); + HEAPU8.set(eval_ret, bytes_ptr); + return 20; // POOL_BYTE_ARRAY + } + break; + + // no default + } + return 0; // NIL + }, +}; + +mergeInto(LibraryManager.library, GodotEval); diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js index 1d9f889bce..7414b8cc47 100644 --- a/platform/javascript/js/libs/library_godot_os.js +++ b/platform/javascript/js/libs/library_godot_os.js @@ -304,6 +304,23 @@ const GodotOS = { godot_js_os_hw_concurrency_get: function () { return navigator.hardwareConcurrency || 1; }, + + godot_js_os_download_buffer__sig: 'viiii', + godot_js_os_download_buffer: function (p_ptr, p_size, p_name, p_mime) { + const buf = GodotRuntime.heapSlice(HEAP8, p_ptr, p_size); + const name = GodotRuntime.parseString(p_name); + const mime = GodotRuntime.parseString(p_mime); + const blob = new Blob([buf], { type: mime }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = name; + a.style.display = 'none'; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }, }; autoAddDeps(GodotOS, '$GodotOS'); diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json index b8c434b3dd..8bf5c52ff6 100644 --- a/platform/javascript/package-lock.json +++ b/platform/javascript/package-lock.json @@ -44,9 +44,9 @@ } }, "@babel/parser": { - "version": "7.13.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.4.tgz", - "integrity": "sha512-uvoOulWHhI+0+1f9L4BoozY7U5cIkZ9PgJqvb041d6vypgUmtVPG4vmGm4pSggjl8BELzvHyUeJSUyEMY6b+qA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", "dev": true }, "@eslint/eslintrc": { @@ -812,9 +812,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "ignore": { @@ -962,9 +962,8 @@ } }, "jsdoc": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz", - "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==", + "version": "github:jsdoc/jsdoc#544a992824631fc652183d8b0b4b1281dc961560", + "from": "github:jsdoc/jsdoc#544a992824631fc652183d8b0b4b1281dc961560", "dev": true, "requires": { "@babel/parser": "^7.9.4", @@ -975,12 +974,12 @@ "klaw": "^3.0.0", "markdown-it": "^10.0.0", "markdown-it-anchor": "^5.2.7", - "marked": "^0.8.2", + "marked": "^2.0.3", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", - "underscore": "~1.10.2" + "underscore": "~1.12.1" }, "dependencies": { "escape-string-regexp": { @@ -1069,9 +1068,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "markdown-it": { @@ -1094,9 +1093,9 @@ "dev": true }, "marked": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", - "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz", + "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==", "dev": true }, "mdurl": { @@ -1689,9 +1688,9 @@ "dev": true }, "underscore": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", - "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", "dev": true }, "uri-js": { diff --git a/platform/javascript/package.json b/platform/javascript/package.json index d9d272923e..53748503f9 100644 --- a/platform/javascript/package.json +++ b/platform/javascript/package.json @@ -23,6 +23,6 @@ "eslint": "^7.9.0", "eslint-config-airbnb-base": "^14.2.0", "eslint-plugin-import": "^2.22.0", - "jsdoc": "^3.6.6" + "jsdoc": "github:jsdoc/jsdoc#544a992824631fc652183d8b0b4b1281dc961560" } } diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 1876960c57..ee59537ee0 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -363,6 +363,7 @@ def configure(env): env.Prepend(CPPPATH=["#platform/linuxbsd"]) env.Append(CPPDEFINES=["X11_ENABLED", "UNIX_ENABLED"]) + env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)]) env.Append(CPPDEFINES=["VULKAN_ENABLED"]) if not env["builtin_vulkan"]: diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index be69b2e5da..b50b5f3479 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2166,10 +2166,10 @@ static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p } void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) { - state->set_shift((p_x11_state & ShiftMask)); - state->set_control((p_x11_state & ControlMask)); - state->set_alt((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt - state->set_metakey((p_x11_state & Mod4Mask)); + state->set_shift_pressed((p_x11_state & ShiftMask)); + state->set_ctrl_pressed((p_x11_state & ControlMask)); + state->set_alt_pressed((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt + state->set_meta_pressed((p_x11_state & Mod4Mask)); } unsigned int DisplayServerX11::_get_mouse_button_state(unsigned int p_x11_button, int p_x11_type) { @@ -2281,7 +2281,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, //make it consistent across platforms. k->set_keycode(KEY_TAB); k->set_physical_keycode(KEY_TAB); - k->set_shift(true); + k->set_shift_pressed(true); } Input::get_singleton()->accumulate_input_event(k); @@ -2409,20 +2409,20 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, //make it consistent across platforms. k->set_keycode(KEY_TAB); k->set_physical_keycode(KEY_TAB); - k->set_shift(true); + k->set_shift_pressed(true); } //don't set mod state if modifier keys are released by themselves //else event.is_action() will not work correctly here if (!k->is_pressed()) { if (k->get_keycode() == KEY_SHIFT) { - k->set_shift(false); - } else if (k->get_keycode() == KEY_CONTROL) { - k->set_control(false); + k->set_shift_pressed(false); + } else if (k->get_keycode() == KEY_CTRL) { + k->set_ctrl_pressed(false); } else if (k->get_keycode() == KEY_ALT) { - k->set_alt(false); + k->set_alt_pressed(false); } else if (k->get_keycode() == KEY_META) { - k->set_metakey(false); + k->set_meta_pressed(false); } } diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp index f9f612fa74..74257a7e61 100644 --- a/platform/linuxbsd/key_mapping_x11.cpp +++ b/platform/linuxbsd/key_mapping_x11.cpp @@ -61,8 +61,8 @@ static _XTranslatePair _xkeysym_to_keycode[] = { { XK_Shift_L, KEY_SHIFT }, { XK_Shift_R, KEY_SHIFT }, { XK_Shift_Lock, KEY_SHIFT }, - { XK_Control_L, KEY_CONTROL }, - { XK_Control_R, KEY_CONTROL }, + { XK_Control_L, KEY_CTRL }, + { XK_Control_R, KEY_CTRL }, { XK_Meta_L, KEY_META }, { XK_Meta_R, KEY_META }, { XK_Alt_L, KEY_ALT }, @@ -213,7 +213,7 @@ static _TranslatePair _scancode_to_keycode[] = { { KEY_BRACELEFT, 0x22 }, { KEY_BRACERIGHT, 0x23 }, { KEY_ENTER, 0x24 }, - { KEY_CONTROL, 0x25 }, + { KEY_CTRL, 0x25 }, { KEY_A, 0x26 }, { KEY_S, 0x27 }, { KEY_D, 0x28 }, @@ -272,7 +272,7 @@ static _TranslatePair _scancode_to_keycode[] = { { KEY_F11, 0x5F }, { KEY_F12, 0x60 }, { KEY_KP_ENTER, 0x68 }, - { KEY_CONTROL, 0x69 }, + { KEY_CTRL, 0x69 }, { KEY_KP_DIVIDE, 0x6A }, { KEY_PRINT, 0x6B }, { KEY_ALT, 0x6C }, diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 09e1f9461c..23e448fbd7 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -116,6 +116,8 @@ String OS_LinuxBSD::get_name() const { return "FreeBSD"; #elif defined(__NetBSD__) return "NetBSD"; +#elif defined(__OpenBSD__) + return "OpenBSD"; #else return "BSD"; #endif @@ -164,7 +166,12 @@ bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) { String OS_LinuxBSD::get_config_path() const { if (has_environment("XDG_CONFIG_HOME")) { - return get_environment("XDG_CONFIG_HOME"); + if (get_environment("XDG_CONFIG_HOME").is_abs_path()) { + return get_environment("XDG_CONFIG_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.config` or `.` per the XDG Base Directory specification."); + return has_environment("HOME") ? get_environment("HOME").plus_file(".config") : "."; + } } else if (has_environment("HOME")) { return get_environment("HOME").plus_file(".config"); } else { @@ -174,7 +181,12 @@ String OS_LinuxBSD::get_config_path() const { String OS_LinuxBSD::get_data_path() const { if (has_environment("XDG_DATA_HOME")) { - return get_environment("XDG_DATA_HOME"); + if (get_environment("XDG_DATA_HOME").is_abs_path()) { + return get_environment("XDG_DATA_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.local/share` or `get_config_path()` per the XDG Base Directory specification."); + return has_environment("HOME") ? get_environment("HOME").plus_file(".local/share") : get_config_path(); + } } else if (has_environment("HOME")) { return get_environment("HOME").plus_file(".local/share"); } else { @@ -184,7 +196,12 @@ String OS_LinuxBSD::get_data_path() const { String OS_LinuxBSD::get_cache_path() const { if (has_environment("XDG_CACHE_HOME")) { - return get_environment("XDG_CACHE_HOME"); + if (get_environment("XDG_CACHE_HOME").is_abs_path()) { + return get_environment("XDG_CACHE_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.cache` or `get_config_path()` per the XDG Base Directory specification."); + return has_environment("HOME") ? get_environment("HOME").plus_file(".cache") : get_config_path(); + } } else if (has_environment("HOME")) { return get_environment("HOME").plus_file(".cache"); } else { diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 473ae95036..f53b60891f 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -66,10 +66,10 @@ static bool ignore_momentum_scroll = false; static void _get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) { - r_state->set_shift((p_osx_state & NSEventModifierFlagShift)); - r_state->set_control((p_osx_state & NSEventModifierFlagControl)); - r_state->set_alt((p_osx_state & NSEventModifierFlagOption)); - r_state->set_metakey((p_osx_state & NSEventModifierFlagCommand)); + r_state->set_shift_pressed((p_osx_state & NSEventModifierFlagShift)); + r_state->set_ctrl_pressed((p_osx_state & NSEventModifierFlagControl)); + r_state->set_alt_pressed((p_osx_state & NSEventModifierFlagOption)); + r_state->set_meta_pressed((p_osx_state & NSEventModifierFlagCommand)); } static Vector2i _get_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_locationInWindow) { @@ -368,6 +368,10 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { if (wd.resize_disabled) { [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; } + + if (wd.on_top) { + [wd.window_object setLevel:NSFloatingWindowLevel]; + } } - (void)windowDidChangeBackingProperties:(NSNotification *)notification { @@ -1133,10 +1137,10 @@ static int translateKey(unsigned int key) { /* 38 */ KEY_SHIFT, /* 39 */ KEY_CAPSLOCK, /* 3a */ KEY_ALT, - /* 3b */ KEY_CONTROL, + /* 3b */ KEY_CTRL, /* 3c */ KEY_SHIFT, /* 3d */ KEY_ALT, - /* 3e */ KEY_CONTROL, + /* 3e */ KEY_CTRL, /* 3f */ KEY_UNKNOWN, /* Function */ /* 40 */ KEY_UNKNOWN, /* F17 */ /* 41 */ KEY_KP_PERIOD, @@ -2437,7 +2441,7 @@ void DisplayServerOSX::_update_window(WindowData p_wd) { [p_wd.window_object setHidesOnDeactivate:YES]; } else { // Reset these when our window is not a borderless window that covers up the screen - if (p_wd.on_top) { + if (p_wd.on_top && !p_wd.fullscreen) { [p_wd.window_object setLevel:NSFloatingWindowLevel]; } else { [p_wd.window_object setLevel:NSNormalWindowLevel]; @@ -2786,6 +2790,7 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { [wd.window_object deminiaturize:nil]; } break; case WINDOW_MODE_FULLSCREEN: { + [wd.window_object setLevel:NSNormalWindowLevel]; if (wd.layered_window) { _set_window_per_pixel_transparency_enabled(true, p_window); } @@ -2903,6 +2908,9 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } break; case WINDOW_FLAG_ALWAYS_ON_TOP: { wd.on_top = p_enabled; + if (wd.fullscreen) { + return; + } if (p_enabled) { [wd.window_object setLevel:NSFloatingWindowLevel]; } else { @@ -2940,7 +2948,11 @@ bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) co return [wd.window_object styleMask] == NSWindowStyleMaskBorderless; } break; case WINDOW_FLAG_ALWAYS_ON_TOP: { - return [wd.window_object level] == NSFloatingWindowLevel; + if (wd.fullscreen) { + return wd.on_top; + } else { + return [wd.window_object level] == NSFloatingWindowLevel; + } } break; case WINDOW_FLAG_TRANSPARENT: { return wd.layered_window; @@ -3467,7 +3479,7 @@ void DisplayServerOSX::set_native_icon(const String &p_filename) { ERR_FAIL_COND(!f); Vector<uint8_t> data; - uint32_t len = f->get_len(); + uint64_t len = f->get_length(); data.resize(len); f->get_buffer((uint8_t *)&data.write[0], len); memdelete(f); diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 51204bc8f6..6d995412ab 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -301,7 +301,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ if (icon_infos[i].is_png) { // Encode PNG icon. it->create_from_image(copy); - String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png"); + String path = EditorPaths::get_singleton()->get_cache_dir().plus_file("icon.png"); ResourceSaver::save(path, it); FileAccess *f = FileAccess::open(path, FileAccess::READ); @@ -312,7 +312,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ } int ofs = data.size(); - uint32_t len = f->get_len(); + uint64_t len = f->get_length(); data.resize(data.size() + len + 8); f->get_buffer(&data.write[ofs + 8], len); memdelete(f); @@ -610,7 +610,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p // Create our application bundle. String tmp_app_dir_name = pkg_name + ".app"; - String tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(tmp_app_dir_name); + String tmp_app_path_name = EditorPaths::get_singleton()->get_cache_dir().plus_file(tmp_app_dir_name); print_line("Exporting to " + tmp_app_path_name); Error err = OK; @@ -689,8 +689,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (iconpath.get_extension() == "icns") { FileAccess *icon = FileAccess::open(iconpath, FileAccess::READ); if (icon) { - data.resize(icon->get_len()); - icon->get_buffer(&data.write[0], icon->get_len()); + data.resize(icon->get_length()); + icon->get_buffer(&data.write[0], icon->get_length()); icon->close(); memdelete(icon); } @@ -774,7 +774,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p String ent_path = p_preset->get("codesign/entitlements/custom_file"); if (sign_enabled && (ent_path == "")) { - ent_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".entitlements"); + ent_path = EditorPaths::get_singleton()->get_cache_dir().plus_file(pkg_name + ".entitlements"); FileAccess *ent_f = FileAccess::open(ent_path, FileAccess::WRITE); if (ent_f) { @@ -894,9 +894,22 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (err == OK) { DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < shared_objects.size(); i++) { - err = da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); + String src_path = ProjectSettings::get_singleton()->globalize_path(shared_objects[i].path); + if (da->dir_exists(src_path)) { +#ifndef UNIX_ENABLED + WARN_PRINT("Relative symlinks are not supported, exported " + src_path.get_file() + " might be broken!"); +#endif + print_verbose("export framework: " + src_path + " -> " + tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file()); + err = da->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file()); + if (err == OK) { + err = da->copy_dir(src_path, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), -1, true); + } + } else { + print_verbose("export dylib: " + src_path + " -> " + tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file()); + err = da->copy(src_path, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file()); + } if (err == OK && sign_enabled) { - err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file(), ent_path); + err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), ent_path); } } memdelete(da); @@ -946,7 +959,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p zlib_filefunc_def io_dst = zipio_create_io_from_file(&dst_f); zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io_dst); - _zip_folder_recursive(zip, EditorSettings::get_singleton()->get_cache_dir(), pkg_name + ".app", pkg_name); + _zip_folder_recursive(zip, EditorPaths::get_singleton()->get_cache_dir(), pkg_name + ".app", pkg_name); zipClose(zip, nullptr); } @@ -980,7 +993,48 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String if (f == "." || f == "..") { continue; } - if (da->current_is_dir()) { + if (da->is_link(f)) { + OS::Time time = OS::get_singleton()->get_time(); + OS::Date date = OS::get_singleton()->get_date(); + + zip_fileinfo zipfi; + zipfi.tmz_date.tm_hour = time.hour; + zipfi.tmz_date.tm_mday = date.day; + zipfi.tmz_date.tm_min = time.min; + zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, http://www.cplusplus.com/reference/ctime/tm/ + zipfi.tmz_date.tm_sec = time.sec; + zipfi.tmz_date.tm_year = date.year; + zipfi.dosDate = 0; + // 0120000: symbolic link type + // 0000755: permissions rwxr-xr-x + // 0000644: permissions rw-r--r-- + uint32_t _mode = 0120644; + zipfi.external_fa = (_mode << 16L) | !(_mode & 0200); + zipfi.internal_fa = 0; + + zipOpenNewFileInZip4(p_zip, + p_folder.plus_file(f).utf8().get_data(), + &zipfi, + nullptr, + 0, + nullptr, + 0, + nullptr, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION, + 0, + -MAX_WBITS, + DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, + nullptr, + 0, + 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions + 0); + + String target = da->read_link(f); + zipWriteInFileInZip(p_zip, target.utf8().get_data(), target.utf8().size()); + zipCloseFileInZip(p_zip); + } else if (da->current_is_dir()) { _zip_folder_recursive(p_zip, p_root_path, p_folder.plus_file(f), p_pkg_name); } else { bool is_executable = (p_folder.ends_with("MacOS") && (f == p_pkg_name)); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index e6feda5a9b..9e3f0350e9 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -188,31 +188,45 @@ MainLoop *OS_OSX::get_main_loop() const { } String OS_OSX::get_config_path() const { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well. if (has_environment("XDG_CONFIG_HOME")) { - return get_environment("XDG_CONFIG_HOME"); - } else if (has_environment("HOME")) { + if (get_environment("XDG_CONFIG_HOME").is_abs_path()) { + return get_environment("XDG_CONFIG_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Application Support` or `.` per the XDG Base Directory specification."); + } + } + if (has_environment("HOME")) { return get_environment("HOME").plus_file("Library/Application Support"); - } else { - return "."; } + return "."; } String OS_OSX::get_data_path() const { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well. if (has_environment("XDG_DATA_HOME")) { - return get_environment("XDG_DATA_HOME"); - } else { - return get_config_path(); + if (get_environment("XDG_DATA_HOME").is_abs_path()) { + return get_environment("XDG_DATA_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification."); + } } + return get_config_path(); } String OS_OSX::get_cache_path() const { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well. if (has_environment("XDG_CACHE_HOME")) { - return get_environment("XDG_CACHE_HOME"); - } else if (has_environment("HOME")) { + if (get_environment("XDG_CACHE_HOME").is_abs_path()) { + return get_environment("XDG_CACHE_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Libary/Caches` or `get_config_path()` per the XDG Base Directory specification."); + } + } + if (has_environment("HOME")) { return get_environment("HOME").plus_file("Library/Caches"); - } else { - return get_config_path(); } + return get_config_path(); } String OS_OSX::get_bundle_resource_dir() const { diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub index 4358b0eead..71c402358f 100644 --- a/platform/uwp/SCsub +++ b/platform/uwp/SCsub @@ -3,7 +3,6 @@ Import("env") files = [ - "thread_uwp.cpp", "#platform/windows/key_mapping_windows.cpp", "#platform/windows/windows_terminal_logger.cpp", "joypad_uwp.cpp", diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index b7e4361831..9d6ff10483 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -383,7 +383,7 @@ void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Wind ke.type = OS_UWP::KeyEvent::MessageType::KEY_EVENT_MESSAGE; ke.unicode = 0; ke.keycode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey); - ke.physical_keycode = KeyMappingWindows::get_scansym((unsigned int)key_args->KeyStatus.ScanCode); + ke.physical_keycode = KeyMappingWindows::get_scansym((unsigned int)key_args->KeyStatus.ScanCode, key_args->KeyStatus.IsExtendedKey); ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown); } else { diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 217c119978..351aaa5957 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -567,12 +567,12 @@ void AppxPackager::finish() { // Create and add block map file EditorNode::progress_task_step("export", "Creating block map...", 4); - const String &tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); + const String &tmp_blockmap_file_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); make_block_map(tmp_blockmap_file_path); FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ); Vector<uint8_t> blockmap_buffer; - blockmap_buffer.resize(blockmap_file->get_len()); + blockmap_buffer.resize(blockmap_file->get_length()); blockmap_file->get_buffer(blockmap_buffer.ptrw(), blockmap_buffer.size()); @@ -585,12 +585,12 @@ void AppxPackager::finish() { EditorNode::progress_task_step("export", "Setting content types...", 5); - const String &tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); + const String &tmp_content_types_file_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); make_content_types(tmp_content_types_file_path); FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ); Vector<uint8_t> types_buffer; - types_buffer.resize(types_file->get_len()); + types_buffer.resize(types_file->get_length()); types_file->get_buffer(types_buffer.ptrw(), types_buffer.size()); @@ -879,7 +879,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform { return data; } - String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("uwp_tmp_logo.png"); + String tmp_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("uwp_tmp_logo.png"); Error err = texture->get_image()->save_png(tmp_path); @@ -900,7 +900,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform { ERR_FAIL_V_MSG(data, err_string); } - data.resize(f->get_len()); + data.resize(f->get_length()); f->get_buffer(data.ptrw(), data.size()); f->close(); diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 2314a392cc..435f829c9b 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -565,9 +565,9 @@ void OS_UWP::process_key_events() { Ref<InputEventKey> key_event; key_event.instance(); - key_event->set_alt(kev.alt); - key_event->set_shift(kev.shift); - key_event->set_control(kev.control); + key_event->set_alt_pressed(kev.alt); + key_event->set_shift_pressed(kev.shift); + key_event->set_ctrl_pressed(kev.control); key_event->set_echo(kev.echo); key_event->set_keycode(kev.keycode); key_event->set_physical_keycode(kev.physical_keycode); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 4b859da340..0dd02b4888 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1966,9 +1966,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm.instance(); mm->set_window_id(window_id); - mm->set_control(control_mem); - mm->set_shift(shift_mem); - mm->set_alt(alt_mem); + mm->set_ctrl_pressed(control_mem); + mm->set_shift_pressed(shift_mem); + mm->set_alt_pressed(alt_mem); mm->set_pressure((raw->data.mouse.ulButtons & RI_MOUSE_LEFT_BUTTON_DOWN) ? 1.0f : 0.0f); @@ -2062,9 +2062,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Ref<InputEventMouseMotion> mm; mm.instance(); mm->set_window_id(window_id); - mm->set_control(GetKeyState(VK_CONTROL) < 0); - mm->set_shift(GetKeyState(VK_SHIFT) < 0); - mm->set_alt(alt_mem); + mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0); + mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0); + mm->set_alt_pressed(alt_mem); mm->set_pressure(windows[window_id].last_pressure); mm->set_tilt(windows[window_id].last_tilt); @@ -2205,9 +2205,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_tilt(Vector2((float)pen_info.tiltX / 90, (float)pen_info.tiltY / 90)); } - mm->set_control(GetKeyState(VK_CONTROL) < 0); - mm->set_shift(GetKeyState(VK_SHIFT) < 0); - mm->set_alt(alt_mem); + mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0); + mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0); + mm->set_alt_pressed(alt_mem); mm->set_button_mask(last_button_state); @@ -2300,9 +2300,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Ref<InputEventMouseMotion> mm; mm.instance(); mm->set_window_id(window_id); - mm->set_control((wParam & MK_CONTROL) != 0); - mm->set_shift((wParam & MK_SHIFT) != 0); - mm->set_alt(alt_mem); + mm->set_ctrl_pressed((wParam & MK_CONTROL) != 0); + mm->set_shift_pressed((wParam & MK_SHIFT) != 0); + mm->set_alt_pressed(alt_mem); if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) { // Note: WinTab sends both WT_PACKET and WM_xBUTTONDOWN/UP/MOUSEMOVE events, use mouse 1/0 pressure only when last_pressure was not updated recently. @@ -2477,10 +2477,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } - mb->set_control((wParam & MK_CONTROL) != 0); - mb->set_shift((wParam & MK_SHIFT) != 0); - mb->set_alt(alt_mem); - //mb->get_alt()=(wParam&MK_MENU)!=0; + mb->set_ctrl_pressed((wParam & MK_CONTROL) != 0); + mb->set_shift_pressed((wParam & MK_SHIFT) != 0); + mb->set_alt_pressed(alt_mem); + //mb->is_alt_pressed()=(wParam&MK_MENU)!=0; if (mb->is_pressed()) last_button_state |= (1 << (mb->get_button_index() - 1)); else @@ -2835,17 +2835,17 @@ void DisplayServerWindows::_process_key_events() { k.instance(); k->set_window_id(ke.window_id); - k->set_shift(ke.shift); - k->set_alt(ke.alt); - k->set_control(ke.control); - k->set_metakey(ke.meta); + k->set_shift_pressed(ke.shift); + k->set_alt_pressed(ke.alt); + k->set_ctrl_pressed(ke.control); + k->set_meta_pressed(ke.meta); k->set_pressed(true); k->set_keycode(KeyMappingWindows::get_keysym(ke.wParam)); k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24))); k->set_unicode(unicode); if (k->get_unicode() && gr_mem) { - k->set_alt(false); - k->set_control(false); + k->set_alt_pressed(false); + k->set_ctrl_pressed(false); } if (k->get_unicode() < 32) @@ -2862,10 +2862,10 @@ void DisplayServerWindows::_process_key_events() { k.instance(); k->set_window_id(ke.window_id); - k->set_shift(ke.shift); - k->set_alt(ke.alt); - k->set_control(ke.control); - k->set_metakey(ke.meta); + k->set_shift_pressed(ke.shift); + k->set_alt_pressed(ke.alt); + k->set_ctrl_pressed(ke.control); + k->set_meta_pressed(ke.meta); k->set_pressed(ke.uMsg == WM_KEYDOWN); @@ -2900,8 +2900,8 @@ void DisplayServerWindows::_process_key_events() { k->set_unicode(unicode); } if (k->get_unicode() && gr_mem) { - k->set_alt(false); - k->set_control(false); + k->set_alt_pressed(false); + k->set_ctrl_pressed(false); } if (k->get_unicode() < 32) diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index 3312c91932..c367c69826 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -47,7 +47,7 @@ static _WinTranslatePair _vk_to_keycode[] = { { KEY_SHIFT, VK_SHIFT }, //(0x10) - { KEY_CONTROL, VK_CONTROL }, //(0x11) + { KEY_CTRL, VK_CONTROL }, //(0x11) { KEY_ALT, VK_MENU }, //(0x12) @@ -166,8 +166,8 @@ static _WinTranslatePair _vk_to_keycode[] = { { KEY_SCROLLLOCK, VK_SCROLL }, // (0x91) { KEY_SHIFT, VK_LSHIFT }, // (0xA0) { KEY_SHIFT, VK_RSHIFT }, // (0xA1) - { KEY_CONTROL, VK_LCONTROL }, // (0xA2) - { KEY_CONTROL, VK_RCONTROL }, // (0xA3) + { KEY_CTRL, VK_LCONTROL }, // (0xA2) + { KEY_CTRL, VK_RCONTROL }, // (0xA3) { KEY_MENU, VK_LMENU }, // (0xA4) { KEY_MENU, VK_RMENU }, // (0xA5) @@ -265,7 +265,7 @@ static _WinTranslatePair _scancode_to_keycode[] = { { KEY_BRACELEFT, 0x1A }, { KEY_BRACERIGHT, 0x1B }, { KEY_ENTER, 0x1C }, - { KEY_CONTROL, 0x1D }, + { KEY_CTRL, 0x1D }, { KEY_A, 0x1E }, { KEY_S, 0x1F }, { KEY_D, 0x20 }, diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index f517190a89..ccf13488ab 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -631,31 +631,45 @@ MainLoop *OS_Windows::get_main_loop() const { } String OS_Windows::get_config_path() const { - if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not? - return get_environment("XDG_CONFIG_HOME"); - } else if (has_environment("APPDATA")) { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. + if (has_environment("XDG_CONFIG_HOME")) { + if (get_environment("XDG_CONFIG_HOME").is_abs_path()) { + return get_environment("XDG_CONFIG_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `%APPDATA%` or `.` per the XDG Base Directory specification."); + } + } + if (has_environment("APPDATA")) { return get_environment("APPDATA"); - } else { - return "."; } + return "."; } String OS_Windows::get_data_path() const { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. if (has_environment("XDG_DATA_HOME")) { - return get_environment("XDG_DATA_HOME"); - } else { - return get_config_path(); + if (get_environment("XDG_DATA_HOME").is_abs_path()) { + return get_environment("XDG_DATA_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification."); + } } + return get_config_path(); } String OS_Windows::get_cache_path() const { + // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. if (has_environment("XDG_CACHE_HOME")) { - return get_environment("XDG_CACHE_HOME"); - } else if (has_environment("TEMP")) { + if (get_environment("XDG_CACHE_HOME").is_abs_path()) { + return get_environment("XDG_CACHE_HOME"); + } else { + WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%TEMP%` or `get_config_path()` per the XDG Base Directory specification."); + } + } + if (has_environment("TEMP")) { return get_environment("TEMP"); - } else { - return get_config_path(); } + return get_config_path(); } // Get properly capitalized engine name for system paths diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 9dfdd7bd0e..597693aa6a 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -118,7 +118,7 @@ void Area2D::_body_enter_tree(ObjectID p_id) { E->get().in_tree = true; emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } } @@ -132,7 +132,7 @@ void Area2D::_body_exit_tree(ObjectID p_id) { E->get().in_tree = false; emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } } @@ -154,6 +154,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (body_in) { if (!E) { E = body_map.insert(objid, BodyState()); + E->get().rid = p_body; E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { @@ -170,7 +171,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } if (!node || E->get().in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape); } } else { @@ -192,7 +193,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape); } } @@ -211,7 +212,7 @@ void Area2D::_area_enter_tree(ObjectID p_id) { E->get().in_tree = true; emit_signal(SceneStringNames::get_singleton()->area_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } } @@ -225,7 +226,7 @@ void Area2D::_area_exit_tree(ObjectID p_id) { E->get().in_tree = false; emit_signal(SceneStringNames::get_singleton()->area_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } } @@ -246,6 +247,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (area_in) { if (!E) { E = area_map.insert(objid, AreaState()); + E->get().rid = p_area; E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { @@ -262,7 +264,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } if (!node || E->get().in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, objid, node, p_area_shape, p_self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape); } } else { @@ -284,7 +286,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape); } } @@ -315,7 +317,7 @@ void Area2D::_clear_monitoring() { } for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } emit_signal(SceneStringNames::get_singleton()->body_exited, obj); @@ -343,7 +345,7 @@ void Area2D::_clear_monitoring() { } for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } emit_signal(SceneStringNames::get_singleton()->area_exited, obj); @@ -532,13 +534,13 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout); ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"))); ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"))); - ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"))); ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"))); @@ -551,7 +553,7 @@ void Area2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-4096,4096,0.001,or_lesser,or_greater"), "set_gravity", "get_gravity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); @@ -568,7 +570,7 @@ void Area2D::_bind_methods() { Area2D::Area2D() : CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) { - set_gravity(98); + set_gravity(980); set_gravity_vector(Vector2(0, 1)); set_monitoring(true); set_monitorable(true); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index d6fcb2c2a5..2c29e4660d 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -83,6 +83,7 @@ private: }; struct BodyState { + RID rid; int rc = 0; bool in_tree = false; VSet<ShapePair> shapes; @@ -114,6 +115,7 @@ private: }; struct AreaState { + RID rid; int rc = 0; bool in_tree = false; VSet<AreaShapePair> shapes; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 01045502d5..ca4b8d72a1 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -270,11 +270,10 @@ void Camera2D::_notification(int p_what) { } if (screen_drawing_enabled) { - Color area_axis_color(0.5, 0.42, 0.87, 0.63); + Color area_axis_color(1, 0.4, 1, 0.63); real_t area_axis_width = 1; if (is_current()) { area_axis_width = 3; - area_axis_color.a = 0.83; } Transform2D inv_camera_transform = get_camera_transform().affine_inverse(); @@ -295,10 +294,9 @@ void Camera2D::_notification(int p_what) { } if (limit_drawing_enabled) { - Color limit_drawing_color(1, 1, 0, 0.63); + Color limit_drawing_color(1, 1, 0.25, 0.63); real_t limit_drawing_width = 1; if (is_current()) { - limit_drawing_color.a = 0.83; limit_drawing_width = 3; } @@ -317,11 +315,10 @@ void Camera2D::_notification(int p_what) { } if (margin_drawing_enabled) { - Color margin_drawing_color(0, 1, 1, 0.63); + Color margin_drawing_color(0.25, 1, 1, 0.63); real_t margin_drawing_width = 1; if (is_current()) { margin_drawing_width = 3; - margin_drawing_color.a = 0.83; } Transform2D inv_camera_transform = get_camera_transform().affine_inverse(); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index ba34a0f45d..92b8be77cf 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -169,7 +169,7 @@ private: Vector<Color> emission_colors; int emission_point_count = 0; - Vector2 gravity = Vector2(0, 98); + Vector2 gravity = Vector2(0, 980); void _update_internal(); void _particles_process(float p_delta); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 8a0631a614..066835ef0a 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -140,6 +140,62 @@ void GPUParticles2D::set_process_material(const Ref<Material> &p_material) { update_configuration_warnings(); } +void GPUParticles2D::set_trail_enabled(bool p_enabled) { + trail_enabled = p_enabled; + RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); + update_configuration_warnings(); + update(); + + RS::get_singleton()->particles_set_transform_align(particles, p_enabled ? RS::PARTICLES_TRANSFORM_ALIGN_Y_TO_VELOCITY : RS::PARTICLES_TRANSFORM_ALIGN_DISABLED); +} +void GPUParticles2D::set_trail_length(float p_seconds) { + ERR_FAIL_COND(p_seconds < 0.001); + trail_length = p_seconds; + RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); + update(); +} + +void GPUParticles2D::set_trail_sections(int p_sections) { + ERR_FAIL_COND(p_sections < 2); + ERR_FAIL_COND(p_sections > 128); + + trail_sections = p_sections; + update(); +} +void GPUParticles2D::set_trail_section_subdivisions(int p_subdivisions) { + ERR_FAIL_COND(trail_section_subdivisions < 1); + ERR_FAIL_COND(trail_section_subdivisions > 1024); + + trail_section_subdivisions = p_subdivisions; + update(); +} + +bool GPUParticles2D::is_trail_enabled() const { + return trail_enabled; +} +float GPUParticles2D::get_trail_length() const { + return trail_length; +} + +void GPUParticles2D::_update_collision_size() { + float csize = collision_base_size; + + if (texture.is_valid()) { + csize *= (texture->get_width() + texture->get_height()) / 4.0; //half size since its a radius + } + + RS::get_singleton()->particles_set_collision_base_size(particles, csize); +} + +void GPUParticles2D::set_collision_base_size(float p_size) { + collision_base_size = p_size; + _update_collision_size(); +} + +float GPUParticles2D::get_collision_base_size() const { + return collision_base_size; +} + void GPUParticles2D::set_speed_scale(float p_scale) { speed_scale = p_scale; RS::get_singleton()->particles_set_speed_scale(particles, p_scale); @@ -157,6 +213,13 @@ float GPUParticles2D::get_lifetime() const { return lifetime; } +int GPUParticles2D::get_trail_sections() const { + return trail_sections; +} +int GPUParticles2D::get_trail_section_subdivisions() const { + return trail_section_subdivisions; +} + bool GPUParticles2D::get_one_shot() const { return one_shot; } @@ -253,6 +316,7 @@ Rect2 GPUParticles2D::capture_rect() const { void GPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; + _update_collision_size(); update(); } @@ -271,10 +335,119 @@ void GPUParticles2D::restart() { void GPUParticles2D::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { RID texture_rid; + Size2 size; if (texture.is_valid()) { texture_rid = texture->get_rid(); + size = texture->get_size(); + } else { + size = Size2(1, 1); } + if (trail_enabled) { + RS::get_singleton()->mesh_clear(mesh); + PackedVector2Array points; + PackedVector2Array uvs; + PackedInt32Array bone_indices; + PackedFloat32Array bone_weights; + PackedInt32Array indices; + + int total_segments = trail_sections * trail_section_subdivisions; + float depth = size.height * trail_sections; + + for (int j = 0; j <= total_segments; j++) { + float v = j; + v /= total_segments; + + float y = depth * v; + y = (depth * 0.5) - y; + + int bone = j / trail_section_subdivisions; + float blend = 1.0 - float(j % trail_section_subdivisions) / float(trail_section_subdivisions); + + float s = size.width; + + points.push_back(Vector2(-s * 0.5, 0)); + points.push_back(Vector2(+s * 0.5, 0)); + + uvs.push_back(Vector2(0, v)); + uvs.push_back(Vector2(1, v)); + + for (int i = 0; i < 2; i++) { + bone_indices.push_back(bone); + bone_indices.push_back(MIN(trail_sections, bone + 1)); + bone_indices.push_back(0); + bone_indices.push_back(0); + + bone_weights.push_back(blend); + bone_weights.push_back(1.0 - blend); + bone_weights.push_back(0); + bone_weights.push_back(0); + } + + if (j > 0) { + int base = j * 2 - 2; + indices.push_back(base + 0); + indices.push_back(base + 1); + indices.push_back(base + 2); + + indices.push_back(base + 1); + indices.push_back(base + 3); + indices.push_back(base + 2); + } + } + + Array arr; + arr.resize(RS::ARRAY_MAX); + arr[RS::ARRAY_VERTEX] = points; + arr[RS::ARRAY_TEX_UV] = uvs; + arr[RS::ARRAY_BONES] = bone_indices; + arr[RS::ARRAY_WEIGHTS] = bone_weights; + arr[RS::ARRAY_INDEX] = indices; + + RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + + Vector<Transform> xforms; + for (int i = 0; i <= trail_sections; i++) { + Transform xform; + /* + xform.origin.y = depth / 2.0 - size.height * float(i); + xform.origin.y = -xform.origin.y; //bind is an inverse transform, so negate y */ + xforms.push_back(xform); + } + + RS::get_singleton()->particles_set_trail_bind_poses(particles, xforms); + + } else { + RS::get_singleton()->mesh_clear(mesh); + Vector<Vector2> points; + points.resize(4); + points.write[0] = Vector2(-size.x / 2.0, -size.y / 2.0); + points.write[1] = Vector2(size.x / 2.0, -size.y / 2.0); + points.write[2] = Vector2(size.x / 2.0, size.y / 2.0); + points.write[3] = Vector2(-size.x / 2.0, size.y / 2.0); + Vector<Vector2> uvs; + uvs.resize(4); + uvs.write[0] = Vector2(0, 0); + uvs.write[1] = Vector2(1, 0); + uvs.write[2] = Vector2(1, 1); + uvs.write[3] = Vector2(0, 1); + Vector<int> indices; + indices.resize(6); + indices.write[0] = 0; + indices.write[1] = 1; + indices.write[2] = 2; + indices.write[3] = 0; + indices.write[4] = 2; + indices.write[5] = 3; + Array arr; + arr.resize(RS::ARRAY_MAX); + arr[RS::ARRAY_VERTEX] = points; + arr[RS::ARRAY_TEX_UV] = uvs; + arr[RS::ARRAY_INDEX] = indices; + + RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + RS::get_singleton()->particles_set_trail_bind_poses(particles, Vector<Transform>()); + } RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid); #ifdef TOOLS_ENABLED @@ -318,6 +491,7 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &GPUParticles2D::set_fractional_delta); ClassDB::bind_method(D_METHOD("set_process_material", "material"), &GPUParticles2D::set_process_material); ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &GPUParticles2D::set_speed_scale); + ClassDB::bind_method(D_METHOD("set_collision_base_size", "size"), &GPUParticles2D::set_collision_base_size); ClassDB::bind_method(D_METHOD("is_emitting"), &GPUParticles2D::is_emitting); ClassDB::bind_method(D_METHOD("get_amount"), &GPUParticles2D::get_amount); @@ -332,6 +506,7 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_fractional_delta"), &GPUParticles2D::get_fractional_delta); ClassDB::bind_method(D_METHOD("get_process_material"), &GPUParticles2D::get_process_material); ClassDB::bind_method(D_METHOD("get_speed_scale"), &GPUParticles2D::get_speed_scale); + ClassDB::bind_method(D_METHOD("get_collision_base_size"), &GPUParticles2D::get_collision_base_size); ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &GPUParticles2D::set_draw_order); ClassDB::bind_method(D_METHOD("get_draw_order"), &GPUParticles2D::get_draw_order); @@ -343,6 +518,18 @@ void GPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("restart"), &GPUParticles2D::restart); + ClassDB::bind_method(D_METHOD("set_trail_enabled", "enabled"), &GPUParticles2D::set_trail_enabled); + ClassDB::bind_method(D_METHOD("set_trail_length", "secs"), &GPUParticles2D::set_trail_length); + + ClassDB::bind_method(D_METHOD("is_trail_enabled"), &GPUParticles2D::is_trail_enabled); + ClassDB::bind_method(D_METHOD("get_trail_length"), &GPUParticles2D::get_trail_length); + + ClassDB::bind_method(D_METHOD("set_trail_sections", "sections"), &GPUParticles2D::set_trail_sections); + ClassDB::bind_method(D_METHOD("get_trail_sections"), &GPUParticles2D::get_trail_sections); + + ClassDB::bind_method(D_METHOD("set_trail_section_subdivisions", "subdivisions"), &GPUParticles2D::set_trail_section_subdivisions); + ClassDB::bind_method(D_METHOD("get_trail_section_subdivisions"), &GPUParticles2D::get_trail_section_subdivisions); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); @@ -354,10 +541,17 @@ void GPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); + ADD_GROUP("Collision", "collision_"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_base_size", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_collision_base_size", "get_collision_base_size"); ADD_GROUP("Drawing", ""); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "visibility_rect"), "set_visibility_rect", "get_visibility_rect"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime"), "set_draw_order", "get_draw_order"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,Reverse Lifetime"), "set_draw_order", "get_draw_order"); + ADD_GROUP("Trails", "trail_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trail_enabled"), "set_trail_enabled", "is_trail_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_length_secs", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_trail_length", "get_trail_length"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_sections", PROPERTY_HINT_RANGE, "2,128,1"), "set_trail_sections", "get_trail_sections"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_section_subdivisions", PROPERTY_HINT_RANGE, "1,1024,1"), "set_trail_section_subdivisions", "get_trail_section_subdivisions"); ADD_GROUP("Process Material", "process_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticlesMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Textures", ""); @@ -365,10 +559,16 @@ void GPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); + BIND_ENUM_CONSTANT(DRAW_ORDER_REVERSE_LIFETIME); } GPUParticles2D::GPUParticles2D() { particles = RS::get_singleton()->particles_create(); + RS::get_singleton()->particles_set_mode(particles, RS::PARTICLES_MODE_2D); + + mesh = RS::get_singleton()->mesh_create(); + RS::get_singleton()->particles_set_draw_passes(particles, 1); + RS::get_singleton()->particles_set_draw_pass_mesh(particles, 0, mesh); one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); @@ -382,10 +582,13 @@ GPUParticles2D::GPUParticles2D() { set_randomness_ratio(0); set_visibility_rect(Rect2(Vector2(-100, -100), Vector2(200, 200))); set_use_local_coordinates(true); - set_draw_order(DRAW_ORDER_INDEX); + set_draw_order(DRAW_ORDER_LIFETIME); set_speed_scale(1); + set_fixed_fps(30); + set_collision_base_size(collision_base_size); } GPUParticles2D::~GPUParticles2D() { RS::get_singleton()->free(particles); + RS::get_singleton()->free(mesh); } diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 20f9f768ed..9d8e61daf7 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -43,6 +43,7 @@ public: enum DrawOrder { DRAW_ORDER_INDEX, DRAW_ORDER_LIFETIME, + DRAW_ORDER_REVERSE_LIFETIME, }; private: @@ -68,11 +69,23 @@ private: void _update_particle_emission_transform(); + NodePath sub_emitter; + float collision_base_size = 1.0; + + bool trail_enabled = false; + float trail_length = 0.3; + int trail_sections = 8; + int trail_section_subdivisions = 4; + + RID mesh; + protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; void _notification(int p_what); + void _update_collision_size(); + public: void set_emitting(bool p_emitting); void set_amount(int p_amount); @@ -85,6 +98,11 @@ public: void set_use_local_coordinates(bool p_enable); void set_process_material(const Ref<Material> &p_material); void set_speed_scale(float p_scale); + void set_collision_base_size(float p_ratio); + void set_trail_enabled(bool p_enabled); + void set_trail_length(float p_seconds); + void set_trail_sections(int p_sections); + void set_trail_section_subdivisions(int p_subdivisions); bool is_emitting() const; int get_amount() const; @@ -98,6 +116,12 @@ public: Ref<Material> get_process_material() const; float get_speed_scale() const; + float get_collision_base_size() const; + bool is_trail_enabled() const; + float get_trail_length() const; + int get_trail_sections() const; + int get_trail_section_subdivisions() const; + void set_fixed_fps(int p_count); int get_fixed_fps() const; diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 8fb765f16b..ce57895341 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -281,7 +281,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Subtract,Mix"), "set_blend_mode", "get_blend_mode"); ADD_GROUP("Range", "range_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); @@ -292,7 +292,7 @@ void Light2D::_bind_methods() { ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None (Fast),PCF5 (Average),PCF13 (Slow)"), "set_shadow_filter", "get_shadow_filter"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 3f2f6d6b1c..4f52f62e99 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -165,7 +165,7 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } contact_monitor->locked = false; @@ -186,13 +186,13 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } contact_monitor->locked = false; } -void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) { +void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape) { bool body_in = p_status == 1; ObjectID objid = p_instance; @@ -207,6 +207,7 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (body_in) { if (!E) { E = contact_monitor->body_map.insert(objid, BodyState()); + E->get().rid = p_body; //E->get().rc=0; E->get().in_scene = node && node->is_inside_tree(); if (node) { @@ -225,7 +226,7 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } if (E->get().in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape); } } else { @@ -249,12 +250,13 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap contact_monitor->body_map.erase(E); } if (node && in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, node, p_body_shape, p_local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, node, p_body_shape, p_local_shape); } } } struct _RigidBody2DInOut { + RID rid; ObjectID id; int shape = 0; int local_shape = 0; @@ -311,6 +313,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //put the ones to add for (int i = 0; i < state->get_contact_count(); i++) { + RID rid = state->get_contact_collider(i); ObjectID obj = state->get_contact_collider_id(i); int local_shape = state->get_contact_local_shape(i); int shape = state->get_contact_collider_shape(i); @@ -319,6 +322,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.find(obj); if (!E) { + toadd[toadd_count].rid = rid; toadd[toadd_count].local_shape = local_shape; toadd[toadd_count].id = obj; toadd[toadd_count].shape = shape; @@ -329,6 +333,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { ShapePair sp(shape, local_shape); int idx = E->get().shapes.find(sp); if (idx == -1) { + toadd[toadd_count].rid = rid; toadd[toadd_count].local_shape = local_shape; toadd[toadd_count].id = obj; toadd[toadd_count].shape = shape; @@ -344,6 +349,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { for (int i = 0; i < E->get().shapes.size(); i++) { if (!E->get().shapes[i].tagged) { + toremove[toremove_count].rid = E->get().rid; toremove[toremove_count].body_id = E->key(); toremove[toremove_count].pair = E->get().shapes[i]; toremove_count++; @@ -354,13 +360,13 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //process removals for (int i = 0; i < toremove_count; i++) { - _body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); + _body_inout(0, toremove[i].rid, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); } //process additions for (int i = 0; i < toadd_count; i++) { - _body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape); + _body_inout(1, toadd[i].rid, toadd[i].id, toadd[i].shape, toadd[i].local_shape); } contact_monitor->locked = false; @@ -755,8 +761,8 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "applied_torque"), "set_applied_torque", "get_applied_torque"); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index e0fc0766bc..47d55d11fa 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -140,10 +140,12 @@ private: } }; struct RigidBody2D_RemoveAction { + RID rid; ObjectID body_id; ShapePair pair; }; struct BodyState { + RID rid; //int rc; bool in_scene = false; VSet<ShapePair> shapes; @@ -158,7 +160,7 @@ private: void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); - void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape); + void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape); void _direct_state_changed(Object *p_state); bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>()); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 1a7038bb80..21083e6a4b 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -302,17 +302,18 @@ void Polygon2D::_notification(int p_what) { colors.write[i] = color_r[i]; } } else { - colors.push_back(color); + colors.resize(len); + for (int i = 0; i < len; i++) { + colors.write[i] = color; + } } + Vector<int> index_array; + if (invert || polygons.size() == 0) { - Vector<int> indices = Geometry2D::triangulate_polygon(points); - if (indices.size()) { - RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1); - } + index_array = Geometry2D::triangulate_polygon(points); } else { //draw individual polygons - Vector<int> total_indices; for (int i = 0; i < polygons.size(); i++) { Vector<int> src_indices = polygons[i]; int ic = src_indices.size(); @@ -333,18 +334,38 @@ void Polygon2D::_notification(int p_what) { int ic2 = indices.size(); const int *r2 = indices.ptr(); - int bic = total_indices.size(); - total_indices.resize(bic + ic2); - int *w2 = total_indices.ptrw(); + int bic = index_array.size(); + index_array.resize(bic + ic2); + int *w2 = index_array.ptrw(); for (int j = 0; j < ic2; j++) { w2[j + bic] = r[r2[j]]; } } + } + + RS::get_singleton()->mesh_clear(mesh); + + if (index_array.size()) { + Array arr; + arr.resize(RS::ARRAY_MAX); + arr[RS::ARRAY_VERTEX] = points; + if (uvs.size() == points.size()) { + arr[RS::ARRAY_TEX_UV] = uvs; + } + if (colors.size() == points.size()) { + arr[RS::ARRAY_COLOR] = colors; + } - if (total_indices.size()) { - RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); + if (bones.size() == points.size() * 4) { + arr[RS::ARRAY_BONES] = bones; + arr[RS::ARRAY_WEIGHTS] = weights; } + + arr[RS::ARRAY_INDEX] = index_array; + + RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + RS::get_singleton()->canvas_item_add_mesh(get_canvas_item(), mesh, Transform2D(), Color(), texture.is_valid() ? texture->get_rid() : RID()); } } break; @@ -655,4 +676,9 @@ void Polygon2D::_bind_methods() { } Polygon2D::Polygon2D() { + mesh = RS::get_singleton()->mesh_create(); +} + +Polygon2D::~Polygon2D() { + RS::get_singleton()->free(mesh); } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index c207024a53..f9f36ff9a2 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -72,6 +72,8 @@ class Polygon2D : public Node2D { void _skeleton_bone_setup_changed(); + RID mesh; + protected: void _notification(int p_what); static void _bind_methods(); @@ -149,6 +151,7 @@ public: NodePath get_skeleton() const; Polygon2D(); + ~Polygon2D(); }; #endif // POLYGON_2D_H diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index 7c93edbff9..20169b1075 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -254,15 +254,15 @@ int Sprite2D::get_frame() const { return frame; } -void Sprite2D::set_frame_coords(const Vector2 &p_coord) { - ERR_FAIL_INDEX(int(p_coord.x), hframes); - ERR_FAIL_INDEX(int(p_coord.y), vframes); +void Sprite2D::set_frame_coords(const Vector2i &p_coord) { + ERR_FAIL_INDEX(p_coord.x, hframes); + ERR_FAIL_INDEX(p_coord.y, vframes); - set_frame(int(p_coord.y) * hframes + int(p_coord.x)); + set_frame(p_coord.y * hframes + p_coord.x); } -Vector2 Sprite2D::get_frame_coords() const { - return Vector2(frame % hframes, frame / hframes); +Vector2i Sprite2D::get_frame_coords() const { + return Vector2i(frame % hframes, frame / hframes); } void Sprite2D::set_vframes(int p_amount) { @@ -452,7 +452,7 @@ void Sprite2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); ADD_GROUP("Region", "region_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled"); diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h index 9db74cfe26..49df78c59d 100644 --- a/scene/2d/sprite_2d.h +++ b/scene/2d/sprite_2d.h @@ -109,8 +109,8 @@ public: void set_frame(int p_frame); int get_frame() const; - void set_frame_coords(const Vector2 &p_coord); - Vector2 get_frame_coords() const; + void set_frame_coords(const Vector2i &p_coord); + Vector2i get_frame_coords() const; void set_vframes(int p_amount); int get_vframes() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 4400198497..8666361e88 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -64,13 +64,13 @@ int TileMapPattern::get_cell_source_id(const Vector2i &p_coords) const { } Vector2i TileMapPattern::get_cell_atlas_coords(const Vector2i &p_coords) const { - ERR_FAIL_COND_V(!pattern.has(p_coords), TileSetAtlasSource::INVALID_ATLAS_COORDS); + ERR_FAIL_COND_V(!pattern.has(p_coords), TileSetSource::INVALID_ATLAS_COORDS); return pattern[p_coords].get_atlas_coords(); } int TileMapPattern::get_cell_alternative_tile(const Vector2i &p_coords) const { - ERR_FAIL_COND_V(!pattern.has(p_coords), TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + ERR_FAIL_COND_V(!pattern.has(p_coords), TileSetSource::INVALID_TILE_ALTERNATIVE); return pattern[p_coords].alternative_tile; } @@ -113,7 +113,7 @@ void TileMapPattern::clear() { }; void TileMapPattern::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMapPattern::set_cell, DEFVAL(-1), DEFVAL(TileSetAtlasSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetAtlasSource::INVALID_TILE_ALTERNATIVE)); + ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMapPattern::set_cell, DEFVAL(-1), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetSource::INVALID_TILE_ALTERNATIVE)); ClassDB::bind_method(D_METHOD("has_cell", "coords"), &TileMapPattern::has_cell); ClassDB::bind_method(D_METHOD("remove_cell", "coords"), &TileMapPattern::remove_cell); ClassDB::bind_method(D_METHOD("get_cell_source_id", "coords"), &TileMapPattern::get_cell_source_id); @@ -520,12 +520,12 @@ void TileMap::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i Vector2i atlas_coords = p_atlas_coords; int alternative_tile = p_alternative_tile; - if ((source_id == -1 || atlas_coords == TileSetAtlasSource::INVALID_ATLAS_COORDS || alternative_tile == TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) && - (source_id != -1 || atlas_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS || alternative_tile != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE)) { + if ((source_id == -1 || atlas_coords == TileSetSource::INVALID_ATLAS_COORDS || alternative_tile == TileSetSource::INVALID_TILE_ALTERNATIVE) && + (source_id != -1 || atlas_coords != TileSetSource::INVALID_ATLAS_COORDS || alternative_tile != TileSetSource::INVALID_TILE_ALTERNATIVE)) { WARN_PRINT("Setting a cell a cell as empty requires both source_id, atlas_coord and alternative_tile to be set to their respective \"invalid\" values. Values were thus changes accordingly."); source_id = -1; - atlas_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS; - alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + atlas_coords = TileSetSource::INVALID_ATLAS_COORDS; + alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE; } if (!E && source_id == -1) { @@ -602,7 +602,7 @@ Vector2i TileMap::get_cell_atlas_coords(const Vector2i &p_coords) const { const Map<Vector2i, TileMapCell>::Element *E = tile_map.find(p_coords); if (!E) { - return TileSetAtlasSource::INVALID_ATLAS_COORDS; + return TileSetSource::INVALID_ATLAS_COORDS; } return E->get().get_atlas_coords(); @@ -613,7 +613,7 @@ int TileMap::get_cell_alternative_tile(const Vector2i &p_coords) const { const Map<Vector2i, TileMapCell>::Element *E = tile_map.find(p_coords); if (!E) { - return TileSetAtlasSource::INVALID_TILE_ALTERNATIVE; + return TileSetSource::INVALID_TILE_ALTERNATIVE; } return E->get().alternative_tile; @@ -721,7 +721,7 @@ void TileMap::fix_invalid_tiles() { for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) { TileSetSource *source = *tile_set->get_source(E->get().source_id); if (!source || !source->has_tile(E->get().get_atlas_coords()) || !source->has_alternative_tile(E->get().get_atlas_coords(), E->get().alternative_tile)) { - set_cell(E->key(), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + set_cell(E->key(), -1, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); } } } @@ -777,6 +777,11 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { int offset = (format >= FORMAT_2) ? 3 : 2; clear(); + +#ifdef DISABLE_DEPRECATED + ERR_FAIL_COND_MSG(format != FORMAT_3, vformat("Cannot handle deprecated TileMap data format version %d. This Godot version was compiled with no support for deprecated data.", format)); +#endif + for (int i = 0; i < c; i += offset) { const uint8_t *ptr = (const uint8_t *)&r[i]; uint8_t local[12]; @@ -806,6 +811,7 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { uint16_t alternative_tile = decode_uint16(&local[10]); set_cell(Vector2i(x, y), source_id, Vector2i(atlas_coords_x, atlas_coords_y), alternative_tile); } else { +#ifndef DISABLE_DEPRECATED uint32_t v = decode_uint32(&local[4]); v &= (1 << 29) - 1; @@ -828,6 +834,7 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) { } set_cell(Vector2i(x, y), v, Vector2i(coord_x, coord_y), compatibility_alternative_tile); +#endif } } } @@ -902,7 +909,7 @@ void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(p); } -Vector2 TileMap::map_to_world(const Vector2 &p_pos) const { +Vector2 TileMap::map_to_world(const Vector2i &p_pos) const { // SHOULD RETURN THE CENTER OF THE TILE ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2()); @@ -980,7 +987,7 @@ Vector2 TileMap::map_to_world(const Vector2 &p_pos) const { } Vector2i TileMap::world_to_map(const Vector2 &p_pos) const { - ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2()); + ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2i()); Vector2 ret = p_pos; ret /= tile_set->get_tile_size(); @@ -1143,7 +1150,7 @@ Vector2i TileMap::world_to_map(const Vector2 &p_pos) const { } else { ret = (ret + Vector2(0.00005, 0.00005)).floor(); } - return ret; + return Vector2i(ret); } bool TileMap::is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const { @@ -1716,7 +1723,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_quadrant_size", "size"), &TileMap::set_quadrant_size); ClassDB::bind_method(D_METHOD("get_quadrant_size"), &TileMap::get_quadrant_size); - ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(-1), DEFVAL(TileSetAtlasSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetAtlasSource::INVALID_TILE_ALTERNATIVE)); + ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(-1), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetSource::INVALID_TILE_ALTERNATIVE)); ClassDB::bind_method(D_METHOD("get_cell_source_id", "coords"), &TileMap::get_cell_source_id); ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "coords"), &TileMap::get_cell_atlas_coords); ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "coords"), &TileMap::get_cell_alternative_tile); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 704897da15..2703e1980e 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -48,7 +48,7 @@ union TileMapCell { }; uint64_t _u64t; - TileMapCell(int p_source_id = -1, Vector2i p_atlas_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) { + TileMapCell(int p_source_id = -1, Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE) { source_id = p_source_id; set_atlas_coords(p_atlas_coords); alternative_tile = p_alternative_tile; @@ -112,16 +112,19 @@ struct TileMapQuadrant { // Debug. RID debug_canvas_item; - // Rendering + // Rendering. List<RID> canvas_items; List<RID> occluders; // Physics. List<RID> bodies; - // Navigation + // Navigation. Map<Vector2i, Vector<RID>> navigation_regions; + // Scenes. + Map<Vector2i, String> scenes; + void operator=(const TileMapQuadrant &q) { coords = q.coords; debug_canvas_item = q.debug_canvas_item; @@ -248,7 +251,7 @@ public: void set_quadrant_size(int p_size); int get_quadrant_size() const; - void set_cell(const Vector2i &p_coords, int p_source_id = -1, const Vector2i p_atlas_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE); + void set_cell(const Vector2i &p_coords, int p_source_id = -1, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE); int get_cell_source_id(const Vector2i &p_coords) const; Vector2i get_cell_atlas_coords(const Vector2i &p_coords) const; int get_cell_alternative_tile(const Vector2i &p_coords) const; @@ -264,7 +267,7 @@ public: void update_dirty_quadrants(); - Vector2 map_to_world(const Vector2 &p_pos) const; + Vector2 map_to_world(const Vector2i &p_pos) const; Vector2i world_to_map(const Vector2 &p_pos) const; bool is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const; diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index e187e06308..44708cddff 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -118,7 +118,7 @@ void Area3D::_body_enter_tree(ObjectID p_id) { E->get().in_tree = true; emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } } @@ -132,7 +132,7 @@ void Area3D::_body_exit_tree(ObjectID p_id) { E->get().in_tree = false; emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } } @@ -154,6 +154,7 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (body_in) { if (!E) { E = body_map.insert(objid, BodyState()); + E->get().rid = p_body; E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { @@ -170,7 +171,7 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } if (E->get().in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape); } } else { @@ -192,7 +193,7 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } } if (node && in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape); } } @@ -224,7 +225,7 @@ void Area3D::_clear_monitoring() { } for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); } emit_signal(SceneStringNames::get_singleton()->body_exited, node); @@ -253,7 +254,7 @@ void Area3D::_clear_monitoring() { } for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } emit_signal(SceneStringNames::get_singleton()->area_exited, obj); @@ -298,7 +299,7 @@ void Area3D::_area_enter_tree(ObjectID p_id) { E->get().in_tree = true; emit_signal(SceneStringNames::get_singleton()->area_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } } @@ -312,7 +313,7 @@ void Area3D::_area_exit_tree(ObjectID p_id) { E->get().in_tree = false; emit_signal(SceneStringNames::get_singleton()->area_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); } } @@ -334,6 +335,7 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (area_in) { if (!E) { E = area_map.insert(objid, AreaState()); + E->get().rid = p_area; E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { @@ -350,7 +352,7 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } if (!node || E->get().in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, objid, node, p_area_shape, p_self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape); } } else { @@ -372,7 +374,7 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape); + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape); } } @@ -582,13 +584,13 @@ void Area3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area3D::set_reverb_uniformity); ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area3D::get_reverb_uniformity); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); - ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"))); ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"))); @@ -601,7 +603,7 @@ void Area3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-32,32,0.001,or_lesser,or_greater"), "set_gravity", "get_gravity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index 9605a937af..5b8d612717 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -83,6 +83,7 @@ private: }; struct BodyState { + RID rid; int rc = 0; bool in_tree = false; VSet<ShapePair> shapes; @@ -114,6 +115,7 @@ private: }; struct AreaState { + RID rid; int rc = 0; bool in_tree = false; VSet<AreaShapePair> shapes; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 72392be5bd..55b26bc9fb 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -962,7 +962,7 @@ void AudioStreamPlayer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,InverseSquare,Log,Disabled"), "set_attenuation_model", "get_attenuation_model"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,Inverse Square,Log,Disabled"), "set_attenuation_model", "get_attenuation_model"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 914b3ad816..cba769a8f8 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -215,6 +215,11 @@ void CollisionObject3D::_shape_changed(const Ref<Shape3D> &p_shape) { } void CollisionObject3D::_update_debug_shapes() { + if (!is_inside_tree()) { + debug_shapes_to_update.clear(); + return; + } + for (Set<uint32_t>::Element *shapedata_idx = debug_shapes_to_update.front(); shapedata_idx; shapedata_idx = shapedata_idx->next()) { if (shapes.has(shapedata_idx->get())) { ShapeData &shapedata = shapes[shapedata_idx->get()]; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 4d7fc29f15..6505fb1ee8 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -454,7 +454,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { mmi->set_multimesh(baker.create_debug_multimesh()); add_child(mmi); #ifdef TOOLS_ENABLED - if (get_tree()->get_edited_scene_root() == this) { + if (is_inside_tree() && get_tree()->get_edited_scene_root() == this) { mmi->set_owner(this); } else { mmi->set_owner(get_owner()); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 5339b8a8da..83181064c3 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -181,7 +181,7 @@ void GPUParticles3D::set_draw_order(DrawOrder p_order) { RS::get_singleton()->particles_set_draw_order(particles, RS::ParticlesDrawOrder(p_order)); } -void GPUParticles3D::set_enable_trail(bool p_enabled) { +void GPUParticles3D::set_trail_enabled(bool p_enabled) { trail_enabled = p_enabled; RS::get_singleton()->particles_set_trails(particles, trail_enabled, trail_length); update_configuration_warnings(); @@ -552,7 +552,7 @@ void GPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("emit_particle", "xform", "velocity", "color", "custom", "flags"), &GPUParticles3D::emit_particle); - ClassDB::bind_method(D_METHOD("set_enable_trail", "enabled"), &GPUParticles3D::set_enable_trail); + ClassDB::bind_method(D_METHOD("set_trail_enabled", "enabled"), &GPUParticles3D::set_trail_enabled); ClassDB::bind_method(D_METHOD("set_trail_length", "secs"), &GPUParticles3D::set_trail_length); ClassDB::bind_method(D_METHOD("is_trail_enabled"), &GPUParticles3D::is_trail_enabled); @@ -579,11 +579,11 @@ void GPUParticles3D::_bind_methods() { ADD_GROUP("Drawing", ""); ADD_PROPERTY(PropertyInfo(Variant::AABB, "visibility_aabb"), "set_visibility_aabb", "get_visibility_aabb"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,View Depth"), "set_draw_order", "get_draw_order"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,Reverse Lifetime,View Depth"), "set_draw_order", "get_draw_order"); ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_align", PROPERTY_HINT_ENUM, "Disabled,ZBillboard,YToVelocity,ZBillboardYToVelocity"), "set_transform_align", "get_transform_align"); ADD_GROUP("Trails", "trail_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trail_enabled"), "set_enable_trail", "is_trail_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_length_secs", PROPERTY_HINT_RANGE, "0.01,4,0.01"), "set_trail_length", "get_trail_length"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trail_enabled"), "set_trail_enabled", "is_trail_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_length_secs", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_trail_length", "get_trail_length"); ADD_GROUP("Process Material", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticlesMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Draw Passes", "draw_"); @@ -595,6 +595,7 @@ void GPUParticles3D::_bind_methods() { BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); + BIND_ENUM_CONSTANT(DRAW_ORDER_REVERSE_LIFETIME); BIND_ENUM_CONSTANT(DRAW_ORDER_VIEW_DEPTH); BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION); @@ -613,6 +614,7 @@ void GPUParticles3D::_bind_methods() { GPUParticles3D::GPUParticles3D() { particles = RS::get_singleton()->particles_create(); + RS::get_singleton()->particles_set_mode(particles, RS::PARTICLES_MODE_3D); set_base(particles); one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); @@ -631,7 +633,7 @@ GPUParticles3D::GPUParticles3D() { set_draw_passes(1); set_draw_order(DRAW_ORDER_INDEX); set_speed_scale(1); - set_collision_base_size(0.01); + set_collision_base_size(collision_base_size); set_transform_align(TRANSFORM_ALIGN_DISABLED); } diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 1f9cea79b6..1b354b0d2a 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -44,6 +44,7 @@ public: enum DrawOrder { DRAW_ORDER_INDEX, DRAW_ORDER_LIFETIME, + DRAW_ORDER_REVERSE_LIFETIME, DRAW_ORDER_VIEW_DEPTH, }; @@ -74,7 +75,7 @@ private: bool fractional_delta; bool interpolate = true; NodePath sub_emitter; - float collision_base_size; + float collision_base_size = 0.01; bool trail_enabled = false; float trail_length = 0.3; @@ -113,7 +114,7 @@ public: void set_process_material(const Ref<Material> &p_material); void set_speed_scale(float p_scale); void set_collision_base_size(float p_ratio); - void set_enable_trail(bool p_enabled); + void set_trail_enabled(bool p_enabled); void set_trail_length(float p_seconds); bool is_emitting() const; diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 628b823f89..2d59461ff0 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -653,7 +653,7 @@ void GPUParticlesCollisionHeightField::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096,8192"), "set_resolution", "get_resolution"); ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "WhenMoved,Always"), "set_update_mode", "get_update_mode"); - ADD_GROUP("Folow Camera", "follow_camera_"); + ADD_GROUP("Follow Camera", "follow_camera_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_camera_enabled"), "set_follow_camera_mode", "is_follow_camera_mode_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_camera_push_ratio", PROPERTY_HINT_RANGE, "0.01,1,0.01"), "set_follow_camera_push_ratio", "get_follow_camera_push_ratio"); diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 27d5487a1a..c495f68890 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -427,7 +427,7 @@ void MeshInstance3D::create_debug_tangents() { add_child(mi); #ifdef TOOLS_ENABLED - if (this == get_tree()->get_edited_scene_root()) { + if (is_inside_tree() && this == get_tree()->get_edited_scene_root()) { mi->set_owner(this); } else { mi->set_owner(get_owner()); diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index dd1a797568..e895d18604 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -178,7 +178,7 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } contact_monitor->locked = false; @@ -199,13 +199,13 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape); } contact_monitor->locked = false; } -void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) { +void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape) { bool body_in = p_status == 1; ObjectID objid = p_instance; @@ -220,6 +220,7 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (body_in) { if (!E) { E = contact_monitor->body_map.insert(objid, BodyState()); + E->get().rid = p_body; //E->get().rc=0; E->get().in_tree = node && node->is_inside_tree(); if (node) { @@ -236,7 +237,7 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } if (E->get().in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape); } } else { @@ -260,12 +261,13 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap contact_monitor->body_map.erase(E); } if (node && in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_local_shape); + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_local_shape); } } } struct _RigidBodyInOut { + RID rid; ObjectID id; int shape = 0; int local_shape = 0; @@ -314,6 +316,7 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { //put the ones to add for (int i = 0; i < state->get_contact_count(); i++) { + RID rid = state->get_contact_collider(i); ObjectID obj = state->get_contact_collider_id(i); int local_shape = state->get_contact_local_shape(i); int shape = state->get_contact_collider_shape(i); @@ -322,6 +325,7 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.find(obj); if (!E) { + toadd[toadd_count].rid = rid; toadd[toadd_count].local_shape = local_shape; toadd[toadd_count].id = obj; toadd[toadd_count].shape = shape; @@ -332,6 +336,7 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { ShapePair sp(shape, local_shape); int idx = E->get().shapes.find(sp); if (idx == -1) { + toadd[toadd_count].rid = rid; toadd[toadd_count].local_shape = local_shape; toadd[toadd_count].id = obj; toadd[toadd_count].shape = shape; @@ -347,6 +352,7 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { for (int i = 0; i < E->get().shapes.size(); i++) { if (!E->get().shapes[i].tagged) { + toremove[toremove_count].rid = E->get().rid; toremove[toremove_count].body_id = E->key(); toremove[toremove_count].pair = E->get().shapes[i]; toremove_count++; @@ -357,13 +363,13 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { //process removals for (int i = 0; i < toremove_count; i++) { - _body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); + _body_inout(0, toremove[i].rid, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); } //process additions for (int i = 0; i < toadd_count; i++) { - _body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape); + _body_inout(1, toremove[i].rid, toadd[i].id, toadd[i].shape, toadd[i].local_shape); } contact_monitor->locked = false; @@ -511,7 +517,7 @@ Vector3 RigidBody3D::get_angular_velocity() const { return angular_velocity; } -Basis RigidBody3D::get_inverse_inertia_tensor() { +Basis RigidBody3D::get_inverse_inertia_tensor() const { return inverse_inertia_tensor; } @@ -745,8 +751,8 @@ void RigidBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); @@ -1952,6 +1958,8 @@ void PhysicalBone3D::_notification(int p_what) { if (parent_skeleton) { if (-1 != bone_id) { parent_skeleton->unbind_physical_bone_from_bone(bone_id); + parent_skeleton->unbind_child_node_from_bone(bone_id, this); + bone_id = -1; } } parent_skeleton = nullptr; diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 21afe66861..818ff97730 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -137,10 +137,12 @@ protected: } }; struct RigidBody3D_RemoveAction { + RID rid; ObjectID body_id; ShapePair pair; }; struct BodyState { + RID rid; //int rc; bool in_tree = false; VSet<ShapePair> shapes; @@ -155,7 +157,7 @@ protected: void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); - void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape); + void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape); virtual void _direct_state_changed(Object *p_state); void _notification(int p_what); @@ -181,7 +183,7 @@ public: void set_angular_velocity(const Vector3 &p_velocity); Vector3 get_angular_velocity() const override; - Basis get_inverse_inertia_tensor(); + Basis get_inverse_inertia_tensor() const; void set_gravity_scale(real_t p_gravity_scale); real_t get_gravity_scale() const; diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 95638ce514..475f8c07fd 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -428,7 +428,7 @@ void RayCast3D::_update_debug_shape_material(bool p_check_collision) { color = get_tree()->get_debug_collisions_color(); } - if (p_check_collision) { + if (p_check_collision && collided) { if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) { // If base color is already quite reddish, highlight collision with green color color = Color(0.0, 1.0, 0.0, color.a); diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index ad24f39bce..7762156b4a 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -230,7 +230,7 @@ void ReflectionProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &ReflectionProbe::set_update_mode); ClassDB::bind_method(D_METHOD("get_update_mode"), &ReflectionProbe::get_update_mode); - ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once,Always"), "set_update_mode", "get_update_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once (Fast),Always (Slow)"), "set_update_mode", "get_update_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,16384,0.1,or_greater"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents"); @@ -242,7 +242,7 @@ void ReflectionProbe::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); ADD_GROUP("Ambient", "ambient_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_mode", PROPERTY_HINT_ENUM, "Disabled,Environment,ConstantColor"), "set_ambient_mode", "get_ambient_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_mode", PROPERTY_HINT_ENUM, "Disabled,Environment,Constant Color"), "set_ambient_mode", "get_ambient_mode"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ambient_color", "get_ambient_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_color_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_color_energy", "get_ambient_color_energy"); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59233708f6..82927df5f1 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -94,20 +94,6 @@ bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) { set_bone_enabled(which, p_value); } else if (what == "pose") { set_bone_pose(which, p_value); - } else if (what == "bound_children") { - Array children = p_value; - - if (is_inside_tree()) { - bones.write[which].nodes_bound.clear(); - - for (int i = 0; i < children.size(); i++) { - NodePath npath = children[i]; - ERR_CONTINUE(npath.operator String() == ""); - Node *node = get_node(npath); - ERR_CONTINUE(!node); - bind_child_node_to_bone(which, node); - } - } } else { return false; } @@ -137,19 +123,6 @@ bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const { r_ret = is_bone_enabled(which); } else if (what == "pose") { r_ret = get_bone_pose(which); - } else if (what == "bound_children") { - Array children; - - for (const List<ObjectID>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->get()); - ERR_CONTINUE(!obj); - Node *node = Object::cast_to<Node>(obj); - ERR_CONTINUE(!node); - NodePath npath = get_path_to(node); - children.push_back(npath); - } - - r_ret = children; } else { return false; } @@ -165,7 +138,6 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::ARRAY, prep + "bound_children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } @@ -726,7 +698,7 @@ void Skeleton3D::_rebuild_physical_bones_cache() { const int b_size = bones.size(); for (int i = 0; i < b_size; ++i) { PhysicalBone3D *parent_pb = _get_physical_bone_parent(i); - if (parent_pb != bones[i].physical_bone) { + if (parent_pb != bones[i].cache_parent_physical_bone) { bones.write[i].cache_parent_physical_bone = parent_pb; if (bones[i].physical_bone) { bones[i].physical_bone->_on_bone_parent_changed(); @@ -912,10 +884,6 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bone_disable_rest", "bone_idx", "disable"), &Skeleton3D::set_bone_disable_rest); ClassDB::bind_method(D_METHOD("is_bone_rest_disabled", "bone_idx"), &Skeleton3D::is_bone_rest_disabled); - ClassDB::bind_method(D_METHOD("bind_child_node_to_bone", "bone_idx", "node"), &Skeleton3D::bind_child_node_to_bone); - ClassDB::bind_method(D_METHOD("unbind_child_node_from_bone", "bone_idx", "node"), &Skeleton3D::unbind_child_node_from_bone); - ClassDB::bind_method(D_METHOD("get_bound_child_nodes_to_bone", "bone_idx"), &Skeleton3D::_get_bound_child_nodes_to_bone); - ClassDB::bind_method(D_METHOD("clear_bones"), &Skeleton3D::clear_bones); ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton3D::get_bone_pose); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 508cd7c329..299a4b6a02 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -114,18 +114,6 @@ private: uint64_t version = 1; - // bind helpers - Array _get_bound_child_nodes_to_bone(int p_bone) const { - Array bound; - List<Node *> children; - get_bound_child_nodes_to_bone(p_bone, &children); - - for (int i = 0; i < children.size(); i++) { - bound.push_back(children[i]); - } - return bound; - } - void _update_process_order(); protected: diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index bd1c202205..294e313300 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -129,7 +129,7 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain return true; } -void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) { +void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet, Vector3 p_origin_pos) { real_t distance_to_goal(1e4); real_t previous_distance_to_goal(0); int can_solve(p_task->max_iterations); @@ -138,7 +138,7 @@ void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) { --can_solve; solve_simple_backwards(p_task->chain, p_solve_magnet); - solve_simple_forwards(p_task->chain, p_solve_magnet); + solve_simple_forwards(p_task->chain, p_solve_magnet, p_origin_pos); distance_to_goal = (p_task->chain.tips[0].chain_item->current_pos - p_task->chain.tips[0].end_effector->goal_transform.origin).length(); } @@ -176,13 +176,13 @@ void FabrikInverseKinematic::solve_simple_backwards(Chain &r_chain, bool p_solve } } -void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet) { +void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet, Vector3 p_origin_pos) { if (p_solve_magnet && !r_chain.middle_chain_item) { return; } ChainItem *sub_chain_root(&r_chain.chain_root); - Vector3 origin(r_chain.chain_root.initial_transform.origin); + Vector3 origin = p_origin_pos; while (sub_chain_root) { // Reach the tip sub_chain_root->current_pos = origin; @@ -273,13 +273,16 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // Update the initial root transform so its synced with any animation changes _update_chain(p_task->skeleton, &p_task->chain.chain_root); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, false); + Vector3 origin_pos = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone).origin; + make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta); if (p_use_magnet && p_task->chain.middle_chain_item) { p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); - solve_simple(p_task, true); + solve_simple(p_task, true, origin_pos); } - solve_simple(p_task, false); + solve_simple(p_task, false, origin_pos); // Assign new bone position. ChainItem *ci(&p_task->chain.chain_root); diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 9255e18b72..9b5ae240f6 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -106,10 +106,10 @@ private: /// Init a chain that starts from the root to tip static bool build_chain(Task *p_task, bool p_force_simple_chain = true); - static void solve_simple(Task *p_task, bool p_solve_magnet); + static void solve_simple(Task *p_task, bool p_solve_magnet, Vector3 p_origin_pos); /// Special solvers that solve only chains with one end effector static void solve_simple_backwards(Chain &r_chain, bool p_solve_magnet); - static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet); + static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet, Vector3 p_origin_pos); public: static Task *create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 33b8b488c6..be474e82e0 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -551,15 +551,15 @@ int Sprite3D::get_frame() const { return frame; } -void Sprite3D::set_frame_coords(const Vector2 &p_coord) { - ERR_FAIL_INDEX(int(p_coord.x), hframes); - ERR_FAIL_INDEX(int(p_coord.y), vframes); +void Sprite3D::set_frame_coords(const Vector2i &p_coord) { + ERR_FAIL_INDEX(p_coord.x, hframes); + ERR_FAIL_INDEX(p_coord.y, vframes); - set_frame(int(p_coord.y) * hframes + int(p_coord.x)); + set_frame(p_coord.y * hframes + p_coord.x); } -Vector2 Sprite3D::get_frame_coords() const { - return Vector2(frame % hframes, frame / hframes); +Vector2i Sprite3D::get_frame_coords() const { + return Vector2i(frame % hframes, frame / hframes); } void Sprite3D::set_vframes(int p_amount) { @@ -657,7 +657,7 @@ void Sprite3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); ADD_GROUP("Region", "region_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 5e47e66bcb..e3dd117804 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -176,8 +176,8 @@ public: void set_frame(int p_frame); int get_frame() const; - void set_frame_coords(const Vector2 &p_coord); - Vector2 get_frame_coords() const; + void set_frame_coords(const Vector2i &p_coord); + Vector2i get_frame_coords() const; void set_vframes(int p_amount); int get_vframes() const; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 246fff6d57..65918a2989 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -115,7 +115,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() { ClassDB::bind_method(D_METHOD("set_priority", "priority"), &AnimationNodeStateMachineTransition::set_priority); ClassDB::bind_method(D_METHOD("get_priority"), &AnimationNodeStateMachineTransition::get_priority); - ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,At End"), "set_switch_mode", "get_switch_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time"); diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp index c7f6c0e2da..fb6fa9dec9 100644 --- a/scene/gui/aspect_ratio_container.cpp +++ b/scene/gui/aspect_ratio_container.cpp @@ -155,7 +155,7 @@ void AspectRatioContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_alignment_vertical"), &AspectRatioContainer::get_alignment_vertical); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ratio"), "set_ratio", "get_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width controls height,Height controls width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width Controls Height,Height Controls Width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); ADD_GROUP("Alignment", "alignment_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment_horizontal", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment_horizontal", "get_alignment_horizontal"); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index b0bcde8865..c0df5271b4 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -533,7 +533,7 @@ void Button::_bind_methods() { BIND_ENUM_CONSTANT(ALIGN_RIGHT); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 114abbd4da..c0b4563615 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -84,6 +84,55 @@ void ColorPicker::_notification(int p_what) { } } +Ref<Shader> ColorPicker::wheel_shader; +Ref<Shader> ColorPicker::circle_shader; + +void ColorPicker::init_shaders() { + wheel_shader.instance(); + wheel_shader->set_code( + "shader_type canvas_item;" + "void fragment() {" + " float x = UV.x - 0.5;" + " float y = UV.y - 0.5;" + " float a = atan(y, x);" + " x += 0.001;" + " y += 0.001;" + " float b = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" + " x -= 0.002;" + " float b2 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" + " y -= 0.002;" + " float b3 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" + " x += 0.002;" + " float b4 = float(sqrt(x * x + y * y) < 0.5) * float(sqrt(x * x + y * y) > 0.42);" + " COLOR = vec4(clamp((abs(fract(((a - TAU) / TAU) + vec3(3.0, 2.0, 1.0) / 3.0) * 6.0 - 3.0) - 1.0), 0.0, 1.0), (b + b2 + b3 + b4) / 4.00);" + "}"); + + circle_shader.instance(); + circle_shader->set_code( + "shader_type canvas_item;" + "uniform float v = 1.0;" + "void fragment() {" + " float x = UV.x - 0.5;" + " float y = UV.y - 0.5;" + " float a = atan(y, x);" + " x += 0.001;" + " y += 0.001;" + " float b = float(sqrt(x * x + y * y) < 0.5);" + " x -= 0.002;" + " float b2 = float(sqrt(x * x + y * y) < 0.5);" + " y -= 0.002;" + " float b3 = float(sqrt(x * x + y * y) < 0.5);" + " x += 0.002;" + " float b4 = float(sqrt(x * x + y * y) < 0.5);" + " COLOR = vec4(mix(vec3(1.0), clamp(abs(fract(vec3((a - TAU) / TAU) + vec3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - vec3(3.0)) - vec3(1.0), 0.0, 1.0), ((float(sqrt(x * x + y * y)) * 2.0)) / 1.0) * vec3(v), (b + b2 + b3 + b4) / 4.00);" + "}"); +} + +void ColorPicker::finish_shaders() { + wheel_shader.unref(); + circle_shader.unref(); +} + void ColorPicker::set_focus_on_line_edit() { c_text->call_deferred("grab_focus"); } @@ -470,6 +519,19 @@ void ColorPicker::_update_text_value() { c_text->set_visible(visible); } +void ColorPicker::_sample_input(const Ref<InputEvent> &p_event) { + const Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95)); + if (rect_old.has_point(mb->get_position())) { + // Revert to the old color when left-clicking the old color sample. + color = old_color; + _update_color(); + emit_signal("color_changed", color); + } + } +} + void ColorPicker::_sample_draw() { // Covers the right half of the sample if the old color is being displayed, // or the whole sample if it's not being displayed. @@ -1067,6 +1129,7 @@ ColorPicker::ColorPicker() : hb_smpl->add_child(sample); sample->set_h_size_flags(SIZE_EXPAND_FILL); + sample->connect("gui_input", callable_mp(this, &ColorPicker::_sample_input)); sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw)); btn_pick->set_flat(true); @@ -1151,14 +1214,8 @@ ColorPicker::ColorPicker() : hb_edit->add_child(wheel_edit); wheel_mat.instance(); - circle_mat.instance(); - - Ref<Shader> wheel_shader(memnew(Shader)); - wheel_shader->set_code("shader_type canvas_item;const float TAU=6.28318530718;void fragment(){float x=UV.x-0.5;float y=UV.y-0.5;float a=atan(y,x);x+=0.001;y+=0.001;float b=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);x-=0.002;float b2=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);y-=0.002;float b3=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);x+=0.002;float b4=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);COLOR=vec4(clamp((abs(fract(((a-TAU)/TAU)+vec3(3.0,2.0,1.0)/3.0)*6.0-3.0)-1.0),0.0,1.0),(b+b2+b3+b4)/4.00);}"); wheel_mat->set_shader(wheel_shader); - - Ref<Shader> circle_shader(memnew(Shader)); - circle_shader->set_code("shader_type canvas_item;const float TAU=6.28318530718;uniform float v=1.0;void fragment(){float x=UV.x-0.5;float y=UV.y-0.5;float a=atan(y,x);x+=0.001;y+=0.001;float b=float(sqrt(x*x+y*y)<0.5);x-=0.002;float b2=float(sqrt(x*x+y*y)<0.5);y-=0.002;float b3=float(sqrt(x*x+y*y)<0.5);x+=0.002;float b4=float(sqrt(x*x+y*y)<0.5);COLOR=vec4(mix(vec3(1.0),clamp(abs(fract(vec3((a-TAU)/TAU)+vec3(1.0,2.0/3.0,1.0/3.0))*6.0-vec3(3.0))-vec3(1.0),0.0,1.0),((float(sqrt(x*x+y*y))*2.0))/1.0)*vec3(v),(b+b2+b3+b4)/4.00);}"); + circle_mat.instance(); circle_mat->set_shader(circle_shader); MarginContainer *wheel_margin(memnew(MarginContainer)); @@ -1210,7 +1267,9 @@ ColorPicker::ColorPicker() : void ColorPickerButton::_about_to_popup() { set_pressed(true); - picker->set_old_color(color); + if (picker) { + picker->set_old_color(color); + } } void ColorPickerButton::_color_changed(const Color &p_color) { diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 13fe5fd60e..14113467d0 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -56,6 +56,9 @@ public: }; private: + static Ref<Shader> wheel_shader; + static Ref<Shader> circle_shader; + Control *screen = nullptr; Control *uv_edit = memnew(Control); Control *w_edit = memnew(Control); @@ -108,6 +111,7 @@ private: void _update_presets(); void _update_text_value(); void _text_type_toggled(); + void _sample_input(const Ref<InputEvent> &p_event); void _sample_draw(); void _hsv_draw(int p_which, Control *c); void _slider_draw(int p_which); @@ -127,6 +131,9 @@ protected: static void _bind_methods(); public: + static void init_shaders(); + static void finish_shaders(); + void set_edit_alpha(bool p_show); bool is_editing_alpha() const; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 191f94b2b8..0ae1dec46d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -168,6 +168,12 @@ Size2 Control::_edit_get_minimum_size() const { } #endif +void Control::accept_event() { + if (is_inside_tree()) { + get_viewport()->_gui_accept_event(); + } +} + void Control::set_custom_minimum_size(const Size2 &p_custom) { if (p_custom == data.custom_minimum_size) { return; @@ -345,72 +351,72 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { List<StringName> names; theme->get_icon_list(get_class_name(), &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.icon_override.has(E->get())) { - hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", hint)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); } } { List<StringName> names; theme->get_stylebox_list(get_class_name(), &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.style_override.has(E->get())) { - hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", hint)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); } } { List<StringName> names; theme->get_font_list(get_class_name(), &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.font_override.has(E->get())) { - hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Font", hint)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); } } { List<StringName> names; theme->get_font_size_list(get_class_name(), &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.font_size_override.has(E->get())) { - hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E->get(), PROPERTY_HINT_NONE, "", hint)); + p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E->get(), PROPERTY_HINT_NONE, "", usage)); } } { List<StringName> names; theme->get_color_list(get_class_name(), &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.color_override.has(E->get())) { - hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", hint)); + p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", usage)); } } { List<StringName> names; theme->get_constant_list(get_class_name(), &names); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.constant_override.has(E->get())) { - hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", hint)); + p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", usage)); } } } @@ -765,32 +771,27 @@ Size2 Control::get_minimum_size() const { } template <class T> -bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, T &r_ret, T (Theme::*get_func)(const StringName &, const StringName &) const, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_node_type) { - // try with custom themes +T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // For each control iterate through its inheritance chain and see if p_name exists in any of them. Control *theme_owner = p_theme_owner; Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - StringName class_name = p_node_type; - - while (class_name != StringName()) { - if (theme_owner && (theme_owner->data.theme.operator->()->*has_func)(p_name, class_name)) { - r_ret = (theme_owner->data.theme.operator->()->*get_func)(p_name, class_name); - return true; + for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E->get())) { + return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E->get()); } - if (theme_owner_window && (theme_owner_window->theme.operator->()->*has_func)(p_name, class_name)) { - r_ret = (theme_owner_window->theme.operator->()->*get_func)(p_name, class_name); - return true; + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) { + return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E->get()); } - - class_name = ClassDB::get_parent_class_nocheck(class_name); } Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { theme_owner = parent_c->data.theme_owner; theme_owner_window = parent_c->data.theme_owner_window; @@ -805,33 +806,47 @@ bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_win } } } - return false; + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E->get())) { + return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E->get()); + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E->get())) { + return Theme::get_default()->get_theme_item(p_data_type, p_name, E->get()); + } + } + // If they don't exist, use any type to return the default/empty value. + return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]); } -bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_node_type) { - // try with custom themes +bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // For each control iterate through its inheritance chain and see if p_name exists in any of them. Control *theme_owner = p_theme_owner; Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - StringName class_name = p_node_type; - - while (class_name != StringName()) { - if (theme_owner && (theme_owner->data.theme.operator->()->*has_func)(p_name, class_name)) { + for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E->get())) { return true; } - if (theme_owner_window && (theme_owner_window->theme.operator->()->*has_func)(p_name, class_name)) { + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) { return true; } - - class_name = ClassDB::get_parent_class_nocheck(class_name); } Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { theme_owner = parent_c->data.theme_owner; theme_owner_window = parent_c->data.theme_owner_window; @@ -846,179 +861,112 @@ bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_wind } } } - return false; -} -Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { - const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); - if (tex) { - return *tex; + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E->get())) { + return true; + } } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return get_icons(data.theme_owner, data.theme_owner_window, p_name, type); + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E->get())) { + return true; + } + } + return false; } -Ref<Texture2D> Control::get_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - Ref<Texture2D> icon; - - if (_find_theme_item(p_theme_owner, p_theme_owner_window, icon, &Theme::get_icon, &Theme::has_icon, p_name, p_node_type)) { - return icon; +void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (data.theme_custom_type != StringName()) { + p_list->push_back(data.theme_custom_type); + } + Theme::get_type_dependencies(get_class_name(), p_list); + } else { + Theme::get_type_dependencies(p_theme_type, p_list); } +} - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_icon(p_name, p_node_type)) { - return Theme::get_project_default()->get_icon(p_name, p_node_type); +Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); + if (tex) { + return *tex; } } - return Theme::get_default()->get_icon(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { const Ref<StyleBox> *style = data.style_override.getptr(p_name); if (style) { return *style; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return get_styleboxs(data.theme_owner, data.theme_owner_window, p_name, type); -} - -Ref<StyleBox> Control::get_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - Ref<StyleBox> stylebox; - - if (_find_theme_item(p_theme_owner, p_theme_owner_window, stylebox, &Theme::get_stylebox, &Theme::has_stylebox, p_name, p_node_type)) { - return stylebox; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_stylebox(p_name, p_node_type)) { - return Theme::get_project_default()->get_stylebox(p_name, p_node_type); - } - } - - return Theme::get_default()->get_stylebox(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { const Ref<Font> *font = data.font_override.getptr(p_name); if (font) { return *font; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return get_fonts(data.theme_owner, data.theme_owner_window, p_name, type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -int Control::get_theme_font_size(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { const int *font_size = data.font_size_override.getptr(p_name); if (font_size) { return *font_size; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return get_font_sizes(data.theme_owner, data.theme_owner_window, p_name, type); -} - -Ref<Font> Control::get_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - Ref<Font> font; - - if (_find_theme_item(p_theme_owner, p_theme_owner_window, font, &Theme::get_font, &Theme::has_font, p_name, p_node_type)) { - return font; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_font(p_name, p_node_type)) { - return Theme::get_project_default()->get_font(p_name, p_node_type); - } - } - - return Theme::get_default()->get_font(p_name, p_node_type); -} - -int Control::get_font_sizes(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - int font_size; - - if (_find_theme_item(p_theme_owner, p_theme_owner_window, font_size, &Theme::get_font_size, &Theme::has_font_size, p_name, p_node_type)) { - return font_size; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_font_size(p_name, p_node_type)) { - return Theme::get_project_default()->get_font_size(p_name, p_node_type); - } - } - - return Theme::get_default()->get_font_size(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -Color Control::get_theme_color(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { const Color *color = data.color_override.getptr(p_name); if (color) { return *color; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return get_colors(data.theme_owner, data.theme_owner_window, p_name, type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -Color Control::get_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - Color color; - - if (_find_theme_item(p_theme_owner, p_theme_owner_window, color, &Theme::get_color, &Theme::has_color, p_name, p_node_type)) { - return color; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_color(p_name, p_node_type)) { - return Theme::get_project_default()->get_color(p_name, p_node_type); - } - } - return Theme::get_default()->get_color(p_name, p_node_type); -} - -int Control::get_theme_constant(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { const int *constant = data.constant_override.getptr(p_name); if (constant) { return *constant; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return get_constants(data.theme_owner, data.theme_owner_window, p_name, type); -} - -int Control::get_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - int constant; - - if (_find_theme_item(p_theme_owner, p_theme_owner_window, constant, &Theme::get_constant, &Theme::has_constant, p_name, p_node_type)) { - return constant; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_constant(p_name, p_node_type)) { - return Theme::get_project_default()->get_constant(p_name, p_node_type); - } - } - return Theme::get_default()->get_constant(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } bool Control::has_theme_icon_override(const StringName &p_name) const { @@ -1051,154 +999,76 @@ bool Control::has_theme_constant_override(const StringName &p_name) const { return constant != nullptr; } -bool Control::has_theme_icon(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { if (has_theme_icon_override(p_name)) { return true; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return has_icons(data.theme_owner, data.theme_owner_window, p_name, type); -} - -bool Control::has_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_icon, p_name, p_node_type)) { - return true; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_color(p_name, p_node_type)) { - return true; - } - } - return Theme::get_default()->has_icon(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { if (has_theme_stylebox_override(p_name)) { return true; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return has_styleboxs(data.theme_owner, data.theme_owner_window, p_name, type); -} - -bool Control::has_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_stylebox, p_name, p_node_type)) { - return true; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_stylebox(p_name, p_node_type)) { - return true; - } - } - return Theme::get_default()->has_stylebox(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -bool Control::has_theme_font(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { if (has_theme_font_override(p_name)) { return true; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return has_fonts(data.theme_owner, data.theme_owner_window, p_name, type); -} - -bool Control::has_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_font, p_name, p_node_type)) { - return true; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_font(p_name, p_node_type)) { - return true; - } - } - return Theme::get_default()->has_font(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { if (has_theme_font_size_override(p_name)) { return true; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return has_font_sizes(data.theme_owner, data.theme_owner_window, p_name, type); -} - -bool Control::has_font_sizes(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_font_size, p_name, p_node_type)) { - return true; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_font_size(p_name, p_node_type)) { - return true; - } - } - return Theme::get_default()->has_font_size(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -bool Control::has_theme_color(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { if (has_theme_color_override(p_name)) { return true; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return has_colors(data.theme_owner, data.theme_owner_window, p_name, type); -} - -bool Control::has_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_color, p_name, p_node_type)) { - return true; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_color(p_name, p_node_type)) { - return true; - } - } - return Theme::get_default()->has_color(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -bool Control::has_theme_constant(const StringName &p_name, const StringName &p_node_type) const { - if (p_node_type == StringName() || p_node_type == get_class_name()) { +bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { if (has_theme_constant_override(p_name)) { return true; } } - StringName type = p_node_type ? p_node_type : get_class_name(); - - return has_constants(data.theme_owner, data.theme_owner_window, p_name, p_node_type); -} - -bool Control::has_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) { - if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_constant, p_name, p_node_type)) { - return true; - } - - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_constant(p_name, p_node_type)) { - return true; - } - } - return Theme::get_default()->has_constant(p_name, p_node_type); + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } Rect2 Control::get_parent_anchorable_rect() const { @@ -2171,16 +2041,19 @@ void Control::set_theme(const Ref<Theme> &p_theme) { } } -void Control::accept_event() { - if (is_inside_tree()) { - get_viewport()->_gui_accept_event(); - } -} - Ref<Theme> Control::get_theme() const { return data.theme; } +void Control::set_theme_custom_type(const StringName &p_theme_type) { + data.theme_custom_type = p_theme_type; + _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); +} + +StringName Control::get_theme_custom_type() const { + return data.theme_custom_type; +} + void Control::set_tooltip(const String &p_tooltip) { data.tooltip = p_tooltip; update_configuration_warnings(); @@ -2499,9 +2372,9 @@ bool Control::is_text_field() const { return false; } -Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_node_type, const Array &p_args, const String p_text) const { +Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const { Vector<Vector2i> ret; - switch (p_node_type) { + switch (p_theme_type) { case STRUCTURED_TEXT_URI: { int prev = 0; for (int i = 0; i < p_text.length(); i++) { @@ -2811,6 +2684,9 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Control::set_theme); ClassDB::bind_method(D_METHOD("get_theme"), &Control::get_theme); + ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Control::set_theme_custom_type); + ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Control::get_theme_custom_type); + ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Control::add_theme_icon_override); ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Control::add_theme_style_override); ClassDB::bind_method(D_METHOD("add_theme_font_override", "name", "font"), &Control::add_theme_font_override); @@ -2825,12 +2701,12 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_theme_color_override", "name"), &Control::remove_theme_color_override); ClassDB::bind_method(D_METHOD("remove_theme_constant_override", "name"), &Control::remove_theme_constant_override); - ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "node_type"), &Control::get_theme_icon, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "node_type"), &Control::get_theme_stylebox, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_font", "name", "node_type"), &Control::get_theme_font, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "node_type"), &Control::get_theme_font_size, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_color", "name", "node_type"), &Control::get_theme_color, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "node_type"), &Control::get_theme_constant, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Control::get_theme_icon, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Control::get_theme_stylebox, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_font", "name", "theme_type"), &Control::get_theme_font, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "theme_type"), &Control::get_theme_font_size, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_color", "name", "theme_type"), &Control::get_theme_color, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "theme_type"), &Control::get_theme_constant, DEFVAL("")); ClassDB::bind_method(D_METHOD("has_theme_icon_override", "name"), &Control::has_theme_icon_override); ClassDB::bind_method(D_METHOD("has_theme_stylebox_override", "name"), &Control::has_theme_stylebox_override); @@ -2839,12 +2715,12 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("has_theme_color_override", "name"), &Control::has_theme_color_override); ClassDB::bind_method(D_METHOD("has_theme_constant_override", "name"), &Control::has_theme_constant_override); - ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "node_type"), &Control::has_theme_icon, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "node_type"), &Control::has_theme_stylebox, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_font", "name", "node_type"), &Control::has_theme_font, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "node_type"), &Control::has_theme_font_size, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_color", "name", "node_type"), &Control::has_theme_color, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "node_type"), &Control::has_theme_constant, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "theme_type"), &Control::has_theme_icon, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "theme_type"), &Control::has_theme_stylebox, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_font", "name", "theme_type"), &Control::has_theme_font, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "theme_type"), &Control::has_theme_font_size, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Control::has_theme_color, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Control::has_theme_constant, DEFVAL("")); ClassDB::bind_method(D_METHOD("get_parent_control"), &Control::get_parent_control); @@ -2925,7 +2801,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction"); ADD_GROUP("Layout Direction", "layout_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-right,Right-to-left"), "set_layout_direction", "get_layout_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); ADD_GROUP("Rect", "rect_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); @@ -2952,14 +2828,15 @@ void Control::_bind_methods() { ADD_GROUP("Mouse", "mouse_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,Ibeam,Pointing hand,Cross,Wait,Busy,Drag,Can drop,Forbidden,Vertical resize,Horizontal resize,Secondary diagonal resize,Main diagonal resize,Move,Vertical split,Horizontal split,Help"), "set_default_cursor_shape", "get_default_cursor_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,I-Beam,Pointing Hand,Cross,Wait,Busy,Drag,Can Drop,Forbidden,Vertical Resize,Horizontal Resize,Secondary Diagonal Resize,Main Diagonal Resize,Move,Vertical Split,Horizontal Split,Help"), "set_default_cursor_shape", "get_default_cursor_shape"); ADD_GROUP("Size Flags", "size_flags_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_v_size_flags", "get_v_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio"); - ADD_GROUP("Theme", ""); + ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type"); ADD_GROUP("", ""); BIND_ENUM_CONSTANT(FOCUS_NONE); diff --git a/scene/gui/control.h b/scene/gui/control.h index 1f397df589..a05025c32d 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -201,6 +201,8 @@ private: Ref<Theme> theme; Control *theme_owner = nullptr; Window *theme_owner_window = nullptr; + StringName theme_custom_type; + String tooltip; CursorShape default_cursor = CURSOR_ARROW; @@ -258,23 +260,9 @@ private: static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign = true); template <class T> - _FORCE_INLINE_ static bool _find_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, T &, T (Theme::*get_func)(const StringName &, const StringName &) const, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_node_type); - - _FORCE_INLINE_ static bool _has_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_node_type); - - static Ref<Texture2D> get_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static Ref<StyleBox> get_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static Ref<Font> get_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static int get_font_sizes(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static Color get_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static int get_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - - static bool has_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static bool has_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static bool has_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static bool has_font_sizes(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static bool has_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); - static bool has_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type = StringName()); + static T get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); + static bool has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); + _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; protected: virtual void add_child_notify(Node *p_child) override; @@ -282,7 +270,7 @@ protected: //virtual void _window_gui_input(InputEvent p_event); - virtual Vector<Vector2i> structured_text_parser(StructuredTextParser p_node_type, const Array &p_args, const String p_text) const; + virtual Vector<Vector2i> structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const; bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -415,6 +403,9 @@ public: void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; + void set_theme_custom_type(const StringName &p_theme_type); + StringName get_theme_custom_type() const; + void set_h_size_flags(int p_flags); int get_h_size_flags() const; @@ -466,12 +457,12 @@ public: void remove_theme_color_override(const StringName &p_name); void remove_theme_constant_override(const StringName &p_name); - Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_node_type = StringName()) const; - Ref<StyleBox> get_theme_stylebox(const StringName &p_name, const StringName &p_node_type = StringName()) const; - Ref<Font> get_theme_font(const StringName &p_name, const StringName &p_node_type = StringName()) const; - int get_theme_font_size(const StringName &p_name, const StringName &p_node_type = StringName()) const; - Color get_theme_color(const StringName &p_name, const StringName &p_node_type = StringName()) const; - int get_theme_constant(const StringName &p_name, const StringName &p_node_type = StringName()) const; + Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + Ref<StyleBox> get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + Ref<Font> get_theme_font(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + int get_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + Color get_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + int get_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; bool has_theme_icon_override(const StringName &p_name) const; bool has_theme_stylebox_override(const StringName &p_name) const; @@ -480,12 +471,12 @@ public: bool has_theme_color_override(const StringName &p_name) const; bool has_theme_constant_override(const StringName &p_name) const; - bool has_theme_icon(const StringName &p_name, const StringName &p_node_type = StringName()) const; - bool has_theme_stylebox(const StringName &p_name, const StringName &p_node_type = StringName()) const; - bool has_theme_font(const StringName &p_name, const StringName &p_node_type = StringName()) const; - bool has_theme_font_size(const StringName &p_name, const StringName &p_node_type = StringName()) const; - bool has_theme_color(const StringName &p_name, const StringName &p_node_type = StringName()) const; - bool has_theme_constant(const StringName &p_name, const StringName &p_node_type = StringName()) const; + bool has_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_font(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; /* TOOLTIP */ diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 5409b44b9e..806039d7ac 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -105,7 +105,7 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { switch (k->get_keycode()) { case KEY_H: { - if (k->get_command()) { + if (k->is_command_pressed()) { set_show_hidden_files(!show_hidden_files); } else { handled = false; @@ -589,8 +589,8 @@ void FileDialog::update_file_list() { files.pop_front(); } - if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == nullptr) { - tree->get_root()->get_children()->select(0); + if (tree->get_root() && tree->get_root()->get_first_child() && tree->get_selected() == nullptr) { + tree->get_root()->get_first_child()->select(0); } } diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index ebefb2938f..7278ca6e94 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -127,7 +127,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { } //Hold alt key to duplicate selected color - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) { + if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->is_alt_pressed()) { int x = mb->get_position().x; grabbed = _get_point_from_pos(x); @@ -236,9 +236,9 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { // Snap to "round" coordinates if holding Ctrl. // Be more precise if holding Shift as well - if (mm->get_control()) { - newofs = Math::snapped(newofs, mm->get_shift() ? 0.025 : 0.1); - } else if (mm->get_shift()) { + if (mm->is_ctrl_pressed()) { + newofs = Math::snapped(newofs, mm->is_shift_pressed() ? 0.025 : 0.1); + } else if (mm->is_shift_pressed()) { // Snap to nearest point if holding just Shift const float snap_threshold = 0.03; float smallest_ofs = snap_threshold; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 06c9cf1b63..5a4dacd897 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -1091,7 +1091,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { // Snapping can be toggled temporarily by holding down Ctrl. // This is done here as to not toggle the grid when holding down Ctrl. - if (is_using_snap() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (is_using_snap() ^ Input::get_singleton()->is_key_pressed(KEY_CTRL)) { const int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } @@ -1174,7 +1174,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { } if (b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed() && dragging) { - if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CTRL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); @@ -1238,7 +1238,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { dragging = true; drag_accum = Vector2(); just_selected = !gn->is_selected(); - if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CTRL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (o_gn) { @@ -1275,7 +1275,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { box_selecting = true; box_selecting_from = b->get_position(); - if (b->get_control()) { + if (b->is_ctrl_pressed()) { box_selection_mode_additive = true; previous_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -1286,7 +1286,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previous_selected.push_back(gn2); } - } else if (b->get_shift()) { + } else if (b->is_shift_pressed()) { box_selection_mode_additive = false; previous_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -1322,9 +1322,9 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { minimap->update(); } - if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CTRL)) { set_zoom_custom(zoom * ZOOM_SCALE, b->get_position()); - } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CTRL)) { set_zoom_custom(zoom / ZOOM_SCALE, b->get_position()); } else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 7d5c53effe..77c502cf8d 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -228,7 +228,7 @@ void GraphNode::_resort() { } stretch_avail += stretch_diff - sb->get_margin(SIDE_BOTTOM) - sb->get_margin(SIDE_TOP); //available stretch space. - /** Second, pass sucessively to discard elements that can't be stretched, this will run while stretchable + /** Second, pass successively to discard elements that can't be stretched, this will run while stretchable elements exist */ while (stretch_ratio_total > 0) { // first of all, don't even be here if no stretchable objects exist @@ -459,7 +459,7 @@ void GraphNode::_shape() { } void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) { - ERR_FAIL_COND(p_idx < 0); + ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set slot with p_idx (%d) lesser than zero.", p_idx)); if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1) && @@ -503,6 +503,26 @@ bool GraphNode::is_slot_enabled_left(int p_idx) const { return slot_info[p_idx].enable_left; } +void GraphNode::set_slot_enabled_left(int p_idx, bool p_enable_left) { + ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set enable_left for the slot with p_idx (%d) lesser than zero.", p_idx)); + + slot_info[p_idx].enable_left = p_enable_left; + update(); + connpos_dirty = true; + + emit_signal("slot_updated", p_idx); +} + +void GraphNode::set_slot_type_left(int p_idx, int p_type_left) { + ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set type_left for the slot '%d' because it hasn't been enabled.", p_idx)); + + slot_info[p_idx].type_left = p_type_left; + update(); + connpos_dirty = true; + + emit_signal("slot_updated", p_idx); +} + int GraphNode::get_slot_type_left(int p_idx) const { if (!slot_info.has(p_idx)) { return 0; @@ -510,6 +530,16 @@ int GraphNode::get_slot_type_left(int p_idx) const { return slot_info[p_idx].type_left; } +void GraphNode::set_slot_color_left(int p_idx, const Color &p_color_left) { + ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set color_left for the slot '%d' because it hasn't been enabled.", p_idx)); + + slot_info[p_idx].color_left = p_color_left; + update(); + connpos_dirty = true; + + emit_signal("slot_updated", p_idx); +} + Color GraphNode::get_slot_color_left(int p_idx) const { if (!slot_info.has(p_idx)) { return Color(1, 1, 1, 1); @@ -524,6 +554,26 @@ bool GraphNode::is_slot_enabled_right(int p_idx) const { return slot_info[p_idx].enable_right; } +void GraphNode::set_slot_enabled_right(int p_idx, bool p_enable_right) { + ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set enable_right for the slot with p_idx (%d) lesser than zero.", p_idx)); + + slot_info[p_idx].enable_right = p_enable_right; + update(); + connpos_dirty = true; + + emit_signal("slot_updated", p_idx); +} + +void GraphNode::set_slot_type_right(int p_idx, int p_type_right) { + ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set type_right for the slot '%d' because it hasn't been enabled.", p_idx)); + + slot_info[p_idx].type_right = p_type_right; + update(); + connpos_dirty = true; + + emit_signal("slot_updated", p_idx); +} + int GraphNode::get_slot_type_right(int p_idx) const { if (!slot_info.has(p_idx)) { return 0; @@ -531,6 +581,16 @@ int GraphNode::get_slot_type_right(int p_idx) const { return slot_info[p_idx].type_right; } +void GraphNode::set_slot_color_right(int p_idx, const Color &p_color_right) { + ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set color_right for the slot '%d' because it hasn't been enabled.", p_idx)); + + slot_info[p_idx].color_right = p_color_right; + update(); + connpos_dirty = true; + + emit_signal("slot_updated", p_idx); +} + Color GraphNode::get_slot_color_right(int p_idx) const { if (!slot_info.has(p_idx)) { return Color(1, 1, 1, 1); @@ -891,11 +951,23 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("clear_slot", "idx"), &GraphNode::clear_slot); ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots); + ClassDB::bind_method(D_METHOD("is_slot_enabled_left", "idx"), &GraphNode::is_slot_enabled_left); + ClassDB::bind_method(D_METHOD("set_slot_enabled_left", "idx", "enable_left"), &GraphNode::set_slot_enabled_left); + + ClassDB::bind_method(D_METHOD("set_slot_type_left", "idx", "type_left"), &GraphNode::set_slot_type_left); ClassDB::bind_method(D_METHOD("get_slot_type_left", "idx"), &GraphNode::get_slot_type_left); + + ClassDB::bind_method(D_METHOD("set_slot_color_left", "idx", "color_left"), &GraphNode::set_slot_color_left); ClassDB::bind_method(D_METHOD("get_slot_color_left", "idx"), &GraphNode::get_slot_color_left); + ClassDB::bind_method(D_METHOD("is_slot_enabled_right", "idx"), &GraphNode::is_slot_enabled_right); + ClassDB::bind_method(D_METHOD("set_slot_enabled_right", "idx", "enable_right"), &GraphNode::set_slot_enabled_right); + + ClassDB::bind_method(D_METHOD("set_slot_type_right", "idx", "type_right"), &GraphNode::set_slot_type_right); ClassDB::bind_method(D_METHOD("get_slot_type_right", "idx"), &GraphNode::get_slot_type_right); + + ClassDB::bind_method(D_METHOD("set_slot_color_right", "idx", "color_right"), &GraphNode::set_slot_color_right); ClassDB::bind_method(D_METHOD("get_slot_color_right", "idx"), &GraphNode::get_slot_color_right); ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphNode::set_position_offset); @@ -927,7 +999,7 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay); ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset"), "set_position_offset", "get_position_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible"); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 1bc54dddb7..c70f616b47 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -113,11 +113,23 @@ public: void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>()); void clear_slot(int p_idx); void clear_all_slots(); + bool is_slot_enabled_left(int p_idx) const; + void set_slot_enabled_left(int p_idx, bool p_enable_left); + + void set_slot_type_left(int p_idx, int p_type_left); int get_slot_type_left(int p_idx) const; + + void set_slot_color_left(int p_idx, const Color &p_color_left); Color get_slot_color_left(int p_idx) const; + bool is_slot_enabled_right(int p_idx) const; + void set_slot_enabled_right(int p_idx, bool p_enable_right); + + void set_slot_type_right(int p_idx, int p_type_right); int get_slot_type_right(int p_idx) const; + + void set_slot_color_right(int p_idx, const Color &p_color_right); Color get_slot_color_right(int p_idx) const; void set_title(const String &p_title); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 0bdae2b118..150980b2e9 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -581,11 +581,11 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) { if (closest != -1) { int i = closest; - if (select_mode == SELECT_MULTI && items[i].selected && mb->get_command()) { + if (select_mode == SELECT_MULTI && items[i].selected && mb->is_command_pressed()) { deselect(i); emit_signal("multi_selected", i, false); - } else if (select_mode == SELECT_MULTI && mb->get_shift() && current >= 0 && current < items.size() && current != i) { + } else if (select_mode == SELECT_MULTI && mb->is_shift_pressed() && current >= 0 && current < items.size() && current != i) { int from = current; int to = i; if (i < current) { @@ -603,7 +603,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) { emit_signal("item_rmb_selected", i, get_local_mouse_position()); } } else { - if (!mb->is_double_click() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (!mb->is_double_click() && !mb->is_command_pressed() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MOUSE_BUTTON_LEFT) { defer_select_single = i; return; } @@ -613,7 +613,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) { } else { bool selected = items[i].selected; - select(i, select_mode == SELECT_SINGLE || !mb->get_command()); + select(i, select_mode == SELECT_SINGLE || !mb->is_command_pressed()); if (!selected || allow_reselect) { if (select_mode == SELECT_SINGLE) { diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index be73fd8f51..de0ee626b9 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -695,7 +695,7 @@ void Label::_bind_methods() { BIND_ENUM_CONSTANT(VALIGN_FILL); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign"); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index bfd739788f..c2ed9c1a3c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -250,11 +250,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { return; } - shift_selection_check_pre(b->get_shift()); + shift_selection_check_pre(b->is_shift_pressed()); set_caret_at_pixel_pos(b->get_position().x); - if (b->get_shift()) { + if (b->is_shift_pressed()) { selection_fill_at_caret(); selection.creating = true; @@ -442,9 +442,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { // Cursor Movement k = k->duplicate(); - bool shift_pressed = k->get_shift(); + bool shift_pressed = k->is_shift_pressed(); // Remove shift or else actions will not match. Use above variable for selection. - k->set_shift(false); + k->set_shift_pressed(false); if (k->is_action("ui_text_caret_word_left", true)) { _move_caret_left(shift_pressed, true); @@ -490,7 +490,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { // Allow unicode handling if: // * No Modifiers are pressed (except shift) - bool allow_unicode_handling = !(k->get_command() || k->get_control() || k->get_alt() || k->get_metakey()); + bool allow_unicode_handling = !(k->is_command_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); if (allow_unicode_handling && editable && k->get_unicode() >= 32) { // Handle Unicode (if no modifiers active) @@ -2209,7 +2209,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 1f7b61e3d1..d45ffde715 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -292,7 +292,7 @@ void LinkButton::_bind_methods() { BIND_ENUM_CONSTANT(UNDERLINE_MODE_NEVER); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 44df8eafdc..2100707d2d 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -1282,16 +1282,16 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo if (code == 0) { code = k->get_unicode(); } - if (k->get_control()) { + if (k->is_ctrl_pressed()) { code |= KEY_MASK_CTRL; } - if (k->get_alt()) { + if (k->is_alt_pressed()) { code |= KEY_MASK_ALT; } - if (k->get_metakey()) { + if (k->is_meta_pressed()) { code |= KEY_MASK_META; } - if (k->get_shift()) { + if (k->is_shift_pressed()) { code |= KEY_MASK_SHIFT; } } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index e8a908c30e..a2c3b4ed8a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1432,10 +1432,11 @@ void RichTextLabel::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PROCESS: { - float dt = get_process_delta_time(); - - _update_fx(main, dt); - update(); + if (is_visible_in_tree()) { + float dt = get_process_delta_time(); + _update_fx(main, dt); + update(); + } } } } @@ -2231,18 +2232,22 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub int size = p_item->subitems.size(); if (size == 0) { p_item->parent->subitems.erase(p_item); + // If a newline was erased, all lines AFTER the newline need to be decremented. if (p_item->type == ITEM_NEWLINE) { current_frame->lines.remove(p_line); - for (int i = p_subitem_line; i < current->subitems.size(); i++) { - if (current->subitems[i]->line > 0) { + for (int i = 0; i < current->subitems.size(); i++) { + if (current->subitems[i]->line > p_subitem_line) { current->subitems[i]->line--; } } } } else { + // First, remove all child items for the provided item. for (int i = 0; i < size; i++) { _remove_item(p_item->subitems.front()->get(), p_line, p_subitem_line); } + // Then remove the provided item itself. + p_item->parent->subitems.erase(p_item); } } @@ -2302,21 +2307,23 @@ bool RichTextLabel::remove_line(const int p_line) { return false; } - int i = 0; - while (i < current->subitems.size() && current->subitems[i]->line < p_line) { - i++; + // Remove all subitems with the same line as that provided. + Vector<int> subitem_indices_to_remove; + for (int i = 0; i < current->subitems.size(); i++) { + if (current->subitems[i]->line == p_line) { + subitem_indices_to_remove.push_back(i); + } } - bool was_newline = false; - while (i < current->subitems.size()) { - was_newline = current->subitems[i]->type == ITEM_NEWLINE; - _remove_item(current->subitems[i], current->subitems[i]->line, p_line); - if (was_newline) { - break; - } + bool had_newline = false; + // Reverse for loop to remove items from the end first. + for (int i = subitem_indices_to_remove.size() - 1; i >= 0; i--) { + int subitem_idx = subitem_indices_to_remove[i]; + had_newline = had_newline || current->subitems[subitem_idx]->type == ITEM_NEWLINE; + _remove_item(current->subitems[subitem_idx], current->subitems[subitem_idx]->line, p_line); } - if (!was_newline) { + if (!had_newline) { current_frame->lines.remove(p_line); if (current_frame->lines.size() == 0) { current_frame->lines.resize(1); @@ -2328,6 +2335,7 @@ bool RichTextLabel::remove_line(const int p_line) { } main->first_invalid_line = 0; // p_line ??? + update(); return true; } @@ -2612,14 +2620,6 @@ void RichTextLabel::pop() { current = current->parent; } -// Creates a new line without adding an ItemNewline to the previous line. -// Useful when wanting to calling remove_line and add a new line immediately after. -void RichTextLabel::increment_line_count() { - _validate_line_caches(main); - current_frame->lines.resize(current_frame->lines.size() + 1); - _invalidate_current_line(current_frame); -} - void RichTextLabel::clear() { main->_clear_children(); current = main; @@ -3934,7 +3934,7 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, "RichTextEffect", (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index afc88e070a..e3e457d1f2 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -483,8 +483,6 @@ public: void push_cell(); void pop(); - void increment_line_count(); - void clear(); void set_offset(int p_pixel); diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 9a15ecb108..5f872644ab 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -98,7 +98,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) { if (mb.is_valid()) { if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) { // only horizontal is enabled, scroll horizontally - if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) { + if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->is_shift_pressed())) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() / 8 * mb->get_factor()); } else if (v_scroll->is_visible_in_tree()) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8 * mb->get_factor()); @@ -107,7 +107,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) { if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) { // only horizontal is enabled, scroll horizontally - if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) { + if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->is_shift_pressed())) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() / 8 * mb->get_factor()); } else if (v_scroll->is_visible()) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8 * mb->get_factor()); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 13ff2c5b86..df4cf9a740 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -353,7 +353,7 @@ void SplitContainer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "split_offset"), "set_split_offset", "get_split_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collapsed"), "set_collapsed", "is_collapsed"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden & Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden and Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); BIND_ENUM_CONSTANT(DRAGGER_VISIBLE); BIND_ENUM_CONSTANT(DRAGGER_HIDDEN); diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 6cbc5890ce..471b26be75 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -127,7 +127,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !mb->get_command()) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !mb->is_command_pressed()) { if (scrolling_enabled && buttons_visible) { if (offset > 0) { offset--; @@ -136,7 +136,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { } } - if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !mb->get_command()) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !mb->is_command_pressed()) { if (scrolling_enabled && buttons_visible) { if (missing_right) { offset++; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c924f89709..4b199d1441 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -253,7 +253,6 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i void TextEdit::Text::insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override) { Line line; line.gutters.resize(gutter_count); - line.marked = false; line.hidden = false; line.data = p_text; line.bidi_override = p_bidi_override; @@ -867,6 +866,8 @@ void TextEdit::_notification(int p_what) { Dictionary color_map = _get_line_syntax_highlighting(minimap_line); + Color line_background_color = text.get_line_background_color(minimap_line); + line_background_color.a *= 0.6; Color current_color = cache.font_color; if (readonly) { current_color = cache.font_readonly_color; @@ -901,6 +902,12 @@ void TextEdit::_notification(int p_what) { } else { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, cache.minimap_width, 2), cache.current_line_color); } + } else if (line_background_color != Color(0, 0, 0, 0)) { + if (rtl) { + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - cache.minimap_width, i * 3, cache.minimap_width, 2), line_background_color); + } else { + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, cache.minimap_width, 2), line_background_color); + } } Color previous_color; @@ -1048,11 +1055,11 @@ void TextEdit::_notification(int p_what) { break; } - if (text.is_marked(line)) { + if (text.get_line_background_color(line) != Color(0, 0, 0, 0)) { if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line)); } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, row_height), text.get_line_background_color(line)); } } @@ -2914,17 +2921,25 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } if (mb->is_pressed()) { - if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !mb->get_command()) { - if (mb->get_shift()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !mb->is_command_pressed()) { + if (mb->is_shift_pressed()) { h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor())); + } else if (mb->is_alt_pressed()) { + // Scroll 5 times as fast as normal (like in Visual Studio Code). + _scroll_up(15 * mb->get_factor()); } else if (v_scroll->is_visible()) { + // Scroll 3 lines. _scroll_up(3 * mb->get_factor()); } } - if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !mb->get_command()) { - if (mb->get_shift()) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !mb->is_command_pressed()) { + if (mb->is_shift_pressed()) { h_scroll->set_value(h_scroll->get_value() + (100 * mb->get_factor())); + } else if (mb->is_alt_pressed()) { + // Scroll 5 times as fast as normal (like in Visual Studio Code). + _scroll_down(15 * mb->get_factor()); } else if (v_scroll->is_visible()) { + // Scroll 3 lines. _scroll_down(3 * mb->get_factor()); } } @@ -2977,7 +2992,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { cursor_set_line(row, false, false); cursor_set_column(col); - if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) { + if (mb->is_shift_pressed() && (cursor.column != prev_col || cursor.line != prev_line)) { if (!selection.active) { selection.active = true; selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER; @@ -3073,7 +3088,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } else { if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { - if (mb->get_command() && highlighted_word != String()) { + if (mb->is_command_pressed() && highlighted_word != String()) { int row, col; _get_mouse_pos(Point2i(mpos.x, mpos.y), row, col); @@ -3116,7 +3131,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { mpos.x = get_size().x - mpos.x; } if (select_identifiers_enabled) { - if (!dragging_minimap && !dragging_selection && mm->get_command() && mm->get_button_mask() == 0) { + if (!dragging_minimap && !dragging_selection && mm->is_command_pressed() && mm->get_button_mask() == 0) { String new_word = get_word_at_pos(mpos); if (new_word != highlighted_word) { emit_signal("symbol_validate", new_word); @@ -3165,7 +3180,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { #ifdef OSX_ENABLED if (k->get_keycode() == KEY_META) { #else - if (k->get_keycode() == KEY_CONTROL) { + if (k->get_keycode() == KEY_CTRL) { #endif if (select_identifiers_enabled) { if (k->is_pressed() && !dragging_minimap && !dragging_selection) { @@ -3183,7 +3198,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } // If a modifier has been pressed, and nothing else, return. - if (k->get_keycode() == KEY_CONTROL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT || k->get_keycode() == KEY_META) { + if (k->get_keycode() == KEY_CTRL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT || k->get_keycode() == KEY_META) { return; } @@ -3191,7 +3206,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { // Allow unicode handling if: // * No Modifiers are pressed (except shift) - bool allow_unicode_handling = !(k->get_command() || k->get_control() || k->get_alt() || k->get_metakey()); + bool allow_unicode_handling = !(k->is_command_pressed() || k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_meta_pressed()); // Save here for insert mode, just in case it is cleared in the following section. bool had_selection = selection.active; @@ -3366,13 +3381,18 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - // SELECT ALL, CUT, COPY, PASTE. + // SELECT ALL, SELECT WORD UNDER CARET, CUT, COPY, PASTE. if (k->is_action("ui_text_select_all", true)) { select_all(); accept_event(); return; } + if (k->is_action("ui_text_select_word_under_caret", true)) { + select_word_under_caret(); + accept_event(); + return; + } if (k->is_action("ui_cut", true)) { cut(); accept_event(); @@ -3436,9 +3456,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { // CURSOR MOVEMENT k = k->duplicate(); - bool shift_pressed = k->get_shift(); + bool shift_pressed = k->is_shift_pressed(); // Remove shift or else actions will not match. Use above variable for selection. - k->set_shift(false); + k->set_shift_pressed(false); // CURSOR MOVEMENT - LEFT, RIGHT. if (k->is_action("ui_text_caret_word_left", true)) { @@ -4781,7 +4801,6 @@ void TextEdit::_update_caches() { cache.font_selected_color = get_theme_color("font_selected_color"); cache.font_readonly_color = get_theme_color("font_readonly_color"); cache.selection_color = get_theme_color("selection_color"); - cache.mark_color = get_theme_color("mark_color"); cache.current_line_color = get_theme_color("current_line_color"); cache.line_length_guideline_color = get_theme_color("line_length_guideline_color"); cache.code_folding_color = get_theme_color("code_folding_color"); @@ -5011,6 +5030,18 @@ bool TextEdit::is_line_gutter_clickable(int p_line, int p_gutter) const { return text.is_line_gutter_clickable(p_line, p_gutter); } +// Line style +void TextEdit::set_line_background_color(int p_line, const Color &p_color) { + ERR_FAIL_INDEX(p_line, text.size()); + text.set_line_background_color(p_line, p_color); + update(); +} + +Color TextEdit::get_line_background_color(int p_line) { + ERR_FAIL_INDEX_V(p_line, text.size(), Color()); + return text.get_line_background_color(p_line); +} + void TextEdit::add_keyword(const String &p_keyword) { keywords.insert(p_keyword); } @@ -5123,6 +5154,39 @@ void TextEdit::select_all() { update(); } +void TextEdit::select_word_under_caret() { + if (!selecting_enabled) { + return; + } + + if (text.size() == 1 && text[0].length() == 0) { + return; + } + + if (selection.active) { + // Allow toggling selection by pressing the shortcut a second time. + // This is also usable as a general-purpose "deselect" shortcut after + // selecting anything. + deselect(); + return; + } + + int begin = 0; + int end = 0; + const Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid()); + for (int i = 0; i < words.size(); i++) { + if (words[i].x <= cursor.column && words[i].y >= cursor.column) { + begin = words[i].x; + end = words[i].y; + break; + } + } + + select(cursor.line, begin, cursor.line, end); + // Move the cursor to the end of the word for easier editing. + cursor_set_column(end, false); +} + void TextEdit::deselect() { selection.active = false; update(); @@ -5429,12 +5493,6 @@ void TextEdit::_text_changed_emit() { text_changed_dirty = false; } -void TextEdit::set_line_as_marked(int p_line, bool p_marked) { - ERR_FAIL_INDEX(p_line, text.size()); - text.set_marked(p_line, p_marked); - update(); -} - void TextEdit::set_line_as_hidden(int p_line, bool p_hidden) { ERR_FAIL_INDEX(p_line, text.size()); if (is_hiding_enabled() || !p_hidden) { @@ -6845,6 +6903,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line_count"), &TextEdit::get_line_count); ClassDB::bind_method(D_METHOD("get_text"), &TextEdit::get_text); ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line); + ClassDB::bind_method(D_METHOD("get_visible_line_count"), &TextEdit::get_total_visible_rows); ClassDB::bind_method(D_METHOD("set_line", "line", "new_text"), &TextEdit::set_line); ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "parser"), &TextEdit::set_structured_text_bidi_override); @@ -6971,6 +7030,10 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_line_gutter_clickable", "line", "gutter", "clickable"), &TextEdit::set_line_gutter_clickable); ClassDB::bind_method(D_METHOD("is_line_gutter_clickable", "line", "gutter"), &TextEdit::is_line_gutter_clickable); + // Line style + ClassDB::bind_method(D_METHOD("set_line_background_color", "line", "color"), &TextEdit::set_line_background_color); + ClassDB::bind_method(D_METHOD("get_line_background_color", "line"), &TextEdit::get_line_background_color); + ClassDB::bind_method(D_METHOD("set_highlight_current_line", "enabled"), &TextEdit::set_highlight_current_line); ClassDB::bind_method(D_METHOD("is_highlight_current_line_enabled"), &TextEdit::is_highlight_current_line_enabled); @@ -6992,7 +7055,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_minimap_width"), &TextEdit::get_minimap_width); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "readonly"), "set_readonly", "is_readonly"); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index b0c7314c65..6ca50f3e2d 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -92,7 +92,7 @@ private: Vector<Vector2i> bidi_override; Ref<TextParagraph> data_buf; - bool marked = false; + Color background_color = Color(0, 0, 0, 0); bool hidden = false; Line() { @@ -129,12 +129,11 @@ private: void set_width(float p_width); int get_line_wrap_amount(int p_line) const; + Vector<Vector2i> get_line_wrap_ranges(int p_line) const; const Ref<TextParagraph> get_line_data(int p_line) const; void set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override); - void set_marked(int p_line, bool p_marked) { text.write[p_line].marked = p_marked; } - bool is_marked(int p_line) const { return text[p_line].marked; } void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; } bool is_hidden(int p_line) const { return text[p_line].hidden; } void insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override); @@ -167,6 +166,10 @@ private: void set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable) { text.write[p_line].gutters.write[p_gutter].clickable = p_clickable; } bool is_line_gutter_clickable(int p_line, int p_gutter) const { return text[p_line].gutters[p_gutter].clickable; } + + /* Line style. */ + void set_line_background_color(int p_line, const Color &p_color) { text.write[p_line].background_color = p_color; } + const Color get_line_background_color(int p_line) const { return text[p_line].background_color; } }; struct Cursor { @@ -484,7 +487,6 @@ protected: Color font_selected_color; Color font_readonly_color; Color selection_color; - Color mark_color; Color code_folding_color; Color current_line_color; Color line_length_guideline_color; @@ -561,6 +563,10 @@ public: void set_line_gutter_clickable(int p_line, int p_gutter, bool p_clickable); bool is_line_gutter_clickable(int p_line, int p_gutter) const; + // Line style + void set_line_background_color(int p_line, const Color &p_color); + Color get_line_background_color(int p_line); + enum MenuItems { MENU_CUT, MENU_COPY, @@ -637,7 +643,6 @@ public: void insert_text_at_cursor(const String &p_text); void insert_at(const String &p_text, int at); int get_line_count() const; - void set_line_as_marked(int p_line, bool p_marked); void set_line_as_hidden(int p_line, bool p_hidden); bool is_line_hidden(int p_line) const; @@ -726,6 +731,7 @@ public: void copy(); void paste(); void select_all(); + void select_word_under_caret(); void select(int p_from_line, int p_from_column, int p_to_line, int p_to_column); void deselect(); void swap_lines(int line1, int line2); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 7028d7aed4..d2b98eb0fa 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -47,36 +47,6 @@ #include <limits.h> -void TreeItem::move_to_top() { - if (!parent || parent->children == this) { - return; //already on top - } - TreeItem *prev = get_prev(); - prev->next = next; - next = parent->children; - parent->children = this; -} - -void TreeItem::move_to_bottom() { - if (!parent || !next) { - return; - } - - TreeItem *prev = get_prev(); - TreeItem *last = next; - while (last->next) { - last = last->next; - } - - if (prev) { - prev->next = next; - } else { - parent->children = next; - } - last->next = this; - next = nullptr; -} - Size2 TreeItem::Cell::get_icon_size() const { if (icon.is_null()) { return Size2(); @@ -118,6 +88,54 @@ void TreeItem::_cell_deselected(int p_cell) { tree->item_deselected(p_cell, this); } +void TreeItem::_change_tree(Tree *p_tree) { + if (p_tree == tree) { + return; + } + + TreeItem *c = first_child; + while (c) { + c->_change_tree(p_tree); + c = c->next; + } + + if (tree && tree->root == this) { + tree->root = nullptr; + } + + if (tree && tree->popup_edited_item == this) { + tree->popup_edited_item = nullptr; + tree->pressing_for_editor = false; + } + + if (tree && tree->cache.hover_item == this) { + tree->cache.hover_item = nullptr; + } + + if (tree && tree->selected_item == this) { + tree->selected_item = nullptr; + } + + if (tree && tree->drop_mode_over == this) { + tree->drop_mode_over = nullptr; + } + + if (tree && tree->single_select_defer == this) { + tree->single_select_defer = nullptr; + } + + if (tree && tree->edited_item == this) { + tree->edited_item = nullptr; + tree->pressing_for_editor = false; + } + + tree = p_tree; + + if (tree) { + cells.resize(tree->columns.size()); + } +} + /* cell mode */ void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) { ERR_FAIL_INDEX(p_column, cells.size()); @@ -427,20 +445,74 @@ int TreeItem::get_custom_minimum_height() const { return custom_min_height; } +/* Item manipulation */ + +TreeItem *TreeItem::create_child(int p_idx) { + TreeItem *ti = memnew(TreeItem(tree)); + if (tree) { + ti->cells.resize(tree->columns.size()); + } + + TreeItem *l_prev = nullptr; + TreeItem *c = first_child; + int idx = 0; + + while (c) { + if (idx++ == p_idx) { + c->prev = ti; + ti->next = c; + break; + } + l_prev = c; + c = c->next; + } + + if (l_prev) { + l_prev->next = ti; + ti->prev = l_prev; + if (!children_cache.is_empty()) { + if (ti->next) { + children_cache.insert(p_idx, ti); + } else { + children_cache.append(ti); + } + } + } else { + first_child = ti; + if (!children_cache.is_empty()) { + children_cache.insert(0, ti); + } + } + + ti->parent = this; + + return ti; +} + +Tree *TreeItem::get_tree() { + return tree; +} + TreeItem *TreeItem::get_next() { return next; } TreeItem *TreeItem::get_prev() { - if (!parent || parent->children == this) { - return nullptr; + if (prev) { + return prev; } - TreeItem *prev = parent->children; - while (prev && prev->next != this) { - prev = prev->next; + if (!parent || parent->first_child == this) { + return nullptr; + } + // This is an edge case + TreeItem *l_prev = parent->first_child; + while (l_prev && l_prev->next != this) { + l_prev = l_prev->next; } + prev = l_prev; + return prev; } @@ -448,8 +520,8 @@ TreeItem *TreeItem::get_parent() { return parent; } -TreeItem *TreeItem::get_children() { - return children; +TreeItem *TreeItem::get_first_child() { + return first_child; } TreeItem *TreeItem::get_prev_visible(bool p_wrap) { @@ -475,10 +547,10 @@ TreeItem *TreeItem::get_prev_visible(bool p_wrap) { } } else { current = prev; - while (!current->collapsed && current->children) { + while (!current->collapsed && current->first_child) { //go to the very end - current = current->children; + current = current->first_child; while (current->next) { current = current->next; } @@ -491,8 +563,8 @@ TreeItem *TreeItem::get_prev_visible(bool p_wrap) { TreeItem *TreeItem::get_next_visible(bool p_wrap) { TreeItem *current = this; - if (!current->collapsed && current->children) { - current = current->children; + if (!current->collapsed && current->first_child) { + current = current->first_child; } else if (current->next) { current = current->next; @@ -515,24 +587,136 @@ TreeItem *TreeItem::get_next_visible(bool p_wrap) { return current; } -void TreeItem::remove_child(TreeItem *p_item) { +TreeItem *TreeItem::get_child(int p_idx) { + _create_children_cache(); + ERR_FAIL_INDEX_V(p_idx, children_cache.size(), nullptr); + return children_cache.get(p_idx); +} + +int TreeItem::get_child_count() { + _create_children_cache(); + return children_cache.size(); +} + +Array TreeItem::get_children() { + int size = get_child_count(); + Array arr; + arr.resize(size); + for (int i = 0; i < size; i++) { + arr[i] = children_cache[i]; + } + + return arr; +} + +int TreeItem::get_index() { + int idx = 0; + TreeItem *c = this; + + while (c) { + c = c->get_prev(); + idx++; + } + return idx - 1; +} + +void TreeItem::move_before(TreeItem *p_item) { ERR_FAIL_NULL(p_item); - TreeItem **c = &children; + ERR_FAIL_COND(is_root); + ERR_FAIL_COND(!p_item->parent); - while (*c) { - if ((*c) == p_item) { - TreeItem *aux = *c; + if (p_item == this) { + return; + } - *c = (*c)->next; + TreeItem *p = p_item->parent; + while (p) { + ERR_FAIL_COND_MSG(p == this, "Can't move to a descendant"); + p = p->parent; + } - aux->parent = nullptr; - return; - } + Tree *old_tree = tree; + _unlink_from_tree(); + _change_tree(p_item->tree); + + parent = p_item->parent; + + TreeItem *item_prev = p_item->get_prev(); + if (item_prev) { + item_prev->next = this; + parent->children_cache.clear(); + } else { + parent->first_child = this; + parent->children_cache.insert(0, this); + } + + prev = item_prev; + next = p_item; + p_item->prev = this; + + if (old_tree && old_tree != tree) { + old_tree->update(); + } + + if (tree) { + tree->update(); + } +} + +void TreeItem::move_after(TreeItem *p_item) { + ERR_FAIL_NULL(p_item); + ERR_FAIL_COND(is_root); + ERR_FAIL_COND(!p_item->parent); + + if (p_item == this) { + return; + } + + TreeItem *p = p_item->parent; + while (p) { + ERR_FAIL_COND_MSG(p == this, "Can't move to a descendant"); + p = p->parent; + } + + Tree *old_tree = tree; + _unlink_from_tree(); + _change_tree(p_item->tree); + + if (p_item->next) { + p_item->next->prev = this; + } + parent = p_item->parent; + prev = p_item; + next = p_item->next; + p_item->next = this; + + if (next) { + parent->children_cache.clear(); + } else { + parent->children_cache.append(this); + } - c = &(*c)->next; + if (old_tree && old_tree != tree) { + old_tree->update(); } - ERR_FAIL(); + if (tree) { + tree->update(); + } +} + +void TreeItem::remove_child(TreeItem *p_item) { + ERR_FAIL_NULL(p_item); + ERR_FAIL_COND(p_item->parent != this); + + p_item->_unlink_from_tree(); + p_item->prev = nullptr; + p_item->next = nullptr; + p_item->parent = nullptr; + + if (tree) { + tree->update(); + } } void TreeItem::set_selectable(int p_column, bool p_selectable) { @@ -785,7 +969,7 @@ void recursive_call_aux(TreeItem *p_item, const StringName &p_method, const Vari return; } p_item->call(p_method, p_args, p_argcount, r_error); - TreeItem *c = p_item->get_children(); + TreeItem *c = p_item->get_first_child(); while (c) { recursive_call_aux(c, p_method, p_args, p_argcount, r_error); c = c->get_next(); @@ -855,16 +1039,6 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom_minimum_height", "height"), &TreeItem::set_custom_minimum_height); ClassDB::bind_method(D_METHOD("get_custom_minimum_height"), &TreeItem::get_custom_minimum_height); - ClassDB::bind_method(D_METHOD("get_next"), &TreeItem::get_next); - ClassDB::bind_method(D_METHOD("get_prev"), &TreeItem::get_prev); - ClassDB::bind_method(D_METHOD("get_parent"), &TreeItem::get_parent); - ClassDB::bind_method(D_METHOD("get_children"), &TreeItem::get_children); - - ClassDB::bind_method(D_METHOD("get_next_visible", "wrap"), &TreeItem::get_next_visible, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_prev_visible", "wrap"), &TreeItem::get_prev_visible, DEFVAL(false)); - - ClassDB::bind_method(D_METHOD("remove_child", "child"), &TreeItem::_remove_child); - ClassDB::bind_method(D_METHOD("set_selectable", "column", "selectable"), &TreeItem::set_selectable); ClassDB::bind_method(D_METHOD("is_selectable", "column"), &TreeItem::is_selectable); @@ -895,19 +1069,38 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("set_button_disabled", "column", "button_idx", "disabled"), &TreeItem::set_button_disabled); ClassDB::bind_method(D_METHOD("is_button_disabled", "column", "button_idx"), &TreeItem::is_button_disabled); - ClassDB::bind_method(D_METHOD("set_expand_right", "column", "enable"), &TreeItem::set_expand_right); - ClassDB::bind_method(D_METHOD("get_expand_right", "column"), &TreeItem::get_expand_right); - ClassDB::bind_method(D_METHOD("set_tooltip", "column", "tooltip"), &TreeItem::set_tooltip); ClassDB::bind_method(D_METHOD("get_tooltip", "column"), &TreeItem::get_tooltip); ClassDB::bind_method(D_METHOD("set_text_align", "column", "text_align"), &TreeItem::set_text_align); ClassDB::bind_method(D_METHOD("get_text_align", "column"), &TreeItem::get_text_align); - ClassDB::bind_method(D_METHOD("move_to_top"), &TreeItem::move_to_top); - ClassDB::bind_method(D_METHOD("move_to_bottom"), &TreeItem::move_to_bottom); + + ClassDB::bind_method(D_METHOD("set_expand_right", "column", "enable"), &TreeItem::set_expand_right); + ClassDB::bind_method(D_METHOD("get_expand_right", "column"), &TreeItem::get_expand_right); ClassDB::bind_method(D_METHOD("set_disable_folding", "disable"), &TreeItem::set_disable_folding); ClassDB::bind_method(D_METHOD("is_folding_disabled"), &TreeItem::is_folding_disabled); + ClassDB::bind_method(D_METHOD("create_child", "idx"), &TreeItem::create_child, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("get_tree"), &TreeItem::get_tree); + + ClassDB::bind_method(D_METHOD("get_next"), &TreeItem::get_next); + ClassDB::bind_method(D_METHOD("get_prev"), &TreeItem::get_prev); + ClassDB::bind_method(D_METHOD("get_parent"), &TreeItem::get_parent); + ClassDB::bind_method(D_METHOD("get_first_child"), &TreeItem::get_first_child); + + ClassDB::bind_method(D_METHOD("get_next_visible", "wrap"), &TreeItem::get_next_visible, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_prev_visible", "wrap"), &TreeItem::get_prev_visible, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("get_child", "idx"), &TreeItem::get_child); + ClassDB::bind_method(D_METHOD("get_child_count"), &TreeItem::get_child_count); + ClassDB::bind_method(D_METHOD("get_children"), &TreeItem::get_children); + ClassDB::bind_method(D_METHOD("get_index"), &TreeItem::get_index); + + ClassDB::bind_method(D_METHOD("move_before", "item"), &TreeItem::_move_before); + ClassDB::bind_method(D_METHOD("move_after", "item"), &TreeItem::_move_after); + + ClassDB::bind_method(D_METHOD("remove_child", "child"), &TreeItem::_remove_child); + { MethodInfo mi; mi.name = "call_recursive"; @@ -932,7 +1125,7 @@ void TreeItem::_bind_methods() { } void TreeItem::clear_children() { - TreeItem *c = children; + TreeItem *c = first_child; while (c) { TreeItem *aux = c; c = c->get_next(); @@ -940,56 +1133,18 @@ void TreeItem::clear_children() { memdelete(aux); } - children = nullptr; + first_child = nullptr; }; TreeItem::TreeItem(Tree *p_tree) { tree = p_tree; - collapsed = false; - disable_folding = false; - custom_min_height = 0; - - parent = nullptr; // parent item - next = nullptr; // next in list - children = nullptr; //child items } TreeItem::~TreeItem() { + _unlink_from_tree(); + prev = nullptr; clear_children(); - - if (parent) { - parent->remove_child(this); - } - - if (tree && tree->root == this) { - tree->root = nullptr; - } - - if (tree && tree->popup_edited_item == this) { - tree->popup_edited_item = nullptr; - tree->pressing_for_editor = false; - } - - if (tree && tree->cache.hover_item == this) { - tree->cache.hover_item = nullptr; - } - - if (tree && tree->selected_item == this) { - tree->selected_item = nullptr; - } - - if (tree && tree->drop_mode_over == this) { - tree->drop_mode_over = nullptr; - } - - if (tree && tree->single_select_defer == this) { - tree->single_select_defer = nullptr; - } - - if (tree && tree->edited_item == this) { - tree->edited_item = nullptr; - tree->pressing_for_editor = false; - } + _change_tree(nullptr); } /**********************************************/ @@ -1029,15 +1184,23 @@ void Tree::update_cache() { cache.font_color = get_theme_color("font_color"); cache.font_selected_color = get_theme_color("font_selected_color"); - cache.guide_color = get_theme_color("guide_color"); cache.drop_position_color = get_theme_color("drop_position_color"); cache.hseparation = get_theme_constant("hseparation"); cache.vseparation = get_theme_constant("vseparation"); cache.item_margin = get_theme_constant("item_margin"); cache.button_margin = get_theme_constant("button_margin"); + cache.draw_guides = get_theme_constant("draw_guides"); + cache.guide_color = get_theme_color("guide_color"); cache.draw_relationship_lines = get_theme_constant("draw_relationship_lines"); + cache.relationship_line_width = get_theme_constant("relationship_line_width"); + cache.parent_hl_line_width = get_theme_constant("parent_hl_line_width"); + cache.children_hl_line_width = get_theme_constant("children_hl_line_width"); + cache.parent_hl_line_margin = get_theme_constant("parent_hl_line_margin"); cache.relationship_line_color = get_theme_color("relationship_line_color"); + cache.parent_hl_line_color = get_theme_color("parent_hl_line_color"); + cache.children_hl_line_color = get_theme_color("children_hl_line_color"); + cache.scroll_border = get_theme_constant("scroll_border"); cache.scroll_speed = get_theme_constant("scroll_speed"); @@ -1116,7 +1279,7 @@ int Tree::get_item_height(TreeItem *p_item) const { if (!p_item->collapsed) { /* if not collapsed, check the children */ - TreeItem *c = p_item->children; + TreeItem *c = p_item->first_child; while (c) { height += get_item_height(c); @@ -1263,7 +1426,7 @@ void Tree::update_item_cache(TreeItem *p_item) { update_item_cell(p_item, i); } - TreeItem *c = p_item->children; + TreeItem *c = p_item->first_child; while (c) { update_item_cache(c); c = c->next; @@ -1430,7 +1593,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (drop_mode_flags && drop_mode_over == p_item) { Rect2 r = cell_rect; - bool has_parent = p_item->get_children() != nullptr; + bool has_parent = p_item->get_first_child() != nullptr; if (rtl) { r.position.x = get_size().width - r.position.x - r.size.x; } @@ -1626,7 +1789,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } } - if (!p_item->disable_folding && !hide_folding && p_item->children) { //has children, draw the guide box + if (!p_item->disable_folding && !hide_folding && p_item->first_child) { //has children, draw the guide box Ref<Texture2D> arrow; @@ -1656,40 +1819,81 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (!p_item->collapsed) { /* if not collapsed, check the children */ - TreeItem *c = p_item->children; + TreeItem *c = p_item->first_child; - int prev_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int base_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int prev_ofs = base_ofs; + int prev_hl_ofs = base_ofs; while (c) { if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); - int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); + int parent_ofs = p_pos.x + cache.item_margin; Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; - if (c->get_children() != nullptr) { + if (c->get_first_child() != nullptr) { root_pos -= Point2i(cache.arrow->get_width(), 0); } - float line_width = 1.0; + float line_width = cache.relationship_line_width; + float parent_line_width = cache.parent_hl_line_width; + float children_line_width = cache.children_hl_line_width; + #ifdef TOOLS_ENABLED line_width *= Math::round(EDSCALE); + parent_line_width *= Math::round(EDSCALE); + children_line_width *= Math::round(EDSCALE); #endif Point2i parent_pos = Point2i(parent_ofs - cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + cache.arrow->get_height() / 2) - cache.offset + p_draw_ofs; + int more_prev_ofs = 0; + if (root_pos.y + line_width >= 0) { if (rtl) { root_pos.x = get_size().width - root_pos.x; parent_pos.x = get_size().width - parent_pos.x; } - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x - Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), Point2i(parent_pos.x, prev_ofs), cache.relationship_line_color, line_width); + + // Order of parts on this bend: the horizontal line first, then the vertical line. + if (_is_branch_selected(c)) { + // If this item or one of its children is selected, we draw the line using parent highlight style. + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + more_prev_ofs = cache.parent_hl_line_margin; + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else if (p_item->is_selected(0)) { + // If parent item is selected (but this item is not), we draw the line using children highlight style. + // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. + if (_is_sibling_branch_selected(c)) { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(children_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(children_line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(children_line_width / 2)), cache.children_hl_line_color, children_line_width); + } + } else { + // If nothing of the above is true, we draw the line using normal style. + // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. + if (_is_sibling_branch_selected(c)) { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + cache.parent_hl_line_margin, root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(line_width / 2)), cache.relationship_line_color, line_width); + } + } } if (htotal < 0) { return -1; } - prev_ofs = root_pos.y; + prev_ofs = root_pos.y + more_prev_ofs; } if (htotal >= 0) { @@ -1698,10 +1902,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (child_h < 0) { if (cache.draw_relationship_lines == 0) { return -1; // break, stop drawing, no need to anymore - } else { - htotal = -1; - children_pos.y = cache.offset.y + p_draw_size.height; } + + htotal = -1; + children_pos.y = cache.offset.y + p_draw_size.height; } else { htotal += child_h; children_pos.y += child_h; @@ -1723,8 +1927,8 @@ int Tree::_count_selected_items(TreeItem *p_from) const { } } - if (p_from->get_children()) { - count += _count_selected_items(p_from->get_children()); + if (p_from->get_first_child()) { + count += _count_selected_items(p_from->get_first_child()); } if (p_from->get_next()) { @@ -1734,6 +1938,36 @@ int Tree::_count_selected_items(TreeItem *p_from) const { return count; } +bool Tree::_is_branch_selected(TreeItem *p_from) const { + for (int i = 0; i < columns.size(); i++) { + if (p_from->is_selected(i)) { + return true; + } + } + + TreeItem *child_item = p_from->get_first_child(); + while (child_item) { + if (_is_branch_selected(child_item)) { + return true; + } + child_item = child_item->get_next(); + } + + return false; +} + +bool Tree::_is_sibling_branch_selected(TreeItem *p_from) const { + TreeItem *sibling_item = p_from->get_next(); + while (sibling_item) { + if (_is_branch_selected(sibling_item)) { + return true; + } + sibling_item = sibling_item->get_next(); + } + + return false; +} + void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev, bool *r_in_range, bool p_force_deselect) { TreeItem::Cell &selected_cell = p_selected->cells.write[p_col]; @@ -1812,7 +2046,7 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c *r_in_range = false; } - TreeItem *c = p_current->children; + TreeItem *c = p_current->first_child; while (c) { select_single_item(p_selected, c, p_col, p_prev, r_in_range, p_current->is_collapsed() || p_force_deselect); @@ -1839,7 +2073,6 @@ void Tree::_range_click_timeout() { click_handled = false; Ref<InputEventMouseButton> mb; mb.instance(); - ; propagate_mouse_activated = false; // done from outside, so signal handler can't clear the tree in the middle of emit (which is a common case) blocked++; @@ -1879,7 +2112,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool } if (!p_item->disable_folding && !hide_folding && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) { - if (p_item->children) { + if (p_item->first_child) { p_item->set_collapsed(!p_item->is_collapsed()); } @@ -1926,7 +2159,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool x -= cache.hseparation; } - if (!p_item->disable_folding && !hide_folding && !p_item->cells[col].editable && !p_item->cells[col].selectable && p_item->get_children()) { + if (!p_item->disable_folding && !hide_folding && !p_item->cells[col].editable && !p_item->cells[col].selectable && p_item->get_first_child()) { p_item->set_collapsed(!p_item->is_collapsed()); return -1; //collapse/uncollapse because nothing can be done with item } @@ -1971,7 +2204,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool return -1; } - if (select_mode == SELECT_MULTI && p_mod->get_command() && c.selectable) { + if (select_mode == SELECT_MULTI && p_mod->is_command_pressed() && c.selectable) { if (!c.selected || p_button == MOUSE_BUTTON_RIGHT) { p_item->select(col); emit_signal("multi_selected", p_item, col, true); @@ -1988,7 +2221,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool } else { if (c.selectable) { - if (select_mode == SELECT_MULTI && p_mod->get_shift() && selected_item && selected_item != p_item) { + if (select_mode == SELECT_MULTI && p_mod->is_shift_pressed() && selected_item && selected_item != p_item) { bool inrange = false; select_single_item(p_item, root, col, selected_item, &inrange); @@ -2164,7 +2397,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool if (!p_item->collapsed) { /* if not collapsed, check the children */ - TreeItem *c = p_item->children; + TreeItem *c = p_item->first_child; while (c) { int child_h = propagate_mouse_event(new_pos, x_ofs, y_ofs, p_double_click, c, p_button, p_mod); @@ -2270,7 +2503,7 @@ void Tree::popup_select(int p_option) { void Tree::_go_left() { if (selected_col == 0) { - if (selected_item->get_children() != nullptr && !selected_item->is_collapsed()) { + if (selected_item->get_first_child() != nullptr && !selected_item->is_collapsed()) { selected_item->set_collapsed(true); } else { if (columns.size() == 1) { // goto parent with one column @@ -2298,7 +2531,7 @@ void Tree::_go_left() { void Tree::_go_right() { if (selected_col == (columns.size() - 1)) { - if (selected_item->get_children() != nullptr && selected_item->is_collapsed()) { + if (selected_item->get_first_child() != nullptr && selected_item->is_collapsed()) { selected_item->set_collapsed(false); } else if (selected_item->get_next_visible()) { selected_col = 0; @@ -2406,7 +2639,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventKey> k = p_event; - bool is_command = k.is_valid() && k->get_command(); + bool is_command = k.is_valid() && k->is_command_pressed(); if (p_event->is_action("ui_right") && p_event->is_pressed()) { if (!cursor_can_exit_tree) { accept_event(); @@ -2415,9 +2648,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { if (!selected_item || select_mode == SELECT_ROW || selected_col > (columns.size() - 1)) { return; } - if (k.is_valid() && k->get_alt()) { + if (k.is_valid() && k->is_alt_pressed()) { selected_item->set_collapsed(false); - TreeItem *next = selected_item->get_children(); + TreeItem *next = selected_item->get_first_child(); while (next && next != selected_item->next) { next->set_collapsed(false); next = next->get_next_visible(); @@ -2434,9 +2667,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { return; } - if (k.is_valid() && k->get_alt()) { + if (k.is_valid() && k->is_alt_pressed()) { selected_item->set_collapsed(true); - TreeItem *next = selected_item->get_children(); + TreeItem *next = selected_item->get_first_child(); while (next && next != selected_item->next) { next->set_collapsed(true); next = next->get_next_visible(); @@ -2564,7 +2797,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { if (!k->is_pressed()) { return; } - if (k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey()) { + if (k->is_command_pressed() || (k->is_shift_pressed() && k->get_unicode() == 0) || k->is_meta_pressed()) { return; } if (!root) { @@ -2834,7 +3067,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { break; } } - if (!root || (!root->get_children() && hide_root)) { + if (!root || (!root->get_first_child() && hide_root)) { if (b->get_button_index() == MOUSE_BUTTON_RIGHT && allow_rmb_select) { emit_signal("empty_tree_rmb_selected", get_local_mouse_position()); } @@ -2880,7 +3113,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { } if (b->get_button_index() == MOUSE_BUTTON_LEFT) { - if (get_item_at_position(b->get_position()) == nullptr && !b->get_shift() && !b->get_control() && !b->get_command()) { + if (get_item_at_position(b->get_position()) == nullptr && !b->is_shift_pressed() && !b->is_ctrl_pressed() && !b->is_command_pressed()) { emit_signal("nothing_selected"); } } @@ -3269,38 +3502,15 @@ TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) { TreeItem *ti = nullptr; if (p_parent) { - // Append or insert a new item to the given parent. - ti = memnew(TreeItem(this)); - ERR_FAIL_COND_V(!ti, nullptr); - ti->cells.resize(columns.size()); - - TreeItem *prev = nullptr; - TreeItem *c = p_parent->children; - int idx = 0; - - while (c) { - if (idx++ == p_idx) { - ti->next = c; - break; - } - prev = c; - c = c->next; - } - - if (prev) { - prev->next = ti; - } else { - p_parent->children = ti; - } - ti->parent = p_parent; - + ERR_FAIL_COND_V_MSG(p_parent->tree != this, nullptr, "A different tree owns the given parent"); + ti = p_parent->create_child(p_idx); } else { if (!root) { // No root exists, make the given item the new root. ti = memnew(TreeItem(this)); ERR_FAIL_COND_V(!ti, nullptr); ti->cells.resize(columns.size()); - + ti->is_root = true; root = ti; } else { // Root exists, append or insert to root. @@ -3321,8 +3531,8 @@ TreeItem *Tree::get_last_item() { while (last) { if (last->next) { last = last->next; - } else if (last->children) { - last = last->children; + } else if (last->first_child) { + last = last->first_child; } else { break; } @@ -3491,8 +3701,8 @@ TreeItem *Tree::get_next_selected(TreeItem *p_item) { if (!p_item) { p_item = root; } else { - if (p_item->children) { - p_item = p_item->children; + if (p_item->first_child) { + p_item = p_item->first_child; } else if (p_item->next) { p_item = p_item->next; @@ -3561,7 +3771,7 @@ int Tree::get_column_width(int p_column) const { void Tree::propagate_set_columns(TreeItem *p_item) { p_item->cells.resize(columns.size()); - TreeItem *c = p_item->get_children(); + TreeItem *c = p_item->get_first_child(); while (c) { propagate_set_columns(c); c = c->next; @@ -3611,8 +3821,8 @@ int Tree::get_item_offset(TreeItem *p_item) const { ofs += cache.vseparation; } - if (it->children && !it->collapsed) { - it = it->children; + if (it->first_child && !it->collapsed) { + it = it->first_child; } else if (it->next) { it = it->next; @@ -3935,7 +4145,7 @@ TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_ return nullptr; // do not try children, it's collapsed } - TreeItem *n = p_item->get_children(); + TreeItem *n = p_item->get_first_child(); while (n) { int ch; TreeItem *r = _find_item_at_pos(n, pos, r_column, ch, section); @@ -4255,7 +4465,7 @@ void Tree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In between"), "set_drop_mode_flags", "get_drop_mode_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode"); ADD_SIGNAL(MethodInfo("item_selected")); @@ -4334,6 +4544,8 @@ Tree::Tree() { set_mouse_filter(MOUSE_FILTER_STOP); set_clip_contents(true); + + update_cache(); } Tree::~Tree() { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 6d36f0df7f..c0948f1b80 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -122,14 +122,18 @@ private: Vector<Cell> cells; - bool collapsed; // won't show children - bool disable_folding; - int custom_min_height; + bool collapsed = false; // won't show children + bool disable_folding = false; + int custom_min_height = 0; - TreeItem *parent; // parent item - TreeItem *next; // next in list - TreeItem *children; //child items - Tree *tree; //tree (for reference) + TreeItem *parent = nullptr; // parent item + TreeItem *prev = nullptr; // previous in list + TreeItem *next = nullptr; // next in list + TreeItem *first_child = nullptr; + + Vector<TreeItem *> children_cache; + bool is_root = false; // for tree root + Tree *tree; // tree (for reference) TreeItem(Tree *p_tree); @@ -138,9 +142,40 @@ private: void _cell_selected(int p_cell); void _cell_deselected(int p_cell); + void _change_tree(Tree *p_tree); + + _FORCE_INLINE_ void _create_children_cache() { + if (children_cache.is_empty()) { + TreeItem *c = first_child; + while (c) { + children_cache.append(c); + c = c->next; + } + } + } + + _FORCE_INLINE_ void _unlink_from_tree() { + TreeItem *p = get_prev(); + if (p) { + p->next = next; + } + if (next) { + next->prev = p; + } + if (parent) { + if (!parent->children_cache.is_empty()) { + parent->children_cache.remove(get_index()); + } + if (parent->first_child == this) { + parent->first_child = next; + } + } + } + protected: static void _bind_methods(); - //bind helpers + + // Bind helpers Dictionary _get_range_config(int p_column) { Dictionary d; double min = 0.0, max = 0.0, step = 0.0; @@ -156,6 +191,13 @@ protected: remove_child(Object::cast_to<TreeItem>(p_child)); } + void _move_before(Object *p_item) { + move_before(Object::cast_to<TreeItem>(p_item)); + } + void _move_after(Object *p_item) { + move_after(Object::cast_to<TreeItem>(p_item)); + } + Variant _call_recursive_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); public: @@ -234,16 +276,6 @@ public: void set_custom_minimum_height(int p_height); int get_custom_minimum_height() const; - TreeItem *get_prev(); - TreeItem *get_next(); - TreeItem *get_parent(); - TreeItem *get_children(); - - TreeItem *get_prev_visible(bool p_wrap = false); - TreeItem *get_next_visible(bool p_wrap = false); - - void remove_child(TreeItem *p_item); - void set_selectable(int p_column, bool p_selectable); bool is_selectable(int p_column) const; @@ -269,22 +301,43 @@ public: void set_tooltip(int p_column, const String &p_tooltip); String get_tooltip(int p_column) const; - void clear_children(); - void set_text_align(int p_column, TextAlign p_align); TextAlign get_text_align(int p_column) const; void set_expand_right(int p_column, bool p_enable); bool get_expand_right(int p_column) const; - void move_to_top(); - void move_to_bottom(); - void set_disable_folding(bool p_disable); bool is_folding_disabled() const; + /* Item manipulation */ + + TreeItem *create_child(int p_idx = -1); + + Tree *get_tree(); + + TreeItem *get_prev(); + TreeItem *get_next(); + TreeItem *get_parent(); + TreeItem *get_first_child(); + + TreeItem *get_prev_visible(bool p_wrap = false); + TreeItem *get_next_visible(bool p_wrap = false); + + TreeItem *get_child(int p_idx); + int get_child_count(); + Array get_children(); + int get_index(); + + void move_before(TreeItem *p_item); + void move_after(TreeItem *p_item); + + void remove_child(TreeItem *p_item); + void call_recursive(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + void clear_children(); + ~TreeItem(); }; @@ -441,6 +494,8 @@ private: Color guide_color; Color drop_position_color; Color relationship_line_color; + Color parent_hl_line_color; + Color children_hl_line_color; Color custom_button_font_highlight; int hseparation = 0; @@ -449,6 +504,10 @@ private: int button_margin = 0; Point2 offset; int draw_relationship_lines = 0; + int relationship_line_width = 0; + int parent_hl_line_width = 0; + int children_hl_line_width = 0; + int parent_hl_line_margin = 0; int draw_guides = 0; int scroll_border = 0; int scroll_speed = 0; @@ -521,6 +580,8 @@ private: bool hide_folding = false; int _count_selected_items(TreeItem *p_from) const; + bool _is_branch_selected(TreeItem *p_from) const; + bool _is_sibling_branch_selected(TreeItem *p_from) const; void _go_left(); void _go_right(); void _go_down(); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index fa98a10a26..181fe606c8 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -271,7 +271,7 @@ void CanvasItemMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &CanvasItemMaterial::set_particles_anim_loop); ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &CanvasItemMaterial::get_particles_anim_loop); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,Premult Alpha"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply,Premultiplied Alpha"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"), "set_light_mode", "get_light_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_animation"), "set_particles_animation", "get_particles_animation"); @@ -1414,7 +1414,7 @@ CanvasItem::~CanvasItem() { /////////////////////////////////////////////////////////////////// void CanvasTexture::set_diffuse_texture(const Ref<Texture2D> &p_diffuse) { - ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_diffuse.ptr()) != nullptr, "Cant self-assign a CanvasTexture"); + ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_diffuse.ptr()) != nullptr, "Can't self-assign a CanvasTexture"); diffuse_texture = p_diffuse; RID tex_rid = diffuse_texture.is_valid() ? diffuse_texture->get_rid() : RID(); @@ -1426,7 +1426,7 @@ Ref<Texture2D> CanvasTexture::get_diffuse_texture() const { } void CanvasTexture::set_normal_texture(const Ref<Texture2D> &p_normal) { - ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_normal.ptr()) != nullptr, "Cant self-assign a CanvasTexture"); + ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_normal.ptr()) != nullptr, "Can't self-assign a CanvasTexture"); normal_texture = p_normal; RID tex_rid = normal_texture.is_valid() ? normal_texture->get_rid() : RID(); RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_NORMAL, tex_rid); @@ -1436,7 +1436,7 @@ Ref<Texture2D> CanvasTexture::get_normal_texture() const { } void CanvasTexture::set_specular_texture(const Ref<Texture2D> &p_specular) { - ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_specular.ptr()) != nullptr, "Cant self-assign a CanvasTexture"); + ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_specular.ptr()) != nullptr, "Can't self-assign a CanvasTexture"); specular_texture = p_specular; RID tex_rid = specular_texture.is_valid() ? specular_texture->get_rid() : RID(); RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_SPECULAR, tex_rid); @@ -1554,7 +1554,7 @@ void CanvasTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "specular_shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular_shininess", "get_specular_shininess"); ADD_GROUP("Texture", "texture_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Inherit,Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Inherit,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Aniso.,Linear Mipmap Aniso."), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Inherit,Disabled,Enabled,Mirror"), "set_texture_repeat", "get_texture_repeat"); } diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 884696d58d..927b114fbc 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -375,17 +375,19 @@ bool HTTPRequest::_update_connection() { } PackedByteArray chunk = client->read_response_body_chunk(); - downloaded.add(chunk.size()); - if (file) { - const uint8_t *r = chunk.ptr(); - file->store_buffer(r, chunk.size()); - if (file->get_error() != OK) { - call_deferred("_request_done", RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PackedByteArray()); - return true; + if (chunk.size()) { + downloaded.add(chunk.size()); + if (file) { + const uint8_t *r = chunk.ptr(); + file->store_buffer(r, chunk.size()); + if (file->get_error() != OK) { + call_deferred("_request_done", RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PackedByteArray()); + return true; + } + } else { + body.append_array(chunk); } - } else { - body.append_array(chunk); } if (body_size_limit >= 0 && downloaded.get() > body_size_limit) { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index c90d3e4a32..dc7057f339 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2872,7 +2872,7 @@ void Node::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); ADD_GROUP("Process", "process_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,WhenPaused,Always,Disabled"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,When Paused,Always,Disabled"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); ADD_GROUP("Editor Description", "editor_"); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 387af3703b..3e08f86fc9 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1267,7 +1267,7 @@ void SceneTree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multiplayer_poll"), "set_multiplayer_poll_enabled", "is_multiplayer_poll_enabled"); ADD_SIGNAL(MethodInfo("tree_changed")); - ADD_SIGNAL(MethodInfo("tree_process_mode_changed")); //editor only signal, but due to API hash it cant be removed in run-time + ADD_SIGNAL(MethodInfo("tree_process_mode_changed")); //editor only signal, but due to API hash it can't be removed in run-time ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_renamed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index b94a818b06..77667cf188 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -617,10 +617,10 @@ void Viewport::_process_picking() { mm->set_device(InputEvent::DEVICE_ID_INTERNAL); mm->set_global_position(physics_last_mousepos); mm->set_position(physics_last_mousepos); - mm->set_alt(physics_last_mouse_state.alt); - mm->set_shift(physics_last_mouse_state.shift); - mm->set_control(physics_last_mouse_state.control); - mm->set_metakey(physics_last_mouse_state.meta); + mm->set_alt_pressed(physics_last_mouse_state.alt); + mm->set_shift_pressed(physics_last_mouse_state.shift); + mm->set_ctrl_pressed(physics_last_mouse_state.control); + mm->set_meta_pressed(physics_last_mouse_state.meta); mm->set_button_mask(physics_last_mouse_state.mouse_mask); physics_picking_events.push_back(mm); } @@ -641,10 +641,10 @@ void Viewport::_process_picking() { physics_has_last_mousepos = true; physics_last_mousepos = pos; - physics_last_mouse_state.alt = mm->get_alt(); - physics_last_mouse_state.shift = mm->get_shift(); - physics_last_mouse_state.control = mm->get_control(); - physics_last_mouse_state.meta = mm->get_metakey(); + physics_last_mouse_state.alt = mm->is_alt_pressed(); + physics_last_mouse_state.shift = mm->is_shift_pressed(); + physics_last_mouse_state.control = mm->is_ctrl_pressed(); + physics_last_mouse_state.meta = mm->is_meta_pressed(); physics_last_mouse_state.mouse_mask = mm->get_button_mask(); } @@ -656,10 +656,10 @@ void Viewport::_process_picking() { physics_has_last_mousepos = true; physics_last_mousepos = pos; - physics_last_mouse_state.alt = mb->get_alt(); - physics_last_mouse_state.shift = mb->get_shift(); - physics_last_mouse_state.control = mb->get_control(); - physics_last_mouse_state.meta = mb->get_metakey(); + physics_last_mouse_state.alt = mb->is_alt_pressed(); + physics_last_mouse_state.shift = mb->is_shift_pressed(); + physics_last_mouse_state.control = mb->is_ctrl_pressed(); + physics_last_mouse_state.meta = mb->is_meta_pressed(); if (mb->is_pressed()) { physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1)); @@ -676,10 +676,10 @@ void Viewport::_process_picking() { Ref<InputEventKey> k = ev; if (k.is_valid()) { //only for mask - physics_last_mouse_state.alt = k->get_alt(); - physics_last_mouse_state.shift = k->get_shift(); - physics_last_mouse_state.control = k->get_control(); - physics_last_mouse_state.meta = k->get_metakey(); + physics_last_mouse_state.alt = k->is_alt_pressed(); + physics_last_mouse_state.shift = k->is_shift_pressed(); + physics_last_mouse_state.control = k->is_ctrl_pressed(); + physics_last_mouse_state.meta = k->is_meta_pressed(); continue; } @@ -2402,10 +2402,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *from = gui.key_focus ? gui.key_focus : nullptr; //hmm //keyboard focus - //if (from && p_event->is_pressed() && !p_event->get_alt() && !p_event->get_metakey() && !p_event->key->get_command()) { + //if (from && p_event->is_pressed() && !p_event->is_alt_pressed() && !p_event->is_meta_pressed() && !p_event->key->is_command_pressed()) { Ref<InputEventKey> k = p_event; //need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/right/etc> is handled here when it shouldn't be. - bool mods = k.is_valid() && (k->get_control() || k->get_alt() || k->get_shift() || k->get_metakey()); + bool mods = k.is_valid() && (k->is_ctrl_pressed() || k->is_alt_pressed() || k->is_shift_pressed() || k->is_meta_pressed()); if (from && p_event->is_pressed()) { Control *next = nullptr; @@ -3601,8 +3601,8 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled"); ADD_GROUP("Rendering", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"), "set_msaa", "get_msaa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 2e88e1251d..a55df4fbc2 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -231,7 +231,7 @@ private: Transform2D global_canvas_transform; Transform2D stretch_transform; - Size2i size; + Size2i size = Size2i(512, 512); Size2i size_2d_override; bool size_allocated = false; bool use_xr = false; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index bacb0030bb..d793be1869 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1169,64 +1169,96 @@ Ref<Theme> Window::get_theme() const { return theme; } -Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::get_icons(theme_owner, theme_owner_window, p_name, type); +void Window::set_theme_custom_type(const StringName &p_theme_type) { + theme_custom_type = p_theme_type; + Control::_propagate_theme_changed(this, theme_owner, theme_owner_window); } -Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::get_styleboxs(theme_owner, theme_owner_window, p_name, type); +StringName Window::get_theme_custom_type() const { + return theme_custom_type; } -Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::get_fonts(theme_owner, theme_owner_window, p_name, type); +void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_custom_type) { + if (theme_custom_type != StringName()) { + p_list->push_back(theme_custom_type); + } + Theme::get_type_dependencies(get_class_name(), p_list); + } else { + Theme::get_type_dependencies(p_theme_type, p_list); + } +} + +Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::get_theme_item_in_types<Ref<Texture2D>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -int Window::get_theme_font_size(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::get_font_sizes(theme_owner, theme_owner_window, p_name, type); +Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::get_theme_item_in_types<Ref<StyleBox>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -Color Window::get_theme_color(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::get_colors(theme_owner, theme_owner_window, p_name, type); +Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::get_theme_item_in_types<Ref<Font>>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -int Window::get_theme_constant(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::get_constants(theme_owner, theme_owner_window, p_name, type); +int Window::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -bool Window::has_theme_icon(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::has_icons(theme_owner, theme_owner_window, p_name, type); +Color Window::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::get_theme_item_in_types<Color>(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::has_styleboxs(theme_owner, theme_owner_window, p_name, type); +int Window::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::get_theme_item_in_types<int>(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } -bool Window::has_theme_font(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::has_fonts(theme_owner, theme_owner_window, p_name, type); +bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::has_font_sizes(theme_owner, theme_owner_window, p_name, type); +bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -bool Window::has_theme_color(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::has_colors(theme_owner, theme_owner_window, p_name, type); +bool Window::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -bool Window::has_theme_constant(const StringName &p_name, const StringName &p_type) const { - StringName type = p_type ? p_type : get_class_name(); - return Control::has_constants(theme_owner, theme_owner_window, p_name, type); +bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); +} + +bool Window::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); +} + +bool Window::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return Control::has_theme_item_in_types(theme_owner, theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } Rect2i Window::get_parent_rect() const { @@ -1382,19 +1414,22 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Window::set_theme); ClassDB::bind_method(D_METHOD("get_theme"), &Window::get_theme); - ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "type"), &Window::get_theme_icon, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "type"), &Window::get_theme_stylebox, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_font", "name", "type"), &Window::get_theme_font, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "type"), &Window::get_theme_font_size, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_color", "name", "type"), &Window::get_theme_color, DEFVAL("")); - ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "type"), &Window::get_theme_constant, DEFVAL("")); + ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Window::set_theme_custom_type); + ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Window::get_theme_custom_type); + + ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Window::get_theme_icon, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Window::get_theme_stylebox, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_font", "name", "theme_type"), &Window::get_theme_font, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "theme_type"), &Window::get_theme_font_size, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_color", "name", "theme_type"), &Window::get_theme_color, DEFVAL("")); + ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "theme_type"), &Window::get_theme_constant, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "type"), &Window::has_theme_icon, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "type"), &Window::has_theme_stylebox, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_font", "name", "type"), &Window::has_theme_font, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "type"), &Window::has_theme_font_size, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_color", "name", "type"), &Window::has_theme_color, DEFVAL("")); - ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "type"), &Window::has_theme_constant, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "theme_type"), &Window::has_theme_icon, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "theme_type"), &Window::has_theme_stylebox, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_font", "name", "theme_type"), &Window::has_theme_font, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "theme_type"), &Window::has_theme_font_size, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Window::has_theme_color, DEFVAL("")); + ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Window::has_theme_constant, DEFVAL("")); ClassDB::bind_method(D_METHOD("set_layout_direction", "direction"), &Window::set_layout_direction); ClassDB::bind_method(D_METHOD("get_layout_direction"), &Window::get_layout_direction); @@ -1409,7 +1444,7 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,FullScreen"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_screen"), "set_current_screen", "get_current_screen"); ADD_GROUP("Flags", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); @@ -1426,10 +1461,11 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "max_size"), "set_max_size", "get_max_size"); ADD_GROUP("Content Scale", "content_scale_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,CanvasItems,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,KeepWidth,KeepHeight,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); - ADD_GROUP("Theme", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); + ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type"); ADD_SIGNAL(MethodInfo("window_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"))); diff --git a/scene/main/window.h b/scene/main/window.h index 38846ed00e..494c386606 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -130,6 +130,7 @@ private: Ref<Theme> theme; Control *theme_owner = nullptr; Window *theme_owner_window = nullptr; + StringName theme_custom_type; Viewport *embedder = nullptr; @@ -241,6 +242,10 @@ public: void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; + void set_theme_custom_type(const StringName &p_theme_type); + StringName get_theme_custom_type() const; + _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; + Size2 get_contents_minimum_size() const; void grab_focus(); @@ -252,19 +257,19 @@ public: Rect2i get_usable_parent_rect() const; - Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_type = StringName()) const; - Ref<StyleBox> get_theme_stylebox(const StringName &p_name, const StringName &p_type = StringName()) const; - Ref<Font> get_theme_font(const StringName &p_name, const StringName &p_type = StringName()) const; - int get_theme_font_size(const StringName &p_name, const StringName &p_type = StringName()) const; - Color get_theme_color(const StringName &p_name, const StringName &p_type = StringName()) const; - int get_theme_constant(const StringName &p_name, const StringName &p_type = StringName()) const; - - bool has_theme_icon(const StringName &p_name, const StringName &p_type = StringName()) const; - bool has_theme_stylebox(const StringName &p_name, const StringName &p_type = StringName()) const; - bool has_theme_font(const StringName &p_name, const StringName &p_type = StringName()) const; - bool has_theme_font_size(const StringName &p_name, const StringName &p_type = StringName()) const; - bool has_theme_color(const StringName &p_name, const StringName &p_type = StringName()) const; - bool has_theme_constant(const StringName &p_name, const StringName &p_type = StringName()) const; + Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + Ref<StyleBox> get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + Ref<Font> get_theme_font(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + int get_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + Color get_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + int get_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + + bool has_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_font(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_font_size(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_color(const StringName &p_name, const StringName &p_theme_type = StringName()) const; + bool has_theme_constant(const StringName &p_name, const StringName &p_theme_type = StringName()) const; Rect2i get_parent_rect() const; virtual DisplayServer::WindowID get_window_id() const override; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 5b5eb946f0..e8ee4cb9fc 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -597,6 +597,7 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeIs>(); ClassDB::register_class<VisualShaderNodeCompare>(); ClassDB::register_class<VisualShaderNodeMultiplyAdd>(); + ClassDB::register_class<VisualShaderNodeBillboard>(); ClassDB::register_class<VisualShaderNodeSDFToScreenUV>(); ClassDB::register_class<VisualShaderNodeScreenUVToSDF>(); @@ -657,6 +658,7 @@ void register_scene_types() { ClassDB::register_class<TileSet>(); ClassDB::register_virtual_class<TileSetSource>(); ClassDB::register_class<TileSetAtlasSource>(); + ClassDB::register_class<TileSetScenesCollectionSource>(); ClassDB::register_class<TileData>(); ClassDB::register_class<TileMap>(); ClassDB::register_class<ParallaxBackground>(); @@ -979,6 +981,7 @@ void register_scene_types() { // Always make the default theme to avoid invalid default font/icon/style in the given theme. if (RenderingServer::get_singleton()) { make_default_theme(default_theme_hidpi, font); + ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed. } if (theme_path != String()) { @@ -1035,5 +1038,6 @@ void unregister_scene_types() { ParticlesMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); + ColorPicker::finish_shaders(); SceneStringNames::free(); } diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index e9bfac3653..0ffeb8a5bf 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -38,7 +38,7 @@ void BitMap::create(const Size2 &p_size) { width = p_size.width; height = p_size.height; - bitmask.resize(((width * height) / 8) + 1); + bitmask.resize((((width * height) - 1) / 8) + 1); memset(bitmask.ptrw(), 0, bitmask.size()); } diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp index 9e030bc077..6b895da606 100644 --- a/scene/resources/convex_polygon_shape_3d.cpp +++ b/scene/resources/convex_polygon_shape_3d.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "convex_polygon_shape_3d.h" -#include "core/math/quick_hull.h" +#include "core/math/convex_hull.h" #include "servers/physics_server_3d.h" Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const { @@ -38,7 +38,7 @@ Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const { if (points.size() > 3) { Vector<Vector3> varr = Variant(points); Geometry3D::MeshData md; - Error err = QuickHull::build(varr, md); + Error err = ConvexHullComputer::convex_hull(varr, md); if (err == OK) { Vector<Vector3> lines; lines.resize(md.edges.size() * 2); diff --git a/scene/resources/default_theme/SCsub b/scene/resources/default_theme/SCsub index fc61250247..0fb6bb2c62 100644 --- a/scene/resources/default_theme/SCsub +++ b/scene/resources/default_theme/SCsub @@ -2,4 +2,16 @@ Import("env") +import os +import os.path +from platform_methods import run_in_subprocess +import default_theme_builders + env.add_source_files(env.scene_sources, "*.cpp") + +env.Depends("#scene/resources/default_theme/default_font.gen.h", "#thirdparty/fonts/OpenSans_SemiBold.ttf") +env.CommandNoCache( + "#scene/resources/default_theme/default_font.gen.h", + "#thirdparty/fonts/OpenSans_SemiBold.ttf", + run_in_subprocess(default_theme_builders.make_fonts_header), +) diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 7c00c6d146..3a5b3534c6 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -30,15 +30,12 @@ #include "default_theme.h" -#include "scene/resources/theme.h" - #include "core/os/os.h" -#include "theme_data.h" - -#include "font_hidpi.inc" -#include "font_lodpi.inc" - +#include "default_font.gen.h" +#include "scene/resources/font.h" +#include "scene/resources/theme.h" #include "servers/text_server.h" +#include "theme_data.h" typedef Map<const void *, Ref<ImageTexture>> TexCacheMap; @@ -128,38 +125,6 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, return texture; } -static Ref<FontData> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) { - Ref<FontData> font(memnew(FontData)); - font->new_bitmap(p_height, p_ascent, p_height); - - Ref<Image> image = memnew(Image(p_img)); - Ref<ImageTexture> tex = memnew(ImageTexture); - tex->create_from_image(image); - - font->bitmap_add_texture(tex); - - for (int i = 0; i < p_charcount; i++) { - const int *c = &p_char_rects[i * 8]; - - int chr = c[0]; - Rect2 frect; - frect.position.x = c[1]; - frect.position.y = c[2]; - frect.size.x = c[3]; - frect.size.y = c[4]; - Point2 align(c[6], c[5]); - int advance = c[7]; - - font->bitmap_add_char(chr, 0, frect, align, advance); - } - - for (int i = 0; i < p_kerning_count; i++) { - font->bitmap_add_kerning_pair(p_kernings[i * 3 + 0], p_kernings[i * 3 + 1], p_kernings[i * 3 + 2]); - } - - return font; -} - static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) { Ref<StyleBox> style(memnew(StyleBoxEmpty)); @@ -486,7 +451,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_readonly_color", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); theme->set_color("font_outline_color", "TextEdit", Color(1, 1, 1)); theme->set_color("selection_color", "TextEdit", control_selection_color); - theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4)); theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8)); theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8)); theme->set_color("caret_color", "TextEdit", control_font_color); @@ -529,7 +493,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_readonly_color", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); theme->set_color("font_outline_color", "CodeEdit", Color(1, 1, 1)); theme->set_color("selection_color", "CodeEdit", control_selection_color); - theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4)); theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8)); theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3)); theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27)); @@ -756,6 +719,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1)); theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); + theme->set_color("parent_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); + theme->set_color("children_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); theme->set_color("custom_button_font_highlight", "Tree", control_font_hover_color); theme->set_constant("hseparation", "Tree", 4 * scale); @@ -763,6 +728,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("item_margin", "Tree", 12 * scale); theme->set_constant("button_margin", "Tree", 4 * scale); theme->set_constant("draw_relationship_lines", "Tree", 0); + theme->set_constant("relationship_line_width", "Tree", 1); + theme->set_constant("parent_hl_line_width", "Tree", 1); + theme->set_constant("children_hl_line_width", "Tree", 1); + theme->set_constant("parent_hl_line_margin", "Tree", 0); theme->set_constant("draw_guides", "Tree", 1); theme->set_constant("scroll_border", "Tree", 4); theme->set_constant("scroll_speed", "Tree", 12); @@ -1024,18 +993,25 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { Ref<StyleBox> default_style; Ref<Texture2D> default_icon; Ref<Font> default_font; - int default_font_size = 14; + int default_font_size = 16; if (p_font.is_valid()) { + // Use the custom font defined in the Project Settings. default_font = p_font; - } else if (p_hidpi) { - Ref<FontData> font_data = make_font(_hidpi_font_height, _hidpi_font_ascent, _hidpi_font_charcount, &_hidpi_font_charrects[0][0], _hidpi_font_kerning_pair_count, &_hidpi_font_kerning_pairs[0][0], _hidpi_font_img_width, _hidpi_font_img_height, _hidpi_font_img_data); - default_font.instance(); - default_font->add_data(font_data); } else { - Ref<FontData> font_data = make_font(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data); - default_font.instance(); - default_font->add_data(font_data); + // Use the default DynamicFont (separate from the editor font). + // The default DynamicFont is chosen to have a small file size since it's + // embedded in both editor and export template binaries. + Ref<Font> dynamic_font; + dynamic_font.instance(); + + Ref<FontData> dynamic_font_data; + dynamic_font_data.instance(); + dynamic_font_data->load_memory(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size, "ttf", default_font_size); + dynamic_font->add_data(dynamic_font_data); + + default_font = dynamic_font; } + Ref<Font> large_font = default_font; fill_default_theme(t, default_font, large_font, default_icon, default_style, p_hidpi ? 2.0 : 1.0); diff --git a/scene/resources/default_theme/default_theme_builders.py b/scene/resources/default_theme/default_theme_builders.py new file mode 100644 index 0000000000..0455d6d246 --- /dev/null +++ b/scene/resources/default_theme/default_theme_builders.py @@ -0,0 +1,40 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. + +""" +import os +import os.path +from platform_methods import subprocess_main + + +def make_fonts_header(target, source, env): + dst = target[0] + + g = open(dst, "w", encoding="utf-8") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _DEFAULT_FONTS_H\n") + g.write("#define _DEFAULT_FONTS_H\n") + + # Saving uncompressed, since FreeType will reference from memory pointer. + for i in range(len(source)): + with open(source[i], "rb") as f: + buf = f.read() + + name = os.path.splitext(os.path.basename(source[i]))[0] + + g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n") + g.write("static const unsigned char _font_" + name + "[] = {\n") + for j in range(len(buf)): + g.write("\t" + str(buf[j]) + ",\n") + + g.write("};\n") + + g.write("#endif") + + g.close() + + +if __name__ == "__main__": + subprocess_main(globals()) diff --git a/scene/resources/default_theme/font_hidpi.inc b/scene/resources/default_theme/font_hidpi.inc deleted file mode 100644 index 4860149e6b..0000000000 --- a/scene/resources/default_theme/font_hidpi.inc +++ /dev/null @@ -1,25463 +0,0 @@ -/* clang-format off */ -static const int _hidpi_font_height=25; -static const int _hidpi_font_ascent=19; -static const int _hidpi_font_charcount=191; -static const int _hidpi_font_charrects[191][8]={ -/* charidx , ofs_x, ofs_y, size_x, size_y, valign, halign, advance */ -{192,63,23,16,23,-4,-1,15}, -{224,184,182,10,19,0,1,13}, -{64,98,2,18,19,2,1,21}, -{96,159,234,5,4,0,5,14}, -{160,0,0,0,0,19,0,6}, -{32,0,0,0,0,19,0,6}, -{33,2,249,3,17,2,2,6}, -{193,83,25,16,23,-4,-1,15}, -{225,92,160,10,19,0,1,13}, -{65,163,23,16,17,2,-1,15}, -{161,246,236,3,17,6,2,6}, -{97,142,190,10,13,6,1,13}, -{162,67,214,9,17,2,2,13}, -{98,242,136,11,18,1,2,14}, -{194,103,25,16,23,-4,-1,15}, -{226,106,160,10,19,0,1,13}, -{66,122,146,11,17,2,2,15}, -{34,226,203,8,6,2,1,10}, -{35,189,44,14,17,2,1,16}, -{163,62,166,11,17,2,1,13}, -{195,123,23,16,23,-4,-1,15}, -{227,134,167,10,19,0,1,13}, -{67,209,65,12,17,2,1,14}, -{99,225,186,9,13,6,1,11}, -{228,170,182,10,18,1,1,13}, -{100,227,143,11,18,1,1,14}, -{196,23,23,16,22,-3,-1,15}, -{36,2,179,10,20,1,2,13}, -{68,193,65,12,17,2,2,16}, -{164,176,65,13,12,5,0,13}, -{37,120,2,18,17,2,1,20}, -{69,41,222,9,17,2,2,13}, -{165,98,99,12,17,2,1,13}, -{197,43,23,16,21,-2,-1,15}, -{229,16,179,10,20,-1,1,13}, -{101,189,109,11,13,6,1,13}, -{38,183,23,16,17,2,1,17}, -{70,54,222,9,17,2,2,12}, -{198,75,2,19,17,2,-1,20}, -{102,202,212,8,18,1,1,8}, -{166,44,268,2,24,1,6,13}, -{230,142,2,18,13,6,1,20}, -{71,2,71,14,17,2,1,17}, -{167,176,160,10,18,1,0,12}, -{199,146,94,12,23,2,1,14}, -{103,159,67,13,19,6,0,13}, -{231,212,189,9,19,6,1,11}, -{39,30,271,3,6,2,1,5}, -{72,130,99,12,17,2,2,17}, -{104,162,160,10,18,1,2,14}, -{200,238,186,9,23,-4,2,13}, -{40,46,243,7,21,2,1,7}, -{232,2,156,11,19,0,1,13}, -{168,68,235,7,3,1,4,14}, -{73,106,209,8,17,2,0,9}, -{169,230,2,17,17,2,1,20}, -{105,222,232,4,18,1,1,6}, -{201,28,222,9,23,-4,2,13}, -{41,130,238,6,21,2,0,7}, -{233,197,126,11,19,0,1,13}, -{202,93,209,9,23,-4,2,13}, -{74,13,225,7,22,2,-2,7}, -{234,167,137,11,19,0,1,13}, -{42,82,120,12,11,1,0,13}, -{170,100,236,6,8,2,1,8}, -{106,110,237,6,24,1,-1,6}, -{171,144,121,11,10,8,0,12}, -{43,2,119,12,12,5,1,13}, -{203,80,209,9,22,-3,2,13}, -{107,32,177,11,18,1,2,12}, -{235,77,166,11,18,1,1,13}, -{75,74,77,13,17,2,2,14}, -{44,230,213,4,6,16,1,6}, -{172,204,109,11,7,10,1,13}, -{236,204,234,5,19,0,0,6}, -{204,130,211,8,23,-4,0,9}, -{108,23,271,3,18,1,2,6}, -{76,86,188,10,17,2,2,12}, -{173,140,238,6,2,12,1,8}, -{45,120,237,6,2,12,1,8}, -{109,208,2,18,13,6,2,22}, -{205,178,205,8,23,-4,0,9}, -{237,213,234,5,19,0,2,6}, -{77,143,19,16,17,2,2,21}, -{46,9,251,3,3,16,2,6}, -{110,100,183,10,13,6,2,14}, -{206,154,207,8,23,-4,0,9}, -{238,238,213,8,19,0,-1,6}, -{174,2,23,17,17,2,1,20}, -{78,91,78,13,17,2,2,18}, -{175,18,125,12,2,-1,0,12}, -{111,162,90,12,13,6,1,14}, -{207,118,211,8,22,-3,0,9}, -{239,24,249,7,18,1,0,6}, -{79,203,23,15,17,2,1,18}, -{47,120,167,10,17,2,-1,9}, -{176,166,207,8,8,2,1,10}, -{112,212,143,11,19,6,2,14}, -{240,18,103,12,18,1,1,14}, -{208,171,44,14,17,2,0,16}, -{80,128,190,10,17,2,2,14}, -{48,234,115,11,17,2,1,13}, -{177,66,127,12,14,5,1,13}, -{113,182,126,11,19,6,1,14}, -{241,30,199,10,19,0,2,14}, -{81,97,52,15,22,2,1,18}, -{209,142,67,13,23,-4,2,18}, -{49,57,243,7,17,2,2,13}, -{178,190,206,8,10,2,0,8}, -{114,142,207,8,13,6,2,10}, -{242,242,87,12,19,0,1,14}, -{210,59,50,15,23,-4,1,18}, -{82,82,99,12,17,2,2,14}, -{50,2,135,11,17,2,1,13}, -{179,35,249,7,10,2,0,8}, -{115,72,188,10,13,6,0,11}, -{243,226,92,12,19,0,1,14}, -{211,40,49,15,23,-4,1,18}, -{83,129,125,11,17,2,0,13}, -{51,17,135,11,17,2,1,13}, -{180,168,219,5,4,0,5,14}, -{116,214,212,8,16,3,0,8}, -{244,194,86,12,19,0,1,14}, -{212,21,49,15,23,-4,1,18}, -{84,66,106,12,17,2,0,13}, -{52,125,78,13,17,2,0,13}, -{53,32,156,11,17,2,1,13}, -{85,50,106,12,17,2,2,17}, -{181,204,166,10,19,6,2,14}, -{117,198,189,10,13,6,2,14}, -{245,178,86,12,19,0,1,14}, -{213,2,44,15,23,-4,1,18}, -{54,47,156,11,17,2,1,13}, -{86,222,23,15,17,2,-1,14}, -{246,241,65,12,18,1,1,14}, -{214,116,52,15,22,-3,1,18}, -{182,34,131,12,21,1,1,16}, -{118,135,50,14,13,6,-1,12}, -{55,62,145,11,17,2,1,13}, -{87,2,2,22,17,2,-1,21}, -{119,28,2,20,13,6,-1,18}, -{215,114,125,11,11,5,1,13}, -{247,210,92,12,10,6,0,13}, -{183,16,251,3,3,9,2,6}, -{56,77,145,11,17,2,1,13}, -{88,225,44,14,17,2,-1,13}, -{216,78,52,15,19,1,1,18}, -{248,98,120,12,15,5,1,14}, -{120,50,127,12,13,6,0,12}, -{184,150,234,5,6,19,0,5}, -{89,207,44,14,17,2,-1,13}, -{121,153,44,14,19,6,-1,12}, -{217,225,65,12,23,-4,2,17}, -{249,44,199,10,19,0,2,14}, -{57,92,139,11,17,2,1,13}, -{185,177,232,5,10,2,0,8}, -{218,2,92,12,23,-4,2,17}, -{250,156,184,10,19,0,2,14}, -{90,232,165,10,17,2,1,13}, -{122,148,167,10,13,6,1,11}, -{58,37,263,3,13,6,2,6}, -{186,90,236,6,8,2,1,8}, -{219,34,104,12,23,-4,2,17}, -{123,2,224,7,21,2,1,9}, -{91,186,232,5,21,2,2,7}, -{251,58,191,10,19,0,2,14}, -{59,238,236,4,16,6,1,6}, -{187,47,177,11,10,8,1,12}, -{188,164,2,18,17,2,0,18}, -{252,190,149,10,18,1,2,14}, -{124,50,268,2,24,1,6,13}, -{220,114,99,12,22,-3,2,17}, -{92,137,146,11,17,2,-1,9}, -{60,159,121,11,12,5,1,13}, -{189,186,2,18,17,2,0,18}, -{253,56,77,14,25,0,-1,12}, -{221,20,76,14,23,-4,-1,13}, -{125,79,235,7,21,2,1,9}, -{93,195,234,5,21,2,0,7}, -{61,152,137,11,6,8,1,13}, -{190,52,2,19,17,2,0,18}, -{222,114,188,10,17,2,2,14}, -{254,219,115,11,24,1,2,14}, -{62,174,109,11,12,5,1,13}, -{94,108,78,13,11,2,0,13}, -{126,107,140,11,5,8,1,13}, -{223,17,156,11,18,1,2,14}, -{191,15,203,9,18,6,0,10}, -{255,38,76,14,24,1,-1,12}, -{63,2,203,9,17,2,0,10}, -{95,218,166,10,2,21,0,10}, -}; -static const int _hidpi_font_kerning_pair_count=0; -static const int _hidpi_font_kerning_pairs[1][3]={ -{0,0,0} -}; -static const int _hidpi_font_img_width=256; -static const int _hidpi_font_img_height=512; -static const int _hidpi_font_img_data_size=25255; -static const unsigned char _hidpi_font_img_data[25255]={ -137, -80, -78, -71, -13, -10, -26, -10, -0, -0, -0, -13, -73, -72, -68, -82, -0, -0, -1, -0, -0, -0, -2, -0, -8, -6, -0, -0, -0, -109, -154, -178, -251, -0, -0, -32, -0, -73, -68, -65, -84, -120, -156, -236, -157, -119, -184, -38, -53, -245, -199, -51, -84, -165, -55, -1, -21, -16, -41, -34, -42, -130, -98, -23, -1, -21, -20, -84, -108, -40, -138, -138, -10, -34, -40, -86, -148, -159, -216, -11, -34, -138, -130, -162, -40, -32, -160, -128, -160, -2, -162, -32, -162, -34, -34, -29, -145, -142, -235, -210, -219, -210, -151, -14, -219, -251, -231, -247, -199, -57, -97, -114, -231, -205, -204, -100, -102, -50, -239, -189, -119, -111, -190, -207, -179, -207, -221, -55, -57, -57, -147, -153, -73, -206, -36, -39, -167, -24, -147, -144, -144, -144, -144, -144, -144, -48, -129, -1, -172, -75, -142, -45, -74, -104, -158, -231, -208, -188, -176, -132, -230, -85, -14, -205, -58, -158, -250, -245, -156, -250, -103, -121, -234, -95, -237, -212, -239, -225, -169, -95, -25, -88, -160, -245, -235, -122, -234, -55, -5, -78, -0, -238, -5, -230, -2, -83, -128, -95, -2, -107, -149, -244, -119, -105, -224, -22, -224, -65, -96, -37, -31, -77, -8, -128, -143, -211, -0, -129, -60, -215, -1, -190, -8, -156, -15, -220, -13, -204, -1, -30, -7, -38, -1, -63, -3, -182, -12, -228, -243, -33, -224, -102, -109, -255, -63, -224, -109, -21, -180, -235, -3, -179, -244, -249, -173, -88, -195, -119, -109, -224, -43, -192, -101, -192, -19, -250, -188, -239, -5, -126, -3, -108, -160, -52, -27, -0, -191, -7, -30, -86, -190, -215, -0, -159, -0, -150, -168, -224, -187, -42, -112, -172, -62, -170, -211, -42, -232, -26, -189, -187, -62, -248, -42, -175, -235, -244, -255, -239, -211, -103, -49, -67, -223, -211, -133, -246, -89, -3, -75, -0, -159, -5, -174, -211, -231, -240, -36, -240, -79, -224, -117, -117, -253, -214, -246, -43, -105, -251, -127, -1, -143, -0, -243, -245, -239, -185, -192, -103, -234, -222, -85, -16, -128, -27, -244, -134, -246, -45, -169, -255, -164, -51, -134, -247, -41, -161, -249, -138, -214, -79, -174, -184, -206, -205, -74, -243, -126, -79, -221, -33, -206, -53, -78, -247, -212, -239, -164, -117, -55, -150, -240, -254, -43, -48, -93, -7, -225, -87, -129, -95, -1, -139, -128, -127, -149, -208, -127, -65, -249, -125, -188, -172, -191, -33, -0, -174, -5, -22, -2, -151, -56, -253, -191, -86, -127, -15, -252, -171, -225, -245, -52, -224, -251, -192, -108, -229, -115, -43, -112, -6, -112, -52, -112, -18, -112, -149, -94, -11, -224, -52, -96, -149, -10, -94, -175, -215, -251, -183, -130, -240, -126, -29, -60, -94, -225, -1, -156, -165, -124, -119, -14, -184, -231, -43, -149, -118, -1, -112, -35, -112, -5, -50, -209, -1, -30, -211, -107, -63, -166, -191, -239, -214, -241, -101, -251, -125, -98, -9, -207, -247, -2, -83, -129, -187, -128, -153, -84, -79, -212, -224, -119, -215, -35, -95, -144, -9, -253, -85, -253, -255, -125, -250, -126, -158, -212, -223, -139, -128, -157, -245, -61, -161, -215, -191, -70, -251, -128, -190, -139, -87, -215, -92, -99, -39, -224, -81, -100, -194, -31, -13, -236, -14, -188, -93, -255, -30, -173, -229, -143, -80, -33, -216, -131, -0, -28, -166, -157, -250, -75, -73, -253, -105, -136, -148, -159, -11, -156, -82, -66, -115, -142, -242, -56, -164, -226, -58, -63, -87, -154, -35, -60, -117, -183, -235, -96, -189, -18, -145, -164, -79, -43, -212, -31, -170, -109, -127, -90, -194, -123, -85, -96, -181, -66, -217, -121, -192, -116, -15, -237, -26, -136, -164, -254, -47, -21, -95, -164, -58, -0, -175, -209, -62, -253, -85, -127, -91, -120, -87, -82, -53, -188, -214, -0, -254, -173, -237, -79, -1, -94, -80, -66, -183, -46, -240, -107, -165, -187, -17, -88, -181, -132, -238, -79, -74, -179, -137, -254, -126, -169, -254, -62, -201, -67, -251, -110, -247, -62, -2, -250, -250, -38, -224, -115, -238, -243, -70, -190, -158, -71, -58, -131, -127, -33, -176, -139, -83, -255, -34, -100, -34, -2, -188, -215, -195, -243, -64, -224, -183, -192, -234, -84, -76, -212, -166, -239, -174, -71, -190, -22, -243, -129, -15, -58, -229, -203, -33, -31, -35, -128, -121, -200, -234, -235, -237, -133, -235, -92, -163, -245, -103, -84, -240, -255, -178, -62, -195, -31, -0, -43, -148, -208, -172, -0, -28, -172, -116, -95, -174, -235, -115, -213, -205, -236, -168, -29, -122, -18, -88, -178, -80, -183, -4, -34, -133, -174, -212, -127, -15, -120, -218, -47, -67, -46, -217, -182, -171, -184, -206, -59, -148, -102, -114, -161, -124, -11, -45, -63, -94, -111, -24, -224, -45, -5, -154, -171, -181, -188, -86, -218, -33, -95, -210, -215, -35, -203, -211, -223, -122, -234, -127, -161, -188, -222, -80, -199, -171, -230, -58, -191, -85, -62, -239, -208, -223, -22, -141, -4, -0, -176, -20, -178, -66, -152, -15, -236, -22, -216, -102, -95, -189, -214, -159, -75, -234, -239, -5, -110, -45, -148, -221, -9, -220, -89, -40, -91, -1, -184, -7, -249, -154, -61, -183, -73, -191, -61, -215, -92, -203, -121, -6, -199, -121, -234, -247, -215, -186, -127, -212, -240, -129, -242, -137, -218, -250, -221, -197, -228, -235, -220, -231, -209, -158, -186, -45, -156, -250, -67, -61, -245, -239, -209, -186, -7, -75, -120, -239, -132, -76, -234, -93, -245, -247, -18, -192, -222, -200, -252, -155, -137, -204, -199, -75, -128, -79, -107, -253, -110, -74, -223, -110, -37, -128, -72, -173, -57, -218, -169, -87, -20, -234, -236, -151, -227, -112, -231, -33, -109, -82, -160, -217, -74, -203, -103, -0, -203, -86, -92, -103, -37, -29, -228, -139, -128, -213, -157, -242, -3, -180, -253, -135, -145, -175, -11, -192, -145, -78, -253, -202, -122, -131, -243, -40, -145, -134, -14, -173, -139, -127, -22, -251, -3, -188, -0, -89, -186, -122, -39, -78, -40, -128, -103, -32, -43, -162, -251, -80, -161, -233, -92, -183, -169, -0, -248, -134, -182, -251, -124, -195, -118, -118, -121, -249, -90, -79, -221, -60, -224, -226, -66, -217, -165, -192, -220, -66, -217, -143, -149, -199, -87, -155, -92, -187, -162, -79, -115, -149, -223, -174, -158, -186, -55, -106, -221, -35, -53, -60, -192, -51, -81, -187, -190, -187, -152, -124, -157, -119, -61, -48, -233, -128, -167, -59, -245, -59, -120, -234, -55, -211, -186, -5, -37, -109, -31, -6, -14, -114, -202, -78, -82, -250, -169, -250, -255, -211, -149, -230, -215, -14, -205, -193, -200, -118, -160, -157, -78, -0, -81, -42, -0, -236, -95, -40, -255, -63, -251, -66, -129, -15, -234, -255, -247, -46, -208, -216, -1, -124, -86, -192, -117, -46, -85, -218, -119, -56, -101, -215, -35, -66, -97, -45, -125, -0, -179, -129, -123, -157, -122, -187, -255, -191, -48, -128, -255, -14, -200, -222, -235, -8, -109, -115, -80, -161, -254, -108, -100, -114, -108, -92, -199, -171, -230, -58, -86, -231, -241, -93, -167, -204, -34, -88, -0, -32, -66, -241, -9, -100, -133, -147, -57, -229, -203, -34, -203, -192, -201, -136, -112, -158, -141, -124, -193, -207, -36, -95, -214, -219, -47, -141, -111, -75, -53, -157, -130, -206, -1, -217, -98, -76, -115, -126, -111, -142, -12, -252, -27, -128, -165, -27, -244, -121, -73, -68, -241, -117, -18, -162, -220, -186, -31, -152, -166, -207, -53, -4, -11, -107, -248, -131, -127, -162, -118, -122, -119, -49, -249, -58, -247, -178, -89, -77, -253, -139, -61, -117, -27, -217, -74, -79, -221, -199, -16, -37, -228, -242, -250, -251, -189, -74, -122, -5, -35, -63, -154, -203, -0, -43, -59, -191, -87, -64, -4, -192, -103, -66, -239, -161, -120, -97, -59, -209, -255, -81, -40, -63, -91, -203, -159, -173, -255, -0, -126, -87, -160, -57, -79, -203, -63, -29, -112, -157, -111, -43, -237, -161, -250, -219, -158, -48, -92, -234, -208, -252, -93, -203, -94, -170, -191, -237, -254, -255, -107, -13, -239, -233, -66, -224, -9, -231, -183, -221, -234, -252, -184, -9, -31, -15, -223, -37, -16, -125, -197, -66, -224, -57, -78, -185, -69, -19, -1, -176, -151, -182, -249, -136, -83, -182, -52, -114, -2, -0, -162, -80, -60, -4, -89, -129, -221, -173, -101, -175, -117, -104, -239, -3, -174, -247, -240, -189, -137, -193, -45, -192, -20, -84, -137, -10, -100, -228, -58, -135, -109, -27, -244, -119, -13, -70, -42, -1, -255, -131, -40, -94, -127, -10, -28, -228, -60, -131, -235, -40, -81, -132, -82, -175, -12, -133, -194, -68, -141, -241, -238, -98, -242, -117, -238, -115, -163, -166, -245, -84, -11, -128, -243, -25, -185, -250, -253, -135, -146, -110, -19, -208, -167, -163, -129, -115, -155, -220, -135, -219, -120, -115, -189, -208, -12, -244, -107, -64, -190, -183, -191, -201, -161, -187, -13, -184, -207, -249, -189, -44, -185, -214, -218, -251, -48, -10, -215, -121, -173, -210, -94, -166, -191, -191, -172, -191, -247, -115, -104, -62, -165, -101, -223, -208, -223, -118, -192, -189, -162, -130, -239, -42, -133, -223, -75, -34, -95, -182, -71, -244, -247, -82, -246, -183, -75, -11, -124, -196, -55, -48, -106, -238, -225, -237, -218, -230, -239, -133, -242, -90, -120, -120, -157, -170, -85, -207, -112, -202, -172, -48, -62, -13, -88, -202, -41, -63, -89, -203, -95, -228, -148, -93, -12, -60, -238, -225, -251, -59, -165, -45, -42, -1, -79, -214, -223, -123, -235, -239, -19, -244, -119, -208, -145, -33, -162, -167, -1, -81, -150, -61, -167, -80, -151, -57, -183, -218, -90, -191, -82, -124, -31, -177, -222, -93, -13, -223, -117, -17, -1, -118, -135, -62, -131, -59, -145, -15, -79, -153, -2, -206, -34, -182, -0, -120, -20, -248, -168, -243, -219, -30, -253, -45, -89, -164, -245, -180, -221, -157, -154, -237, -85, -85, -227, -12, -120, -64, -251, -181, -149, -150, -109, -173, -191, -143, -112, -232, -236, -121, -234, -70, -250, -123, -91, -253, -125, -91, -224, -117, -150, -66, -148, -141, -115, -144, -47, -157, -61, -62, -219, -208, -161, -89, -95, -203, -46, -66, -20, -122, -243, -245, -193, -84, -157, -33, -207, -65, -142, -204, -190, -11, -124, -29, -153, -24, -0, -7, -107, -253, -167, -245, -247, -167, -156, -54, -175, -64, -246, -85, -115, -66, -7, -145, -182, -179, -171, -162, -119, -21, -202, -45, -130, -143, -1, -145, -163, -190, -187, -10, -101, -147, -148, -207, -250, -37, -215, -93, -199, -41, -59, -135, -194, -190, -94, -203, -95, -137, -124, -161, -167, -144, -31, -3, -46, -68, -236, -45, -158, -129, -28, -211, -61, -166, -255, -15, -62, -50, -212, -247, -0, -126, -77, -254, -218, -206, -51, -104, -183, -20, -53, -222, -137, -26, -229, -221, -85, -241, -5, -254, -172, -207, -224, -12, -228, -163, -100, -79, -90, -6, -148, -200, -14, -47, -136, -47, -0, -22, -48, -242, -212, -96, -62, -30, -197, -123, -201, -53, -223, -14, -204, -15, -161, -45, -99, -240, -27, -237, -151, -253, -242, -126, -71, -127, -191, -199, -161, -249, -144, -150, -125, -76, -127, -219, -37, -253, -207, -27, -92, -231, -207, -218, -230, -213, -200, -222, -107, -146, -135, -102, -178, -214, -109, -163, -180, -127, -168, -225, -121, -16, -114, -44, -54, -83, -7, -197, -100, -196, -152, -102, -73, -228, -136, -240, -17, -68, -215, -176, -148, -210, -175, -141, -104, -202, -247, -68, -20, -87, -161, -131, -104, -35, -29, -40, -247, -227, -124, -157, -181, -206, -162, -201, -22, -224, -73, -224, -170, -66, -217, -108, -224, -81, -15, -237, -85, -202, -127, -69, -167, -236, -106, -28, -125, -73, -129, -254, -29, -200, -23, -110, -174, -254, -221, -89, -203, -237, -123, -222, -75, -127, -255, -81, -127, -23, -87, -11, -3, -103, -246, -228, -202, -226, -55, -122, -234, -236, -106, -14, -224, -114, -28, -157, -70, -19, -104, -251, -211, -244, -255, -49, -223, -93, -41, -95, -96, -53, -224, -85, -5, -250, -243, -128, -89, -21, -188, -160, -255, -21, -192, -195, -200, -60, -8, -57, -154, -108, -191, -2, -80, -6, -86, -201, -247, -47, -253, -125, -1, -131, -26, -251, -117, -148, -230, -4, -135, -6, -26, -28, -65, -144, -75, -222, -163, -245, -239, -119, -60, -52, -7, -219, -235, -232, -223, -214, -6, -59, -192, -79, -148, -199, -14, -250, -123, -25, -68, -25, -249, -91, -253, -253, -212, -192, -8, -224, -101, -245, -17, -85, -104, -34, -0, -230, -1, -255, -46, -148, -61, -12, -60, -89, -40, -179, -43, -39, -236, -96, -32, -63, -189, -105, -162, -189, -182, -43, -182, -127, -163, -19, -20, -255, -145, -225, -20, -10, -71, -134, -90, -110, -183, -99, -167, -0, -203, -104, -89, -134, -28, -69, -205, -70, -116, -2, -183, -43, -205, -177, -192, -154, -78, -219, -117, -16, -163, -178, -183, -54, -232, -111, -180, -119, -87, -197, -183, -132, -230, -122, -60, -31, -39, -231, -186, -16, -95, -0, -92, -200, -72, -29, -128, -213, -135, -189, -38, -224, -158, -142, -166, -196, -240, -45, -8, -192, -154, -200, -132, -159, -142, -44, -207, -103, -162, -230, -142, -5, -186, -219, -144, -189, -210, -82, -250, -210, -231, -160, -90, -203, -192, -235, -108, -162, -55, -53, -189, -108, -194, -0, -175, -211, -186, -25, -250, -119, -253, -150, -247, -180, -49, -50, -201, -254, -238, -148, -253, -18, -217, -195, -46, -167, -191, -131, -6, -17, -114, -66, -241, -168, -62, -35, -223, -18, -223, -162, -137, -0, -152, -138, -163, -99, -209, -178, -127, -41, -159, -173, -156, -178, -143, -146, -91, -211, -109, -168, -101, -86, -87, -50, -112, -228, -86, -114, -173, -101, -144, -85, -210, -124, -28, -237, -180, -62, -31, -223, -137, -129, -111, -107, -177, -141, -211, -143, -135, -145, -21, -136, -181, -250, -187, -9, -153, -228, -47, -39, -223, -42, -44, -210, -255, -91, -59, -17, -8, -80, -22, -235, -181, -162, -189, -187, -58, -190, -30, -154, -207, -107, -223, -119, -42, -169, -183, -136, -45, -0, -246, -98, -228, -41, -128, -181, -25, -248, -15, -176, -70, -129, -118, -25, -231, -255, -246, -20, -224, -115, -229, -119, -30, -0, -114, -43, -165, -119, -234, -95, -159, -33, -131, -213, -3, -216, -115, -221, -198, -154, -71, -114, -141, -246, -192, -87, -70, -235, -151, -116, -6, -214, -45, -109, -238, -69, -249, -156, -137, -12, -248, -23, -232, -239, -79, -40, -223, -13, -28, -154, -160, -65, -4, -236, -81, -117, -191, -206, -75, -111, -34, -0, -46, -213, -254, -173, -224, -148, -189, -81, -7, -223, -147, -136, -117, -221, -73, -58, -96, -63, -141, -28, -25, -94, -139, -216, -100, -204, -210, -246, -75, -85, -93, -195, -225, -251, -53, -223, -59, -37, -224, -200, -176, -80, -183, -53, -114, -108, -252, -48, -50, -177, -111, -68, -108, -57, -220, -99, -169, -231, -32, -71, -177, -119, -34, -203, -244, -25, -218, -239, -131, -128, -181, -3, -251, -27, -237, -221, -85, -241, -245, -212, -127, -82, -235, -247, -172, -224, -97, -17, -91, -0, -44, -135, -8, -204, -239, -57, -101, -118, -203, -246, -16, -162, -8, -62, -22, -177, -113, -113, -143, -116, -127, -160, -207, -102, -229, -34, -207, -70, -64, -108, -209, -33, -215, -56, -15, -44, -215, -200, -245, -0, -182, -99, -251, -249, -120, -141, -54, -200, -5, -212, -207, -157, -178, -186, -179, -234, -245, -43, -248, -217, -229, -239, -46, -37, -245, -22, -77, -4, -192, -129, -218, -230, -125, -133, -242, -183, -34, -75, -208, -185, -136, -118, -126, -119, -45, -223, -17, -89, -98, -63, -170, -207, -127, -117, -63, -231, -129, -235, -108, -128, -8, -140, -187, -41, -104, -182, -41, -63, -50, -108, -45, -120, -187, -34, -246, -187, -171, -226, -91, -168, -255, -54, -34, -120, -223, -226, -171, -31, -6, -128, -119, -225, -152, -82, -35, -91, -172, -61, -80, -161, -140, -163, -220, -213, -250, -15, -40, -253, -59, -99, -92, -252, -245, -250, -128, -158, -64, -164, -224, -128, -101, -17, -185, -30, -224, -113, -253, -251, -34, -31, -175, -209, -4, -178, -130, -248, -175, -246, -209, -213, -97, -124, -222, -243, -15, -228, -220, -250, -243, -148, -120, -129, -33, -90, -103, -144, -229, -153, -215, -104, -198, -25, -136, -77, -4, -192, -198, -250, -66, -175, -43, -227, -27, -3, -192, -223, -180, -111, -239, -242, -212, -149, -29, -25, -54, -222, -91, -199, -64, -236, -119, -87, -199, -215, -169, -251, -37, -34, -12, -159, -223, -215, -189, -133, -2, -57, -201, -90, -8, -124, -143, -146, -237, -53, -176, -60, -242, -193, -94, -8, -124, -61, -214, -133, -151, -33, -223, -119, -95, -86, -65, -119, -155, -210, -220, -19, -229, -194, -145, -65, -110, -96, -227, -245, -112, -44, -208, -214, -14, -118, -114, -101, -228, -193, -53, -124, -160, -161, -55, -32, -185, -213, -226, -81, -116, -112, -78, -170, -232, -151, -221, -71, -122, -45, -53, -41, -63, -50, -12, -114, -89, -141, -141, -216, -239, -46, -132, -47, -114, -252, -55, -19, -248, -166, -71, -200, -120, -173, -253, -250, -6, -178, -18, -120, -28, -249, -232, -28, -137, -232, -129, -222, -174, -127, -143, -212, -242, -199, -136, -241, -229, -47, -92, -248, -47, -250, -160, -190, -87, -65, -99, -245, -0, -199, -70, -189, -120, -4, -32, -230, -181, -15, -34, -190, -221, -181, -95, -213, -186, -65, -132, -120, -146, -205, -70, -246, -229, -165, -198, -78, -4, -160, -164, -221, -178, -228, -74, -196, -243, -241, -216, -246, -59, -180, -27, -0, -95, -168, -187, -39, -135, -126, -69, -68, -203, -63, -139, -234, -237, -205, -187, -144, -189, -252, -92, -253, -235, -221, -230, -244, -141, -216, -239, -46, -148, -111, -205, -107, -251, -68, -219, -251, -233, -10, -96, -21, -228, -56, -251, -2, -100, -219, -183, -64, -255, -94, -128, -184, -47, -119, -219, -243, -39, -140, -13, -168, -16, -248, -57, -178, -237, -2, -57, -29, -248, -27, -112, -34, -162, -4, -252, -7, -98, -246, -91, -42, -72, -134, -216, -87, -23, -63, -11, -160, -255, -180, -219, -96, -24, -125, -76, -72, -24, -151, -0, -158, -139, -24, -96, -93, -128, -44, -197, -231, -32, -202, -175, -135, -16, -37, -208, -143, -40, -24, -172, -140, -66, -31, -93, -220, -75, -141, -193, -15, -35, -143, -72, -147, -0, -72, -72, -24, -207, -208, -121, -188, -8, -177, -182, -132, -10, -35, -21, -68, -97, -188, -8, -81, -212, -37, -1, -48, -70, -16, -93, -209, -148, -48, -225, -144, -25, -99, -206, -214, -255, -191, -167, -130, -238, -125, -74, -219, -41, -254, -66, -194, -144, -64, -79, -65, -8, -17, -207, -182, -219, -172, -210, -2, -177, -197, -190, -3, -245, -78, -107, -201, -115, -51, -196, -230, -124, -134, -46, -153, -91, -251, -248, -147, -219, -217, -79, -199, -241, -204, -155, -104, -32, -204, -235, -204, -194, -6, -111, -185, -171, -130, -246, -74, -29, -67, -79, -5, -141, -109, -208, -151, -23, -58, -215, -218, -60, -180, -93, -129, -199, -43, -16, -95, -135, -169, -228, -78, -101, -127, -35, -192, -189, -182, -132, -223, -106, -72, -28, -192, -75, -17, -165, -226, -60, -253, -123, -9, -240, -37, -234, -143, -34, -215, -38, -183, -164, -172, -220, -202, -57, -207, -108, -33, -129, -198, -83, -157, -64, -143, -65, -8, -201, -157, -72, -94, -171, -191, -109, -20, -161, -217, -29, -250, -123, -57, -162, -28, -219, -6, -241, -138, -187, -168, -3, -175, -231, -234, -139, -4, -79, -128, -141, -197, -9, -58, -8, -207, -67, -142, -152, -78, -67, -237, -22, -16, -123, -254, -251, -2, -218, -91, -108, -130, -24, -43, -129, -199, -85, -27, -57, -177, -0, -241, -98, -124, -81, -11, -1, -240, -67, -231, -90, -3, -22, -169, -1, -237, -183, -39, -87, -170, -62, -138, -152, -45, -91, -19, -229, -133, -148, -152, -249, -86, -240, -123, -55, -185, -237, -11, -136, -149, -227, -21, -228, -71, -226, -232, -24, -26, -112, -148, -42, -240, -185, -64, -105, -75, -143, -148, -149, -206, -250, -195, -92, -208, -164, -159, -173, -64, -207, -65, -8, -25, -92, -1, -172, -130, -172, -0, -188, -65, -70, -3, -121, -206, -68, -221, -82, -129, -93, -240, -4, -0, -109, -200, -111, -75, -196, -0, -106, -33, -240, -242, -46, -188, -10, -124, -215, -36, -183, -173, -184, -162, -3, -31, -87, -155, -30, -100, -79, -95, -194, -231, -56, -228, -88, -112, -50, -178, -63, -183, -251, -249, -89, -192, -49, -1, -237, -45, -54, -35, -247, -24, -253, -145, -135, -206, -70, -204, -253, -8, -121, -188, -137, -208, -208, -232, -75, -34, -167, -30, -211, -244, -223, -3, -4, -172, -78, -10, -60, -236, -170, -238, -120, -52, -52, -28, -114, -218, -98, -45, -88, -7, -252, -92, -42, -120, -237, -72, -30, -150, -254, -116, -10, -199, -193, -136, -233, -243, -239, -181, -126, -14, -21, -95, -119, -114, -31, -142, -74, -75, -75, -228, -200, -18, -28, -55, -232, -94, -192, -96, -16, -66, -23, -179, -16, -5, -206, -103, -28, -250, -110, -65, -8, -35, -1, -89, -94, -158, -133, -216, -166, -159, -67, -64, -200, -176, -0, -158, -91, -234, -96, -187, -33, -70, -31, -149, -231, -81, -250, -44, -31, -160, -16, -68, -163, -1, -143, -23, -33, -66, -196, -78, -136, -25, -148, -216, -178, -7, -240, -154, -10, -124, -64, -255, -255, -98, -68, -56, -63, -137, -172, -10, -188, -121, -20, -10, -237, -45, -182, -32, -143, -111, -119, -135, -135, -110, -146, -78, -134, -149, -112, -2, -101, -6, -246, -241, -205, -74, -126, -166, -254, -3, -216, -177, -225, -125, -218, -85, -231, -75, -10, -229, -91, -218, -137, -26, -200, -231, -105, -200, -105, -7, -72, -0, -151, -210, -83, -15, -228, -216, -22, -196, -124, -219, -43, -176, -24, -185, -13, -240, -90, -209, -146, -111, -127, -250, -93, -254, -227, -15, -66, -8, -178, -23, -62, -10, -248, -3, -185, -27, -234, -199, -28, -154, -110, -65, -8, -35, -0, -177, -129, -182, -152, -6, -60, -111, -180, -250, -82, -6, -196, -51, -110, -33, -178, -116, -108, -28, -46, -92, -121, -172, -133, -44, -55, -167, -33, -49, -20, -94, -167, -2, -224, -142, -144, -9, -235, -225, -23, -228, -60, -84, -209, -254, -41, -1, -160, -191, -109, -190, -135, -45, -29, -154, -77, -181, -236, -116, -253, -221, -84, -0, -216, -136, -203, -123, -34, -113, -242, -0, -126, -223, -176, -159, -214, -225, -236, -205, -133, -114, -203, -47, -200, -215, -129, -220, -77, -126, -54, -142, -123, -115, -9, -173, -13, -63, -14, -78, -220, -75, -15, -221, -133, -74, -243, -141, -146, -250, -175, -107, -125, -231, -143, -90, -37, -40, -4, -33, -212, -50, -128, -41, -206, -239, -151, -105, -217, -121, -78, -89, -227, -32, -132, -68, -80, -234, -20, -248, -117, -218, -35, -14, -3, -136, -85, -221, -84, -2, -179, -249, -148, -240, -184, -10, -49, -211, -117, -93, -120, -95, -138, -36, -155, -184, -170, -170, -109, -31, -240, -8, -0, -235, -208, -244, -125, -135, -198, -110, -13, -172, -67, -75, -176, -0, -64, -172, -23, -103, -34, -75, -238, -103, -32, -138, -183, -121, -200, -106, -52, -56, -139, -19, -121, -20, -235, -243, -200, -99, -31, -108, -71, -190, -143, -31, -240, -139, -40, -225, -99, -151, -246, -65, -39, -25, -228, -1, -86, -142, -175, -160, -177, -219, -185, -107, -75, -234, -109, -24, -252, -214, -91, -189, -32, -80, -8, -66, -168, -101, -69, -1, -176, -162, -150, -253, -175, -64, -215, -40, -8, -97, -204, -9, -75, -132, -61, -162, -135, -103, -84, -1, -53, -214, -209, -246, -126, -61, -2, -192, -78, -238, -91, -28, -154, -155, -144, -85, -202, -114, -5, -154, -16, -1, -96, -221, -174, -255, -233, -148, -89, -103, -166, -143, -85, -181, -45, -240, -121, -22, -185, -75, -249, -49, -200, -170, -98, -17, -34, -76, -62, -217, -128, -143, -93, -225, -4, -133, -78, -39, -143, -140, -52, -16, -172, -213, -161, -113, -183, -1, -235, -23, -234, -108, -26, -189, -133, -192, -51, -67, -251, -217, -10, -20, -66, -16, -105, -217, -83, -2, -0, -241, -79, -182, -46, -194, -71, -20, -232, -130, -67, -16, -197, -158, -176, -68, -216, -35, -122, -120, -142, -249, -21, -69, -76, -180, -189, -223, -162, -0, -208, -178, -91, -181, -108, -115, -103, -178, -255, -214, -169, -111, -34, -0, -172, -150, -124, -79, -167, -236, -35, -90, -214, -104, -73, -76, -158, -245, -200, -226, -82, -52, -218, -116, -3, -30, -118, -11, -252, -161, -64, -250, -221, -148, -254, -177, -26, -58, -187, -13, -216, -183, -80, -254, -89, -45, -111, -125, -170, -21, -12, -10, -65, -8, -181, -12, -68, -82, -90, -205, -181, -125, -112, -69, -23, -202, -224, -32, -132, -68, -158, -176, -68, -216, -35, -22, -248, -141, -249, -21, -69, -76, -126, -93, -238, -215, -233, -131, -43, -0, -108, -70, -167, -3, -157, -255, -239, -228, -212, -7, -9, -0, -68, -155, -110, -191, -210, -110, -234, -177, -149, -17, -165, -222, -34, -2, -163, -67, -33, -43, -9, -155, -142, -204, -226, -7, -33, -109, -11, -124, -172, -246, -191, -54, -111, -162, -210, -239, -172, -244, -149, -115, -131, -124, -27, -80, -76, -224, -114, -190, -150, -183, -14, -172, -26, -12, -202, -87, -0, -51, -16, -39, -148, -187, -245, -1, -108, -224, -105, -219, -100, -5, -16, -109, -194, -18, -105, -143, -88, -224, -57, -230, -87, -20, -49, -249, -117, -185, -95, -167, -15, -174, -0, -176, -154, -245, -155, -17, -229, -228, -99, -140, -12, -89, -21, -42, -0, -108, -146, -153, -129, -112, -93, -136, -203, -46, -192, -55, -107, -120, -44, -137, -28, -117, -218, -113, -252, -85, -36, -145, -137, -205, -90, -244, -253, -2, -189, -53, -104, -242, -70, -182, -70, -142, -134, -33, -60, -109, -91, -232, -10, -224, -153, -200, -50, -127, -33, -170, -92, -68, -242, -46, -44, -64, -4, -221, -64, -22, -237, -232, -160, -16, -132, -80, -203, -32, -223, -2, -216, -24, -248, -190, -140, -42, -65, -65, -8, -137, -60, -97, -137, -180, -71, -44, -240, -28, -211, -43, -138, -30, -248, -181, -190, -95, -114, -108, -81, -40, -191, -195, -169, -59, -182, -80, -23, -42, -0, -110, -161, -30, -183, -214, -240, -176, -123, -240, -135, -113, -210, -217, -35, -81, -150, -236, -209, -160, -171, -176, -252, -165, -150, -121, -147, -131, -32, -138, -92, -8, -215, -1, -212, -102, -202, -118, -104, -47, -82, -218, -143, -235, -239, -143, -234, -239, -139, -235, -218, -70, -1, -133, -32, -132, -90, -6, -35, -149, -128, -231, -107, -217, -235, -157, -178, -224, -32, -132, -68, -158, -176, -68, -220, -35, -106, -219, -49, -191, -162, -136, -201, -175, -235, -253, -146, -163, -40, -0, -126, -228, -212, -109, -87, -168, -171, -21, -0, -200, -17, -39, -200, -87, -187, -44, -171, -144, -13, -36, -91, -229, -128, -100, -163, -18, -15, -164, -178, -71, -12, -122, -158, -18, -2, -72, -102, -170, -57, -136, -197, -160, -215, -148, -156, -60, -55, -95, -232, -41, -128, -205, -204, -60, -144, -32, -213, -67, -251, -25, -165, -61, -189, -208, -246, -179, -33, -215, -234, -12, -252, -65, -8, -97, -164, -0, -216, -18, -89, -146, -92, -75, -30, -146, -58, -56, -8, -33, -113, -149, -58, -207, -33, -210, -30, -209, -105, -59, -30, -86, -20, -49, -183, -80, -157, -238, -151, -28, -69, -1, -96, -195, -166, -77, -101, -48, -203, -116, -136, -0, -176, -6, -83, -135, -87, -208, -252, -76, -105, -142, -170, -160, -177, -177, -3, -183, -45, -169, -127, -51, -121, -54, -43, -123, -74, -240, -195, -10, -126, -239, -83, -154, -57, -52, -179, -3, -120, -123, -21, -173, -210, -219, -109, -192, -147, -200, -92, -156, -174, -99, -248, -217, -117, -109, -163, -129, -193, -32, -132, -224, -8, -0, -45, -179, -22, -78, -31, -163, -65, -16, -66, -34, -79, -88, -34, -236, -17, -61, -237, -198, -244, -138, -162, -7, -126, -81, -239, -55, -6, -16, -19, -93, -59, -25, -95, -89, -65, -103, -29, -100, -30, -163, -36, -19, -53, -146, -238, -28, -224, -43, -21, -124, -118, -37, -199, -29, -84, -68, -31, -210, -190, -221, -165, -180, -191, -43, -163, -83, -90, -107, -102, -124, -19, -225, -74, -85, -187, -13, -248, -162, -254, -173, -204, -157, -216, -11, -232, -41, -8, -97, -236, -9, -75, -132, -61, -98, -129, -223, -115, -24, -227, -43, -138, -152, -252, -250, -184, -223, -24, -32, -143, -91, -88, -107, -157, -71, -190, -196, -247, -186, -33, -147, -39, -253, -152, -173, -207, -206, -205, -175, -184, -30, -146, -123, -241, -225, -194, -152, -57, -160, -230, -154, -111, -34, -63, -13, -56, -133, -193, -188, -136, -235, -145, -7, -87, -157, -67, -133, -16, -243, -240, -182, -219, -128, -251, -245, -111, -183, -216, -254, -109, -65, -15, -65, -8, -137, -56, -97, -137, -180, -71, -44, -240, -28, -15, -43, -138, -152, -91, -168, -232, -247, -27, -3, -228, -113, -40, -107, -175, -77, -110, -121, -120, -102, -73, -253, -74, -136, -167, -168, -197, -124, -228, -52, -203, -245, -228, -91, -136, -108, -57, -118, -116, -198, -204, -64, -134, -170, -2, -223, -119, -21, -120, -220, -166, -215, -113, -189, -1, -167, -226, -232, -202, -2, -239, -253, -89, -136, -224, -69, -255, -174, -83, -223, -170, -39, -16, -49, -8, -33, -145, -39, -44, -145, -246, -136, -5, -250, -49, -189, -162, -232, -129, -95, -212, -251, -141, -1, -100, -91, -99, -221, -118, -7, -142, -155, -61, -244, -214, -207, -96, -30, -37, -177, -27, -144, -204, -86, -159, -68, -20, -216, -54, -174, -197, -99, -136, -99, -219, -161, -56, -161, -191, -145, -109, -133, -61, -234, -251, -118, -205, -181, -215, -64, -132, -232, -101, -72, -152, -54, -27, -174, -237, -98, -100, -101, -209, -54, -94, -134, -77, -102, -251, -239, -122, -234, -113, -2, -34, -78, -88, -34, -238, -17, -29, -218, -49, -191, -162, -136, -201, -175, -143, -251, -77, -72, -240, -34, -246, -132, -37, -226, -30, -209, -161, -27, -15, -43, -138, -152, -91, -168, -232, -247, -155, -144, -224, -69, -236, -9, -75, -196, -61, -162, -210, -140, -249, -21, -69, -76, -126, -125, -220, -111, -66, -66, -41, -98, -78, -88, -250, -217, -35, -142, -249, -21, -69, -76, -126, -125, -220, -111, -194, -4, -3, -225, -231, -154, -209, -39, -108, -108, -196, -20, -80, -74, -19, -123, -203, -19, -155, -95, -212, -251, -13, -1, -162, -48, -179, -86, -119, -165, -249, -246, -144, -252, -136, -32, -182, -250, -107, -84, -208, -21, -177, -16, -57, -206, -187, -4, -177, -247, -95, -181, -97, -255, -214, -82, -62, -39, -20, -202, -47, -3, -30, -172, -104, -183, -10, -185, -210, -240, -131, -21, -116, -239, -82, -154, -39, -129, -85, -60, -245, -43, -146, -219, -44, -236, -81, -193, -103, -71, -165, -185, -135, -190, -3, -240, -208, -49, -96, -228, -120, -0, -227, -96, -69, -17, -147, -95, -31, -247, -27, -10, -242, -179, -241, -42, -75, -187, -131, -148, -230, -212, -26, -94, -22, -54, -247, -226, -127, -200, -163, -254, -160, -99, -118, -32, -155, -117, -5, -191, -237, -181, -221, -23, -157, -178, -12, -217, -86, -253, -179, -166, -237, -183, -181, -109, -105, -92, -65, -114, -205, -254, -129, -21, -52, -86, -72, -60, -130, -39, -211, -51, -18, -142, -204, -190, -223, -119, -135, -222, -91, -107, -208, -49, -96, -228, -68, -5, -241, -87, -20, -67, -255, -98, -247, -1, -36, -98, -51, -136, -243, -210, -64, -40, -50, -96, -9, -242, -120, -123, -111, -170, -225, -101, -81, -52, -65, -222, -20, -248, -179, -214, -45, -160, -196, -4, -216, -195, -239, -11, -218, -102, -123, -167, -204, -70, -50, -174, -244, -182, -100, -228, -42, -224, -205, -158, -122, -27, -69, -107, -186, -111, -98, -23, -104, -109, -223, -127, -229, -169, -179, -130, -198, -155, -216, -53, -58, -232, -24, -48, -114, -34, -130, -200, -95, -216, -216, -252, -70, -27, -136, -89, -44, -120, -108, -227, -129, -29, -180, -110, -10, -53, -153, -145, -203, -4, -128, -214, -101, -192, -201, -90, -127, -23, -97, -137, -69, -143, -87, -250, -181, -157, -178, -119, -106, -217, -71, -3, -218, -219, -201, -57, -224, -17, -75, -190, -242, -25, -136, -150, -236, -161, -93, -151, -220, -7, -96, -43, -167, -124, -67, -196, -154, -113, -38, -195, -178, -206, -164, -99, -192, -200, -132, -132, -34, -200, -191, -180, -103, -120, -234, -78, -209, -186, -111, -5, -240, -41, -21, -0, -90, -191, -6, -185, -147, -207, -7, -2, -248, -93, -13, -60, -84, -40, -179, -118, -23, -181, -81, -131, -24, -185, -10, -112, -3, -162, -174, -163, -2, -124, -22, -129, -31, -77, -96, -95, -229, -243, -63, -59, -7, -201, -205, -189, -27, -133, -224, -31, -115, -32, -82, -60, -123, -135, -95, -148, -56, -251, -9, -195, -1, -226, -33, -103, -93, -110, -215, -116, -202, -87, -213, -242, -133, -192, -122, -1, -124, -42, -5, -128, -210, -216, -128, -156, -94, -167, -29, -90, -160, -166, -79, -118, -21, -112, -170, -83, -102, -19, -122, -252, -180, -238, -158, -156, -54, -75, -2, -215, -104, -187, -47, -145, -235, -6, -38, -19, -176, -154, -137, -2, -58, -166, -61, -42, -225, -25, -45, -158, -189, -195, -179, -83, -156, -125, -82, -26, -176, -74, -32, -91, -16, -235, -82, -91, -186, -5, -1, -54, -82, -154, -218, -173, -7, -185, -59, -243, -126, -78, -153, -77, -144, -113, -118, -85, -91, -135, -222, -162, -74, -0, -236, -175, -52, -94, -227, -40, -224, -88, -253, -119, -186, -210, -93, -227, -148, -29, -139, -172, -32, -30, -118, -203, -106, -250, -100, -87, -1, -11, -144, -37, -251, -242, -200, -137, -204, -28, -26, -186, -244, -34, -122, -131, -133, -58, -71, -238, -69, -182, -4, -175, -107, -194, -163, -53, -136, -148, -246, -168, -192, -51, -106, -60, -123, -229, -25, -35, -206, -254, -132, -73, -3, -214, -22, -228, -138, -169, -82, -37, -36, -240, -93, -165, -249, -99, -0, -191, -173, -149, -246, -122, -167, -204, -10, -226, -247, -214, -180, -173, -68, -129, -214, -134, -227, -122, -162, -134, -167, -141, -219, -183, -135, -83, -182, -188, -142, -173, -63, -212, -221, -79, -129, -151, -93, -5, -28, -65, -190, -218, -109, -101, -73, -73, -110, -215, -1, -240, -235, -54, -60, -218, -92, -52, -90, -218, -163, -66, -187, -232, -241, -236, -137, -16, -103, -95, -249, -244, -146, -6, -172, -112, -141, -12, -9, -38, -81, -171, -87, -33, -242, -234, -139, -142, -201, -88, -201, -163, -233, -122, -143, -33, -245, -222, -166, -40, -77, -80, -134, -40, -242, -208, -90, -47, -37, -87, -92, -62, -140, -19, -59, -176, -164, -157, -181, -122, -180, -184, -214, -41, -187, -164, -64, -107, -39, -246, -188, -26, -158, -7, -40, -157, -187, -119, -183, -1, -77, -188, -201, -58, -42, -120, -217, -85, -192, -44, -125, -38, -243, -105, -169, -180, -3, -246, -113, -238, -179, -113, -0, -211, -54, -23, -140, -154, -246, -104, -60, -129, -142, -105, -192, -60, -147, -118, -46, -98, -172, -113, -1, -226, -137, -182, -159, -62, -175, -223, -214, -240, -9, -89, -125, -61, -68, -33, -204, -86, -13, -207, -78, -201, -88, -129, -101, -144, -179, -105, -240, -8, -124, -224, -245, -90, -231, -61, -222, -43, -225, -249, -121, -109, -115, -32, -185, -178, -205, -27, -135, -175, -164, -189, -69, -213, -22, -224, -163, -74, -83, -25, -172, -22, -9, -171, -182, -0, -120, -154, -83, -182, -167, -182, -13, -118, -119, -119, -218, -126, -219, -233, -95, -171, -47, -55, -226, -225, -249, -48, -162, -245, -159, -133, -108, -71, -106, -117, -35, -157, -64, -15, -105, -143, -38, -2, -60, -147, -246, -14, -157, -180, -247, -144, -251, -118, -131, -124, -201, -189, -249, -223, -148, -79, -211, -213, -87, -168, -87, -98, -231, -100, -172, -192, -225, -122, -221, -95, -120, -234, -236, -17, -90, -169, -129, -143, -167, -205, -106, -58, -206, -46, -35, -95, -254, -7, -235, -131, -2, -5, -128, -205, -72, -52, -201, -83, -231, -238, -245, -31, -211, -177, -236, -150, -93, -171, -109, -255, -68, -192, -254, -191, -192, -123, -21, -167, -127, -175, -14, -109, -87, -224, -113, -168, -182, -255, -46, -121, -124, -197, -147, -218, -240, -106, -114, -209, -232, -105, -143, -148, -46, -218, -146, -54, -38, -175, -24, -40, -76, -218, -211, -128, -13, -11, -245, -27, -147, -235, -24, -230, -80, -72, -78, -233, -208, -181, -89, -125, -221, -194, -144, -142, -106, -201, -141, -89, -30, -193, -209, -68, -35, -123, -101, -235, -132, -84, -106, -226, -91, -194, -243, -68, -125, -127, -139, -128, -203, -26, -182, -181, -168, -18, -0, -231, -42, -205, -128, -209, -26, -45, -16, -187, -127, -21, -109, -55, -66, -86, -144, -15, -34, -38, -194, -107, -144, -219, -6, -116, -218, -238, -214, -93, -184, -143, -180, -71, -209, -20, -138, -49, -121, -41, -191, -78, -194, -132, -145, -147, -246, -119, -120, -38, -45, -240, -33, -173, -183, -198, -60, -215, -151, -208, -181, -93, -125, -5, -229, -180, -139, -1, -228, -24, -10, -156, -21, -31, -240, -97, -45, -107, -52, -129, -181, -173, -221, -138, -64, -243, -112, -102, -22, -101, -118, -0, -27, -147, -167, -219, -42, -53, -9, -38, -87, -72, -126, -163, -80, -254, -16, -112, -121, -147, -62, -53, -233, -95, -77, -91, -27, -219, -97, -31, -167, -236, -123, -90, -118, -126, -219, -62, -133, -92, -56, -106, -218, -35, -226, -230, -81, -143, -170, -156, -36, -130, -48, -33, -159, -180, -179, -240, -56, -174, -32, -146, -251, -97, -29, -136, -111, -35, -159, -180, -3, -138, -50, -198, -199, -234, -235, -255, -244, -154, -238, -57, -183, -253, -202, -238, -21, -202, -199, -105, -187, -190, -182, -157, -14, -172, -208, -176, -173, -133, -207, -18, -240, -233, -228, -138, -194, -201, -84, -175, -166, -62, -169, -116, -174, -80, -123, -166, -150, -5, -47, -251, -155, -244, -175, -166, -157, -213, -167, -220, -204, -200, -248, -133, -171, -146, -27, -26, -213, -70, -24, -110, -5, -34, -166, -61, -34, -162, -66, -49, -38, -47, -165, -137, -34, -76, -28, -26, -239, -209, -23, -121, -84, -216, -159, -233, -111, -27, -231, -221, -183, -36, -109, -187, -250, -42, -85, -90, -18, -127, -197, -244, -76, -125, -110, -51, -145, -176, -213, -107, -33, -194, -173, -109, -68, -98, -155, -246, -186, -241, -68, -115, -250, -239, -102, -36, -90, -2, -216, -22, -184, -82, -235, -102, -81, -51, -1, -129, -159, -43, -237, -115, -157, -50, -155, -29, -168, -117, -64, -78, -95, -255, -2, -218, -44, -129, -132, -41, -3, -143, -179, -15, -240, -45, -173, -187, -145, -62, -182, -126, -68, -76, -123, -68, -68, -133, -98, -100, -94, -49, -5, -147, -157, -180, -251, -123, -234, -172, -119, -217, -221, -232, -215, -141, -138, -44, -49, -180, -95, -125, -61, -94, -82, -223, -215, -113, -174, -53, -73, -221, -25, -216, -91, -255, -127, -98, -72, -219, -2, -159, -165, -16, -129, -4, -240, -178, -22, -237, -45, -236, -49, -224, -181, -228, -46, -211, -32, -199, -203, -175, -8, -224, -115, -62, -98, -155, -146, -57, -101, -246, -196, -230, -13, -77, -251, -229, -233, -95, -19, -1, -176, -151, -182, -185, -180, -164, -126, -37, -36, -38, -39, -120, -18, -157, -116, -6, -17, -211, -30, -17, -113, -73, -27, -153, -87, -76, -97, -226, -157, -180, -200, -215, -209, -166, -198, -122, -171, -83, -110, -245, -1, -143, -122, -120, -181, -93, -125, -45, -240, -212, -245, -118, -156, -75, -158, -24, -227, -120, -224, -239, -250, -255, -70, -19, -5, -57, -86, -180, -167, -10, -23, -52, -105, -235, -240, -40, -98, -54, -114, -234, -114, -38, -240, -113, -2, -35, -24, -33, -123, -253, -127, -23, -202, -78, -80, -158, -149, -227, -35, -176, -127, -65, -2, -0, -153, -220, -86, -89, -92, -149, -233, -200, -206, -185, -135, -136, -173, -240, -38, -98, -218, -35, -34, -42, -20, -35, -243, -138, -41, -76, -188, -147, -150, -252, -216, -230, -228, -66, -121, -213, -150, -169, -237, -234, -107, -154, -167, -174, -183, -227, -92, -68, -184, -216, -112, -241, -179, -144, -175, -120, -169, -128, -113, -218, -173, -132, -40, -64, -175, -32, -183, -41, -120, -130, -0, -15, -199, -132, -126, -225, -186, -93, -254, -69, -255, -190, -57, -100, -224, -24, -99, -172, -239, -243, -233, -30, -18, -235, -86, -121, -119, -96, -63, -108, -128, -145, -103, -246, -204, -203, -122, -118, -133, -106, -120, -175, -212, -191, -62, -11, -193, -233, -250, -247, -233, -182, -0, -241, -28, -219, -215, -24, -243, -152, -49, -166, -184, -135, -92, -174, -208, -206, -197, -3, -250, -119, -221, -192, -126, -217, -120, -241, -119, -121, -234, -172, -146, -241, -156, -44, -203, -30, -242, -212, -63, -133, -44, -203, -30, -53, -198, -88, -251, -251, -218, -19, -133, -44, -203, -230, -24, -99, -78, -49, -198, -172, -105, -228, -190, -79, -200, -178, -44, -228, -136, -108, -145, -49, -102, -101, -99, -204, -22, -198, -152, -101, -140, -140, -181, -151, -100, -89, -118, -71, -64, -219, -132, -30, -225, -10, -128, -51, -140, -76, -178, -101, -141, -49, -135, -213, -180, -251, -137, -145, -1, -125, -179, -49, -230, -175, -158, -122, -155, -81, -40, -200, -218, -204, -24, -51, -75, -255, -250, -194, -28, -197, -228, -21, -83, -152, -216, -201, -181, -142, -49, -198, -32, -75, -232, -99, -140, -49, -75, -26, -99, -246, -203, -178, -172, -24, -74, -202, -78, -218, -251, -61, -188, -174, -214, -191, -161, -89, -100, -172, -64, -242, -153, -81, -199, -20, -114, -3, -200, -178, -236, -19, -89, -142, -111, -7, -182, -153, -145, -101, -217, -58, -89, -150, -45, -147, -101, -217, -74, -89, -150, -189, -61, -203, -178, -59, -3, -251, -151, -208, -35, -158, -18, -0, -89, -150, -205, -53, -198, -124, -220, -24, -179, -208, -24, -179, -43, -21, -105, -143, -140, -49, -187, -25, -99, -230, -26, -99, -62, -146, -101, -217, -66, -15, -223, -25, -250, -119, -57, -79, -157, -15, -85, -95, -199, -152, -188, -98, -10, -19, -59, -249, -236, -196, -217, -215, -200, -228, -59, -47, -203, -50, -95, -54, -88, -75, -119, -165, -167, -174, -237, -234, -107, -192, -175, -222, -196, -21, -114, -9, -139, -57, -70, -68, -94, -201, -178, -236, -28, -99, -204, -123, -141, -49, -79, -24, -99, -118, -49, -198, -76, -193, -73, -123, -100, -100, -201, -185, -171, -49, -230, -65, -99, -204, -142, -89, -150, -149, -125, -101, -218, -46, -105, -125, -95, -199, -152, -188, -98, -10, -147, -127, -232, -223, -29, -16, -141, -243, -119, -140, -8, -150, -189, -139, -132, -1, -91, -166, -54, -171, -175, -27, -77, -46, -56, -92, -196, -20, -114, -227, -2, -136, -157, -197, -41, -148, -28, -143, -33, -217, -129, -254, -136, -39, -100, -151, -214, -23, -209, -58, -200, -40, -18, -196, -117, -111, -224, -31, -192, -125, -136, -237, -197, -52, -228, -136, -239, -135, -56, -14, -113, -37, -237, -59, -185, -168, -211, -209, -249, -203, -50, -233, -148, -246, -136, -184, -10, -197, -152, -188, -98, -158, -116, -44, -67, -158, -196, -209, -42, -210, -6, -142, -4, -149, -182, -54, -83, -44, -205, -146, -78, -206, -162, -228, -152, -139, -136, -199, -185, -227, -5, -58, -232, -209, -231, -252, -101, -224, -6, -125, -39, -147, -145, -99, -189, -83, -181, -222, -39, -48, -125, -199, -138, -173, -130, -140, -34, -169, -207, -111, -119, -218, -77, -69, -20, -159, -55, -146, -91, -38, -86, -230, -112, -164, -163, -139, -58, -29, -157, -191, -162, -128, -136, -121, -212, -35, -243, -138, -38, -76, -180, -126, -123, -231, -197, -78, -7, -54, -45, -212, -55, -202, -20, -75, -120, -210, -201, -109, -43, -120, -68, -19, -114, -49, -64, -216, -241, -226, -234, -192, -33, -136, -127, -195, -92, -202, -225, -245, -55, -64, -162, -232, -252, -202, -161, -187, -29, -17, -162, -147, -157, -178, -83, -40, -113, -55, -118, -104, -90, -7, -25, -5, -94, -64, -46, -124, -255, -11, -108, -83, -168, -95, -11, -137, -16, -84, -155, -48, -148, -14, -46, -234, -68, -112, -254, -234, -12, -34, -230, -81, -143, -204, -43, -154, -48, -81, -154, -103, -146, -219, -3, -128, -56, -108, -220, -197, -160, -197, -93, -112, -166, -88, -6, -87, -95, -11, -201, -133, -204, -69, -212, -251, -40, -68, -21, -114, -129, -60, -90, -135, -144, -215, -251, -181, -95, -205, -219, -129, -99, -128, -163, -129, -91, -157, -231, -119, -55, -226, -33, -87, -122, -239, -228, -246, -242, -199, -49, -210, -97, -201, -90, -28, -126, -161, -162, -173, -69, -171, -32, -163, -74, -99, -45, -16, -175, -37, -66, -204, -126, -58, -186, -168, -143, -58, -136, -152, -71, -61, -22, -47, -34, -10, -19, -165, -57, -70, -105, -14, -71, -246, -138, -255, -209, -151, -22, -37, -83, -172, -115, -29, -43, -184, -102, -2, -149, -186, -16, -34, -11, -185, -192, -254, -29, -71, -203, -16, -242, -192, -79, -245, -250, -255, -194, -49, -224, -65, -246, -237, -103, -107, -93, -109, -48, -76, -100, -245, -48, -3, -88, -190, -80, -158, -33, -1, -54, -7, -220, -130, -29, -26, -139, -86, -65, -70, -201, -45, -63, -33, -32, -136, -232, -132, -1, -17, -243, -168, -199, -226, -69, -92, -193, -180, -2, -146, -66, -189, -215, -220, -121, -200, -18, -215, -46, -103, -47, -5, -158, -94, -65, -27, -85, -200, -5, -246, -175, -117, -8, -121, -114, -147, -224, -29, -61, -117, -111, -214, -186, -255, -5, -244, -97, -54, -37, -201, -57, -144, -85, -209, -204, -138, -182, -22, -173, -130, -140, -34, -43, -22, -40, -49, -227, -29, -22, -144, -109, -198, -65, -136, -192, -155, -129, -8, -247, -255, -34, -65, -74, -26, -101, -75, -50, -192, -243, -145, -101, -213, -165, -200, -87, -109, -46, -98, -111, -125, -35, -98, -6, -250, -57, -28, -39, -138, -10, -62, -209, -242, -168, -199, -226, -69, -68, -193, -52, -44, -32, -49, -16, -173, -91, -241, -5, -84, -36, -153, -32, -162, -144, -11, -236, -91, -107, -231, -20, -242, -61, -255, -102, -158, -186, -205, -180, -110, -150, -175, -109, -129, -246, -118, -68, -219, -62, -32, -28, -17, -13, -252, -109, -21, -109, -67, -4, -64, -105, -144, -81, -157, -112, -0, -223, -173, -235, -103, -9, -239, -5, -250, -111, -243, -10, -154, -45, -108, -39, -75, -234, -95, -69, -110, -101, -57, -11, -9, -117, -126, -13, -249, -202, -229, -30, -42, -2, -210, -184, -140, -150, -71, -150, -116, -118, -223, -185, -0, -89, -94, -93, -142, -104, -87, -109, -148, -88, -232, -224, -49, -53, -218, -32, -162, -96, -26, -22, -16, -51, -95, -27, -101, -168, -50, -172, -58, -227, -68, -200, -145, -231, -196, -27, -176, -68, -36, -79, -206, -225, -59, -210, -45, -210, -218, -40, -58, -199, -48, -210, -149, -214, -78, -220, -210, -12, -63, -206, -243, -168, -18, -0, -165, -65, -70, -157, -231, -252, -209, -186, -126, -118, -184, -126, -169, -0, -64, -20, -125, -246, -68, -234, -199, -56, -66, -16, -153, -207, -214, -235, -241, -14, -10, -91, -164, -34, -163, -21, -201, -195, -33, -61, -12, -124, -134, -194, -210, -1, -89, -98, -110, -143, -68, -62, -45, -93, -138, -38, -244, -3, -96, -23, -2, -61, -240, -232, -81, -200, -21, -132, -72, -41, -159, -170, -129, -171, -245, -214, -49, -104, -50, -78, -0, -77, -36, -169, -198, -127, -237, -164, -174, -233, -75, -230, -240, -1, -249, -96, -157, -236, -180, -135, -138, -175, -115, -224, -4, -44, -13, -50, -74, -67, -103, -174, -150, -215, -175, -18, -0, -214, -255, -165, -204, -147, -48, -67, -20, -211, -0, -159, -173, -234, -136, -117, -150, -185, -135, -228, -168, -145, -80, -1, -70, -162, -42, -225, -103, -157, -0, -88, -93, -39, -44, -136, -128, -186, -65, -133, -129, -221, -26, -76, -193, -73, -217, -85, -194, -227, -56, -165, -253, -13, -162, -140, -189, -17, -89, -6, -223, -164, -191, -109, -236, -127, -239, -185, -122, -224, -4, -252, -168, -210, -12, -4, -25, -37, -63, -254, -251, -112, -85, -63, -43, -120, -119, -21, -0, -151, -106, -213, -167, -42, -218, -127, -86, -105, -46, -40, -35, -120, -137, -211, -145, -237, -189, -68, -9, -9, -10, -29, -39, -139, -16, -101, -211, -92, -10, -49, -7, -28, -186, -74, -1, -160, -52, -171, -146, -123, -125, -46, -64, -244, -18, -55, -35, -231, -230, -171, -5, -244, -229, -173, -192, -31, -40, -183, -4, -92, -22, -73, -178, -234, -141, -242, -27, -56, -1, -171, -130, -140, -90, -219, -139, -218, -4, -174, -29, -174, -95, -37, -0, -108, -44, -132, -82, -215, -108, -224, -141, -101, -2, -204, -18, -28, -166, -4, -215, -182, -185, -137, -16, -208, -33, -149, -23, -49, -76, -28, -19, -162, -193, -25, -180, -223, -210, -191, -139, -86, -90, -155, -0, -0, -32, -0, -73, -68, -65, -84, -222, -140, -196, -129, -2, -224, -215, -136, -206, -105, -167, -254, -122, -92, -142, -192, -9, -88, -21, -100, -212, -218, -94, -84, -166, -18, -239, -120, -253, -42, -1, -96, -149, -195, -85, -39, -86, -175, -84, -154, -1, -119, -116, -75, -96, -247, -254, -223, -111, -115, -19, -33, -160, -67, -42, -47, -122, -48, -113, -108, -34, -144, -234, -94, -18, -178, -207, -178, -3, -225, -34, -156, -56, -243, -139, -35, -156, -231, -241, -108, -242, -0, -40, -3, -105, -189, -3, -5, -192, -44, -228, -200, -106, -83, -106, -50, -3, -247, -129, -128, -119, -91, -25, -100, -20, -120, -175, -214, -45, -4, -158, -23, -251, -250, -74, -83, -37, -0, -108, -164, -160, -170, -24, -150, -219, -41, -205, -64, -64, -154, -34, -147, -221, -155, -222, -64, -8, -232, -152, -202, -139, -30, -76, -28, -105, -32, -144, -2, -6, -137, -53, -104, -249, -175, -237, -99, -5, -143, -78, -138, -51, -15, -253, -174, -74, -94, -155, -89, -55, -128, -215, -55, -156, -126, -174, -82, -65, -103, -177, -62, -185, -130, -236, -6, -10, -203, -240, -144, -123, -97, -164, -25, -175, -139, -25, -136, -113, -85, -109, -134, -223, -46, -168, -122, -183, -4, -4, -25, -69, -140, -150, -172, -53, -227, -165, -64, -168, -179, -89, -237, -245, -29, -154, -42, -1, -112, -145, -86, -149, -42, -248, -144, -99, -123, -128, -139, -203, -8, -236, -50, -194, -171, -201, -44, -121, -65, -193, -241, -210, -137, -148, -202, -43, -22, -104, -40, -144, -106, -6, -137, -53, -55, -189, -3, -40, -117, -171, -45, -60, -186, -214, -138, -179, -2, -173, -59, -248, -158, -164, -194, -62, -32, -128, -151, -107, -107, -0, -97, -2, -96, -83, -253, -125, -158, -254, -254, -92, -129, -174, -78, -9, -248, -2, -68, -121, -103, -147, -97, -62, -162, -255, -30, -103, -100, -98, -149, -248, -113, -240, -6, -239, -165, -117, -144, -81, -36, -196, -184, -85, -92, -94, -173, -109, -151, -40, -208, -108, -4, -236, -27, -114, -125, -15, -77, -149, -0, -176, -153, -150, -188, -222, -185, -140, -60, -5, -248, -82, -217, -5, -172, -34, -225, -35, -37, -245, -151, -56, -255, -174, -45, -235, -204, -120, -1, -13, -5, -82, -217, -75, -34, -15, -142, -249, -32, -37, -138, -176, -2, -143, -40, -138, -51, -135, -246, -51, -74, -106, -99, -244, -253, -40, -228, -126, -60, -124, -150, -67, -180, -230, -247, -146, -159, -41, -135, -8, -128, -23, -235, -239, -23, -35, -10, -188, -199, -113, -194, -164, -215, -12, -220, -237, -17, -205, -255, -21, -192, -11, -61, -245, -43, -146, -39, -30, -237, -197, -89, -169, -112, -47, -93, -131, -140, -190, -9, -57, -102, -181, -120, -20, -49, -198, -185, -66, -199, -90, -217, -115, -240, -142, -173, -2, -77, -213, -115, -92, -158, -252, -35, -240, -115, -156, -179, -126, -125, -175, -246, -136, -244, -94, -74, -86, -167, -6, -152, -164, -68, -7, -4, -220, -104, -163, -37, -106, -27, -32, -103, -216, -118, -223, -95, -154, -117, -6, -217, -159, -129, -76, -168, -129, -248, -252, -17, -251, -51, -240, -146, -144, -189, -223, -66, -228, -203, -235, -205, -250, -83, -194, -227, -91, -250, -183, -181, -226, -76, -233, -86, -68, -4, -207, -253, -200, -82, -245, -106, -228, -75, -245, -172, -22, -247, -247, -11, -189, -228, -62, -206, -96, -13, -17, -0, -238, -243, -56, -82, -203, -142, -114, -202, -170, -6, -174, -61, -254, -219, -164, -226, -58, -171, -42, -77, -111, -238, -172, -12, -162, -85, -144, -81, -229, -181, -18, -226, -130, -124, -62, -178, -181, -156, -175, -255, -30, -68, -44, -56, -7, -188, -52, -125, -207, -210, -67, -83, -183, -146, -122, -33, -185, -11, -243, -108, -68, -240, -216, -241, -128, -94, -191, -60, -2, -51, -249, -126, -216, -191, -71, -8, -236, -12, -121, -134, -84, -128, -15, -86, -240, -120, -151, -210, -60, -89, -54, -208, -200, -205, -85, -171, -150, -203, -7, -41, -205, -169, -101, -52, -49, -80, -124, -73, -136, -82, -101, -46, -34, -164, -182, -109, -200, -163, -179, -226, -76, -233, -236, -209, -212, -167, -244, -247, -219, -245, -247, -145, -13, -239, -109, -7, -109, -247, -111, -196, -239, -192, -42, -70, -155, -10, -128, -53, -144, -21, -192, -83, -102, -173, -53, -99, -197, -46, -153, -253, -95, -37, -243, -212, -22, -1, -96, -177, -141, -31, -232, -60, -239, -82, -171, -76, -224, -13, -74, -227, -11, -78, -99, -105, -86, -65, -236, -254, -255, -139, -40, -85, -103, -34, -102, -202, -223, -163, -238, -227, -232, -92, -0, -106, -150, -197, -117, -3, -148, -60, -67, -170, -215, -57, -67, -105, -46, -86, -154, -3, -43, -104, -182, -81, -26, -111, -230, -89, -100, -159, -102, -67, -96, -15, -76, -36, -165, -137, -178, -146, -112, -7, -60, -226, -170, -57, -29, -249, -250, -15, -36, -113, -168, -184, -134, -69, -12, -197, -217, -154, -218, -135, -187, -112, -252, -220, -17, -201, -63, -143, -64, -67, -46, -196, -16, -231, -126, -229, -181, -161, -150, -89, -115, -239, -70, -2, -64, -203, -173, -178, -233, -124, -253, -253, -162, -178, -123, -33, -223, -95, -123, -93, -117, -145, -252, -5, -151, -43, -205, -183, -67, -238, -103, -60, -130, -124, -245, -253, -241, -10, -26, -155, -197, -168, -116, -78, -197, -232, -200, -191, -157, -65, -89, -234, -74, -90, -55, -64, -25, -185, -10, -24, -8, -195, -68, -158, -108, -114, -58, -53, -74, -43, -100, -95, -10, -254, -0, -31, -246, -203, -53, -133, -138, -227, -35, -34, -172, -36, -156, -1, -191, -3, -185, -208, -241, -133, -247, -170, -186, -23, -139, -78, -138, -51, -165, -177, -246, -221, -123, -22, -202, -173, -253, -124, -80, -54, -89, -114, -47, -183, -61, -156, -50, -171, -124, -107, -35, -0, -150, -210, -241, -3, -240, -30, -36, -194, -141, -247, -94, -16, -197, -153, -93, -162, -254, -27, -217, -171, -254, -16, -248, -37, -162, -217, -182, -10, -201, -83, -41, -9, -230, -177, -56, -128, -60, -148, -252, -85, -248, -79, -25, -50, -242, -172, -65, -223, -235, -179, -35, -27, -146, -31, -7, -222, -141, -56, -64, -12, -228, -109, -67, -60, -143, -234, -6, -168, -93, -5, -252, -203, -83, -103, -39, -100, -173, -194, -10, -248, -130, -210, -14, -4, -192, -68, -60, -221, -160, -230, -248, -139, -56, -43, -9, -139, -251, -116, -130, -44, -212, -191, -193, -137, -49, -28, -30, -173, -21, -103, -90, -191, -33, -242, -149, -190, -181, -120, -63, -206, -96, -89, -72, -141, -247, -23, -185, -121, -235, -31, -11, -229, -22, -141, -5, -128, -214, -89, -55, -222, -41, -228, -57, -0, -203, -238, -101, -19, -100, -251, -121, -51, -34, -12, -22, -32, -219, -194, -73, -136, -99, -207, -152, -241, -200, -236, -11, -136, -223, -131, -13, -44, -115, -56, -206, -156, -67, -244, -60, -86, -183, -242, -8, -53, -102, -209, -49, -58, -243, -60, -242, -37, -9, -58, -208, -110, -38, -207, -229, -126, -47, -206, -241, -76, -5, -31, -119, -21, -176, -165, -83, -190, -14, -34, -217, -103, -81, -227, -43, -174, -244, -171, -35, -75, -248, -249, -56, -171, -18, -68, -57, -52, -71, -7, -250, -122, -1, -124, -58, -173, -36, -156, -231, -49, -21, -73, -189, -101, -87, -12, -247, -16, -232, -107, -237, -155, -52, -52, -84, -156, -105, -189, -141, -80, -227, -77, -37, -134, -228, -5, -4, -143, -208, -116, -104, -214, -215, -65, -119, -63, -133, -85, -152, -211, -207, -86, -2, -64, -235, -255, -162, -245, -7, -215, -141, -149, -97, -129, -6, -49, -15, -128, -79, -59, -247, -88, -233, -121, -25, -3, -58, -166, -108, -112, -22, -87, -137, -103, -221, -121, -31, -167, -16, -102, -172, -207, -206, -44, -1, -188, -31, -89, -122, -77, -33, -151, -204, -51, -144, -227, -134, -115, -244, -197, -122, -163, -172, -58, -124, -236, -42, -192, -205, -40, -107, -7, -196, -79, -27, -244, -231, -183, -218, -102, -63, -167, -236, -83, -90, -118, -118, -85, -91, -135, -190, -211, -74, -194, -25, -12, -175, -210, -223, -75, -147, -71, -112, -13, -50, -70, -242, -77, -26, -154, -43, -206, -182, -68, -4, -240, -13, -148, -11, -171, -140, -92, -136, -15, -28, -95, -233, -251, -189, -72, -249, -248, -148, -144, -22, -93, -4, -192, -198, -228, -74, -82, -239, -189, -244, -1, -58, -132, -39, -115, -120, -188, -72, -199, -250, -52, -253, -55, -3, -120, -65, -191, -61, -55, -6, -217, -46, -253, -28, -57, -29, -153, -173, -215, -189, -30, -217, -34, -4, -127, -249, -233, -24, -89, -56, -26, -200, -87, -1, -11, -144, -101, -235, -242, -200, -249, -234, -28, -224, -217, -13, -248, -216, -60, -238, -215, -59, -101, -246, -38, -223, -27, -200, -163, -211, -74, -162, -100, -242, -110, -66, -46, -181, -107, -61, -193, -202, -38, -13, -205, -20, -103, -255, -12, -185, -111, -100, -255, -13, -112, -174, -167, -206, -250, -200, -123, -67, -144, -59, -253, -108, -45, -0, -148, -230, -71, -14, -221, -176, -4, -192, -113, -180, -12, -79, -166, -237, -215, -66, -162, -20, -77, -3, -94, -13, -188, -14, -153, -136, -119, -16, -176, -98, -29, -11, -160, -99, -100, -225, -216, -157, -177, -171, -128, -35, -200, -151, -85, -71, -213, -183, -28, -224, -99, -61, -174, -94, -138, -216, -140, -131, -196, -44, -8, -86, -14, -209, -97, -37, -81, -54, -224, -201, -181, -179, -79, -226, -248, -179, -55, -228, -17, -172, -56, -139, -1, -242, -227, -183, -91, -116, -114, -20, -255, -89, -88, -215, -92, -95, -88, -116, -239, -189, -20, -104, -86, -162, -194, -0, -166, -15, -208, -33, -60, -153, -182, -185, -10, -89, -245, -190, -216, -41, -123, -41, -114, -218, -226, -203, -196, -52, -38, -65, -135, -200, -194, -177, -59, -98, -87, -1, -179, -244, -193, -206, -175, -155, -40, -37, -124, -172, -185, -227, -129, -228, -246, -234, -63, -110, -200, -163, -245, -74, -162, -106, -192, -3, -103, -105, -221, -37, -84, -236, -51, -107, -120, -4, -43, -206, -186, -130, -22, -232, -163, -31, -37, -125, -235, -20, -215, -142, -14, -225, -201, -22, -55, -48, -86, -34, -11, -147, -175, -2, -0, -126, -221, -146, -199, -106, -200, -190, -200, -42, -35, -161, -197, -190, -140, -150, -43, -137, -154, -201, -187, -38, -249, -146, -235, -235, -109, -120, -104, -253, -152, -80, -156, -57, -253, -44, -221, -2, -244, -116, -221, -56, -113, -237, -18, -226, -129, -14, -62, -252, -14, -143, -85, -156, -65, -245, -234, -14, -125, -57, -17, -57, -149, -88, -4, -92, -214, -146, -71, -171, -149, -68, -192, -228, -125, -155, -214, -207, -167, -100, -201, -21, -192, -99, -84, -20, -103, -158, -126, -12, -93, -0, -16, -41, -174, -29, -221, -87, -16, -209, -34, -235, -34, -167, -103, -181, -122, -135, -26, -30, -157, -231, -95, -39, -208, -193, -135, -191, -192, -167, -114, -240, -7, -242, -216, -202, -225, -243, -177, -150, -60, -90, -173, -36, -66, -250, -143, -232, -57, -64, -246, -214, -3, -131, -52, -144, -199, -208, -21, -103, -158, -62, -140, -134, -0, -232, -28, -215, -142, -142, -43, -136, -174, -237, -61, -252, -126, -5, -124, -38, -148, -190, -132, -71, -163, -249, -71, -228, -208, -224, -157, -124, -248, -11, -188, -106, -7, -127, -0, -15, -187, -55, -158, -142, -199, -64, -169, -1, -159, -206, -43, -137, -150, -215, -13, -17, -0, -67, -87, -156, -121, -250, -208, -73, -0, -208, -34, -65, -38, -29, -227, -218, -209, -113, -5, -209, -181, -125, -31, -104, -58, -255, -136, -189, -133, -34, -162, -15, -127, -36, -1, -96, -253, -238, -143, -237, -216, -151, -206, -43, -137, -4, -63, -104, -153, -32, -147, -142, -113, -237, -232, -184, -130, -232, -218, -190, -15, -52, -153, -127, -99, -81, -128, -21, -59, -216, -73, -0, -32, -71, -101, -119, -42, -143, -114, -183, -198, -48, -94, -81, -86, -18, -9, -35, -65, -135, -4, -153, -116, -140, -107, -71, -247, -21, -68, -140, -21, -72, -40, -46, -41, -187, -70, -91, -208, -82, -128, -141, -139, -35, -19, -68, -67, -127, -168, -49, -102, -125, -99, -204, -133, -89, -150, -117, -61, -143, -181, -38, -180, -167, -100, -89, -54, -163, -35, -175, -4, -35, -3, -204, -24, -115, -130, -49, -102, -101, -99, -204, -117, -198, -152, -173, -179, -44, -27, -225, -186, -154, -101, -217, -131, -198, -24, -111, -10, -117, -99, -204, -52, -99, -204, -106, -198, -152, -42, -129, -188, -162, -67, -91, -132, -205, -204, -124, -99, -69, -123, -123, -252, -235, -91, -6, -119, -109, -191, -192, -24, -19, -154, -26, -172, -52, -79, -97, -7, -216, -128, -170, -222, -116, -112, -89, -150, -129, -56, -136, -189, -220, -24, -243, -110, -99, -204, -207, -70, -16, -16, -33, -61, -81, -21, -28, -233, -23, -180, -2, -64, -246, -194, -215, -171, -212, -178, -251, -154, -39, -232, -152, -175, -128, -136, -43, -137, -132, -28, -116, -76, -144, -73, -199, -184, -118, -116, -95, -65, -116, -143, -172, -27, -1, -180, -84, -226, -209, -53, -52, -120, -200, -4, -237, -34, -0, -154, -2, -73, -188, -121, -47, -185, -2, -233, -76, -2, -114, -17, -214, -240, -92, -134, -60, -60, -210, -5, -145, -186, -106, -121, -23, -49, -23, -217, -147, -253, -3, -248, -24, -53, -6, -42, -228, -129, -39, -75, -51, -225, -146, -251, -51, -84, -126, -105, -104, -17, -66, -189, -235, -251, -167, -99, -130, -76, -58, -198, -181, -163, -99, -100, -220, -174, -237, -99, -128, -14, -74, -60, -186, -10, -176, -174, -3, -96, -172, -130, -158, -86, -18, -158, -235, -88, -216, -184, -114, -87, -58, -215, -3, -9, -128, -82, -26, -45, -150, -220, -142, -224, -94, -252, -57, -232, -151, -32, -87, -174, -13, -228, -209, -43, -208, -54, -14, -161, -222, -245, -253, -211, -61, -65, -102, -167, -184, -118, -116, -95, -65, -116, -143, -172, -59, -72, -255, -107, -2, -143, -1, -233, -126, -138, -209, -77, -128, -117, -29, -0, -99, -21, -244, -176, -146, -40, -185, -206, -192, -243, -67, -38, -237, -174, -228, -19, -242, -59, -21, -237, -109, -30, -123, -240, -231, -160, -183, -2, -226, -22, -106, -98, -231, -211, -34, -132, -122, -215, -247, -79, -199, -4, -153, -202, -163, -117, -92, -59, -186, -175, -32, -186, -71, -214, -29, -108, -115, -51, -112, -116, -32, -109, -215, -83, -140, -110, -2, -172, -235, -0, -152, -232, -168, -122, -126, -192, -207, -180, -174, -74, -193, -100, -128, -15, -41, -221, -149, -158, -186, -127, -104, -221, -39, -98, -246, -219, -225, -223, -233, -253, -211, -49, -65, -166, -195, -167, -85, -92, -59, -186, -175, -32, -186, -71, -214, -237, -118, -223, -93, -79, -33, -186, -9, -176, -174, -3, -192, -211, -153, -115, -129, -29, -156, -178, -231, -33, -174, -154, -222, -32, -22, -227, -29, -85, -207, -15, -137, -173, -0, -48, -167, -134, -135, -171, -160, -220, -202, -41, -223, -4, -49, -90, -122, -136, -158, -50, -50, -119, -125, -255, -116, -76, -144, -25, -3, -116, -140, -140, -219, -181, -125, -199, -190, -119, -181, -131, -232, -38, -192, -186, -14, -128, -2, -221, -1, -228, -246, -203, -23, -35, -89, -135, -23, -34, -231, -238, -223, -174, -106, -235, -240, -24, -106, -68, -150, -174, -168, -122, -126, -72, -104, -105, -0, -223, -241, -85, -145, -214, -222, -247, -31, -157, -50, -251, -242, -170, -2, -150, -116, -58, -197, -233, -250, -254, -233, -152, -32, -51, -22, -232, -18, -25, -55, -66, -251, -14, -253, -238, -124, -10, -65, -23, -1, -214, -117, -0, -120, -104, -119, -33, -247, -59, -7, -177, -189, -175, -205, -244, -170, -109, -71, -37, -34, -75, -23, -84, -61, -63, -36, -200, -37, -4, -68, -47, -66, -226, -251, -63, -132, -8, -204, -231, -34, -49, -225, -166, -233, -75, -172, -90, -2, -119, -157, -192, -93, -219, -119, -74, -144, -57, -209, -65, -164, -83, -8, -218, -10, -176, -88, -2, -0, -216, -131, -60, -28, -213, -125, -136, -115, -203, -44, -100, -9, -91, -27, -189, -135, -150, -17, -89, -136, -247, -5, -12, -66, -69, -251, -162, -18, -112, -119, -68, -186, -47, -162, -66, -186, -23, -120, -89, -147, -231, -159, -144, -103, -254, -169, -140, -236, -210, -245, -253, -69, -184, -255, -78, -9, -50, -39, -58, -232, -225, -20, -34, -4, -125, -88, -2, -46, -105, -140, -153, -103, -140, -217, -205, -136, -165, -221, -124, -36, -212, -213, -89, -198, -152, -223, -0, -87, -102, -89, -54, -165, -162, -253, -95, -141, -49, -153, -49, -102, -171, -44, -203, -38, -25, -99, -12, -176, -181, -49, -230, -116, -173, -43, -219, -131, -217, -64, -28, -3, -97, -149, -3, -225, -211, -190, -190, -86, -255, -94, -103, -140, -153, -25, -200, -231, -56, -96, -166, -49, -102, -89, -99, -204, -6, -70, -172, -219, -102, -24, -99, -246, -200, -178, -204, -171, -160, -241, -224, -23, -198, -152, -47, -25, -99, -62, -102, -140, -121, -208, -24, -179, -200, -24, -211, -40, -248, -73, -7, -84, -221, -235, -242, -198, -152, -50, -1, -115, -134, -49, -230, -14, -35, -247, -124, -28, -176, -125, -150, -101, -179, -122, -232, -223, -226, -138, -63, -25, -99, -94, -103, -140, -249, -160, -41, -90, -233, -25, -81, -226, -105, -157, -49, -198, -252, -37, -250, -213, -187, -126, -65, -2, -248, -31, -170, -77, -91, -103, -243, -173, -225, -31, -189, -255, -33, -60, -61, -180, -69, -60, -66, -96, -96, -70, -242, -48, -221, -85, -240, -234, -67, -186, -222, -127, -140, -231, -71, -135, -4, -153, -19, -29, -140, -242, -41, -132, -33, -82, -122, -162, -138, -182, -171, -144, -159, -21, -15, -229, -28, -222, -67, -51, -12, -1, -224, -110, -1, -206, -215, -178, -61, -170, -218, -58, -244, -59, -50, -50, -9, -171, -197, -181, -78, -153, -55, -19, -81, -215, -251, -143, -245, -252, -104, -153, -32, -179, -41, -144, -60, -123, -219, -118, -228, -241, -44, -228, -136, -246, -118, -196, -86, -227, -17, -36, -188, -155, -55, -55, -132, -182, -9, -70, -139, -254, -140, -218, -41, -132, -33, -82, -122, -34, -224, -53, -136, -214, -255, -110, -228, -107, -48, -93, -95, -254, -231, -145, -68, -15, -0, -159, -247, -180, -27, -85, -45, -118, -9, -125, -45, -207, -42, -90, -224, -37, -200, -158, -248, -65, -90, -72, -237, -174, -215, -247, -208, -12, -229, -249, -209, -34, -65, -102, -83, -144, -107, -205, -91, -9, -2, -196, -215, -222, -42, -222, -166, -33, -147, -237, -86, -231, -57, -120, -141, -182, -24, -41, -160, -203, -254, -61, -25, -58, -198, -60, -252, -71, -229, -20, -194, -16, -33, -61, -17, -240, -85, -242, -164, -33, -211, -148, -151, -43, -193, -30, -208, -191, -255, -240, -180, -29, -51, -3, -184, -9, -207, -58, -90, -36, -42, -12, -192, -192, -190, -206, -195, -99, -92, -111, -1, -74, -218, -188, -4, -249, -154, -109, -90, -79, -29, -14, -196, -165, -251, -23, -228, -99, -43, -88, -16, -32, -2, -234, -30, -109, -247, -45, -70, -230, -86, -220, -1, -249, -104, -65, -131, -172, -79, -5, -254, -151, -52, -121, -70, -99, -2, -116, -76, -79, -68, -126, -68, -177, -200, -243, -80, -159, -142, -8, -7, -139, -123, -60, -237, -199, -220, -0, -14, -225, -89, -71, -11, -60, -83, -7, -212, -2, -60, -145, -112, -10, -180, -227, -126, -11, -224, -105, -243, -7, -29, -19, -231, -19, -89, -8, -40, -255, -53, -17, -239, -57, -107, -136, -84, -43, -8, -128, -47, -42, -173, -55, -115, -18, -240, -93, -173, -255, -83, -203, -62, -141, -63, -1, -96, -204, -83, -3, -176, -85, -122, -34, -242, -208, -216, -165, -81, -127, -129, -19, -44, -111, -79, -221, -152, -27, -192, -33, -60, -67, -104, -129, -175, -105, -221, -69, -33, -215, -141, -125, -125, -135, -102, -52, -4, -192, -187, -17, -223, -4, -128, -107, -67, -219, -53, -5, -242, -85, -223, -159, -124, -149, -89, -42, -8, -128, -11, -149, -198, -107, -181, -136, -232, -49, -0, -166, -182, -236, -203, -248, -20, -0, -198, -24, -67, -203, -244, -68, -72, -104, -109, -128, -247, -87, -208, -188, -85, -105, -230, -122, -234, -198, -220, -0, -142, -53, -1, -145, -21, -208, -93, -90, -255, -65, -95, -251, -62, -175, -239, -208, -12, -93, -0, -56, -109, -47, -5, -158, -104, -218, -174, -197, -117, -150, -5, -62, -129, -56, -67, -129, -223, -110, -222, -245, -210, -172, -194, -194, -150, -125, -24, -55, -2, -96, -192, -14, -32, -203, -178, -59, -141, -49, -109, -76, -111, -173, -146, -235, -222, -10, -154, -39, -245, -239, -99, -45, -248, -143, -91, -100, -89, -54, -27, -241, -243, -255, -157, -49, -230, -71, -192, -153, -197, -104, -57, -17, -48, -211, -200, -57, -125, -85, -228, -87, -107, -137, -57, -148, -40, -72, -136, -99, -16, -70, -108, -7, -182, -52, -198, -252, -97, -24, -215, -213, -107, -90, -248, -140, -146, -236, -88, -253, -175, -233, -231, -89, -124, -222, -24, -51, -16, -80, -213, -17, -10, -27, -103, -89, -118, -91, -27, -198, -192, -134, -198, -152, -111, -24, -99, -182, -55, -198, -172, -110, -196, -78, -228, -76, -99, -204, -1, -89, -150, -61, -220, -174, -187, -17, -64, -190, -244, -218, -165, -130, -230, -195, -74, -243, -119, -79, -221, -152, -251, -130, -133, -240, -28, -43, -32, -210, -41, -78, -228, -62, -205, -64, -180, -245, -83, -144, -227, -182, -222, -130, -81, -34, -91, -128, -47, -57, -227, -112, -10, -176, -15, -176, -172, -135, -214, -58, -222, -148, -154, -221, -246, -212, -71, -139, -141, -90, -182, -127, -41, -185, -158, -110, -6, -146, -241, -218, -42, -65, -239, -35, -32, -75, -118, -111, -32, -79, -89, -253, -199, -10, -154, -191, -41, -205, -94, -158, -186, -174, -2, -32, -186, -29, -195, -56, -19, -0, -157, -79, -113, -198, -35, -16, -37, -224, -247, -200, -109, -76, -110, -70, -204, -175, -75, -173, -92, -201, -93, -111, -191, -48, -228, -190, -182, -22, -0, -136, -89, -185, -77, -113, -127, -2, -42, -76, -129, -149, -17, -69, -43, -104, -114, -217, -81, -1, -114, -220, -99, -207, -102, -191, -138, -35, -121, -145, -125, -217, -119, -156, -23, -52, -224, -210, -26, -65, -0, -68, -255, -2, -142, -51, -1, -208, -233, -20, -103, -188, -1, -57, -6, -252, -57, -249, -23, -112, -18, -226, -118, -93, -25, -44, -69, -219, -238, -167, -109, -174, -199, -19, -125, -169, -47, -116, -20, -0, -111, -215, -182, -247, -2, -79, -43, -212, -45, -79, -158, -154, -238, -85, -49, -59, -124, -24, -13, -98, -160, -3, -31, -32, -63, -49, -152, -129, -156, -32, -92, -77, -254, -117, -190, -7, -120, -97, -73, -219, -174, -2, -32, -250, -23, -112, -60, -9, -0, -99, -186, -157, -226, -140, -55, -144, -127, -108, -174, -4, -222, -233, -123, -231, -21, -109, -87, -64, -182, -8, -32, -17, -162, -54, -44, -212, -63, -7, -81, -36, -238, -80, -198, -163, -101, -159, -187, -8, -0, -43, -192, -189, -246, -36, -228, -89, -169, -126, -208, -189, -167, -57, -83, -104, -24, -195, -28, -9, -252, -113, -4, -249, -41, -130, -141, -106, -250, -29, -186, -231, -155, -175, -18, -0, -209, -191, -128, -93, -5, -0, -34, -248, -162, -41, -153, -144, -124, -134, -223, -167, -58, -55, -94, -171, -83, -156, -241, -6, -196, -123, -238, -205, -29, -218, -111, -70, -126, -50, -3, -242, -5, -157, -66, -110, -4, -4, -145, -227, -80, -56, -124, -159, -131, -28, -143, -90, -171, -65, -155, -190, -252, -45, -21, -109, -255, -163, -109, -119, -43, -169, -223, -93, -235, -207, -139, -221, -225, -232, -73, -12, -74, -174, -213, -121, -15, -79, -228, -47, -96, -4, -1, -112, -59, -208, -72, -219, -203, -96, -88, -232, -39, -245, -30, -190, -133, -44, -119, -103, -0, -207, -106, -211, -159, -190, -129, -68, -93, -62, -7, -103, -27, -230, -43, -107, -200, -115, -91, -34, -71, -112, -118, -120, -175, -12, -124, -5, -89, -69, -76, -67, -140, -181, -30, -211, -201, -246, -157, -216, -2, -211, -25, -79, -63, -212, -191, -247, -1, -151, -147, -7, -3, -5, -143, -153, -188, -182, -181, -202, -77, -239, -252, -32, -143, -22, -52, -96, -100, -215, -181, -195, -195, -18, -0, -177, -124, -17, -162, -125, -1, -35, -8, -128, -127, -211, -32, -76, -54, -254, -176, -208, -147, -28, -1, -6, -112, -112, -155, -190, -12, -3, -120, -150, -169, -190, -178, -64, -94, -219, -34, -198, -60, -208, -99, -28, -254, -97, -194, -121, -135, -115, -113, -98, -99, -32, -219, -83, -27, -247, -97, -30, -158, -120, -10, -228, -186, -14, -111, -206, -5, -224, -101, -90, -31, -239, -88, -115, -200, -2, -96, -92, -107, -177, -129, -53, -144, -200, -174, -155, -57, -101, -167, -227, -152, -147, -34, -169, -179, -190, -136, -39, -203, -43, -213, -97, -161, -63, -224, -12, -158, -41, -140, -193, -116, -102, -228, -71, -188, -215, -160, -10, -96, -95, -89, -0, -31, -119, -226, -207, -70, -236, -253, -215, -239, -181, -243, -67, -130, -243, -14, -189, -193, -93, -200, -79, -201, -14, -241, -212, -217, -188, -138, -155, -149, -180, -125, -177, -214, -183, -50, -94, -50, -192, -15, -8, -199, -59, -91, -93, -164, -250, -250, -227, -90, -139, -141, -248, -194, -91, -220, -141, -164, -117, -190, -88, -255, -29, -73, -174, -116, -2, -216, -201, -211, -222, -27, -22, -26, -241, -37, -176, -86, -150, -118, -25, -232, -93, -38, -142, -22, -128, -205, -145, -47, -212, -116, -244, -235, -229, -43, -171, -225, -225, -78, -252, -39, -16, -93, -199, -154, -253, -247, -126, -120, -112, -222, -255, -219, -74, -234, -109, -236, -200, -171, -61, -117, -118, -107, -91, -183, -2, -8, -13, -92, -51, -192, -224, -19, -12, -186, -53, -162, -147, -178, -88, -254, -186, -138, -155, -11, -66, -73, -31, -198, -173, -22, -27, -17, -0, -255, -208, -254, -22, -149, -73, -211, -181, -236, -106, -100, -63, -60, -224, -111, -142, -39, -44, -52, -178, -234, -177, -225, -192, -143, -5, -246, -213, -255, -15, -100, -215, -85, -250, -205, -41, -28, -17, -57, -117, -75, -81, -227, -75, -142, -104, -199, -191, -174, -207, -221, -26, -241, -60, -140, -8, -177, -239, -80, -208, -150, -107, -155, -149, -200, -205, -110, -63, -92, -86, -86, -113, -77, -119, -226, -79, -69, -4, -225, -74, -85, -109, -198, -43, -156, -241, -80, -246, -21, -127, -189, -214, -15, -152, -76, -35, -250, -2, -168, -215, -1, -60, -16, -187, -195, -65, -91, -0, -36, -40, -100, -240, -191, -10, -62, -139, -133, -22, -27, -145, -230, -243, -16, -79, -184, -218, -88, -254, -228, -214, -105, -175, -119, -202, -108, -172, -247, -91, -144, -179, -222, -29, -244, -183, -47, -44, -244, -11, -17, -69, -214, -63, -138, -66, -0, -88, -26, -217, -142, -204, -161, -228, -156, -24, -81, -62, -222, -172, -252, -23, -234, -4, -190, -18, -39, -136, -7, -254, -132, -26, -43, -147, -135, -50, -255, -112, -89, -89, -201, -53, -237, -196, -191, -3, -209, -239, -120, -133, -87, -23, -32, -31, -149, -243, -200, -181, -237, -23, -163, -43, -88, -116, -75, -217, -128, -215, -154, -228, -202, -234, -43, -90, -244, -197, -98, -227, -146, -250, -170, -220, -133, -54, -102, -96, -153, -3, -147, -61, -5, -184, -172, -105, -191, -234, -58, -60, -20, -29, -64, -87, -32, -57, -7, -64, -190, -164, -3, -86, -96, -200, -23, -208, -126, -101, -75, -61, -22, -11, -109, -26, -217, -65, -56, -237, -94, -128, -172, -100, -78, -1, -206, -70, -4, -153, -87, -234, -59, -109, -70, -132, -133, -70, -142, -169, -230, -32, -66, -228, -101, -90, -246, -170, -138, -1, -178, -52, -112, -134, -214, -63, -37, -4, -16, -45, -252, -153, -90, -126, -22, -37, -123, -113, -224, -120, -165, -185, -141, -66, -4, -102, -196, -200, -235, -8, -74, -162, -58, -35, -38, -170, -179, -25, -185, -5, -24, -40, -243, -180, -179, -58, -143, -219, -145, -21, -104, -84, -1, -64, -158, -72, -3, -100, -251, -228, -70, -37, -250, -50, -170, -88, -107, -192, -239, -40, -135, -215, -128, -30, -39, -160, -189, -133, -55, -232, -13, -249, -87, -252, -113, -79, -221, -33, -90, -119, -120, -73, -219, -95, -104, -125, -101, -240, -216, -54, -29, -30, -47, -2, -96, -57, -96, -178, -246, -249, -32, -79, -253, -247, -181, -110, -18, -129, -201, -53, -218, -220, -63, -226, -249, -103, -83, -124, -109, -79, -254, -213, -190, -145, -234, -243, -123, -27, -157, -230, -77, -192, -211, -28, -30, -95, -118, -104, -42, -195, -66, -35, -66, -224, -207, -74, -115, -54, -242, -37, -254, -171, -254, -46, -157, -252, -218, -214, -158, -62, -148, -250, -114, -212, -220, -183, -253, -2, -185, -74, -192, -129, -178, -66, -155, -101, -17, -123, -125, -171, -31, -153, -138, -184, -244, -118, -222, -2, -0, -27, -147, -199, -39, -252, -63, -84, -177, -140, -108, -171, -62, -70, -174, -84, -11, -245, -11, -121, -185, -182, -121, -156, -246, -167, -66, -22, -239, -40, -169, -255, -148, -214, -95, -229, -169, -179, -249, -29, -239, -163, -218, -18, -208, -171, -95, -104, -5, -101, -56, -46, -4, -128, -49, -198, -0, -155, -34, -75, -180, -69, -192, -118, -78, -249, -246, -90, -54, -29, -216, -164, -1, -191, -198, -247, -79, -158, -6, -236, -78, -29, -108, -25, -112, -131, -150, -253, -178, -162, -221, -83, -97, -161, -129, -159, -234, -255, -207, -199, -49, -109, -37, -32, -44, -52, -242, -197, -183, -66, -192, -218, -199, -87, -78, -126, -109, -103, -151, -182, -91, -85, -209, -213, -240, -176, -249, -15, -126, -86, -85, -230, -105, -183, -52, -34, -44, -236, -22, -228, -9, -196, -22, -162, -181, -18, -144, -60, -8, -173, -215, -48, -134, -60, -54, -69, -168, -0, -184, -17, -17, -80, -91, -118, -232, -147, -197, -175, -74, -234, -207, -211, -250, -31, -150, -212, -91, -189, -220, -111, -200, -125, -1, -86, -4, -78, -213, -242, -235, -9, -48, -133, -110, -210, -225, -237, -232, -43, -8, -97, -79, -0, -62, -168, -15, -99, -42, -178, -175, -93, -139, -124, -217, -87, -26, -171, -160, -132, -23, -52, -23, -0, -107, -35, -58, -140, -253, -157, -178, -143, -35, -91, -148, -117, -42, -218, -89, -5, -223, -221, -136, -176, -122, -12, -88, -215, -169, -15, -78, -78, -137, -40, -243, -236, -201, -193, -163, -192, -138, -1, -253, -182, -118, -24, -165, -9, -76, -3, -120, -44, -139, -40, -57, -247, -170, -42, -171, -104, -111, -147, -169, -218, -213, -207, -44, -125, -150, -235, -183, -232, -203, -53, -202, -99, -159, -146, -250, -157, -155, -8, -128, -24, -112, -4, -192, -2, -36, -252, -155, -187, -42, -249, -63, -173, -155, -75, -137, -169, -48, -162, -31, -179, -39, -65, -51, -16, -161, -100, -149, -230, -143, -83, -19, -113, -106, -204, -67, -7, -192, -62, -136, -1, -141, -61, -18, -244, -162, -134, -143, -205, -85, -127, -142, -254, -131, -22, -123, -35, -109, -55, -44, -59, -136, -21, -200, -21, -103, -224, -40, -123, -104, -16, -22, -154, -145, -219, -0, -43, -4, -254, -130, -19, -162, -173, -164, -157, -141, -90, -52, -15, -89, -138, -46, -89, -69, -223, -39, -116, -66, -188, -19, -81, -66, -66, -11, -67, -32, -242, -16, -97, -222, -184, -126, -136, -94, -163, -118, -44, -197, -132, -243, -110, -109, -170, -239, -7, -24, -180, -4, -172, -212, -57, -33, -31, -152, -35, -17, -191, -154, -185, -250, -247, -215, -140, -119, -91, -9, -125, -233, -127, -28, -152, -233, -57, -30, -66, -20, -84, -15, -213, -189, -52, -100, -15, -125, -157, -211, -246, -42, -234, -151, -192, -163, -106, -7, -161, -125, -248, -142, -115, -141, -89, -72, -44, -192, -38, -201, -45, -93, -69, -224, -25, -200, -222, -240, -116, -253, -93, -41, -4, -180, -173, -213, -23, -128, -8, -163, -175, -50, -202, -103, -241, -192, -155, -105, -24, -74, -77, -219, -217, -108, -197, -175, -40, -169, -223, -216, -222, -104, -5, -143, -198, -97, -195, -107, -250, -100, -241, -44, -100, -165, -243, -31, -100, -91, -58, -29, -9, -83, -22, -111, -255, -62, -222, -64, -158, -65, -183, -12, -159, -80, -186, -79, -84, -189, -52, -135, -159, -155, -92, -116, -239, -0, -250, -78, -118, -16, -93, -1, -60, -3, -249, -106, -205, -5, -14, -70, -150, -228, -51, -144, -37, -222, -36, -234, -211, -99, -219, -163, -62, -244, -239, -210, -78, -185, -141, -201, -119, -38, -213, -66, -96, -9, -125, -110, -246, -204, -25, -29, -248, -63, -165, -143, -100, -20, -61, -130, -124, -5, -89, -22, -195, -114, -51, -123, -131, -37, -245, -173, -194, -134, -215, -244, -201, -98, -192, -158, -98, -194, -131, -220, -12, -178, -12, -193, -2, -0, -241, -182, -122, -2, -209, -218, -46, -68, -246, -211, -165, -251, -239, -10, -62, -48, -188, -45, -192, -114, -58, -201, -127, -212, -178, -253, -243, -145, -125, -224, -83, -147, -223, -169, -91, -10, -9, -216, -50, -147, -18, -75, -50, -15, -253, -206, -228, -138, -73, -16, -5, -221, -184, -177, -204, -35, -95, -1, -238, -89, -82, -255, -182, -50, -1, -64, -79, -97, -195, -157, -103, -217, -42, -34, -80, -239, -64, -236, -217, -191, -133, -72, -187, -39, -145, -165, -231, -36, -36, -81, -65, -165, -253, -57, -34, -81, -15, -71, -52, -222, -51, -144, -51, -224, -155, -144, -4, -151, -181, -222, -107, -228, -202, -141, -78, -2, -0, -88, -18, -49, -246, -0, -49, -30, -178, -231, -167, -23, -208, -80, -67, -170, -237, -198, -211, -41, -200, -243, -139, -147, -223, -169, -91, -146, -22, -74, -34, -36, -144, -171, -221, -79, -7, -217, -79, -140, -5, -144, -159, -164, -120, -243, -232, -145, -155, -150, -251, -4, -64, -47, -97, -195, -199, -180, -0, -0, -62, -68, -190, -108, -90, -128, -236, -123, -220, -165, -224, -245, -128, -55, -224, -164, -78, -124, -155, -16, -100, -14, -98, -185, -118, -143, -83, -246, -48, -53, -199, -111, -140, -76, -37, -238, -67, -168, -0, -248, -166, -210, -79, -66, -52, -208, -203, -146, -107, -184, -191, -214, -240, -153, -192, -56, -18, -0, -125, -193, -62, -115, -224, -161, -209, -238, -75, -40, -16, -97, -104, -141, -171, -246, -41, -212, -189, -7, -81, -118, -226, -27, -75, -244, -20, -54, -220, -25, -203, -209, -5, -64, -103, -222, -58, -137, -231, -81, -56, -127, -5, -94, -65, -254, -117, -246, -102, -168, -37, -143, -199, -254, -49, -70, -122, -177, -61, -31, -57, -170, -128, -18, -73, -236, -208, -186, -46, -175, -173, -4, -0, -146, -78, -124, -1, -34, -76, -94, -236, -148, -111, -174, -101, -243, -9, -76, -209, -173, -237, -146, -0, -48, -198, -0, -175, -213, -103, -49, -16, -206, -61, -160, -109, -48, -2, -120, -185, -122, -157, -218, -96, -29, -228, -71, -171, -144, -251, -222, -219, -165, -189, -253, -138, -251, -4, -64, -47, -97, -195, -157, -118, -99, -82, -0, -44, -65, -121, -184, -174, -189, -148, -249, -93, -21, -109, -189, -91, -4, -224, -29, -218, -182, -210, -79, -153, -145, -222, -114, -62, -84, -10, -0, -100, -223, -118, -135, -210, -250, -108, -214, -247, -215, -186, -219, -9, -56, -23, -215, -54, -227, -206, -14, -162, -15, -56, -239, -255, -198, -22, -109, -67, -114, -233, -93, -66, -141, -160, -5, -94, -132, -108, -45, -167, -233, -191, -25, -20, -76, -150, -75, -218, -189, -13, -249, -162, -91, -109, -251, -127, -128, -247, -2, -235, -218, -129, -229, -105, -99, -87, -14, -215, -117, -233, -179, -135, -111, -183, -73, -58, -74, -188, -173, -70, -20, -96, -94, -139, -182, -219, -106, -219, -1, -251, -230, -2, -221, -239, -171, -231, -127, -173, -0, -56, -73, -233, -46, -194, -179, -215, -71, -132, -148, -85, -106, -157, -232, -169, -247, -157, -2, -148, -253, -235, -124, -10, -128, -8, -151, -179, -144, -175, -205, -28, -68, -195, -124, -8, -125, -38, -128, -44, -239, -203, -230, -200, -113, -215, -43, -139, -207, -14, -177, -162, -180, -95, -196, -74, -3, -164, -30, -251, -183, -22, -114, -44, -57, -13, -89, -229, -189, -14, -17, -0, -119, -0, -107, -181, -228, -185, -161, -29, -88, -158, -186, -81, -9, -27, -222, -5, -125, -11, -0, -187, -231, -169, -74, -250, -81, -214, -214, -58, -41, -84, -42, -144, -24, -233, -79, -223, -88, -0, -116, -5, -67, -180, -3, -32, -95, -141, -128, -124, -149, -110, -38, -215, -129, -220, -71, -3, -115, -229, -24, -32, -119, -50, -2, -153, -100, -215, -33, -138, -96, -55, -205, -247, -31, -168, -8, -181, -221, -115, -255, -174, -66, -86, -136, -238, -182, -238, -165, -72, -76, -191, -1, -187, -249, -64, -158, -27, -217, -27, -243, -212, -141, -74, -216, -240, -46, -112, -222, -211, -6, -125, -48, -183, -17, -71, -143, -9, -164, -95, -6, -217, -255, -255, -4, -81, -4, -94, -67, -137, -39, -89, -161, -221, -215, -201, -21, -135, -69, -244, -42, -0, -134, -5, -228, -43, -187, -72, -39, -252, -7, -200, -205, -65, -159, -129, -216, -254, -163, -19, -208, -231, -209, -248, -74, -224, -159, -200, -215, -111, -22, -98, -26, -252, -85, -224, -185, -14, -205, -218, -192, -111, -27, -246, -105, -69, -36, -54, -222, -121, -200, -22, -105, -58, -162, -15, -186, -15, -49, -40, -122, -87, -135, -251, -13, -70, -219, -107, -180, -236, -87, -149, -0, -24, -149, -176, -225, -93, -224, -60, -198, -117, -128, -93, -16, -33, -22, -20, -112, -180, -142, -241, -115, -144, -37, -234, -2, -2, -150, -23, -133, -119, -58, -9, -177, -121, -14, -126, -136, -136, -100, -63, -88, -7, -222, -223, -201, -221, -124, -23, -23, -1, -96, -183, -42, -62, -143, -197, -101, -201, -245, -24, -239, -241, -212, -91, -69, -230, -181, -140, -52, -74, -1, -81, -182, -94, -133, -76, -220, -57, -195, -185, -155, -122, -16, -73, -7, -208, -67, -191, -170, -4, -192, -168, -132, -13, -239, -2, -103, -28, -88, -147, -241, -224, -128, -163, -85, -76, -151, -6, -46, -211, -198, -65, -241, -198, -145, -175, -215, -36, -196, -1, -103, -33, -114, -58, -112, -8, -29, -44, -201, -22, -51, -1, -112, -183, -222, -207, -75, -74, -234, -109, -16, -144, -147, -61, -117, -39, -1, -207, -116, -126, -111, -4, -124, -67, -5, -194, -60, -196, -208, -231, -92, -26, -156, -116, -140, -7, -16, -217, -36, -87, -121, -150, -10, -0, -173, -111, -21, -54, -92, -203, -175, -211, -255, -55, -10, -253, -221, -165, -207, -78, -159, -230, -225, -56, -189, -17, -16, -112, -180, -234, -130, -191, -210, -134, -151, -208, -98, -255, -135, -44, -107, -191, -174, -23, -190, -159, -246, -57, -209, -22, -39, -1, -96, -207, -159, -159, -81, -82, -111, -143, -220, -90, -37, -143, -92, -220, -64, -15, -38, -185, -202, -183, -82, -0, -40, -77, -227, -176, -225, -202, -114, -22, -178, -53, -131, -24, -95, -226, -128, -62, -59, -188, -27, -7, -28, -45, -187, -216, -193, -218, -224, -150, -178, -193, -218, -160, -227, -214, -56, -231, -172, -150, -237, -163, -11, -0, -26, -160, -130, -199, -70, -136, -95, -249, -125, -200, -210, -252, -126, -196, -87, -187, -84, -202, -234, -64, -2, -120, -126, -73, -253, -139, -180, -62, -118, -246, -224, -113, -7, -122, -50, -201, -237, -19, -206, -176, -105, -28, -250, -59, -128, -119, -136, -0, -104, -28, -112, -212, -71, -252, -37, -37, -190, -31, -71, -193, -212, -22, -228, -199, -136, -173, -34, -150, -106, -219, -216, -2, -96, -114, -205, -191, -59, -170, -250, -140, -28, -157, -89, -203, -201, -153, -136, -38, -223, -250, -102, -79, -163, -124, -137, -111, -51, -188, -120, -29, -148, -200, -5, -111, -212, -88, -248, -248, -49, -27, -89, -214, -158, -137, -196, -81, -240, -154, -74, -3, -171, -43, -237, -28, -58, -126, -12, -26, -246, -185, -23, -147, -220, -62, -225, -60, -219, -56, -95, -226, -145, -109, -67, -4, -128, -215, -220, -155, -138, -128, -163, -69, -66, -43, -41, -30, -2, -54, -109, -218, -201, -18, -158, -219, -40, -207, -39, -91, -182, -135, -33, -111, -1, -16, -255, -7, -128, -95, -148, -212, -159, -171, -245, -167, -161, -70, -80, -136, -242, -200, -122, -222, -157, -91, -210, -110, -31, -173, -191, -31, -71, -72, -32, -118, -10, -159, -33, -15, -85, -85, -105, -55, -209, -226, -126, -44, -174, -37, -87, -188, -93, -67, -110, -231, -15, -162, -120, -245, -230, -216, -67, -124, -206, -1, -190, -26, -179, -95, -53, -125, -238, -197, -36, -183, -79, -56, -207, -178, -251, -151, -120, -176, -109, -136, -0, -40, -139, -191, -88, -26, -112, -212, -37, -218, -133, -220, -123, -46, -90, -66, -76, -242, -0, -8, -173, -242, -150, -105, -219, -161, -9, -0, -196, -51, -239, -17, -125, -22, -94, -215, -77, -114, -31, -253, -77, -10, -229, -207, -215, -242, -178, -149, -195, -146, -72, -188, -62, -144, -109, -195, -69, -200, -23, -248, -78, -189, -158, -77, -144, -50, -37, -242, -61, -89, -108, -81, -40, -95, -18, -216, -155, -252, -248, -213, -123, -228, -135, -156, -206, -128, -40, -49, -135, -18, -44, -132, -158, -76, -114, -251, -132, -211, -167, -198, -161, -191, -29, -154, -98, -36, -227, -75, -16, -235, -197, -245, -44, -243, -138, -235, -54, -10, -56, -234, -198, -155, -219, -193, -24, -115, -146, -49, -102, -166, -49, -102, -199, -44, -203, -130, -82, -104, -107, -219, -115, -145, -44, -48, -43, -23, -202, -215, -0, -14, -52, -198, -88, -103, -12, -175, -47, -193, -24, -196, -158, -198, -152, -213, -141, -49, -103, -100, -89, -118, -123, -9, -205, -52, -253, -187, -160, -80, -190, -72, -255, -122, -95, -112, -150, -101, -11, -141, -49, -59, -25, -99, -190, -96, -140, -153, -108, -140, -121, -153, -49, -102, -107, -99, -204, -29, -198, -152, -237, -140, -49, -147, -148, -244, -250, -86, -61, -111, -136, -44, -203, -22, -102, -89, -246, -75, -99, -204, -63, -181, -104, -235, -18, -186, -107, -140, -49, -151, -25, -99, -214, -53, -198, -120, -131, -90, -246, -0, -59, -158, -254, -107, -140, -185, -180, -226, -95, -235, -80, -216, -200, -138, -237, -54, -59, -118, -129, -85, -145, -237, -223, -192, -41, -76, -67, -148, -29, -197, -206, -210, -191, -222, -0, -177, -72, -68, -160, -191, -25, -99, -94, -175, -180, -55, -27, -99, -54, -50, -198, -156, -106, -140, -217, -55, -224, -186, -235, -151, -148, -91, -157, -147, -127, -60, -147, -239, -95, -167, -82, -189, -55, -30, -152, -196, -142, -244, -89, -132, -40, -109, -254, -135, -124, -209, -236, -87, -101, -1, -78, -116, -219, -166, -80, -30, -67, -89, -1, -32, -190, -240, -246, -248, -231, -213, -21, -116, -39, -42, -205, -247, -10, -229, -54, -241, -99, -144, -209, -148, -135, -175, -221, -215, -182, -142, -205, -87, -194, -215, -194, -187, -178, -67, -18, -143, -0, -28, -86, -193, -99, -87, -165, -137, -151, -129, -182, -2, -12, -193, -36, -23, -209, -107, -0, -188, -86, -127, -219, -232, -187, -179, -91, -242, -179, -104, -19, -250, -187, -117, -36, -99, -231, -186, -173, -2, -142, -54, -209, -138, -159, -230, -105, -187, -35, -162, -13, -159, -132, -156, -151, -206, -71, -20, -97, -147, -17, -43, -194, -78, -193, -10, -245, -186, -195, -18, -0, -187, -233, -245, -42, -147, -122, -34, -203, -49, -235, -37, -249, -83, -96, -3, -242, -173, -206, -245, -180, -8, -158, -161, -47, -218, -186, -46, -87, -230, -17, -104, -193, -219, -98, -64, -0, -32, -250, -7, -27, -64, -99, -192, -0, -201, -161, -91, -218, -185, -103, -175, -227, -88, -76, -48, -4, -147, -92, -6, -87, -0, -171, -32, -43, -128, -83, -90, -242, -179, -104, -19, -250, -187, -117, -36, -99, -231, -186, -173, -2, -142, -38, -152, -167, -30, -150, -141, -72, -91, -107, -254, -138, -72, -236, -171, -25, -137, -95, -2, -171, -180, -188, -190, -245, -186, -59, -191, -77, -251, -26, -222, -3, -2, -0, -49, -217, -222, -20, -56, -70, -235, -254, -76, -137, -18, -208, -105, -99, -227, -22, -30, -25, -187, -143, -158, -107, -141, -103, -147, -220, -198, -95, -98, -58, -68, -50, -214, -226, -7, -201, -117, -72, -141, -3, -142, -78, -120, -32, -209, -111, -64, -108, -31, -106, -163, -7, -233, -132, -189, -23, -145, -186, -214, -113, -230, -6, -26, -154, -136, -34, -193, -59, -191, -170, -124, -102, -81, -178, -124, -236, -2, -170, -113, -17, -162, -195, -169, -156, -252, -202, -231, -89, -200, -57, -246, -116, -122, -142, -19, -200, -248, -54, -201, -109, -252, -37, -166, -67, -36, -99, -45, -254, -147, -254, -63, -5, -28, -109, -3, -114, -119, -225, -79, -214, -208, -45, -1, -252, -86, -105, -47, -70, -52, -255, -203, -34, -73, -61, -158, -64, -116, -31, -7, -86, -180, -255, -53, -146, -190, -235, -207, -72, -8, -116, -27, -12, -229, -1, -122, -74, -126, -234, -12, -76, -247, -24, -240, -74, -36, -142, -224, -2, -189, -247, -215, -4, -242, -58, -89, -121, -125, -174, -143, -190, -22, -174, -213, -202, -36, -55, -128, -175, -133, -111, -34, -214, -90, -9, -6, -240, -109, -28, -250, -155, -8, -145, -140, -19, -90, -2, -241, -51, -7, -9, -95, -86, -153, -58, -140, -220, -162, -235, -66, -10, -81, -118, -145, -175, -210, -157, -90, -255, -145, -146, -246, -199, -32, -147, -126, -1, -114, -212, -117, -33, -98, -244, -210, -219, -23, -213, -25, -124, -190, -99, -192, -143, -146, -7, -80, -173, -253, -154, -146, -43, -202, -110, -33, -96, -213, -208, -21, -180, -48, -201, -13, -224, -217, -183, -0, -104, -28, -250, -155, -142, -145, -140, -163, -0, -241, -40, -67, -59, -28, -108, -245, -165, -15, -237, -24, -68, -241, -247, -184, -182, -191, -9, -113, -96, -241, -90, -197, -105, -187, -189, -169, -135, -215, -168, -166, -192, -103, -101, -100, -207, -120, -33, -50, -169, -230, -107, -31, -130, -246, -170, -228, -201, -52, -106, -181, -239, -228, -169, -175, -203, -94, -148, -205, -225, -55, -102, -236, -249, -157, -103, -89, -119, -10, -16, -116, -164, -134, -172, -36, -96, -12, -45, -191, -155, -192, -121, -30, -125, -9, -128, -198, -161, -191, -233, -16, -201, -56, -26, -144, -244, -67, -54, -209, -96, -80, -54, -29, -196, -44, -214, -218, -184, -207, -69, -20, -105, -215, -144, -47, -211, -230, -1, -59, -149, -180, -253, -134, -210, -84, -29, -63, -86, -30, -169, -33, -150, -134, -110, -84, -225, -7, -181, -221, -20, -224, -204, -128, -254, -111, -138, -44, -219, -103, -19, -32, -244, -200, -29, -122, -188, -209, -142, -129, -103, -107, -253, -88, -114, -203, -173, -19, -0, -31, -209, -250, -89, -190, -122, -15, -253, -158, -74, -223, -202, -191, -99, -180, -49, -4, -1, -208, -88, -219, -78, -135, -72, -198, -81, -1, -108, -73, -30, -87, -255, -229, -1, -244, -103, -105, -191, -46, -99, -100, -64, -209, -229, -200, -143, -46, -38, -151, -180, -181, -254, -203, -94, -205, -103, -192, -181, -55, -35, -183, -202, -251, -13, -133, -227, -41, -2, -180, -199, -228, -49, -7, -74, -147, -119, -22, -232, -173, -75, -175, -247, -235, -135, -88, -84, -2, -220, -20, -118, -23, -253, -35, -64, -0, -216, -19, -136, -202, -216, -141, -14, -253, -211, -17, -47, -189, -133, -244, -17, -133, -166, -103, -140, -81, -1, -208, -58, -146, -113, -116, -168, -16, -120, -0, -184, -33, -128, -214, -106, -47, -7, -98, -229, -145, -155, -144, -122, -191, -134, -192, -41, -90, -223, -202, -186, -140, -252, -88, -165, -84, -233, -86, -211, -126, -29, -125, -176, -139, -8, -244, -208, -34, -63, -175, -189, -157, -130, -177, -16, -98, -19, -97, -87, -80, -251, -151, -241, -24, -54, -2, -4, -128, -117, -253, -190, -188, -1, -79, -123, -228, -116, -104, -188, -158, -14, -7, -99, -81, -0, -104, -251, -170, -72, -198, -95, -71, -21, -198, -109, -120, -247, -134, -154, -135, -121, -144, -214, -253, -179, -164, -237, -249, -90, -95, -187, -210, -240, -180, -125, -177, -182, -157, -66, -77, -242, -203, -10, -30, -118, -50, -255, -185, -65, -155, -21, -201, -189, -250, -64, -190, -132, -55, -50, -50, -161, -233, -25, -4, -158, -93, -3, -107, -146, -167, -231, -190, -34, -176, -77, -211, -16, -217, -22, -69, -37, -96, -6, -236, -65, -174, -129, -174, -205, -226, -235, -180, -125, -46, -185, -239, -200, -114, -161, -237, -106, -250, -215, -118, -226, -108, -139, -124, -76, -110, -211, -73, -50, -3, -49, -170, -58, -20, -143, -14, -170, -102, -204, -142, -154, -0, -80, -30, -222, -72, -198, -90, -119, -93, -155, -228, -11, -222, -105, -0, -0, -32, -0, -73, -68, -65, -84, -126, -245, -10, -223, -77, -35, -103, -184, -54, -55, -252, -109, -192, -179, -75, -218, -94, -175, -52, -222, -250, -154, -235, -30, -168, -109, -127, -210, -178, -223, -171, -146, -235, -41, -26, -69, -250, -69, -172, -226, -246, -65, -142, -207, -30, -211, -9, -244, -40, -18, -179, -239, -169, -88, -127, -129, -188, -142, -210, -62, -60, -0, -60, -39, -128, -190, -113, -136, -108, -231, -29, -185, -199, -128, -151, -147, -103, -16, -6, -57, -222, -107, -154, -61, -233, -47, -218, -246, -227, -77, -218, -85, -244, -175, -205, -210, -217, -21, -134, -183, -35, -177, -18, -239, -33, -55, -157, -29, -88, -29, -86, -93, -143, -252, -195, -50, -42, -2, -96, -84, -65, -139, -240, -75, -197, -155, -70, -190, -12, -54, -106, -203, -239, -168, -176, -140, -115, -6, -224, -13, -228, -122, -135, -25, -136, -34, -241, -48, -96, -227, -138, -182, -214, -183, -250, -3, -136, -34, -240, -92, -228, -4, -194, -102, -214, -221, -151, -81, -138, -100, -27, -10, -36, -86, -194, -66, -237, -119, -173, -7, -38, -45, -67, -100, -227, -199, -34, -114, -161, -181, -107, -203, -254, -91, -151, -220, -255, -182, -105, -239, -233, -95, -27, -1, -96, -141, -176, -182, -43, -148, -175, -130, -152, -118, -15, -40, -107, -201, -133, -195, -139, -60, -117, -54, -151, -197, -216, -250, -210, -246, -13, -90, -134, -95, -42, -190, -60, -242, -188, -238, -181, -54, -220, -192, -57, -74, -251, -24, -18, -84, -99, -50, -249, -30, -26, -68, -8, -121, -191, -46, -228, -86, -98, -135, -32, -95, -224, -123, -144, -47, -210, -69, -228, -10, -147, -191, -50, -138, -185, -238, -235, -128, -108, -29, -166, -2, -91, -6, -210, -71, -15, -145, -61, -22, -208, -81, -0, -216, -49, -251, -170, -6, -109, -236, -24, -123, -183, -167, -238, -232, -9, -39, -0, -232, -16, -126, -201, -35, -0, -172, -86, -62, -40, -35, -47, -158, -76, -61, -192, -243, -200, -45, -206, -22, -1, -219, -122, -104, -158, -112, -234, -191, -228, -78, -116, -196, -108, -210, -30, -13, -214, -166, -7, -79, -24, -93, -116, -20, -0, -214, -131, -114, -26, -18, -200, -165, -54, -89, -8, -185, -221, -199, -21, -56, -33, -235, -17, -109, -187, -213, -196, -79, -40, -1, -208, -58, -252, -146, -71, -0, -156, -161, -191, -255, -71, -71, -175, -54, -135, -215, -217, -158, -58, -171, -184, -250, -105, -73, -91, -107, -100, -84, -233, -217, -151, -48, -250, -112, -198, -208, -250, -72, -120, -178, -43, -244, -67, -242, -36, -178, -69, -169, -212, -209, -0, -7, -56, -60, -230, -35, -137, -76, -94, -91, -65, -255, -26, -103, -252, -204, -64, -156, -186, -172, -201, -241, -183, -24, -35, -218, -118, -2, -17, -227, -66, -173, -195, -47, -57, -253, -176, -2, -96, -53, -196, -198, -29, -100, -41, -254, -77, -90, -46, -195, -145, -99, -53, -240, -251, -79, -91, -205, -185, -55, -12, -54, -98, -224, -3, -53, -161, -200, -144, -213, -198, -137, -200, -82, -124, -62, -178, -31, -191, -4, -201, -224, -227, -205, -136, -172, -237, -90, -5, -147, -64, -146, -119, -124, -13, -81, -194, -77, -211, -107, -78, -69, -132, -221, -86, -177, -219, -141, -7, -56, -99, -200, -166, -115, -191, -27, -217, -130, -218, -119, -60, -159, -146, -248, -12, -192, -203, -144, -45, -228, -99, -200, -135, -234, -50, -135, -223, -241, -192, -178, -37, -237, -222, -128, -156, -66, -77, -67, -38, -252, -53, -168, -249, -54, -37, -218, -246, -226, -88, -47, -212, -133, -132, -236, -170, -132, -167, -93, -85, -46, -5, -107, -143, -210, -42, -212, -94, -241, -66, -173, -195, -47, -249, -30, -10, -162, -37, -255, -6, -121, -128, -131, -179, -129, -167, -181, -232, -151, -245, -128, -26, -8, -208, -128, -40, -42, -161, -160, -252, -113, -234, -159, -161, -245, -165, -89, -109, -17, -187, -118, -235, -140, -51, -23, -209, -67, -184, -105, -209, -75, -99, -236, -211, -50, -152, -4, -185, -185, -245, -124, -228, -20, -228, -42, -242, -237, -204, -2, -224, -245, -49, -219, -85, -244, -227, -45, -218, -54, -232, -232, -209, -211, -126, -64, -168, -35, -19, -174, -18, -37, -188, -44, -230, -3, -187, -56, -229, -171, -59, -247, -93, -182, -58, -181, -31, -155, -55, -59, -101, -219, -144, -7, -118, -245, -174, -16, -219, -192, -233, -103, -83, -1, -112, -82, -200, -191, -6, -253, -88, -146, -252, -4, -173, -117, -176, -29, -151, -97, -235, -140, -168, -53, -15, -101, -11, -114, -79, -168, -160, -228, -34, -133, -246, -239, -212, -182, -183, -122, -234, -172, -17, -145, -247, -1, -144, -11, -143, -187, -43, -248, -219, -243, -252, -75, -113, -204, -128, -17, -171, -172, -255, -171, -233, -91, -171, -96, -18, -136, -78, -229, -211, -56, -206, -63, -136, -213, -164, -221, -151, -150, -5, -20, -109, -213, -174, -162, -31, -246, -20, -197, -187, -234, -83, -154, -181, -17, -99, -171, -199, -245, -126, -183, -208, -242, -221, -128, -251, -60, -244, -239, -69, -242, -44, -22, -255, -253, -81, -175, -229, -181, -52, -116, -198, -208, -81, -158, -58, -235, -7, -255, -96, -73, -91, -43, -192, -87, -45, -148, -111, -169, -229, -211, -124, -237, -218, -160, -102, -172, -183, -182, -31, -104, -209, -15, -107, -185, -121, -55, -45, -62, -172, -62, -134, -173, -195, -47, -85, -61, -20, -173, -183, -166, -177, -222, -244, -226, -53, -188, -173, -153, -241, -64, -116, -94, -29, -108, -32, -202, -203, -1, -15, -62, -224, -251, -90, -95, -154, -43, -143, -124, -133, -210, -58, -99, -75, -44, -144, -123, -36, -54, -90, -210, -181, -105, -135, -100, -199, -93, -132, -28, -161, -121, -151, -200, -74, -119, -28, -178, -23, -159, -172, -244, -139, -244, -255, -179, -8, -207, -21, -185, -20, -249, -87, -220, -235, -106, -237, -140, -161, -1, -111, -57, -242, -92, -9, -197, -248, -139, -182, -222, -58, -103, -125, -177, -80, -190, -154, -150, -63, -28, -210, -207, -16, -140, -5, -1, -128, -196, -143, -176, -10, -238, -82, -225, -221, -148, -105, -235, -240, -75, -1, -2, -96, -11, -173, -247, -45, -227, -255, -12, -236, -4, -172, -84, -40, -127, -22, -185, -121, -234, -116, -96, -125, -79, -219, -165, -200, -61, -168, -46, -70, -181, -191, -136, -117, -219, -222, -200, -228, -94, -68, -197, -241, -144, -211, -247, -129, -243, -224, -97, -131, -138, -156, -245, -177, -219, -1, -63, -214, -38, -3, -57, -10, -11, -116, -83, -129, -15, -232, -255, -95, -140, -172, -2, -108, -154, -171, -160, -212, -220, -136, -82, -13, -224, -156, -10, -26, -139, -1, -165, -113, -221, -196, -66, -44, -231, -108, -252, -201, -19, -201, -117, -81, -54, -191, -197, -9, -33, -253, -12, -188, -151, -210, -177, -94, -215, -207, -136, -125, -248, -182, -94, -230, -26, -98, -185, -99, -211, -33, -252, -146, -251, -80, -244, -101, -63, -203, -169, -91, -154, -220, -34, -112, -96, -175, -233, -180, -93, -132, -68, -215, -185, -158, -145, -250, -136, -71, -41, -217, -227, -107, -251, -231, -147, -239, -217, -231, -33, -123, -120, -55, -88, -68, -229, -254, -200, -161, -107, -44, -0, -104, -153, -179, -14, -17, -92, -31, -68, -142, -57, -39, -33, -210, -124, -58, -185, -86, -186, -108, -160, -183, -106, -231, -225, -179, -28, -121, -32, -144, -245, -234, -250, -26, -194, -179, -162, -253, -75, -245, -189, -60, -65, -197, -177, -176, -59, -134, -60, -117, -33, -105, -188, -94, -67, -190, -202, -88, -132, -40, -74, -23, -33, -218, -253, -213, -187, -220, -67, -204, -126, -70, -184, -254, -51, -201, -21, -163, -241, -130, -165, -210, -33, -252, -146, -251, -80, -156, -23, -112, -51, -98, -16, -100, -39, -243, -130, -146, -182, -111, -67, -162, -235, -220, -138, -44, -43, -109, -176, -135, -203, -144, -211, -131, -218, -224, -154, -136, -178, -239, -80, -229, -49, -87, -219, -159, -77, -64, -242, -72, -167, -239, -141, -4, -0, -237, -141, -166, -214, -36, -247, -165, -183, -207, -197, -70, -82, -182, -171, -25, -159, -18, -169, -85, -187, -146, -62, -216, -253, -227, -233, -77, -238, -185, -41, -144, -152, -131, -54, -198, -226, -110, -53, -180, -79, -141, -33, -79, -93, -240, -196, -2, -94, -133, -172, -28, -109, -148, -235, -203, -112, -18, -170, -118, -69, -172, -126, -118, -184, -190, -141, -223, -248, -215, -62, -152, -119, -201, -136, -138, -62, -128, -189, -244, -161, -79, -67, -36, -255, -20, -100, -153, -223, -200, -214, -190, -111, -144, -107, -240, -189, -168, -105, -219, -197, -104, -234, -55, -90, -55, -21, -49, -58, -121, -186, -83, -87, -165, -69, -110, -213, -174, -164, -255, -255, -85, -242, -202, -47, -8, -29, -143, -29, -17, -229, -31, -4, -164, -238, -114, -199, -144, -167, -174, -241, -196, -66, -78, -15, -78, -213, -102, -165, -91, -143, -166, -168, -233, -103, -175, -17, -123, -128, -23, -34, -130, -127, -1, -125, -69, -101, -166, -135, -240, -75, -99, -17, -136, -143, -194, -105, -206, -11, -61, -71, -127, -159, -134, -39, -244, -121, -161, -109, -23, -163, -41, -187, -106, -24, -8, -23, -70, -158, -67, -209, -39, -0, -90, -181, -243, -208, -110, -173, -164, -33, -110, -222, -173, -143, -29, -17, -197, -164, -13, -150, -26, -178, -138, -171, -154, -88, -173, -190, -172, -136, -16, -128, -192, -32, -39, -129, -60, -45, -124, -62, -4, -189, -70, -236, -33, -63, -181, -57, -186, -15, -254, -19, -18, -85, -47, -180, -162, -77, -23, -163, -41, -123, -234, -176, -173, -167, -206, -38, -21, -241, -9, -128, -86, -237, -60, -180, -246, -171, -248, -169, -0, -218, -182, -199, -149, -79, -71, -182, -128, -224, -177, -181, -47, -105, -211, -74, -0, -32, -142, -103, -251, -81, -80, -18, -35, -129, -91, -191, -172, -205, -188, -193, -104, -218, -192, -233, -167, -207, -135, -224, -136, -190, -4, -0, -121, -66, -145, -25, -44, -38, -31, -225, -49, -129, -150, -2, -160, -139, -209, -148, -221, -175, -31, -135, -42, -216, -116, -176, -238, -69, -133, -50, -175, -109, -187, -2, -143, -103, -145, -39, -109, -25, -240, -191, -104, -112, -255, -149, -199, -142, -136, -98, -20, -224, -196, -6, -60, -45, -154, -10, -128, -45, -156, -182, -83, -145, -149, -235, -21, -228, -43, -166, -57, -56, -6, -66, -93, -225, -92, -171, -232, -67, -240, -46, -122, -138, -216, -163, -239, -217, -234, -127, -190, -21, -147, -247, -168, -163, -234, -197, -7, -180, -253, -56, -18, -94, -123, -153, -170, -178, -138, -246, -75, -59, -215, -127, -126, -29, -189, -211, -174, -139, -209, -212, -78, -133, -1, -123, -53, -185, -13, -198, -126, -168, -34, -54, -86, -187, -2, -15, -107, -47, -255, -243, -208, -123, -45, -225, -83, -122, -236, -136, -36, -191, -180, -39, -58, -193, -9, -82, -170, -198, -1, -213, -2, -96, -57, -224, -115, -250, -188, -109, -92, -134, -199, -16, -229, -227, -49, -68, -202, -112, -237, -233, -39, -228, -62, -4, -174, -242, -124, -126, -221, -123, -104, -113, -205, -143, -40, -255, -7, -0, -111, -78, -193, -113, -139, -170, -23, -31, -208, -214, -198, -19, -60, -162, -170, -172, -162, -253, -122, -206, -245, -87, -171, -163, -119, -218, -117, -202, -89, -135, -248, -155, -95, -142, -40, -11, -167, -33, -166, -172, -239, -214, -186, -147, -203, -6, -80, -219, -118, -90, -239, -166, -245, -10, -18, -118, -180, -56, -118, -116, -38, -195, -121, -248, -45, -2, -127, -0, -172, -27, -246, -164, -198, -30, -156, -241, -178, -23, -114, -234, -51, -15, -17, -118, -135, -33, -6, -58, -255, -139, -41, -0, -144, -237, -148, -85, -56, -119, -10, -186, -210, -244, -194, -0, -199, -55, -108, -179, -153, -14, -208, -25, -192, -5, -84, -4, -243, -40, -92, -167, -173, -0, -88, -150, -124, -105, -180, -91, -89, -89, -69, -123, -155, -171, -189, -209, -30, -145, -33, -228, -172, -139, -13, -36, -104, -10, -4, -154, -11, -211, -254, -184, -50, -4, -193, -126, -251, -99, -13, -206, -61, -84, -218, -79, -68, -188, -222, -87, -236, -24, -101, -152, -113, -45, -90, -10, -128, -203, -145, -229, -247, -54, -136, -86, -253, -162, -192, -235, -180, -18, -0, -218, -254, -121, -136, -192, -153, -137, -6, -201, -240, -149, -121, -218, -109, -133, -236, -229, -231, -18, -96, -47, -80, -104, -59, -30, -115, -214, -89, -135, -153, -218, -156, -135, -74, -31, -237, -216, -113, -113, -130, -51, -94, -135, -18, -9, -153, -60, -206, -228, -221, -52, -216, -106, -182, -189, -216, -26, -136, -59, -166, -53, -222, -88, -136, -44, -233, -206, -69, -114, -215, -85, -38, -59, -208, -9, -103, -131, -23, -238, -2, -76, -15, -184, -102, -39, -1, -160, -60, -62, -172, -60, -110, -69, -77, -138, -125, -101, -37, -215, -125, -130, -234, -116, -232, -3, -171, -3, -198, -89, -206, -58, -114, -167, -168, -187, -8, -252, -138, -16, -233, -216, -113, -113, -67, -140, -241, -218, -242, -122, -149, -136, -113, -161, -13, -200, -227, -243, -89, -239, -170, -39, -201, -205, -14, -161, -102, -201, -139, -104, -96, -207, -66, -206, -154, -207, -1, -46, -108, -112, -131, -27, -21, -202, -215, -118, -38, -217, -55, -107, -120, -216, -201, -126, -39, -185, -103, -222, -64, -89, -201, -117, -91, -61, -92, -122, -202, -89, -215, -7, -144, -92, -132, -0, -95, -105, -208, -38, -202, -177, -99, -108, -208, -62, -6, -67, -171, -140, -87, -30, -62, -222, -241, -58, -238, -1, -252, -93, -111, -236, -100, -228, -11, -7, -226, -219, -157, -33, -129, -53, -190, -10, -172, -80, -195, -99, -115, -228, -120, -100, -38, -226, -156, -83, -27, -103, -223, -247, -64, -245, -250, -54, -237, -118, -93, -86, -160, -231, -233, -75, -157, -141, -134, -127, -246, -149, -245, -1, -250, -203, -89, -119, -157, -254, -191, -113, -100, -28, -15, -191, -213, -180, -253, -156, -38, -3, -159, -8, -199, -142, -125, -128, -246, -49, -24, -26, -103, -188, -42, -225, -179, -216, -10, -0, -251, -213, -127, -174, -254, -134, -134, -58, -128, -150, -215, -29, -241, -64, -17, -205, -179, -21, -70, -103, -81, -177, -100, -101, -164, -194, -239, -163, -101, -101, -227, -9, -218, -239, -89, -136, -9, -46, -52, -136, -140, -19, -185, -31, -157, -143, -29, -27, -92, -43, -56, -47, -2, -45, -99, -48, -40, -109, -163, -140, -87, -37, -60, -22, -91, -1, -96, -131, -118, -188, -64, -127, -15, -91, -0, -172, -171, -191, -173, -179, -195, -21, -212, -156, -121, -146, -31, -249, -29, -85, -85, -54, -158, -224, -60, -143, -198, -145, -113, -122, -232, -75, -235, -99, -199, -134, -215, -105, -148, -23, -161, -227, -181, -130, -51, -94, -77, -40, -144, -107, -125, -207, -71, -210, -101, -5, -11, -0, -58, -56, -141, -56, -3, -126, -37, -242, -175, -222, -109, -132, -217, -143, -239, -133, -232, -26, -150, -169, -42, -27, -79, -112, -158, -71, -227, -200, -56, -227, -17, -52, -204, -139, -176, -56, -3, -120, -1, -146, -165, -249, -78, -68, -7, -243, -32, -178, -157, -252, -70, -9, -125, -20, -189, -134, -101, -182, -22, -185, -59, -171, -53, -105, -60, -139, -138, -104, -49, -158, -142, -180, -113, -26, -65, -7, -192, -251, -201, -131, -58, -116, -138, -36, -60, -158, -225, -8, -128, -198, -145, -113, -198, -35, -104, -144, -23, -161, -203, -135, -102, -172, -3, -9, -125, -103, -183, -225, -243, -17, -155, -11, -155, -113, -219, -235, -250, -75, -36, -189, -134, -203, -112, -5, -196, -189, -213, -77, -181, -253, -40, -146, -130, -107, -224, -40, -205, -105, -215, -58, -86, -157, -35, -0, -102, -59, -215, -236, -100, -170, -218, -7, -144, -147, -141, -63, -170, -144, -156, -141, -40, -58, -39, -35, -22, -96, -3, -251, -73, -231, -94, -26, -125, -213, -156, -118, -141, -34, -227, -180, -189, -222, -120, -2, -237, -131, -169, -142, -105, -193, -129, -164, -147, -183, -167, -71, -191, -64, -77, -168, -17, -5, -252, -22, -84, -40, -178, -137, -160, -215, -240, -49, -93, -74, -59, -243, -8, -249, -106, -224, -54, -26, -90, -63, -17, -16, -171, -206, -25, -184, -23, -0, -219, -59, -15, -98, -224, -11, -56, -90, -0, -118, -37, -95, -157, -216, -140, -173, -55, -145, -167, -151, -58, -204, -211, -166, -171, -0, -104, -27, -118, -122, -113, -22, -0, -109, -189, -19, -27, -11, -142, -182, -239, -193, -161, -9, -94, -206, -147, -39, -208, -253, -119, -248, -211, -24, -209, -62, -190, -94, -67, -59, -116, -60, -34, -157, -172, -251, -107, -35, -229, -19, -1, -177, -234, -138, -15, -26, -201, -84, -11, -226, -71, -62, -38, -220, -30, -201, -131, -78, -126, -169, -80, -190, -58, -240, -73, -60, -130, -177, -237, -132, -108, -59, -240, -34, -92, -207, -98, -158, -14, -166, -179, -245, -93, -84, -157, -194, -52, -254, -178, -182, -189, -191, -154, -123, -168, -243, -78, -108, -44, -56, -186, -244, -147, -134, -203, -121, -68, -225, -13, -99, -196, -110, -196, -24, -51, -242, -20, -0, -216, -68, -127, -151, -133, -116, -110, -29, -171, -206, -247, -160, -201, -67, -72, -159, -67, -172, -160, -135, -35, -175, -217, -52, -181, -182, -53, -138, -121, -69, -131, -107, -88, -12, -91, -0, -88, -204, -67, -38, -227, -57, -192, -158, -148, -196, -246, -115, -232, -109, -214, -224, -171, -16, -133, -156, -197, -69, -148, -164, -254, -102, -20, -190, -172, -37, -253, -104, -27, -76, -181, -84, -112, -116, -120, -15, -141, -151, -243, -228, -199, -171, -3, -17, -164, -70, -13, -218, -161, -227, -245, -255, -214, -231, -218, -151, -157, -167, -83, -172, -58, -223, -131, -70, -190, -172, -54, -208, -231, -126, -145, -239, -171, -77, -106, -109, -187, -2, -186, -140, -26, -115, -104, -167, -141, -197, -176, -5, -64, -217, -68, -190, -20, -207, -177, -170, -175, -159, -72, -210, -137, -221, -201, -183, -56, -7, -148, -244, -117, -216, -95, -214, -40, -65, -81, -29, -126, -85, -110, -205, -109, -223, -67, -227, -229, -60, -185, -123, -121, -155, -15, -76, -41, -66, -121, -89, -134, -199, -2, -219, -162, -199, -103, -202, -227, -120, -36, -20, -180, -205, -246, -251, -27, -79, -187, -78, -78, -35, -101, -15, -26, -209, -7, -44, -66, -190, -190, -47, -109, -116, -51, -229, -215, -106, -155, -90, -251, -185, -228, -89, -102, -108, -222, -185, -186, -120, -122, -22, -163, -182, -5, -96, -112, -34, -127, -183, -73, -63, -117, -76, -0, -220, -212, -240, -30, -250, -248, -178, -182, -254, -208, -208, -206, -173, -185, -109, -63, -27, -47, -231, -201, -87, -77, -219, -54, -104, -99, -97, -5, -126, -55, -7, -33, -135, -225, -28, -242, -227, -192, -69, -78, -249, -36, -60, -103, -243, -116, -116, -26, -169, -121, -208, -54, -118, -253, -77, -68, -8, -132, -64, -135, -212, -218, -200, -151, -237, -235, -140, -60, -33, -249, -95, -217, -75, -115, -104, -70, -93, -7, -64, -197, -68, -174, -105, -183, -187, -29, -19, -13, -239, -161, -143, -47, -107, -219, -96, -170, -93, -221, -154, -155, -246, -179, -241, -114, -30, -177, -244, -132, -6, -89, -172, -171, -222, -91, -43, -32, -190, -241, -127, -67, -150, -222, -118, -73, -50, -13, -56, -29, -217, -67, -150, -37, -88, -28, -147, -78, -35, -125, -1, -9, -172, -241, -254, -194, -160, -218, -217, -67, -215, -234, -5, -117, -24, -120, -165, -215, -163, -98, -34, -215, -180, -219, -77, -235, -158, -40, -233, -235, -48, -191, -172, -109, -131, -169, -182, -21, -28, -109, -251, -217, -102, -57, -127, -176, -182, -57, -191, -65, -155, -210, -247, -22, -5, -202, -252, -248, -0, -186, -49, -233, -52, -210, -55, -244, -30, -109, -16, -200, -41, -158, -250, -126, -95, -80, -131, -235, -81, -49, -145, -107, -218, -157, -160, -117, -255, -242, -212, -13, -251, -203, -218, -54, -152, -106, -91, -193, -81, -213, -207, -23, -87, -180, -107, -179, -156, -95, -151, -60, -143, -193, -33, -56, -241, -26, -145, -20, -110, -187, -86, -244, -111, -212, -5, -192, -208, -156, -70, -186, -160, -237, -192, -171, -225, -249, -82, -109, -214, -232, -203, -218, -7, -170, -174, -71, -245, -68, -30, -104, -135, -56, -84, -125, -158, -92, -119, -240, -78, -79, -187, -62, -190, -172, -85, -19, -171, -109, -48, -213, -182, -130, -195, -222, -187, -47, -252, -247, -59, -42, -218, -53, -94, -206, -107, -187, -247, -145, -219, -220, -204, -67, -156, -192, -102, -233, -239, -255, -120, -232, -75, -223, -119, -20, -40, -243, -227, -3, -105, -135, -226, -52, -210, -5, -53, -3, -175, -106, -192, -110, -128, -132, -151, -222, -160, -80, -254, -52, -114, -39, -150, -43, -43, -174, -55, -106, -2, -128, -176, -137, -108, -97, -149, -73, -215, -49, -50, -6, -196, -129, -37, -215, -107, -251, -101, -109, -59, -177, -218, -6, -83, -109, -43, -56, -172, -137, -173, -47, -252, -247, -209, -21, -237, -26, -47, -231, -157, -182, -155, -35, -185, -13, -239, -65, -182, -18, -51, -144, -147, -167, -15, -121, -104, -7, -222, -247, -98, -5, -106, -34, -215, -208, -208, -17, -194, -121, -96, -93, -194, -78, -63, -128, -104, -121, -175, -36, -15, -213, -52, -11, -216, -186, -226, -122, -195, -22, -0, -77, -39, -114, -17, -179, -144, -19, -143, -147, -80, -159, -251, -146, -118, -109, -191, -172, -173, -38, -150, -214, -55, -254, -208, -208, -94, -112, -216, -163, -204, -98, -248, -239, -247, -144, -239, -243, -125, -237, -26, -47, -231, -219, -192, -243, -222, -6, -16, -227, -58, -189, -130, -134, -185, -231, -11, -109, -27, -57, -66, -56, -207, -165, -75, -216, -233, -71, -145, -175, -198, -227, -136, -31, -192, -49, -192, -38, -53, -215, -27, -182, -0, -176, -8, -157, -200, -173, -250, -73, -251, -47, -107, -171, -137, -213, -5, -180, -19, -28, -175, -113, -238, -195, -134, -255, -182, -17, -160, -190, -133, -90, -250, -149, -92, -175, -209, -114, -190, -229, -61, -89, -196, -57, -6, -28, -13, -208, -49, -247, -60, -13, -28, -33, -156, -7, -54, -148, -164, -142, -109, -39, -214, -176, -175, -215, -161, -93, -219, -47, -107, -235, -137, -53, -108, -0, -111, -64, -220, -227, -167, -105, -191, -174, -65, -183, -60, -168, -0, -172, -104, -27, -188, -156, -111, -217, -183, -161, -142, -175, -94, -64, -156, -220, -243, -65, -142, -16, -73, -0, -196, -109, -167, -109, -219, -230, -55, -104, -61, -177, -198, -27, -144, -128, -172, -179, -233, -47, -65, -73, -52, -59, -128, -149, -129, -207, -34, -182, -223, -143, -35, -75, -151, -59, -145, -163, -174, -210, -188, -238, -5, -30, -63, -69, -246, -63, -191, -8, -164, -239, -148, -123, -190, -9, -70, -81, -0, -148, -46, -209, -208, -8, -202, -145, -175, -55, -52, -1, -144, -80, -15, -196, -106, -116, -145, -10, -188, -82, -33, -64, -190, -69, -216, -190, -170, -204, -169, -139, -46, -0, -174, -115, -152, -62, -142, -132, -8, -179, -150, -128, -15, -17, -96, -3, -79, -238, -241, -52, -51, -74, -167, -34, -162, -70, -0, -148, -30, -63, -69, -184, -94, -21, -62, -223, -195, -245, -146, -0, -24, -67, -0, -222, -77, -158, -133, -250, -218, -10, -186, -187, -138, -239, -193, -87, -230, -212, -69, -23, -0, -123, -0, -63, -193, -201, -59, -142, -36, -147, -188, -64, -47, -116, -106, -0, -143, -35, -145, -229, -78, -200, -254, -29, -90, -68, -191, -173, -153, -200, -85, -202, -188, -86, -199, -79, -139, -59, -22, -87, -1, -64, -131, -64, -163, -67, -234, -207, -165, -148, -88, -84, -106, -189, -61, -213, -90, -167, -170, -204, -169, -27, -206, -123, -3, -94, -168, -23, -122, -44, -50, -95, -104, -17, -253, -182, -131, -0, -104, -125, -252, -180, -56, -99, -49, -22, -0, -149, -129, -70, -145, -232, -87, -7, -33, -39, -37, -115, -144, -237, -238, -161, -212, -132, -190, -111, -216, -135, -157, -145, -21, -192, -1, -122, -141, -210, -108, -201, -72, -252, -5, -112, -76, -238, -125, -101, -78, -221, -208, -4, -192, -202, -118, -178, -70, -230, -107, -209, -40, -250, -109, -7, -1, -48, -244, -227, -167, -197, -25, -250, -184, -46, -215, -255, -175, -173, -19, -238, -110, -68, -195, -127, -123, -69, -187, -224, -88, -12, -200, -10, -244, -100, -100, -85, -248, -36, -240, -59, -2, -130, -196, -16, -16, -104, -84, -199, -195, -34, -36, -120, -201, -151, -201, -147, -167, -252, -182, -142, -127, -40, -144, -143, -217, -124, -228, -68, -228, -103, -84, -56, -180, -33, -39, -6, -211, -234, -202, -156, -58, -139, -126, -143, -1, -17, -141, -45, -212, -36, -208, -68, -206, -203, -33, -48, -96, -165, -115, -3, -141, -162, -223, -118, -16, -0, -227, -230, -248, -105, -60, -64, -159, -219, -61, -72, -26, -180, -41, -250, -123, -33, -162, -60, -190, -180, -164, -77, -112, -44, -6, -157, -252, -54, -83, -213, -249, -72, -128, -218, -121, -200, -74, -174, -82, -8, -16, -16, -104, -20, -73, -152, -242, -170, -66, -217, -121, -68, -254, -208, -133, -2, -241, -124, -189, -163, -174, -204, -169, -171, -69, -140, -78, -173, -64, -238, -240, -241, -165, -26, -218, -87, -148, -77, -218, -154, -27, -104, -20, -253, -214, -105, -215, -38, -160, -68, -47, -199, -79, -180, -76, -87, -165, -180, -65, -95, -68, -242, -56, -141, -62, -188, -172, -77, -191, -187, -64, -175, -59, -31, -17, -164, -255, -3, -222, -132, -38, -74, -197, -241, -11, -112, -232, -27, -197, -98, -64, -143, -17, -113, -50, -60, -35, -66, -124, -62, -112, -82, -79, -247, -116, -61, -48, -169, -15, -222, -227, -14, -72, -162, -208, -203, -245, -37, -92, -74, -69, -22, -92, -196, -2, -236, -159, -74, -91, -155, -161, -69, -219, -88, -180, -141, -126, -59, -148, -227, -188, -16, -208, -62, -93, -85, -163, -232, -68, -72, -172, -185, -67, -157, -103, -240, -123, -224, -67, -68, -136, -149, -208, -20, -78, -31, -30, -194, -217, -82, -85, -208, -55, -138, -197, -160, -207, -99, -96, -43, -1, -252, -133, -10, -101, -90, -91, -32, -62, -19, -139, -128, -157, -98, -243, -30, -119, -64, -210, -45, -93, -175, -47, -248, -106, -52, -174, -89, -5, -189, -85, -162, -205, -2, -158, -31, -120, -141, -86, -19, -121, -140, -10, -128, -198, -233, -170, -104, -25, -157, -72, -219, -90, -84, -42, -128, -60, -253, -170, -92, -153, -208, -192, -191, -194, -233, -195, -103, -171, -232, -218, -66, -251, -112, -139, -167, -252, -12, -60, -251, -98, -58, -172, -144, -144, -192, -174, -243, -129, -61, -99, -222, -195, -184, -5, -18, -204, -16, -224, -6, -106, -164, -59, -146, -4, -19, -100, -73, -61, -96, -176, -80, -209, -174, -15, -1, -16, -253, -60, -191, -47, -208, -45, -58, -81, -168, -0, -104, -180, -50, -161, -129, -127, -133, -211, -135, -94, -146, -175, -146, -7, -134, -117, -21, -196, -47, -71, -156, -144, -188, -71, -210, -180, -88, -33, -1, -223, -70, -20, -140, -111, -9, -236, -215, -146, -218, -230, -38, -196, -232, -237, -33, -42, -182, -122, -228, -130, -125, -131, -50, -154, -49, -7, -242, -176, -87, -219, -212, -208, -109, -133, -44, -155, -230, -1, -219, -53, -188, -70, -91, -1, -48, -225, -207, -243, -27, -8, -128, -54, -43, -147, -32, -255, -138, -170, -247, -87, -66, -223, -232, -11, -13, -172, -135, -248, -22, -44, -2, -206, -5, -206, -68, -4, -218, -163, -192, -179, -107, -174, -85, -251, -124, -116, -34, -255, -82, -39, -114, -208, -170, -85, -219, -125, -67, -121, -47, -66, -244, -70, -183, -0, -191, -175, -160, -183, -31, -211, -198, -201, -68, -201, -243, -100, -222, -83, -65, -211, -40, -194, -117, -232, -133, -237, -36, -27, -80, -230, -20, -232, -78, -87, -186, -111, -182, -184, -70, -233, -0, -98, -140, -156, -231, -59, -125, -44, -53, -89, -174, -24, -212, -79, -33, -70, -95, -74, -174, -217, -203, -25, -48, -1, -254, -21, -85, -239, -175, -162, -77, -163, -47, -52, -34, -4, -78, -35, -215, -145, -156, -74, -128, -89, -122, -200, -243, -65, -182, -18, -51, -129, -111, -34, -251, -127, -247, -95, -105, -106, -58, -242, -120, -153, -95, -112, -202, -202, -66, -174, -175, -134, -156, -70, -52, -122, -78, -78, -251, -255, -105, -91, -111, -162, -91, -90, -68, -184, -142, -10, -231, -230, -26, -101, -12, -210, -182, -165, -3, -136, -49, -114, -158, -239, -244, -177, -106, -9, -105, -17, -124, -30, -75, -0, -2, -251, -53, -106, -198, -59, -85, -239, -175, -65, -219, -190, -4, -88, -45, -255, -154, -199, -255, -137, -138, -118, -214, -205, -183, -46, -148, -252, -81, -228, -113, -1, -138, -152, -26, -112, -15, -171, -146, -155, -226, -15, -196, -23, -164, -131, -14, -201, -69, -87, -103, -28, -59, -1, -163, -90, -9, -214, -224, -96, -99, -204, -91, -141, -49, -47, -55, -198, -220, -13, -220, -108, -140, -89, -195, -24, -179, -158, -49, -230, -219, -198, -152, -47, -27, -99, -158, -214, -150, -57, -34, -205, -247, -51, -198, -236, -229, -20, -79, -7, -238, -50, -198, -252, -57, -203, -178, -50, -251, -253, -221, -179, -44, -187, -174, -225, -229, -174, -51, -198, -244, -226, -55, -161, -247, -49, -191, -164, -250, -229, -89, -150, -85, -234, -25, -22, -119, -100, -89, -214, -56, -225, -12, -146, -164, -198, -158, -134, -205, -171, -33, -127, -194, -24, -115, -184, -49, -102, -127, -253, -253, -75, -45, -51, -198, -152, -233, -1, -151, -219, -198, -24, -147, -25, -99, -174, -206, -178, -204, -103, -202, -252, -87, -173, -223, -42, -203, -178, -73, -218, -191, -173, -141, -49, -167, -107, -93, -187, -163, -97, -100, -95, -52, -27, -56, -60, -128, -246, -30, -149, -80, -3, -38, -187, -1, -109, -75, -191, -32, -140, -210, -121, -190, -182, -63, -217, -233, -219, -44, -196, -168, -228, -94, -253, -253, -231, -138, -251, -8, -254, -154, -181, -105, -211, -166, -61, -13, -150, -220, -52, -223, -163, -151, -190, -191, -88, -253, -111, -139, -62, -248, -35, -123, -255, -219, -125, -15, -39, -176, -47, -141, -158, -19, -98, -57, -8, -145, -34, -8, -53, -185, -176, -117, -65, -172, -61, -107, -69, -156, -127, -64, -38, -224, -250, -78, -249, -166, -136, -107, -240, -238, -189, -118, -54, -50, -144, -100, -36, -22, -135, -224, -164, -196, -2, -214, -199, -227, -206, -217, -102, -176, -117, -29, -160, -77, -219, -135, -210, -211, -76, -96, -180, -26, -216, -109, -250, -63, -22, -248, -3, -63, -208, -127, -22, -71, -217, -178, -192, -190, -52, -21, -0, -183, -234, -191, -202, -208, -120, -209, -65, -179, -21, -192, -218, -136, -253, -183, -197, -253, -228, -81, -97, -64, -189, -253, -198, -11, -200, -163, -231, -94, -220, -160, -77, -227, -193, -214, -117, -128, -54, -109, -223, -7, -253, -48, -5, -0, -13, -61, -251, -186, -62, -223, -64, -222, -161, -167, -31, -173, -159, -83, -95, -125, -114, -177, -68, -177, -32, -203, -178, -189, -179, -44, -123, -122, -150, -101, -159, -169, -107, -156, -101, -217, -84, -35, -123, -141, -195, -141, -49, -83, -140, -236, -197, -151, -48, -198, -92, -108, -140, -249, -156, -49, -102, -219, -166, -29, -26, -101, -88, -101, -75, -173, -9, -239, -68, -71, -150, -227, -182, -33, -92, -238, -0, -99, -204, -242, -198, -152, -169, -198, -152, -104, -65, -84, -18, -186, -43, -1, -77, -150, -101, -15, -25, -99, -62, -171, -255, -198, -59, -236, -17, -211, -141, -45, -218, -94, -75, -201, -118, -176, -141, -194, -41, -65, -128, -216, -34, -124, -220, -136, -2, -109, -199, -44, -203, -238, -26, -229, -46, -45, -86, -24, -90, -72, -174, -50, -32, -249, -6, -239, -48, -34, -225, -175, -204, -178, -204, -119, -228, -81, -171, -212, -43, -78, -178, -54, -109, -140, -49, -118, -207, -239, -77, -131, -94, -131, -54, -26, -253, -36, -52, -234, -241, -27, -99, -204, -195, -198, -152, -183, -182, -56, -101, -73, -168, -193, -168, -11, -0, -211, -108, -121, -215, -102, -146, -53, -105, -51, -199, -136, -16, -88, -174, -142, -208, -131, -49, -117, -12, -184, -184, -32, -203, -178, -168, -193, -52, -19, -2, -129, -132, -8, -251, -15, -240, -120, -143, -215, -168, -13, -220, -160, -116, -67, -81, -180, -33, -102, -179, -0, -123, -213, -83, -15, -183, -111, -218, -238, -29, -12, -106, -233, -63, -136, -115, -90, -17, -227, -122, -125, -42, -209, -198, -59, -255, -166, -10, -55, -52, -206, -4, -145, -82, -220, -199, -232, -147, -139, -1, -37, -160, -50, -220, -223, -24, -243, -43, -99, -204, -43, -141, -49, -247, -55, -232, -64, -211, -7, -110, -151, -119, -219, -141, -145, -229, -221, -213, -250, -119, -151, -74, -170, -81, -0, -98, -216, -115, -134, -49, -230, -11, -78, -241, -251, -141, -49, -39, -25, -99, -134, -103, -254, -153, -208, -20, -183, -234, -223, -49, -55, -166, -140, -41, -17, -0, -198, -152, -125, -245, -239, -39, -178, -44, -123, -97, -9, -77, -103, -100, -89, -182, -105, -150, -101, -107, -103, -89, -118, -117, -61, -245, -80, -96, -195, -65, -189, -17, -248, -46, -35, -227, -179, -173, -5, -188, -125, -148, -250, -101, -178, -44, -91, -144, -149, -99, -66, -91, -245, -89, -216, -21, -146, -83, -180, -127, -200, -10, -169, -103, -28, -235, -244, -229, -102, -196, -132, -189, -214, -20, -120, -84, -225, -124, -209, -155, -250, -246, -143, -153, -37, -93, -219, -62, -145, -59, -56, -129, -156, -61, -223, -64, -30, -154, -42, -74, -150, -214, -190, -159, -87, -215, -235, -141, -197, -247, -25, -192, -115, -40, -17, -147, -28, -158, -161, -91, -128, -12, -216, -95, -199, -209, -108, -196, -122, -213, -27, -50, -109, -88, -125, -114, -81, -167, -4, -12, -138, -239, -215, -4, -208, -74, -59, -63, -76, -236, -98, -140, -249, -146, -49, -102, -79, -99, -204, -250, -198, -24, -171, -132, -186, -195, -24, -83, -26, -213, -53, -161, -30, -192, -59, -140, -49, -110, -34, -213, -253, -129, -179, -140, -49, -167, -103, -89, -214, -41, -22, -95, -150, -101, -11, -140, -216, -198, -143, -41, -100, -89, -134, -17, -255, -149, -131, -71, -187, -47, -62, -140, -230, -41, -192, -176, -142, -205, -26, -181, -201, -178, -108, -190, -49, -230, -123, -198, -152, -239, -57, -194, -106, -165, -44, -203, -234, -28, -56, -142, -163, -36, -33, -74, -150, -101, -91, -213, -180, -93, -236, -65, -174, -195, -112, -241, -126, -253, -247, -114, -99, -76, -218, -198, -140, -2, -70, -83, -0, -12, -235, -216, -44, -198, -81, -91, -101, -108, -63, -69, -155, -229, -236, -132, -17, -26, -99, -245, -11, -221, -20, -139, -155, -125, -198, -128, -0, -96, -100, -18, -133, -97, -186, -249, -134, -160, -141, -208, -104, -211, -198, -24, -19, -246, -178, -59, -14, -136, -94, -117, -0, -125, -46, -185, -19, -22, -51, -0, -203, -3, -47, -3, -254, -165, -10, -133, -191, -53, -104, -27, -172, -212, -25, -150, -210, -172, -111, -69, -214, -88, -71, -27, -165, -24, -45, -237, -12, -198, -2, -144, -0, -26, -199, -106, -191, -79, -243, -212, -15, -96, -52, -250, -233, -244, -103, -105, -228, -68, -224, -78, -26, -4, -240, -232, -179, -67, -22, -55, -2, -95, -1, -130, -131, -106, -36, -1, -48, -254, -209, -70, -96, -140, -21, -0, -239, -69, -162, -83, -221, -133, -68, -225, -169, -18, -0, -87, -17, -51, -115, -78, -75, -0, -27, -58, -125, -26, -181, -227, -101, -215, -14, -224, -127, -70, -246, -202, -235, -25, -99, -94, -104, -196, -60, -55, -97, -130, -160, -15, -59, -3, -224, -37, -200, -209, -151, -215, -156, -151, -6, -97, -200, -107, -176, -185, -49, -230, -95, -198, -152, -16, -107, -187, -247, -103, -89, -182, -149, -79, -199, -226, -147, -124, -109, -251, -76, -189, -11, -243, -221, -198, -152, -43, -141, -49, -119, -26, -99, -46, -15, -232, -119, -255, -0, -86, -68, -242, -145, -1, -252, -179, -65, -187, -224, -175, -109, -197, -87, -166, -234, -161, -7, -243, -239, -210, -70, -219, -5, -199, -210, -71, -76, -152, -255, -3, -236, -209, -228, -26, -19, -5, -192, -31, -144, -184, -118, -231, -251, -132, -0, -13, -194, -144, -55, -184, -38, -84, -175, -0, -74, -207, -202, -201, -227, -56, -218, -73, -238, -27, -139, -65, -125, -166, -38, -57, -233, -152, -5, -176, -142, -243, -176, -86, -10, -108, -19, -60, -217, -28, -218, -54, -65, -52, -135, -33, -0, -130, -99, -233, -147, -39, -79, -1, -248, -98, -13, -223, -37, -144, -40, -67, -143, -35, -65, -83, -14, -68, -98, -204, -21, -233, -62, -15, -92, -134, -132, -230, -126, -20, -248, -59, -240, -188, -38, -247, -48, -86, -128, -100, -198, -61, -205, -190, -239, -18, -154, -160, -48, -228, -13, -174, -9, -45, -5, -128, -67, -91, -23, -146, -174, -178, -207, -4, -250, -184, -116, -5, -18, -54, -124, -54, -240, -75, -79, -221, -47, -144, -237, -208, -79, -219, -48, -182, -216, -176, -33, -125, -223, -58, -128, -94, -133, -134, -182, -107, -20, -75, -31, -201, -42, -3, -240, -64, -13, -223, -47, -34, -81, -139, -191, -160, -255, -230, -227, -137, -62, -139, -164, -146, -62, -20, -120, -63, -176, -59, -146, -120, -226, -162, -10, -190, -149, -202, -36, -74, -80, -255, -36, -226, -1, -73, -45, -87, -26, -98, -142, -128, -48, -228, -13, -174, -5, -61, -11, -128, -186, -62, -19, -144, -156, -180, -105, -159, -74, -218, -219, -240, -125, -3, -238, -235, -78, -221, -147, -109, -24, -55, -234, -88, -147, -201, -214, -132, -214, -211, -166, -20, -49, -174, -211, -6, -192, -243, -235, -6, -139, -210, -93, -11, -252, -213, -249, -253, -87, -60, -166, -197, -158, -118, -135, -81, -145, -177, -150, -26, -101, -18, -178, -162, -25, -248, -231, -161, -179, -193, -80, -127, -94, -211, -159, -208, -231, -191, -51, -178, -2, -56, -64, -175, -57, -20, -43, -74, -237, -78, -239, -2, -32, -6, -154, -244, -169, -164, -253, -145, -200, -10, -224, -23, -158, -58, -187, -58, -56, -178, -247, -142, -53, -153, -108, -195, -154, -152, -195, -66, -232, -96, -65, -210, -79, -29, -230, -252, -62, -12, -24, -176, -179, -64, -146, -178, -254, -12, -177, -29, -159, -129, -198, -134, -175, -224, -107, -87, -0, -141, -226, -193, -123, -248, -172, -6, -220, -167, -183, -242, -158, -10, -186, -80, -129, -50, -3, -89, -229, -76, -209, -251, -25, -138, -82, -121, -34, -9, -128, -24, -24, -11, -1, -65, -38, -10, -22, -153, -145, -150, -112, -101, -158, -152, -191, -49, -18, -19, -254, -48, -99, -204, -100, -99, -204, -206, -250, -207, -11, -53, -93, -30, -136, -162, -212, -20, -89, -150, -61, -134, -164, -150, -250, -147, -49, -230, -112, -224, -239, -89, -150, -13, -88, -41, -102, -89, -22, -116, -60, -156, -101, -217, -10, -93, -251, -52, -150, -225, -8, -135, -141, -139, -113, -17, -171, -234, -198, -26, -202, -6, -161, -117, -2, -170, -76, -13, -150, -208, -8, -183, -24, -99, -54, -113, -126, -63, -207, -228, -190, -226, -46, -182, -54, -198, -28, -159, -101, -217, -215, -178, -44, -251, -189, -49, -102, -152, -97, -161, -207, -48, -198, -220, -100, -140, -89, -219, -24, -19, -39, -207, -92, -194, -168, -0, -248, -152, -174, -46, -94, -92, -69, -87, -38, -0, -172, -212, -122, -83, -192, -133, -92, -30, -115, -3, -251, -183, -56, -225, -169, -136, -73, -192, -186, -21, -116, -71, -27, -99, -182, -3, -246, -3, -246, -51, -198, -108, -103, -114, -95, -113, -23, -119, -24, -99, -182, -69, -148, -128, -223, -51, -198, -188, -173, -174, -3, -177, -150, -146, -234, -185, -102, -253, -233, -247, -41, -188, -219, -113, -1, -181, -91, -40, -221, -194, -76, -32, -172, -84, -248, -27, -14, -196, -178, -202, -226, -250, -26, -218, -245, -148, -110, -33, -1, -199, -134, -14, -223, -96, -141, -126, -0, -207, -159, -43, -207, -63, -4, -208, -238, -66, -158, -179, -109, -149, -166, -215, -42, -225, -121, -182, -242, -59, -23, -209, -14, -15, -152, -206, -34, -126, -225, -223, -36, -63, -6, -252, -14, -254, -99, -192, -215, -144, -251, -142, -159, -13, -236, -90, -183, -23, -141, -185, -151, -68, -108, -65, -108, -142, -197, -215, -117, -229, -55, -86, -208, -228, -25, -17, -118, -10, -80, -202, -47, -244, -90, -49, -223, -155, -135, -247, -55, -149, -119, -80, -218, -115, -31, -131, -119, -2, -23, -227, -81, -84, -57, -52, -75, -3, -39, -233, -133, -74, -143, -170, -10, -109, -106, -209, -176, -159, -59, -107, -179, -251, -129, -213, -43, -232, -50, -68, -35, -237, -34, -150, -0, -120, -58, -98, -62, -125, -99, -155, -123, -136, -112, -253, -168, -3, -9, -248, -183, -242, -59, -48, -6, -191, -177, -128, -38, -207, -136, -197, -67, -0, -28, -162, -188, -223, -87, -69, -87, -170, -4, -204, -178, -236, -12, -51, -232, -191, -109, -153, -223, -103, -140, -185, -215, -136, -217, -240, -218, -70, -162, -233, -238, -23, -210, -177, -152, -238, -148, -72, -250, -114, -155, -193, -232, -179, -89, -150, -61, -90, -66, -183, -188, -145, -96, -30, -239, -50, -18, -247, -111, -99, -211, -102, -105, -84, -142, -21, -140, -49, -47, -50, -242, -60, -102, -26, -89, -198, -143, -103, -156, -103, -140, -121, -181, -49, -166, -242, -28, -59, -97, -76, -35, -104, -11, -208, -118, -143, -55, -199, -136, -221, -245, -211, -140, -49, -103, -25, -99, -94, -155, -249, -51, -152, -246, -141, -221, -141, -49, -207, -52, -198, -220, -108, -140, -249, -99, -5, -221, -95, -140, -76, -254, -11, -141, -236, -189, -99, -251, -116, -159, -98, -140, -249, -128, -17, -13, -250, -218, -89, -150, -85, -42, -94, -198, -1, -172, -0, -171, -210, -105, -36, -140, -50, -144, -179, -126, -128, -123, -60, -213, -43, -234, -223, -74, -1, -208, -234, -24, -48, -203, -178, -32, -11, -193, -62, -129, -36, -77, -180, -230, -183, -135, -168, -2, -171, -12, -63, -54, -198, -220, -99, -140, -249, -120, -150, -101, -243, -104, -224, -233, -24, -208, -143, -149, -141, -49, -175, -215, -159, -95, -201, -178, -172, -77, -82, -145, -177, -134, -135, -244, -239, -26, -163, -218, -139, -132, -58, -188, -74, -255, -254, -213, -83, -103, -39, -254, -138, -158, -186, -167, -48, -158, -237, -0, -94, -105, -140, -217, -192, -200, -145, -165, -215, -76, -215, -34, -203, -178, -179, -140, -172, -84, -44, -150, -46, -163, -109, -129, -167, -38, -73, -150, -101, -247, -70, -228, -59, -154, -120, -68, -255, -174, -54, -170, -189, -72, -40, -5, -176, -170, -17, -175, -93, -99, -140, -249, -181, -135, -164, -217, -22, -0, -152, -171, -203, -137, -168, -174, -137, -52, -243, -174, -219, -20, -201, -208, -123, -175, -246, -103, -10, -146, -173, -216, -103, -225, -182, -173, -254, -189, -34, -32, -94, -95, -159, -88, -172, -66, -68, -41, -150, -209, -191, -211, -70, -181, -23, -9, -85, -216, -198, -200, -216, -187, -186, -100, -251, -221, -120, -11, -48, -221, -24, -179, -186, -137, -255, -210, -223, -102, -140, -89, -214, -136, -146, -236, -82, -35, -82, -235, -185, -70, -246, -238, -69, -28, -98, -196, -16, -230, -116, -35, -6, -41, -27, -26, -73, -12, -185, -145, -49, -230, -141, -5, -218, -109, -244, -239, -121, -145, -251, -155, -144, -191, -155, -135, -71, -181, -23, -139, -57, -58, -42, -196, -223, -160, -127, -15, -45, -169, -111, -188, -5, -152, -102, -74, -4, -0, -226, -110, -248, -97, -99, -204, -113, -89, -150, -237, -19, -90, -167, -56, -203, -72, -236, -187, -201, -250, -123, -178, -145, -32, -8, -87, -122, -104, -63, -100, -228, -185, -60, -117, -244, -8, -60, -215, -248, -77, -93, -173, -143, -245, -120, -215, -184, -143, -69, -88, -247, -227, -74, -15, -199, -113, -138, -147, -81, -223, -133, -113, -30, -120, -117, -71, -35, -6, -123, -167, -150, -212, -55, -51, -4, -2, -174, -211, -45, -192, -241, -158, -186, -16, -183, -195, -168, -202, -47, -224, -105, -192, -235, -17, -191, -235, -223, -122, -234, -109, -178, -142, -183, -182, -224, -109, -209, -217, -14, -0, -216, -76, -121, -205, -235, -202, -171, -67, -31, -162, -158, -39, -3, -103, -41, -191, -178, -175, -203, -184, -3, -30, -84, -208, -14, -197, -14, -160, -79, -56, -91, -250, -202, -36, -36, -197, -45, -128, -49, -254, -45, -192, -137, -70, -190, -242, -191, -241, -212, -157, -96, -140, -249, -168, -254, -141, -130, -194, -131, -63, -215, -24, -227, -139, -184, -99, -39, -175, -247, -236, -127, -136, -216, -65, -255, -250, -236, -250, -199, -29, -144, -19, -146, -109, -245, -231, -57, -163, -216, -149, -168, -8, -89, -110, -147, -91, -161, -214, -158, -18, -85, -241, -27, -11, -161, -195, -179, -44, -91, -182, -158, -202, -1, -226, -159, -14, -61, -89, -127, -53, -145, -138, -192, -14, -136, -133, -223, -17, -218, -230, -32, -15, -205, -227, -90, -183, -181, -143, -71, -96, -95, -58, -173, -0, -16, -147, -93, -139, -82, -143, -189, -190, -17, -243, -139, -131, -248, -32, -128, -132, -189, -90, -166, -190, -197, -226, -131, -38, -171, -132, -197, -14, -72, -8, -104, -144, -204, -192, -125, -240, -111, -53, -72, -129, -11, -241, -68, -147, -1, -110, -85, -126, -141, -179, -174, -70, -20, -0, -143, -33, -230, -210, -239, -236, -194, -167, -43, -34, -11, -128, -75, -149, -215, -119, -99, -244, -45, -97, -108, -35, -116, -11, -48, -20, -0, -171, -100, -89, -246, -132, -243, -123, -73, -99, -204, -51, -140, -63, -71, -225, -253, -70, -78, -7, -188, -17, -103, -135, -129, -44, -203, -22, -171, -115, -114, -196, -113, -228, -53, -70, -18, -194, -44, -54, -251, -255, -132, -114, -184, -166, -192, -211, -10, -127, -71, -3, -83, -129, -51, -144, -212, -220, -95, -55, -198, -92, -96, -100, -130, -255, -202, -67, -107, -247, -107, -111, -240, -212, -77, -24, -48, -210, -243, -176, -52, -238, -94, -0, -159, -149, -141, -49, -71, -233, -207, -207, -186, -130, -56, -97, -2, -128, -220, -125, -176, -151, -36, -5, -33, -203, -84, -224, -32, -196, -163, -110, -38, -18, -106, -106, -50, -18, -76, -115, -32, -40, -6, -240, -70, -229, -55, -151, -134, -153, -107, -98, -109, -1, -198, -2, -128, -183, -235, -189, -60, -94, -79, -93, -201, -199, -134, -131, -111, -30, -67, -46, -97, -252, -3, -216, -87, -7, -192, -182, -61, -241, -143, -182, -79, -85, -126, -203, -34, -145, -87, -1, -118, -107, -217, -151, -113, -43, -0, -128, -187, -145, -248, -245, -243, -244, -94, -14, -24, -237, -62, -37, -140, -99, -144, -135, -16, -10, -201, -174, -210, -134, -127, -84, -1, -160, -60, -247, -87, -158, -147, -98, -241, -28, -47, -64, -148, -160, -243, -144, -64, -158, -95, -247, -173, -146, -18, -18, -198, -12, -122, -18, -0, -43, -34, -201, -51, -0, -106, -67, -103, -37, -36, -36, -140, -18, -250, -16, -0, -202, -247, -67, -202, -247, -238, -241, -188, -164, -79, -72, -24, -85, -32, -94, -119, -179, -129, -195, -235, -169, -91, -241, -15, -22, -0, -84, -164, -60, -42, -161, -63, -82, -121, -255, -174, -123, -79, -19, -18, -38, -32, -200, -109, -250, -123, -57, -254, -105, -40, -0, -122, -241, -47, -72, -72, -72, -24, -9, -215, -14, -224, -68, -35, -161, -190, -134, -146, -194, -169, -6, -39, -24, -233, -75, -52, -255, -130, -132, -132, -132, -81, -68, -95, -58, -128, -132, -132, -132, -132, -132, -132, -132, -137, -0, -93, -69, -148, -165, -3, -111, -156, -84, -36, -33, -97, -34, -99, -220, -165, -126, -74, -72, -72, -136, -135, -36, -0, -18, -18, -38, -48, -122, -21, -0, -85, -138, -63, -231, -168, -111, -251, -62, -251, -144, -144, -144, -80, -142, -209, -92, -1, -60, -92, -248, -155, -144, -144, -48, -100, -140, -5, -1, -240, -72, -177, -194, -177, -74, -60, -98, -200, -125, -74, -72, -152, -80, -24, -77, -1, -96, -39, -190, -111, -5, -176, -155, -145, -192, -140, -31, -30, -94, -119, -18, -18, -38, -30, -70, -123, -5, -48, -61, -203, -178, -185, -158, -58, -107, -149, -232, -139, -66, -156, -144, -144, -16, -9, -163, -153, -27, -240, -97, -227, -89, -254, -27, -99, -76, -150, -101, -123, -27, -99, -246, -30, -110, -119, -18, -18, -18, -162, -98, -152, -230, -191, -201, -16, -40, -33, -161, -57, -146, -29, -64, -66, -194, -4, -70, -18, -0, -9, -9, -19, -24, -73, -0, -36, -36, -76, -96, -36, -1, -144, -144, -48, -129, -145, -4, -64, -66, -194, -4, -198, -184, -19, -0, -73, -219, -159, -144, -16, -15, -227, -78, -0, -36, -36, -36, -196, -67, -18, -0, -9, -9, -19, -24, -73, -0, -36, -36, -76, -96, -36, -1, -144, -144, -48, -117, -14, -169, -49, -0, -0, -2, -74, -73, -68, -65, -84, -129, -145, -4, -64, -66, -194, -4, -70, -175, -206, -64, -89, -150, -101, -125, -242, -79, -72, -72, -232, -134, -180, -2, -72, -72, -152, -192, -72, -2, -32, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, -225, -255, -219, -131, -3, -2, -0, -0, -0, -0, -33, -253, -95, -221, -17, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -208, -17, -112, -180, -144, -16, -164, -2, -78, -0, -0, -0, -0, -73, -69, -78, -68, -174, -66, -96, -130, -}; -/* clang-format on */ diff --git a/scene/resources/default_theme/font_lodpi.inc b/scene/resources/default_theme/font_lodpi.inc deleted file mode 100644 index d2f5851224..0000000000 --- a/scene/resources/default_theme/font_lodpi.inc +++ /dev/null @@ -1,13117 +0,0 @@ -/* clang-format off */ -static const int _lodpi_font_height=14; -static const int _lodpi_font_ascent=11; -static const int _lodpi_font_charcount=191; -static const int _lodpi_font_charrects[191][8]={ -/* charidx , ofs_x, ofs_y, size_x, size_y, valign, halign, advance */ -{64,72,34,10,11,1,1,12}, -{224,85,180,5,11,0,1,7}, -{192,32,16,11,13,-2,-1,9}, -{96,2,216,3,2,0,3,8}, -{160,0,0,0,0,11,0,4}, -{32,0,0,0,0,11,0,4}, -{33,65,234,2,10,1,1,4}, -{225,112,169,5,11,0,1,7}, -{193,17,16,11,13,-2,-1,9}, -{161,2,222,2,11,3,1,4}, -{65,2,16,11,10,1,-1,9}, -{97,76,188,5,8,3,1,7}, -{98,102,165,6,11,0,1,8}, -{226,72,143,6,11,0,1,7}, -{194,113,2,11,13,-2,-1,9}, -{66,46,109,7,10,1,1,9}, -{162,12,136,6,10,1,1,8}, -{34,49,187,5,4,1,1,6}, -{35,78,66,8,10,1,0,9}, -{163,22,167,6,10,1,1,8}, -{195,53,2,11,14,-3,-1,9}, -{227,2,155,6,12,-1,1,7}, -{67,68,115,7,10,1,1,8}, -{99,40,179,5,8,3,1,7}, -{228,121,169,5,11,0,1,7}, -{196,98,2,11,13,-2,-1,9}, -{36,102,137,6,12,0,1,8}, -{100,82,150,6,11,0,1,8}, -{68,90,66,8,10,1,1,10}, -{164,14,79,8,7,3,0,8}, -{37,2,30,10,10,1,1,12}, -{69,29,191,5,10,1,1,7}, -{165,79,98,7,10,1,0,8}, -{229,20,196,5,12,-1,1,7}, -{197,83,2,11,12,-1,-1,9}, -{101,32,124,6,8,3,1,8}, -{38,67,49,9,10,1,1,10}, -{70,101,105,6,10,1,1,7}, -{198,21,2,12,10,1,-1,12}, -{166,95,228,2,14,0,3,7}, -{102,2,201,5,11,0,0,4}, -{230,58,34,10,8,3,1,12}, -{71,66,65,8,10,1,1,10}, -{231,2,186,5,11,3,1,7}, -{199,57,97,7,13,1,1,8}, -{103,13,107,7,11,3,1,7}, -{167,112,131,6,11,0,0,7}, -{39,119,219,2,4,1,1,3}, -{72,54,65,8,10,1,1,10}, -{232,62,143,6,11,0,1,8}, -{200,47,195,5,13,-2,1,7}, -{40,93,212,4,12,1,1,4}, -{104,72,158,6,11,0,1,8}, -{168,77,217,4,2,0,2,8}, -{73,38,191,5,10,1,0,5}, -{169,44,34,10,10,1,1,12}, -{233,52,142,6,11,0,1,8}, -{201,56,197,5,13,-2,1,7}, -{41,51,226,3,12,1,0,4}, -{105,109,213,3,11,0,0,4}, -{106,101,213,4,14,0,-1,4}, -{74,92,195,5,13,1,-2,3}, -{202,65,202,5,13,-2,1,7}, -{42,108,80,7,6,0,0,8}, -{170,29,205,4,5,1,0,5}, -{234,12,181,6,11,0,1,8}, -{171,22,181,5,6,4,1,7}, -{43,101,94,7,7,3,0,8}, -{107,112,92,7,11,0,1,7}, -{203,83,200,5,13,-2,1,7}, -{235,2,171,6,11,0,1,8}, -{75,102,66,8,10,1,1,8}, -{44,107,231,2,3,9,1,4}, -{172,2,104,7,4,6,0,8}, -{108,113,228,2,11,0,1,4}, -{204,101,196,5,13,-2,0,5}, -{236,30,214,3,11,0,0,4}, -{76,22,124,6,10,1,1,7}, -{173,16,229,3,2,7,1,5}, -{45,123,201,3,2,7,1,5}, -{109,68,2,11,8,3,1,13}, -{205,11,211,5,13,-2,0,5}, -{237,37,214,3,11,0,1,4}, -{77,62,20,10,10,1,1,12}, -{46,101,231,2,2,9,1,4}, -{110,111,107,6,8,3,1,8}, -{206,20,212,5,13,-2,0,5}, -{238,11,196,5,11,0,-1,4}, -{174,30,33,10,10,1,1,12}, -{78,2,79,8,10,1,1,10}, -{175,35,111,7,1,-1,0,7}, -{111,102,153,6,8,3,1,8}, -{207,119,184,5,13,-2,0,5}, -{239,69,219,4,11,0,0,4}, -{79,41,66,9,10,1,1,11}, -{47,90,105,7,10,1,-1,5}, -{176,61,219,4,4,1,1,6}, -{112,32,150,6,11,3,1,8}, -{240,82,165,6,11,0,1,8}, -{208,86,33,9,10,1,0,10}, -{80,52,128,6,10,1,1,8}, -{48,42,135,6,10,1,1,8}, -{177,46,97,7,8,3,0,8}, -{113,22,152,6,11,3,1,8}, -{241,2,112,6,12,-1,1,8}, -{81,15,59,9,13,1,1,11}, -{209,74,80,8,14,-3,1,10}, -{49,45,212,4,10,1,2,8}, -{178,58,187,5,6,1,0,5}, -{114,85,217,4,8,3,1,5}, -{210,2,62,9,13,-2,1,11}, -{242,62,165,6,11,0,1,8}, -{82,35,97,7,10,1,1,8}, -{50,57,114,7,10,1,1,8}, -{179,53,214,4,6,1,0,5}, -{115,112,146,6,8,3,0,7}, -{211,106,49,9,13,-2,1,11}, -{243,52,172,6,11,0,1,8}, -{83,24,96,7,10,1,0,7}, -{51,22,138,6,10,1,1,8}, -{180,9,228,3,2,0,3,8}, -{116,67,188,5,10,1,0,5}, -{212,93,49,9,13,-2,1,11}, -{244,42,164,6,11,0,1,8}, -{84,13,93,7,10,1,0,7}, -{52,24,110,7,10,1,1,8}, -{53,92,119,6,10,1,1,8}, -{85,114,66,8,10,1,1,10}, -{213,2,44,9,14,-3,1,11}, -{117,42,123,6,8,3,1,8}, -{181,2,140,6,11,3,1,8}, -{245,12,165,6,12,-1,1,8}, -{54,82,121,6,10,1,1,8}, -{86,76,18,10,10,1,-1,8}, -{246,72,173,6,11,0,1,8}, -{214,80,49,9,13,-2,1,11}, -{182,68,98,7,13,0,1,9}, -{118,15,47,9,8,3,-1,7}, -{55,72,129,6,10,1,1,8}, -{87,2,2,15,10,1,-1,13}, -{119,37,2,12,8,3,-1,10}, -{247,90,94,7,7,3,0,8}, -{215,2,93,7,7,3,0,8}, -{183,77,223,2,2,5,1,4}, -{56,62,129,6,10,1,1,8}, -{88,90,19,10,10,1,-1,8}, -{216,99,33,9,12,0,1,11}, -{248,2,128,6,8,3,1,8}, -{120,119,80,7,8,3,0,7}, -{184,116,212,3,3,11,0,3}, -{89,28,65,9,10,1,-1,7}, -{217,38,80,8,13,-2,1,10}, -{249,52,157,6,11,0,1,8}, -{121,112,33,9,11,3,-1,7}, -{57,12,122,6,10,1,1,8}, -{185,23,229,3,6,1,0,5}, -{218,26,79,8,13,-2,1,10}, -{250,42,149,6,11,0,1,8}, -{90,32,136,6,10,1,1,8}, -{122,112,119,6,8,3,1,7}, -{58,89,229,2,8,3,1,4}, -{186,37,205,4,5,1,0,5}, -{219,50,80,8,13,-2,1,10}, -{91,58,227,3,12,1,1,4}, -{123,103,180,5,12,1,0,5}, -{251,12,150,6,11,0,1,8}, -{59,71,234,2,9,3,1,4}, -{187,31,181,5,6,4,1,7}, -{188,16,33,10,10,1,0,10}, -{124,83,229,2,14,0,3,7}, -{220,62,79,8,13,-2,1,10}, -{252,92,133,6,11,0,1,8}, -{92,97,80,7,10,1,-1,5}, -{60,92,153,6,7,3,1,8}, -{189,47,20,11,10,1,0,10}, -{253,28,47,9,14,0,-1,7}, -{221,54,48,9,13,-2,-1,7}, -{93,44,226,3,12,1,0,4}, -{125,110,196,5,12,1,0,5}, -{61,79,112,7,5,4,0,8}, -{190,104,19,10,10,1,0,10}, -{222,32,165,6,10,1,1,8}, -{254,102,119,6,14,0,1,8}, -{62,112,158,6,7,3,1,8}, -{94,86,80,7,6,1,0,7}, -{126,62,158,6,3,5,1,8}, -{223,82,135,6,11,0,1,8}, -{255,41,48,9,14,0,-1,7}, -{191,94,180,5,11,3,0,6}, -{63,74,202,5,10,1,0,6}, -{95,92,148,6,1,12,0,6}, -}; -static const int _lodpi_font_kerning_pair_count=0; -static const int _lodpi_font_kerning_pairs[1][3]={ -{0,0,0}, -}; -static const int _lodpi_font_img_width=128; -static const int _lodpi_font_img_height=256; -static const int _lodpi_font_img_data_size=12909; -static const unsigned char _lodpi_font_img_data[12909]={ -137, -80, -78, -71, -13, -10, -26, -10, -0, -0, -0, -13, -73, -72, -68, -82, -0, -0, -0, -128, -0, -0, -1, -0, -8, -6, -0, -0, -0, -123, -249, -126, -167, -0, -0, -32, -0, -73, -68, -65, -84, -120, -156, -237, -157, -119, -184, -30, -85, -181, -255, -191, -59, -128, -8, -210, -155, -82, -77, -232, -221, -2, -210, -164, -132, -26, -154, -5, -164, -131, -63, -224, -98, -65, -4, -68, -46, -8, -42, -23, -84, -80, -41, -94, -16, -21, -17, -197, -10, -22, -80, -17, -21, -4, -5, -65, -16, -41, -42, -185, -116, -19, -106, -128, -80, -46, -32, -33, -148, -208, -18, -62, -191, -63, -214, -122, -115, -230, -204, -217, -51, -179, -103, -222, -121, -223, -115, -146, -123, -190, -207, -115, -158, -51, -101, -237, -50, -243, -174, -217, -123, -237, -213, -182, -52, -138, -81, -140, -98, -20, -2, -150, -3, -222, -0, -54, -207, -93, -255, -32, -134, -247, -231, -174, -111, -237, -244, -203, -38, -212, -61, -31, -48, -149, -2, -68, -232, -87, -242, -91, -107, -102, -174, -253, -28, -184, -58, -115, -190, -178, -211, -172, -88, -243, -57, -199, -84, -220, -7, -216, -17, -184, -21, -120, -21, -184, -23, -216, -9, -56, -192, -143, -103, -0, -55, -1, -235, -36, -180, -245, -117, -224, -122, -224, -244, -58, -125, -244, -178, -247, -0, -239, -4, -222, -13, -220, -85, -179, -236, -55, -253, -57, -190, -89, -69, -59, -251, -101, -132, -16, -30, -151, -116, -171, -164, -157, -114, -52, -59, -74, -186, -94, -210, -118, -185, -235, -59, -73, -250, -123, -8, -225, -137, -132, -62, -237, -39, -233, -113, -73, -11, -248, -249, -206, -126, -188, -64, -230, -218, -108, -132, -16, -30, -145, -116, -175, -164, -205, -252, -129, -230, -149, -180, -161, -164, -21, -129, -133, -156, -108, -115, -73, -147, -67, -8, -143, -150, -53, -12, -28, -9, -76, -3, -206, -4, -198, -74, -186, -49, -161, -191, -103, -75, -58, -76, -210, -242, -178, -103, -191, -88, -210, -17, -146, -118, -151, -52, -78, -210, -51, -146, -190, -157, -80, -207, -102, -33, -132, -45, -37, -109, -157, -64, -155, -199, -204, -204, -241, -172, -212, -66, -192, -119, -37, -45, -41, -105, -13, -73, -75, -251, -121, -114, -225, -19, -128, -137, -185, -107, -15, -1, -59, -3, -255, -202, -93, -191, -11, -248, -108, -98, -189, -119, -2, -251, -250, -49, -64, -158, -153, -98, -101, -206, -1, -206, -247, -227, -109, -128, -75, -129, -31, -117, -70, -34, -224, -188, -20, -14, -7, -110, -241, -209, -226, -76, -224, -57, -224, -136, -10, -122, -128, -79, -100, -206, -215, -205, -247, -217, -71, -136, -23, -18, -218, -190, -223, -203, -222, -93, -69, -59, -34, -0, -172, -159, -29, -214, -129, -53, -128, -71, -252, -120, -42, -176, -188, -31, -175, -232, -15, -182, -118, -66, -157, -59, -1, -143, -250, -87, -92, -135, -1, -62, -216, -121, -113, -192, -89, -192, -97, -192, -65, -192, -185, -126, -237, -110, -114, -211, -82, -65, -61, -165, -67, -126, -132, -30, -96, -219, -204, -249, -88, -191, -54, -54, -115, -109, -115, -24, -58, -117, -69, -234, -186, -12, -248, -53, -240, -251, -58, -125, -240, -178, -59, -121, -187, -249, -17, -185, -167, -101, -59, -95, -252, -193, -126, -124, -100, -230, -43, -252, -17, -112, -144, -31, -127, -28, -184, -47, -177, -190, -107, -128, -207, -100, -206, -135, -160, -160, -220, -162, -192, -107, -254, -255, -62, -76, -46, -88, -14, -120, -16, -88, -204, -239, -45, -146, -216, -135, -228, -23, -226, -116, -155, -103, -206, -59, -12, -176, -66, -230, -90, -37, -3, -0, -227, -128, -151, -252, -99, -121, -41, -203, -64, -137, -125, -238, -134, -121, -26, -151, -21, -112, -54, -112, -177, -31, -255, -1, -216, -211, -143, -247, -7, -46, -244, -227, -75, -129, -175, -37, -212, -245, -110, -224, -5, -96, -177, -204, -53, -252, -7, -121, -115, -231, -175, -164, -252, -77, -192, -129, -192, -29, -153, -107, -119, -0, -7, -3, -55, -212, -120, -166, -228, -23, -210, -34, -3, -156, -14, -252, -218, -143, -47, -1, -78, -171, -209, -223, -198, -204, -211, -45, -227, -9, -216, -22, -19, -154, -22, -0, -158, -7, -22, -247, -235, -111, -5, -30, -199, -36, -250, -231, -201, -173, -22, -10, -234, -250, -121, -236, -139, -39, -97, -10, -240, -242, -39, -3, -55, -0, -95, -201, -92, -59, -195, -25, -227, -164, -196, -58, -106, -189, -144, -54, -24, -192, -25, -251, -25, -96, -15, -63, -223, -195, -207, -11, -153, -61, -87, -190, -27, -230, -105, -92, -182, -83, -193, -188, -206, -0, -31, -7, -110, -206, -221, -187, -29, -27, -9, -158, -162, -122, -57, -53, -22, -27, -166, -215, -206, -126, -237, -53, -25, -96, -75, -167, -223, -44, -115, -109, -187, -252, -181, -138, -58, -106, -189, -144, -150, -24, -224, -64, -255, -72, -22, -240, -243, -55, -3, -211, -129, -3, -19, -250, -219, -152, -121, -186, -101, -188, -108, -69, -63, -195, -164, -231, -47, -230, -174, -127, -205, -191, -190, -31, -36, -212, -113, -54, -240, -219, -200, -117, -72, -156, -2, -186, -69, -107, -47, -164, -126, -187, -127, -39, -142, -91, -18, -202, -118, -195, -60, -141, -203, -230, -43, -218, -219, -59, -252, -222, -220, -245, -9, -126, -253, -3, -21, -229, -23, -7, -94, -4, -198, -71, -238, -13, -65, -173, -206, -213, -64, -107, -47, -164, -94, -155, -239, -1, -102, -97, -43, -168, -236, -200, -183, -154, -95, -223, -176, -162, -124, -55, -204, -211, -184, -236, -92, -137, -225, -120, -33, -216, -106, -233, -55, -5, -247, -46, -5, -126, -88, -82, -182, -49, -243, -116, -203, -120, -115, -29, -134, -227, -133, -0, -75, -2, -47, -3, -91, -21, -220, -223, -214, -239, -47, -89, -112, -191, -27, -230, -105, -92, -118, -174, -196, -156, -246, -66, -186, -97, -158, -110, -25, -111, -174, -195, -232, -11, -105, -1, -116, -163, -78, -180, -242, -75, -1, -255, -11, -252, -180, -102, -185, -159, -123, -185, -165, -154, -180, -59, -138, -150, -64, -55, -234, -68, -43, -127, -5, -166, -195, -175, -171, -139, -159, -7, -51, -163, -254, -161, -73, -187, -163, -104, -1, -116, -171, -78, -156, -139, -1, -44, -3, -188, -14, -108, -19, -185, -183, -131, -223, -91, -102, -56, -250, -214, -4, -69, -95, -231, -39, -36, -93, -233, -182, -246, -63, -250, -121, -50, -186, -153, -62, -186, -157, -122, -122, -141, -16, -194, -83, -146, -174, -146, -180, -103, -228, -246, -158, -146, -254, -228, -52, -131, -0, -44, -136, -57, -121, -124, -46, -114, -239, -72, -191, -183, -96, -228, -222, -217, -152, -129, -238, -62, -224, -204, -204, -245, -177, -152, -133, -54, -201, -32, -150, -12, -90, -208, -158, -117, -51, -125, -212, -41, -235, -194, -222, -143, -129, -215, -114, -215, -43, -95, -142, -51, -217, -171, -184, -173, -35, -119, -239, -77, -192, -211, -80, -104, -169, -220, -215, -229, -148, -121, -50, -215, -230, -245, -50, -251, -148, -180, -185, -30, -102, -28, -219, -58, -115, -109, -99, -204, -79, -97, -221, -130, -50, -107, -250, -180, -184, -46, -240, -104, -230, -250, -133, -192, -167, -138, -218, -106, -12, -186, -212, -158, -117, -51, -125, -212, -45, -11, -252, -2, -179, -77, -204, -200, -93, -175, -124, -57, -206, -0, -55, -147, -113, -254, -200, -220, -219, -3, -184, -177, -132, -1, -22, -244, -119, -180, -77, -230, -218, -118, -217, -247, -86, -210, -238, -199, -128, -39, -129, -101, -157, -129, -31, -6, -62, -86, -81, -230, -58, -103, -174, -143, -248, -249, -187, -48, -103, -147, -55, -149, -149, -107, -4, -186, -212, -158, -49, -12, -150, -44, -96, -102, -230, -56, -233, -229, -248, -51, -29, -79, -206, -224, -229, -247, -254, -0, -28, -81, -196, -0, -78, -243, -35, -220, -57, -197, -207, -207, -3, -126, -148, -216, -223, -95, -96, -190, -130, -127, -0, -126, -145, -88, -102, -89, -224, -223, -126, -252, -39, -220, -195, -170, -85, -208, -189, -30, -123, -88, -44, -89, -57, -6, -72, -122, -57, -206, -0, -219, -98, -243, -235, -26, -153, -235, -203, -3, -255, -196, -220, -208, -202, -24, -96, -59, -124, -26, -240, -191, -167, -200, -120, -18, -85, -180, -189, -48, -54, -69, -61, -69, -197, -28, -142, -59, -189, -2, -107, -97, -158, -85, -219, -99, -14, -171, -1, -27, -253, -94, -43, -43, -95, -11, -116, -169, -61, -99, -152, -44, -89, -29, -6, -200, -188, -156, -147, -128, -73, -216, -240, -26, -157, -10, -156, -1, -182, -195, -124, -14, -190, -156, -185, -254, -121, -224, -112, -191, -87, -198, -0, -99, -128, -199, -156, -81, -182, -246, -31, -52, -105, -201, -235, -31, -218, -116, -108, -154, -27, -178, -154, -200, -209, -222, -130, -9, -128, -119, -2, -239, -243, -231, -219, -14, -88, -221, -127, -175, -25, -101, -229, -147, -65, -11, -218, -51, -134, -201, -146, -5, -204, -244, -47, -162, -243, -114, -54, -197, -28, -90, -22, -3, -166, -23, -148, -233, -48, -192, -106, -206, -40, -99, -188, -142, -187, -49, -107, -102, -41, -3, -120, -29, -103, -96, -186, -142, -179, -73, -116, -253, -118, -198, -254, -23, -240, -73, -224, -88, -108, -4, -90, -168, -186, -164, -4, -236, -7, -252, -17, -152, -31, -184, -26, -120, -27, -240, -122, -74, -217, -158, -131, -97, -182, -100, -117, -94, -78, -238, -218, -4, -224, -138, -2, -122, -112, -199, -20, -76, -224, -219, -22, -24, -143, -207, -201, -137, -12, -240, -14, -108, -249, -54, -25, -88, -191, -170, -143, -94, -230, -76, -224, -42, -103, -182, -121, -128, -127, -0, -149, -46, -230, -216, -202, -228, -126, -44, -86, -224, -28, -6, -166, -202, -153, -85, -101, -251, -2, -134, -209, -146, -149, -125, -57, -153, -107, -155, -2, -215, -82, -108, -121, -203, -50, -192, -161, -216, -114, -242, -2, -96, -123, -191, -86, -201, -0, -78, -119, -59, -112, -123, -21, -157, -211, -110, -9, -60, -75, -38, -152, -5, -243, -196, -126, -149, -204, -210, -176, -160, -236, -81, -192, -5, -126, -252, -47, -108, -138, -155, -228, -207, -49, -188, -90, -83, -134, -217, -146, -149, -125, -57, -126, -190, -13, -112, -17, -176, -112, -73, -153, -44, -3, -44, -14, -252, -219, -95, -236, -24, -191, -150, -196, -0, -169, -0, -222, -2, -60, -64, -68, -166, -193, -228, -144, -7, -129, -183, -20, -148, -93, -4, -147, -55, -198, -70, -238, -141, -140, -17, -96, -184, -16, -123, -57, -206, -48, -247, -101, -190, -146, -141, -34, -229, -102, -51, -128, -159, -255, -146, -140, -11, -92, -219, -12, -48, -226, -1, -108, -229, -28, -122, -47, -176, -113, -230, -250, -242, -152, -144, -212, -174, -202, -113, -20, -35, -11, -152, -20, -190, -13, -166, -139, -191, -46, -115, -253, -7, -192, -145, -195, -217, -183, -81, -244, -1, -216, -154, -244, -45, -192, -66, -248, -210, -9, -211, -63, -223, -75, -47, -84, -142, -163, -24, -89, -192, -140, -20, -29, -6, -120, -222, -175, -93, -78, -137, -113, -195, -105, -26, -27, -100, -156, -110, -39, -204, -0, -116, -149, -255, -93, -6, -76, -232, -254, -137, -134, -31, -12, -198, -12, -44, -170, -233, -68, -42, -236, -5, -5, -117, -189, -189, -224, -250, -82, -190, -138, -200, -135, -245, -111, -130, -197, -101, -44, -157, -218, -192, -13, -153, -41, -224, -111, -216, -154, -248, -159, -152, -150, -107, -136, -108, -144, -41, -215, -141, -65, -230, -100, -224, -123, -89, -9, -31, -88, -218, -175, -149, -70, -254, -212, -101, -28, -111, -107, -50, -240, -138, -255, -159, -0, -124, -26, -51, -204, -60, -5, -156, -75, -196, -28, -155, -41, -191, -14, -240, -83, -23, -56, -159, -198, -150, -157, -167, -149, -49, -184, -255, -240, -157, -24, -136, -177, -192, -7, -48, -101, -213, -223, -139, -218, -194, -116, -254, -223, -243, -118, -94, -5, -166, -248, -52, -252, -34, -176, -92, -65, -153, -139, -240, -24, -206, -204, -181, -115, -113, -187, -74, -18, -128, -205, -48, -201, -249, -126, -96, -139, -140, -76, -16, -149, -13, -34, -229, -107, -25, -100, -128, -93, -24, -80, -186, -128, -169, -70, -31, -7, -142, -245, -107, -223, -43, -250, -65, -155, -48, -14, -102, -194, -125, -15, -182, -228, -251, -152, -127, -145, -147, -176, -105, -110, -37, -255, -0, -162, -241, -142, -192, -110, -254, -110, -246, -194, -109, -19, -152, -99, -200, -119, -252, -171, -142, -46, -55, -253, -185, -182, -203, -93, -91, -8, -91, -242, -157, -16, -161, -95, -10, -19, -184, -127, -131, -41, -153, -22, -1, -54, -192, -84, -228, -143, -20, -49, -27, -3, -150, -200, -5, -253, -124, -126, -44, -186, -107, -151, -24, -125, -37, -128, -125, -112, -229, -2, -17, -217, -160, -160, -76, -45, -131, -12, -230, -50, -182, -148, -31, -131, -169, -53, -87, -195, -194, -211, -23, -244, -31, -244, -178, -72, -185, -44, -227, -172, -4, -252, -197, -31, -246, -119, -126, -173, -144, -113, -50, -117, -204, -139, -105, -24, -63, -150, -185, -182, -7, -240, -112, -132, -118, -172, -191, -252, -149, -10, -234, -186, -144, -140, -45, -33, -119, -111, -8, -3, -248, -245, -207, -17, -201, -250, -1, -252, -183, -51, -229, -152, -28, -237, -3, -152, -138, -250, -11, -5, -237, -4, -103, -170, -255, -231, -231, -123, -249, -199, -52, -79, -140, -190, -20, -152, -86, -237, -94, -92, -181, -73, -68, -54, -40, -40, -151, -55, -200, -148, -90, -171, -24, -156, -238, -5, -224, -67, -192, -113, -152, -110, -188, -163, -140, -185, -42, -82, -46, -203, -56, -191, -195, -244, -241, -99, -112, -61, -64, -9, -227, -172, -128, -133, -188, -61, -236, -127, -49, -188, -17, -41, -247, -117, -224, -56, -63, -94, -13, -83, -27, -79, -197, -134, -230, -21, -48, -245, -245, -189, -145, -114, -67, -144, -185, -247, -65, -224, -229, -72, -153, -201, -157, -182, -252, -124, -93, -76, -167, -177, -165, -191, -155, -59, -242, -101, -50, -180, -159, -7, -174, -241, -227, -203, -129, -83, -139, -104, -75, -1, -124, -138, -140, -93, -27, -147, -7, -182, -198, -101, -131, -146, -114, -121, -131, -76, -169, -181, -42, -194, -0, -87, -96, -115, -241, -58, -153, -235, -49, -6, -200, -150, -123, -14, -88, -61, -66, -19, -43, -247, -103, -204, -211, -104, -17, -103, -24, -176, -16, -184, -172, -237, -97, -136, -233, -25, -251, -34, -215, -246, -227, -107, -128, -195, -252, -248, -85, -44, -98, -122, -12, -240, -74, -164, -92, -39, -16, -118, -167, -124, -221, -192, -238, -192, -139, -145, -50, -175, -0, -123, -249, -241, -188, -152, -12, -118, -150, -159, -239, -89, -244, -46, -253, -254, -114, -152, -208, -183, -14, -230, -151, -184, -70, -17, -109, -33, -252, -229, -60, -202, -96, -93, -245, -32, -217, -160, -162, -124, -178, -181, -202, -127, -240, -37, -253, -24, -167, -61, -16, -56, -207, -175, -45, -69, -252, -75, -206, -51, -192, -106, -17, -154, -24, -3, -188, -4, -236, -234, -199, -227, -188, -205, -83, -202, -158, -199, -105, -95, -102, -96, -110, -125, -9, -120, -59, -54, -26, -130, -141, -150, -139, -3, -79, -23, -148, -133, -248, -20, -240, -37, -224, -214, -200, -245, -87, -24, -200, -199, -112, -2, -54, -34, -116, -204, -227, -123, -17, -25, -53, -114, -229, -127, -135, -77, -191, -133, -31, -106, -207, -64, -77, -107, -21, -102, -219, -254, -185, -31, -119, -24, -32, -96, -158, -50, -155, -96, -115, -249, -16, -199, -208, -28, -227, -252, -22, -243, -34, -26, -195, -192, -180, -80, -196, -56, -147, -176, -233, -226, -173, -216, -84, -112, -163, -51, -208, -222, -206, -16, -239, -5, -118, -143, -148, -123, -9, -88, -212, -143, -31, -194, -134, -227, -29, -176, -17, -96, -25, -44, -140, -254, -226, -130, -103, -28, -194, -0, -94, -230, -73, -224, -63, -35, -244, -147, -49, -47, -165, -245, -48, -33, -117, -211, -204, -189, -227, -129, -59, -99, -237, -228, -222, -41, -184, -235, -88, -95, -65, -3, -107, -21, -240, -85, -44, -16, -36, -43, -205, -47, -133, -45, -45, -79, -46, -40, -147, -101, -156, -149, -176, -37, -224, -52, -60, -137, -85, -9, -227, -108, -143, -205, -253, -211, -129, -111, -97, -67, -236, -209, -126, -237, -117, -108, -78, -143, -249, -7, -78, -196, -163, -156, -177, -161, -123, -138, -63, -215, -4, -224, -127, -48, -225, -108, -229, -130, -190, -130, -77, -1, -11, -96, -242, -194, -1, -152, -176, -118, -13, -145, -21, -18, -230, -91, -112, -15, -54, -141, -158, -150, -185, -62, -143, -51, -71, -244, -157, -100, -232, -118, -114, -134, -45, -52, -130, -245, -4, -116, -97, -173, -242, -31, -244, -10, -108, -202, -184, -218, -143, -75, -151, -47, -77, -24, -167, -41, -128, -255, -44, -98, -224, -132, -178, -89, -60, -143, -45, -169, -143, -2, -230, -43, -160, -95, -6, -147, -222, -95, -198, -150, -172, -11, -99, -115, -250, -149, -206, -116, -67, -150, -129, -206, -28, -11, -97, -194, -232, -93, -192, -25, -77, -250, -58, -199, -161, -9, -227, -52, -108, -103, -62, -255, -98, -127, -69, -198, -117, -219, -127, -172, -86, -29, -51, -177, -21, -204, -115, -152, -101, -242, -49, -76, -168, -155, -234, -35, -86, -52, -84, -206, -71, -150, -87, -188, -220, -15, -128, -249, -219, -236, -147, -168, -25, -218, -53, -55, -194, -153, -224, -211, -152, -84, -62, -13, -243, -29, -120, -0, -23, -88, -91, -110, -43, -26, -31, -208, -55, -144, -203, -172, -73, -196, -109, -122, -20, -115, -15, -98, -95, -247, -254, -146, -54, -240, -227, -219, -36, -213, -138, -238, -29, -197, -28, -142, -58, -67, -190, -207, -89, -175, -145, -243, -184, -193, -194, -157, -94, -45, -154, -183, -114, -180, -141, -194, -200, -71, -209, -3, -48, -216, -18, -213, -17, -64, -190, -77, -137, -73, -17, -211, -174, -125, -35, -119, -237, -219, -20, -172, -141, -35, -229, -107, -133, -145, -211, -48, -139, -246, -40, -163, -85, -128, -1, -75, -212, -165, -12, -88, -162, -214, -243, -31, -248, -62, -92, -25, -18, -41, -183, -11, -166, -194, -237, -228, -2, -126, -147, -11, -73, -61, -177, -233, -99, -214, -183, -14, -3, -36, -121, -227, -122, -185, -36, -70, -195, -20, -66, -19, -49, -69, -204, -237, -84, -104, -63, -115, -101, -107, -51, -39, -53, -82, -187, -231, -202, -181, -203, -208, -152, -37, -234, -94, -114, -22, -36, -76, -203, -54, -153, -98, -139, -215, -60, -62, -98, -236, -226, -231, -187, -59, -35, -69, -95, -52, -109, -57, -48, -244, -8, -152, -54, -243, -84, -96, -9, -76, -115, -152, -148, -19, -217, -203, -214, -98, -78, -224, -187, -152, -86, -114, -117, -76, -135, -145, -156, -218, -189, -238, -200, -153, -82, -225, -32, -75, -84, -238, -222, -241, -101, -28, -141, -41, -102, -126, -230, -199, -191, -161, -192, -108, -153, -161, -175, -229, -192, -208, -132, -105, -176, -168, -160, -105, -228, -220, -176, -49, -83, -247, -179, -37, -35, -218, -11, -25, -102, -222, -139, -2, -61, -255, -92, -7, -50, -150, -168, -200, -189, -82, -67, -4, -102, -38, -157, -142, -185, -135, -205, -160, -192, -118, -158, -161, -175, -237, -192, -80, -151, -105, -252, -254, -137, -152, -118, -44, -100, -174, -221, -70, -196, -25, -35, -115, -255, -39, -152, -61, -98, -2, -166, -149, -59, -172, -236, -89, -188, -76, -19, -217, -169, -47, -101, -146, -209, -13, -3, -56, -205, -95, -49, -15, -153, -63, -150, -209, -57, -109, -109, -7, -134, -134, -76, -179, -136, -127, -237, -239, -243, -243, -157, -177, -136, -227, -178, -128, -145, -245, -48, -211, -246, -27, -192, -222, -9, -207, -82, -91, -118, -234, -87, -153, -90, -192, -116, -205, -199, -23, -220, -75, -177, -68, -29, -236, -47, -46, -150, -58, -37, -70, -95, -203, -129, -161, -9, -211, -100, -218, -185, -193, -143, -255, -74, -193, -52, -231, -247, -223, -235, -12, -115, -54, -166, -233, -251, -25, -3, -206, -41, -135, -19, -113, -200, -160, -129, -236, -212, -175, -50, -181, -128, -37, -130, -190, -47, -210, -64, -146, -37, -170, -65, -123, -181, -29, -24, -234, -50, -141, -211, -45, -236, -95, -253, -103, -49, -169, -57, -26, -126, -229, -180, -119, -0, -95, -242, -227, -149, -24, -112, -200, -92, -206, -153, -237, -195, -145, -50, -181, -101, -167, -126, -149, -169, -133, -204, -16, -115, -21, -230, -138, -148, -181, -68, -117, -63, -196, -196, -219, -172, -229, -192, -208, -132, -105, -188, -220, -113, -24, -134, -216, -224, -115, -116, -47, -2, -187, -101, -206, -87, -198, -28, -100, -94, -0, -190, -95, -80, -166, -246, -212, -217, -175, -50, -41, -200, -238, -26, -246, -140, -164, -77, -36, -77, -145, -244, -39, -73, -255, -150, -101, -8, -123, -80, -182, -251, -85, -161, -67, -104, -23, -248, -158, -164, -237, -37, -37, -165, -109, -245, -157, -205, -174, -148, -116, -150, -108, -199, -178, -201, -137, -237, -116, -148, -82, -67, -210, -215, -231, -112, -163, -164, -227, -176, -101, -220, -56, -73, -155, -202, -118, -239, -154, -79, -210, -180, -196, -182, -230, -40, -204, -155, -61, -241, -45, -224, -62, -218, -199, -246, -103, -74, -154, -33, -233, -162, -26, -101, -190, -39, -233, -119, -170, -215, -207, -212, -32, -207, -131, -36, -125, -93, -198, -248, -11, -73, -154, -36, -233, -11, -146, -110, -146, -116, -45, -240, -74, -8, -33, -191, -130, -152, -34, -41, -234, -16, -226, -215, -239, -143, -92, -239, -87, -153, -222, -131, -226, -165, -73, -52, -89, -34, -93, -58, -48, -208, -192, -235, -133, -129, -93, -63, -86, -173, -211, -86, -98, -221, -181, -101, -167, -126, -149, -233, -57, -40, -95, -154, -60, -64, -102, -179, -168, -76, -153, -218, -14, -12, -45, -48, -77, -47, -25, -160, -182, -236, -212, -175, -50, -61, -7, -189, -94, -154, -12, -212, -215, -91, -175, -151, -46, -145, -25, -5, -31, -167, -190, -82, -167, -167, -101, -154, -62, -80, -82, -198, -110, -122, -189, -52, -25, -197, -240, -128, -196, -140, -221, -244, -104, -105, -50, -138, -254, -97, -222, -216, -197, -16, -194, -44, -73, -71, -181, -80, -127, -123, -73, -12, -71, -209, -19, -12, -50, -37, -82, -223, -216, -48, -69, -229, -75, -147, -41, -249, -139, -52, -180, -210, -213, -133, -11, -125, -177, -168, -156, -194, -220, -63, -152, -47, -195, -49, -152, -63, -192, -75, -152, -98, -232, -110, -160, -141, -143, -97, -100, -163, -66, -162, -47, -146, -76, -171, -150, -38, -255, -85, -208, -86, -19, -43, -93, -45, -230, -172, -203, -0, -254, -227, -95, -135, -5, -101, -236, -224, -140, -250, -86, -224, -253, -177, -122, -114, -253, -122, -202, -143, -151, -6, -30, -47, -233, -79, -7, -149, -201, -34, -98, -253, -199, -98, -45, -175, -35, -30, -195, -56, -147, -248, -30, -6, -105, -201, -174, -104, -102, -160, -40, -91, -154, -220, -73, -65, -6, -76, -106, -90, -233, -26, -50, -103, -93, -6, -56, -14, -75, -252, -80, -107, -4, -2, -118, -197, -147, -81, -98, -219, -202, -71, -211, -220, -123, -127, -146, -147, -69, -228, -251, -15, -124, -25, -27, -153, -138, -114, -4, -212, -122, -222, -14, -178, -83, -192, -174, -146, -190, -239, -243, -255, -108, -132, -16, -222, -144, -169, -106, -135, -108, -22, -25, -81, -31, -79, -147, -116, -151, -164, -151, -36, -109, -17, -66, -24, -18, -1, -235, -229, -158, -151, -244, -223, -146, -58, -43, -136, -207, -74, -58, -35, -132, -240, -66, -65, -63, -63, -43, -233, -85, -73, -31, -10, -33, -220, -30, -66, -120, -62, -132, -112, -167, -108, -131, -134, -55, -36, -125, -166, -160, -92, -29, -236, -39, -233, -188, -6, -42, -239, -13, -36, -77, -140, -28, -199, -240, -122, -8, -225, -149, -16, -194, -148, -16, -194, -111, -37, -109, -37, -105, -41, -73, -71, -151, -53, -0, -28, -42, -105, -15, -73, -59, -250, -187, -107, -31, -180, -36, -209, -99, -86, -186, -137, -249, -145, -36, -66, -87, -199, -74, -215, -196, -122, -86, -138, -8, -253, -12, -96, -191, -148, -103, -116, -250, -231, -252, -111, -38, -102, -44, -26, -116, -92, -208, -159, -58, -201, -34, -240, -175, -247, -3, -62, -250, -69, -115, -4, -37, -212, -159, -60, -2, -180, -133, -79, -75, -90, -69, -210, -37, -148, -36, -67, -242, -175, -253, -12, -73, -95, -145, -116, -122, -8, -225, -165, -146, -58, -223, -46, -233, -161, -130, -123, -15, -122, -123, -49, -236, -44, -105, -129, -220, -223, -206, -69, -93, -146, -217, -38, -102, -163, -140, -97, -66, -8, -139, -133, -16, -22, -147, -244, -164, -164, -181, -252, -248, -127, -37, -173, -238, -199, -169, -184, -167, -164, -255, -235, -75, -250, -153, -108, -116, -28, -146, -189, -164, -13, -100, -25, -96, -138, -90, -48, -54, -132, -16, -238, -149, -89, -248, -222, -144, -84, -149, -201, -58, -213, -74, -215, -20, -157, -33, -119, -246, -95, -73, -159, -30, -148, -148, -207, -53, -80, -198, -48, -194, -118, -20, -39, -132, -48, -21, -75, -224, -52, -203, -13, -106, -117, -48, -70, -210, -172, -130, -123, -235, -203, -166, -166, -147, -128, -229, -107, -214, -155, -220, -120, -7, -151, -73, -58, -36, -63, -116, -251, -249, -193, -146, -46, -77, -173, -52, -132, -240, -247, -16, -194, -110, -33, -132, -170, -60, -182, -169, -86, -186, -41, -234, -189, -37, -236, -18, -73, -135, -146, -145, -176, -203, -24, -198, -135, -249, -127, -73, -90, -214, -143, -39, -75, -90, -174, -51, -53, -212, -104, -247, -157, -94, -54, -134, -11, -93, -86, -184, -72, -210, -79, -200, -172, -154, -34, -152, -37, -51, -91, -231, -241, -38, -229, -70, -182, -44, -178, -12, -112, -170, -19, -95, -73, -70, -162, -151, -116, -185, -211, -69, -51, -104, -245, -9, -173, -49, -103, -9, -206, -144, -9, -175, -127, -194, -178, -164, -45, -138, -173, -74, -162, -95, -158, -15, -243, -231, -72, -58, -209, -143, -207, -148, -116, -82, -102, -106, -168, -4, -102, -49, -253, -152, -108, -152, -47, -195, -103, -36, -173, -36, -233, -216, -18, -154, -123, -37, -189, -59, -114, -125, -35, -191, -151, -212, -161, -254, -24, -27, -6, -218, -75, -178, -210, -209, -204, -122, -86, -91, -40, -194, -188, -154, -191, -137, -101, -5, -155, -233, -130, -225, -189, -20, -236, -235, -227, -237, -79, -240, -227, -203, -40, -217, -234, -206, -251, -83, -39, -89, -196, -160, -254, -99, -233, -239, -95, -6, -54, -200, -211, -250, -253, -61, -48, -167, -217, -3, -253, -119, -124, -27, -112, -144, -11, -165, -251, -23, -245, -107, -142, -65, -191, -153, -51, -177, -79, -79, -116, -218, -247, -227, -183, -149, -208, -102, -145, -146, -44, -98, -8, -3, -99, -241, -23, -147, -41, -78, -43, -255, -62, -44, -132, -253, -101, -103, -222, -155, -129, -15, -117, -243, -140, -163, -24, -197, -40, -70, -49, -138, -185, -31, -62, -231, -220, -157, -159, -147, -42, -132, -166, -43, -124, -94, -126, -210, -231, -230, -239, -2, -151, -39, -180, -53, -98, -66, -181, -105, -24, -110, -62, -183, -32, -175, -9, -92, -84, -210, -49, -53, -202, -63, -41, -105, -89, -73, -107, -75, -90, -75, -210, -91, -252, -90, -21, -46, -144, -45, -125, -134, -4, -90, -228, -65, -162, -119, -82, -174, -76, -157, -144, -235, -236, -26, -185, -72, -33, -83, -214, -86, -85, -184, -249, -10, -152, -89, -121, -205, -18, -154, -206, -190, -73, -235, -213, -108, -187, -52, -112, -21, -203, -99, -124, -117, -238, -218, -159, -201, -236, -175, -148, -189, -1, -240, -31, -46, -161, -142, -203, -92, -47, -27, -1, -30, -3, -86, -201, -156, -47, -82, -213, -169, -186, -32, -209, -59, -41, -67, -223, -56, -228, -58, -177, -254, -90, -57, -148, -128, -243, -49, -251, -72, -105, -194, -12, -108, -207, -133, -115, -203, -104, -156, -110, -33, -6, -194, -213, -254, -234, -255, -3, -17, -203, -171, -255, -30, -15, -2, -255, -225, -231, -135, -96, -206, -186, -67, -173, -174, -206, -0, -91, -250, -131, -93, -158, -185, -94, -198, -0, -79, -144, -73, -146, -136, -173, -207, -163, -241, -244, -116, -107, -175, -110, -25, -77, -251, -131, -237, -228, -185, -178, -191, -167, -231, -128, -35, -74, -104, -215, -240, -23, -62, -63, -102, -30, -127, -103, -9, -237, -70, -216, -154, -189, -106, -131, -141, -19, -48, -179, -245, -79, -49, -31, -138, -159, -98, -9, -58, -190, -88, -64, -191, -137, -223, -127, -167, -255, -31, -178, -231, -67, -135, -16, -108, -139, -182, -133, -176, -112, -168, -78, -170, -215, -50, -6, -248, -1, -150, -174, -117, -49, -255, -241, -127, -82, -244, -197, -121, -253, -117, -236, -243, -181, -126, -160, -6, -244, -181, -250, -147, -185, -95, -39, -135, -210, -175, -128, -143, -250, -241, -190, -68, -82, -216, -230, -232, -255, -9, -28, -94, -65, -179, -8, -182, -165, -252, -49, -216, -212, -114, -180, -159, -23, -250, -49, -96, -142, -39, -51, -136, -56, -232, -228, -31, -38, -184, -13, -255, -40, -73, -103, -71, -135, -138, -193, -120, -171, -164, -103, -100, -170, -198, -251, -100, -115, -104, -105, -110, -128, -26, -152, -39, -210, -191, -54, -233, -107, -193, -25, -230, -110, -111, -39, -123, -189, -136, -193, -54, -148, -244, -46, -13, -132, -189, -93, -36, -105, -53, -96, -147, -146, -102, -206, -145, -52, -36, -93, -109, -22, -238, -15, -48, -77, -246, -27, -29, -44, -179, -190, -78, -171, -240, -99, -24, -39, -233, -89, -255, -63, -8, -209, -23, -22, -66, -248, -181, -44, -69, -220, -41, -42, -49, -36, -132, -16, -118, -9, -33, -28, -18, -66, -88, -38, -132, -240, -182, -16, -194, -193, -33, -132, -29, -203, -30, -96, -14, -71, -29, -33, -249, -84, -73, -167, -116, -12, -98, -238, -88, -243, -21, -73, -101, -177, -18, -191, -144, -244, -54, -42, -118, -17, -149, -180, -177, -164, -137, -33, -132, -95, -74, -186, -69, -210, -123, -139, -8, -49, -175, -171, -237, -36, -189, -71, -210, -14, -120, -198, -244, -24, -225, -160, -33, -17, -203, -160, -253, -60, -182, -189, -74, -215, -115, -116, -131, -41, -96, -36, -210, -215, -18, -146, -155, -0, -115, -205, -251, -101, -75, -117, -45, -137, -201, -105, -157, -233, -124, -79, -63, -95, -162, -67, -83, -56, -100, -134, -16, -30, -146, -244, -85, -73, -95, -106, -163, -51, -115, -9, -238, -151, -116, -190, -164, -111, -245, -176, -141, -115, -37, -189, -159, -130, -13, -162, -106, -226, -219, -146, -238, -8, -33, -252, -74, -146, -124, -196, -184, -211, -175, -75, -170, -158, -51, -191, -38, -11, -19, -111, -3, -141, -236, -213, -61, -68, -147, -254, -204, -39, -233, -68, -73, -235, -119, -190, -170, -182, -17, -66, -184, -95, -210, -181, -50, -51, -113, -183, -117, -237, -29, -66, -152, -144, -187, -182, -67, -8, -97, -246, -86, -128, -217, -252, -0, -33, -132, -112, -117, -142, -248, -245, -16, -194, -58, -33, -132, -50, -71, -132, -84, -212, -181, -87, -215, -253, -129, -234, -210, -55, -177, -159, -215, -21, -146, -155, -226, -28, -73, -31, -197, -115, -47, -206, -21, -160, -166, -189, -26, -83, -209, -126, -62, -114, -253, -11, -46, -141, -119, -75, -95, -183, -63, -121, -25, -233, -114, -44, -151, -208, -248, -54, -101, -128, -185, -26, -212, -176, -87, -55, -248, -129, -106, -59, -68, -212, -236, -79, -158, -1, -90, -21, -146, -71, -17, -65, -157, -31, -168, -9, -125, -205, -190, -12, -89, -53, -96, -46, -237, -79, -14, -39, -3, -120, -191, -54, -175, -166, -76, -171, -108, -173, -252, -57, -17, -71, -68, -74, -208, -74, -71, -70, -32, -10, -24, -96, -62, -204, -130, -58, -231, -51, -0, -176, -10, -166, -99, -222, -193, -207, -183, -33, -183, -143, -95, -134, -182, -179, -207, -222, -26, -222, -129, -181, -41, -216, -119, -111, -20, -67, -129, -109, -170, -149, -36, -88, -99, -6, -173, -168, -219, -152, -223, -111, -117, -4, -216, -210, -153, -224, -243, -254, -127, -124, -5, -253, -88, -239, -64, -235, -169, -87, -230, -102, -164, -254, -248, -78, -75, -217, -135, -149, -101, -0, -204, -225, -244, -38, -114, -41, -117, -235, -118, -238, -24, -175, -52, -154, -53, -52, -71, -155, -196, -0, -88, -46, -225, -171, -49, -227, -197, -19, -152, -141, -255, -255, -252, -94, -68, -41, -72, -101, -0, -44, -136, -247, -55, -192, -239, -105, -178, -103, -176, -87, -182, -149, -127, -249, -157, -72, -217, -237, -43, -232, -83, -25, -224, -70, -44, -217, -243, -50, -152, -229, -234, -160, -146, -135, -129, -129, -125, -252, -206, -1, -22, -79, -232, -119, -233, -48, -233, -52, -75, -97, -142, -34, -83, -177, -56, -200, -135, -40, -216, -45, -188, -23, -192, -220, -192, -99, -136, -109, -33, -123, -97, -1, -237, -175, -34, -180, -96, -91, -204, -125, -195, -191, -254, -232, -182, -244, -41, -29, -28, -135, -205, -249, -219, -248, -249, -22, -126, -190, -86, -73, -153, -84, -6, -120, -153, -34, -35, -196, -96, -58, -48, -223, -249, -133, -49, -251, -248, -157, -120, -26, -250, -132, -114, -101, -95, -201, -34, -152, -59, -245, -213, -152, -235, -215, -226, -254, -124, -177, -212, -175, -11, -3, -23, -224, -210, -125, -22, -17, -218, -107, -129, -255, -206, -93, -59, -25, -207, -77, -156, -187, -62, -134, -220, -62, -197, -254, -55, -36, -225, -21, -38, -92, -118, -238, -131, -5, -169, -188, -153, -8, -147, -251, -253, -142, -7, -212, -16, -121, -173, -22, -200, -24, -57, -252, -188, -40, -104, -177, -115, -63, -149, -1, -238, -33, -205, -219, -5, -6, -175, -181, -247, -7, -42, -85, -209, -9, -12, -112, -10, -230, -189, -84, -24, -172, -154, -161, -61, -39, -247, -187, -79, -194, -116, -10, -147, -34, -180, -91, -96, -211, -90, -103, -43, -219, -249, -253, -163, -121, -127, -69, -27, -109, -203, -0, -191, -194, -188, -160, -174, -168, -83, -119, -215, -168, -193, -0, -59, -99, -27, -62, -92, -71, -137, -61, -60, -194, -0, -31, -6, -162, -193, -150, -212, -27, -38, -239, -166, -98, -19, -139, -12, -237, -99, -185, -250, -238, -242, -235, -81, -135, -81, -44, -215, -241, -201, -126, -124, -176, -51, -123, -233, -143, -64, -15, -86, -1, -216, -200, -245, -16, -240, -233, -148, -122, -91, -65, -42, -3, -56, -237, -234, -152, -144, -50, -139, -200, -208, -235, -52, -48, -48, -5, -108, -140, -165, -145, -249, -66, -1, -109, -157, -97, -242, -21, -96, -159, -88, -61, -17, -218, -153, -53, -25, -96, -19, -204, -71, -112, -17, -108, -47, -225, -131, -83, -218, -105, -11, -29, -6, -240, -227, -205, -49, -5, -216, -187, -250, -213, -120, -237, -101, -32, -182, -15, -79, -52, -214, -63, -242, -53, -31, -153, -88, -39, -148, -15, -147, -175, -144, -176, -249, -131, -211, -78, -175, -195, -0, -126, -239, -114, -76, -250, -158, -74, -36, -206, -175, -151, -200, -50, -128, -159, -127, -5, -155, -182, -10, -19, -110, -12, -43, -176, -164, -75, -209, -52, -39, -254, -48, -219, -249, -241, -223, -129, -66, -239, -155, -220, -8, -112, -169, -143, -26, -69, -35, -192, -36, -224, -115, -137, -253, -251, -83, -42, -3, -48, -48, -250, -228, -177, -66, -74, -91, -35, -10, -184, -85, -43, -134, -46, -235, -93, -10, -51, -208, -44, -141, -249, -200, -95, -6, -252, -174, -128, -54, -203, -0, -187, -97, -75, -209, -162, -68, -83, -117, -100, -128, -51, -177, -249, -177, -242, -235, -196, -146, -80, -61, -156, -194, -0, -126, -61, -59, -13, -237, -196, -156, -170, -13, -37, -190, -76, -89, -180, -5, -6, -88, -28, -219, -170, -165, -147, -71, -231, -18, -10, -162, -104, -115, -12, -16, -48, -225, -45, -233, -203, -173, -232, -195, -210, -152, -167, -243, -223, -176, -53, -243, -34, -216, -178, -183, -72, -22, -121, -51, -176, -1, -176, -97, -25, -3, -208, -197, -8, -224, -12, -254, -40, -17, -165, -77, -65, -157, -253, -183, -55, -116, -30, -176, -143, -237, -205, -102, -0, -63, -255, -48, -45, -37, -143, -4, -150, -7, -190, -143, -133, -176, -205, -194, -76, -185, -215, -38, -148, -235, -201, -8, -128, -229, -58, -40, -202, -163, -56, -187, -174, -236, -95, -74, -189, -173, -2, -155, -103, -135, -36, -71, -192, -180, -121, -127, -241, -151, -217, -193, -227, -100, -156, -13, -71, -50, -128, -139, -129, -75, -18, -105, -43, -133, -64, -191, -63, -136, -121, -43, -104, -87, -199, -150, -197, -149, -35, -97, -66, -155, -187, -96, -59, -156, -206, -192, -130, -86, -214, -79, -233, -67, -87, -192, -134, -244, -147, -252, -248, -68, -224, -250, -158, -55, -218, -34, -176, -41, -33, -41, -223, -94, -42, -3, -212, -108, -255, -44, -160, -112, -151, -148, -154, -12, -48, -25, -155, -170, -150, -193, -132, -225, -222, -255, -22, -206, -109, -219, -250, -241, -182, -68, -244, -217, -125, -232, -67, -22, -47, -99, -243, -233, -197, -84, -107, -47, -255, -138, -173, -48, -62, -153, -216, -78, -171, -12, -128, -89, -236, -166, -1, -91, -149, -208, -68, -81, -64, -247, -137, -204, -249, -142, -64, -81, -178, -205, -40, -154, -90, -228, -238, -151, -244, -65, -31, -242, -63, -168, -226, -44, -87, -131, -128, -205, -233, -80, -18, -35, -87, -19, -157, -60, -128, -111, -147, -101, -50, -93, -82, -210, -144, -85, -64, -22, -33, -132, -45, -66, -8, -27, -133, -16, -206, -105, -169, -15, -117, -177, -159, -164, -199, -66, -8, -215, -85, -208, -197, -114, -28, -198, -144, -117, -96, -125, -81, -182, -215, -81, -111, -225, -67, -206, -52, -204, -106, -55, -145, -4, -205, -19, -176, -32, -166, -217, -123, -190, -136, -1, -48, -189, -122, -244, -47, -66, -59, -100, -152, -196, -36, -235, -178, -132, -147, -195, -14, -204, -101, -173, -116, -244, -169, -57, -5, -100, -149, -64, -155, -199, -70, -138, -50, -148, -186, -29, -3, -99, -60, -164, -105, -16, -66, -8, -255, -196, -214, -212, -107, -132, -16, -30, -76, -108, -235, -51, -178, -221, -184, -10, -99, -223, -66, -8, -141, -184, -23, -83, -254, -140, -149, -237, -36, -86, -103, -7, -178, -174, -128, -57, -204, -68, -87, -18, -49, -87, -122, -44, -50, -119, -13, -73, -63, -233, -109, -207, -26, -130, -26, -177, -239, -88, -122, -179, -14, -158, -164, -68, -213, -138, -45, -193, -158, -192, -148, -66, -111, -180, -49, -5, -20, -76, -147, -23, -208, -212, -25, -162, -89, -31, -138, -76, -188, -209, -37, -27, -233, -57, -0, -250, -54, -2, -228, -101, -128, -253, -101, -25, -175, -37, -11, -14, -141, -166, -112, -1, -206, -145, -101, -239, -92, -213, -255, -206, -85, -121, -34, -201, -175, -74, -58, -199, -179, -139, -183, -105, -174, -236, -204, -147, -11, -75, -26, -47, -11, -234, -248, -122, -164, -191, -27, -98, -186, -250, -233, -88, -130, -234, -139, -40, -73, -233, -150, -138, -16, -194, -27, -249, -84, -180, -153, -148, -180, -249, -62, -44, -41, -105, -47, -101, -194, -178, -70, -28, -72, -116, -211, -242, -121, -121, -163, -204, -249, -38, -20, -164, -71, -197, -52, -111, -143, -227, -198, -9, -231, -218, -182, -70, -128, -188, -12, -176, -63, -240, -108, -132, -246, -66, -204, -81, -99, -101, -108, -13, -126, -45, -5, -121, -253, -157, -62, -201, -123, -136, -30, -169, -207, -135, -5, -222, -239, -36, -165, -2, -102, -207, -62, -210, -143, -23, -244, -23, -28, -141, -104, -5, -110, -192, -44, -84, -171, -250, -31, -152, -255, -126, -87, -201, -143, -11, -24, -224, -96, -224, -177, -132, -178, -239, -163, -216, -32, -85, -199, -123, -168, -214, -20, -48, -162, -225, -47, -52, -73, -169, -224, -95, -252, -173, -152, -243, -196, -67, -88, -166, -176, -168, -22, -176, -232, -11, -1, -254, -210, -66, -127, -59, -234, -210, -69, -49, -143, -230, -251, -129, -51, -19, -202, -126, -130, -72, -184, -152, -223, -75, -246, -30, -154, -171, -224, -47, -180, -43, -165, -66, -141, -118, -218, -22, -2, -103, -98, -185, -120, -78, -166, -98, -83, -73, -44, -5, -206, -125, -192, -199, -11, -238, -39, -123, -15, -205, -85, -240, -23, -185, -109, -230, -188, -182, -68, -89, -163, -157, -182, -20, -65, -117, -219, -158, -199, -71, -182, -223, -80, -224, -146, -69, -13, -239, -161, -134, -125, -56, -44, -50, -26, -198, -18, -85, -64, -66, -192, -7, -240, -59, -76, -86, -153, -138, -9, -184, -93, -233, -1, -94, -173, -83, -184, -9, -90, -10, -53, -175, -13, -76, -192, -253, -129, -164, -197, -101, -123, -239, -148, -189, -168, -94, -10, -113, -75, -73, -186, -66, -82, -214, -219, -169, -82, -110, -41, -66, -8, -97, -182, -3, -42, -240, -99, -21, -107, -12, -163, -152, -123, -226, -207, -75, -224, -95, -251, -119, -100, -75, -214, -9, -33, -132, -178, -253, -143, -166, -168, -120, -11, -151, -170, -118, -86, -150, -229, -1, -218, -82, -166, -150, -30, -31, -66, -184, -41, -71, -182, -148, -164, -7, -61, -17, -68, -107, -0, -54, -147, -244, -33, -89, -194, -206, -100, -212, -182, -5, -96, -82, -242, -143, -128, -127, -99, -10, -160, -202, -8, -162, -17, -128, -111, -200, -244, -4, -71, -200, -146, -48, -117, -86, -36, -177, -156, -124, -127, -144, -37, -103, -168, -229, -219, -135, -101, -50, -189, -78, -54, -122, -76, -144, -237, -115, -116, -103, -132, -116, -41, -217, -222, -66, -41, -216, -4, -19, -204, -103, -96, -249, -0, -163, -242, -141, -143, -110, -223, -146, -244, -213, -16, -194, -163, -117, -250, -157, -173, -100, -208, -156, -83, -36, -3, -0, -223, -193, -44, -106, -171, -57, -205, -35, -192, -1, -141, -26, -237, -65, -255, -74, -202, -198, -240, -145, -8, -109, -45, -239, -161, -76, -185, -255, -194, -54, -131, -172, -218, -45, -237, -50, -204, -59, -234, -53, -76, -63, -242, -109, -34, -153, -70, -188, -127, -183, -97, -190, -23, -107, -98, -130, -235, -23, -10, -234, -60, -212, -239, -247, -126, -87, -117, -239, -244, -142, -153, -243, -143, -18, -89, -46, -22, -9, -55, -5, -117, -158, -128, -229, -3, -126, -26, -56, -151, -226, -141, -20, -187, -82, -123, -166, -130, -6, -222, -67, -88, -46, -130, -74, -247, -53, -44, -115, -215, -170, -216, -82, -123, -107, -204, -97, -245, -194, -8, -29, -120, -138, -87, -63, -255, -52, -241, -76, -39, -75, -98, -163, -241, -46, -169, -207, -215, -21, -48, -117, -234, -123, -51, -231, -59, -0, -67, -146, -20, -166, -50, -0, -176, -31, -166, -88, -90, -23, -88, -9, -83, -28, -197, -180, -110, -125, -99, -128, -38, -192, -252, -29, -191, -136, -133, -179, -189, -128, -69, -233, -84, -42, -187, -176, -61, -25, -103, -68, -174, -67, -38, -95, -32, -166, -188, -26, -34, -164, -99, -35, -114, -105, -6, -210, -50, -52, -241, -7, -184, -94, -210, -17, -62, -52, -190, -93, -182, -251, -103, -179, -128, -68, -195, -17, -146, -190, -22, -66, -184, -43, -132, -240, -136, -76, -151, -191, -103, -23, -245, -13, -23, -22, -146, -180, -181, -164, -221, -36, -173, -40, -233, -101, -153, -141, -164, -10, -243, -73, -122, -170, -224, -222, -152, -220, -113, -140, -225, -63, -42, -105, -51, -6, -150, -130, -83, -233, -165, -91, -186, -127, -165, -87, -98, -246, -128, -59, -157, -235, -159, -137, -208, -165, -142, -0, -207, -50, -20, -67, -76, -208, -145, -17, -96, -251, -17, -54, -2, -188, -64, -38, -0, -22, -83, -31, -199, -70, -198, -227, -125, -180, -91, -26, -139, -198, -190, -15, -56, -37, -66, -7, -158, -103, -216, -207, -143, -161, -7, -251, -25, -204, -230, -48, -76, -175, -125, -134, -255, -32, -79, -99, -33, -221, -135, -228, -11, -132, -16, -30, -9, -33, -236, -24, -66, -88, -40, -132, -176, -158, -164, -87, -148, -186, -45, -89, -113, -31, -246, -209, -96, -207, -151, -216, -136, -242, -146, -6, -123, -187, -172, -17, -171, -44, -195, -68, -179, -48, -19, -244, -55, -72, -8, -49, -111, -1, -119, -201, -190, -252, -14, -22, -146, -121, -232, -228, -241, -30, -217, -40, -58, -85, -210, -121, -146, -126, -36, -41, -154, -233, -91, -210, -145, -152, -0, -184, -150, -164, -195, -212, -75, -63, -2, -224, -63, -157, -27, -215, -198, -50, -91, -19, -99, -128, -72, -185, -137, -192, -137, -145, -235, -169, -35, -192, -45, -120, -112, -101, -5, -221, -13, -152, -6, -111, -25, -76, -58, -159, -28, -27, -1, -188, -221, -78, -124, -225, -38, -152, -106, -247, -231, -17, -186, -113, -88, -166, -243, -206, -30, -192, -151, -18, -217, -159, -55, -50, -58, -81, -208, -238, -129, -152, -13, -97, -75, -108, -133, -116, -3, -240, -157, -170, -231, -42, -121, -94, -128, -207, -96, -246, -141, -151, -177, -125, -7, -122, -23, -118, -134, -5, -54, -30, -229, -199, -215, -96, -214, -176, -91, -34, -116, -243, -99, -238, -226, -75, -98, -142, -35, -83, -137, -108, -221, -86, -131, -1, -246, -194, -156, -80, -62, -4, -172, -136, -229, -5, -216, -45, -66, -247, -78, -103, -182, -87, -48, -139, -229, -174, -37, -12, -144, -141, -45, -56, -0, -152, -22, -161, -187, -25, -11, -169, -30, -135, -229, -71, -250, -5, -112, -107, -132, -110, -213, -220, -223, -215, -40, -112, -148, -193, -150, -130, -79, -97, -82, -249, -15, -169, -200, -253, -95, -6, -127, -142, -118, -114, -255, -36, -54, -56, -29, -147, -52, -183, -193, -252, -214, -118, -45, -120, -113, -27, -97, -107, -216, -255, -197, -162, -124, -242, -251, -237, -118, -232, -146, -24, -192, -105, -63, -130, -133, -99, -205, -116, -134, -250, -84, -23, -207, -145, -103, -128, -168, -137, -24, -155, -179, -179, -50, -197, -150, -84, -24, -191, -48, -91, -194, -20, -122, -104, -43, -200, -180, -149, -204, -0, -152, -60, -52, -209, -71, -138, -169, -36, -140, -168, -177, -74, -166, -97, -67, -231, -141, -152, -37, -240, -3, -68, -156, -43, -106, -212, -7, -67, -163, -91, -74, -211, -184, -180, -129, -76, -187, -139, -49, -32, -100, -157, -29, -161, -251, -33, -240, -107, -204, -58, -184, -16, -230, -49, -84, -234, -41, -12, -236, -141, -41, -137, -122, -174, -66, -175, -201, -0, -79, -98, -250, -152, -69, -177, -216, -198, -241, -77, -26, -252, -7, -22, -230, -220, -217, -135, -230, -104, -224, -239, -181, -43, -26, -168, -47, -134, -82, -151, -237, -54, -144, -105, -107, -38, -230, -171, -112, -10, -241, -173, -89, -231, -199, -194, -179, -158, -197, -134, -236, -243, -168, -222, -0, -234, -22, -224, -179, -45, -244, -177, -213, -157, -202, -188, -190, -243, -233, -38, -132, -14, -248, -148, -191, -184, -253, -49, -65, -240, -1, -224, -208, -110, -59, -215, -111, -248, -51, -164, -200, -30, -187, -251, -151, -179, -157, -63, -251, -179, -148, -7, -107, -116, -146, -47, -44, -217, -66, -31, -239, -200, -48, -192, -237, -45, -212, -55, -30, -115, -209, -159, -142, -109, -47, -91, -223, -153, -5, -203, -171, -251, -15, -127, -17, -211, -128, -47, -85, -125, -17, -253, -4, -22, -45, -124, -154, -247, -237, -25, -34, -137, -161, -157, -46, -149, -1, -38, -147, -209, -239, -99, -94, -66, -49, -227, -77, -231, -254, -111, -40, -217, -129, -12, -203, -104, -50, -209, -153, -228, -206, -70, -195, -112, -67, -120, -123, -7, -249, -135, -123, -11, -240, -219, -126, -53, -12, -53, -247, -186, -43, -168, -99, -8, -34, -116, -7, -99, -235, -250, -119, -97, -110, -107, -79, -1, -187, -23, -212, -151, -194, -0, -47, -98, -38, -212, -206, -249, -86, -68, -20, -55, -126, -111, -21, -159, -82, -10, -179, -112, -249, -87, -253, -77, -204, -135, -240, -43, -64, -212, -220, -235, -253, -107, -85, -165, -141, -9, -180, -59, -249, -241, -102, -244, -58, -56, -6, -56, -28, -19, -174, -240, -161, -39, -105, -79, -191, -130, -186, -242, -14, -149, -151, -17, -9, -156, -196, -150, -166, -95, -204, -156, -159, -76, -68, -7, -94, -131, -1, -174, -196, -214, -254, -227, -176, -117, -251, -31, -129, -95, -23, -208, -126, -11, -184, -170, -162, -190, -89, -157, -175, -30, -19, -66, -135, -232, -247, -51, -253, -171, -197, -0, -20, -120, -92, -103, -238, -159, -238, -31, -196, -193, -192, -73, -192, -53, -101, -244, -93, -193, -27, -121, -209, -135, -156, -21, -176, -124, -193, -155, -69, -232, -222, -135, -101, -5, -123, -17, -27, -182, -47, -7, -86, -175, -168, -123, -107, -108, -41, -51, -54, -114, -111, -42, -153, -204, -223, -152, -222, -160, -177, -39, -141, -247, -253, -82, -6, -166, -148, -11, -137, -236, -78, -234, -95, -244, -139, -84, -88, -219, -178, -63, -44, -230, -36, -251, -199, -42, -58, -63, -239, -154, -1, -156, -102, -87, -76, -249, -4, -137, -249, -144, -26, -1, -83, -194, -156, -154, -64, -247, -117, -224, -8, -76, -149, -185, -10, -54, -135, -22, -174, -42, -48, -85, -244, -109, -192, -87, -10, -238, -191, -204, -96, -159, -197, -109, -129, -215, -154, -61, -69, -79, -60, -184, -94, -0, -0, -18, -40, -73, -68, -65, -84, -251, -200, -49, -192, -115, -192, -7, -170, -232, -252, -188, -200, -239, -98, -69, -76, -178, -159, -226, -101, -30, -163, -64, -238, -201, -149, -251, -36, -53, -118, -111, -205, -218, -2, -82, -57, -115, -13, -73, -149, -203, -195, -16, -194, -81, -33, -132, -111, -134, -16, -38, -133, -16, -30, -144, -237, -23, -92, -54, -2, -252, -135, -108, -31, -194, -175, -22, -220, -207, -247, -101, -94, -73, -175, -87, -245, -99, -152, -48, -70, -233, -190, -121, -69, -116, -157, -60, -74, -239, -147, -244, -188, -164, -93, -36, -253, -45, -79, -132, -173, -253, -247, -195, -54, -201, -88, -92, -182, -181, -221, -16, -5, -94, -17, -154, -40, -52, -130, -226, -102, -201, -40, -48, -231, -142, -119, -201, -12, -30, -81, -243, -40, -230, -17, -115, -138, -164, -207, -135, -16, -138, -180, -113, -79, -203, -28, -58, -59, -88, -212, -175, -141, -68, -156, -45, -233, -187, -192, -191, -66, -8, -249, -101, -94, -146, -81, -75, -182, -41, -247, -255, -132, -16, -238, -4, -8, -33, -220, -86, -210, -222, -161, -50, -195, -82, -144, -52, -81, -210, -190, -181, -123, -92, -99, -104, -186, -139, -136, -249, -178, -164, -78, -48, -1, -233, -28, -10, -220, -165, -176, -181, -235, -109, -148, -44, -59, -49, -161, -237, -212, -204, -249, -233, -84, -11, -102, -125, -219, -166, -62, -55, -5, -4, -151, -47, -254, -26, -161, -75, -53, -106, -77, -192, -220, -237, -30, -197, -150, -150, -221, -229, -1, -174, -243, -0, -126, -94, -196, -0, -31, -193, -92, -164, -14, -192, -92, -167, -86, -195, -118, -167, -140, -213, -185, -152, -207, -101, -31, -196, -116, -253, -223, -143, -208, -140, -245, -249, -189, -116, -183, -76, -204, -104, -244, -12, -166, -60, -121, -47, -166, -175, -56, -168, -162, -204, -21, -88, -58, -150, -40, -99, -81, -99, -107, -122, -42, -182, -164, -143, -188, -191, -9, -192, -16, -239, -99, -18, -141, -90, -78, -59, -47, -102, -163, -152, -137, -41, -121, -26, -219, -72, -42, -17, -121, -128, -66, -135, -11, -44, -140, -60, -187, -12, -188, -60, -70, -151, -43, -179, -47, -145, -120, -60, -44, -173, -203, -101, -164, -133, -87, -127, -145, -1, -69, -213, -233, -116, -153, -24, -153, -196, -173, -233, -73, -216, -146, -62, -55, -2, -108, -134, -105, -23, -155, -121, -232, -14, -173, -251, -57, -10, -140, -115, -173, -193, -31, -32, -235, -236, -121, -120, -17, -3, -228, -202, -36, -41, -130, -176, -244, -48, -49, -171, -92, -20, -245, -159, -96, -80, -157, -149, -78, -166, -109, -35, -199, -0, -19, -177, -81, -114, -136, -215, -113, -141, -250, -254, -11, -27, -233, -222, -234, -117, -157, -69, -36, -99, -121, -107, -240, -7, -200, -206, -77, -15, -116, -243, -67, -248, -215, -250, -78, -44, -213, -250, -54, -36, -6, -110, -118, -11, -18, -157, -76, -157, -54, -197, -27, -121, -127, -76, -203, -247, -146, -255, -47, -220, -168, -185, -77, -96, -166, -246, -71, -49, -211, -251, -27, -254, -28, -27, -20, -208, -110, -129, -5, -235, -118, -204, -193, -73, -50, -90, -190, -18, -48, -109, -219, -11, -192, -189, -152, -121, -177, -27, -6, -184, -16, -211, -78, -189, -234, -204, -244, -101, -250, -16, -54, -141, -237, -154, -113, -72, -230, -124, -15, -224, -225, -8, -93, -170, -55, -242, -54, -152, -60, -180, -4, -182, -81, -228, -255, -244, -250, -25, -34, -125, -168, -210, -4, -62, -132, -237, -243, -180, -24, -150, -225, -116, -124, -147, -70, -160, -124, -111, -251, -57, -2, -164, -59, -153, -38, -49, -74, -174, -204, -22, -68, -92, -179, -107, -246, -47, -41, -9, -86, -174, -76, -21, -3, -60, -5, -28, -219, -77, -191, -134, -8, -129, -35, -21, -84, -44, -237, -48, -129, -105, -111, -42, -132, -202, -26, -140, -50, -214, -135, -227, -39, -241, -189, -4, -122, -241, -92, -221, -0, -19, -176, -103, -0, -127, -198, -183, -252, -105, -82, -73, -45, -6, -160, -98, -89, -84, -179, -221, -221, -72, -136, -129, -115, -250, -170, -165, -93, -170, -147, -105, -42, -163, -252, -5, -243, -143, -92, -15, -91, -218, -165, -134, -163, -245, -53, -112, -5, -147, -181, -78, -195, -150, -151, -69, -94, -198, -173, -53, -86, -185, -44, -170, -81, -23, -152, -67, -106, -101, -12, -92, -98, -125, -169, -78, -166, -169, -140, -50, -3, -247, -247, -119, -134, -25, -145, -12, -144, -105, -247, -195, -20, -152, -181, -251, -221, -145, -249, -177, -180, -104, -51, -48, -97, -235, -253, -177, -23, -226, -12, -144, -18, -3, -55, -104, -132, -42, -123, -193, -36, -56, -153, -214, -96, -148, -251, -49, -211, -243, -242, -62, -26, -140, -40, -6, -192, -4, -191, -15, -99, -182, -128, -37, -48, -79, -237, -59, -122, -217, -96, -210, -15, -129, -217, -165, -31, -194, -188, -84, -214, -197, -252, -214, -138, -24, -32, -37, -6, -46, -153, -1, -106, -60, -75, -10, -163, -124, -8, -243, -25, -124, -12, -83, -198, -12, -73, -1, -231, -116, -89, -134, -159, -236, -140, -92, -217, -63, -204, -185, -101, -136, -74, -155, -193, -129, -58, -207, -98, -190, -141, -177, -228, -147, -139, -98, -102, -247, -23, -48, -129, -242, -58, -224, -29, -169, -239, -160, -54, -106, -48, -192, -36, -50, -91, -190, -224, -169, -81, -10, -234, -203, -154, -121, -63, -16, -123, -201, -189, -96, -128, -54, -17, -97, -248, -127, -149, -245, -15, -155, -62, -47, -246, -15, -99, -136, -241, -134, -193, -129, -58, -107, -251, -113, -235, -62, -154, -85, -94, -176, -221, -248, -4, -142, -211, -224, -144, -177, -178, -140, -24, -43, -103, -142, -87, -171, -160, -29, -169, -216, -87, -150, -12, -243, -158, -16, -194, -93, -146, -138, -108, -6, -203, -97, -17, -67, -151, -72, -250, -173, -164, -117, -67, -8, -67, -34, -151, -36, -29, -144, -169, -239, -30, -89, -130, -201, -131, -218, -238, -244, -160, -31, -152, -92, -170, -88, -73, -55, -118, -81, -247, -171, -210, -32, -179, -241, -204, -18, -218, -38, -49, -112, -35, -45, -141, -91, -42, -195, -79, -150, -180, -130, -164, -119, -135, -16, -126, -26, -203, -197, -236, -88, -89, -210, -3, -185, -250, -74, -61, -170, -154, -160, -81, -170, -216, -28, -138, -126, -136, -71, -52, -248, -203, -46, -203, -187, -115, -129, -164, -203, -100, -182, -236, -107, -20, -73, -247, -170, -116, -59, -122, -45, -43, -95, -139, -72, -101, -248, -141, -100, -161, -227, -119, -96, -22, -213, -162, -140, -34, -111, -104, -112, -90, -221, -222, -123, -104, -167, -12, -249, -46, -104, -84, -26, -141, -128, -207, -97, -42, -229, -53, -49, -147, -241, -173, -37, -50, -64, -74, -58, -180, -36, -59, -186, -211, -86, -90, -249, -48, -255, -132, -231, -177, -37, -232, -62, -152, -4, -253, -229, -46, -250, -119, -87, -86, -136, -164, -66, -149, -142, -121, -55, -95, -238, -178, -210, -144, -20, -59, -216, -166, -22, -71, -103, -206, -163, -129, -58, -88, -112, -75, -212, -70, -80, -11, -36, -26, -61, -82, -127, -8, -76, -177, -242, -83, -204, -64, -113, -63, -190, -45, -125, -132, -46, -245, -5, -39, -219, -209, -83, -0, -156, -138, -5, -184, -238, -131, -249, -213, -191, -72, -36, -147, -119, -141, -254, -229, -25, -126, -98, -74, -255, -128, -77, -137, -120, -241, -2, -135, -248, -123, -235, -8, -129, -209, -64, -29, -76, -11, -120, -15, -150, -0, -59, -26, -167, -153, -4, -18, -141, -30, -77, -127, -8, -138, -87, -11, -73, -47, -56, -21, -249, -250, -138, -218, -109, -90, -95, -9, -93, -158, -225, -119, -239, -178, -221, -128, -237, -199, -52, -141, -138, -64, -29, -108, -201, -184, -191, -51, -242, -119, -128, -101, -155, -182, -219, -169, -176, -107, -163, -71, -164, -206, -126, -41, -70, -122, -193, -0, -71, -210, -239, -157, -185, -26, -0, -120, -19, -150, -243, -32, -57, -197, -111, -214, -43, -120, -182, -209, -67, -182, -11, -70, -95, -247, -192, -29, -225, -56, -92, -210, -33, -178, -93, -73, -158, -144, -229, -228, -27, -49, -192, -100, -158, -3, -36, -221, -46, -233, -53, -153, -160, -89, -187, -146, -70, -70, -143, -145, -134, -30, -141, -0, -61, -79, -162, -221, -20, -216, -74, -98, -18, -230, -86, -215, -60, -7, -51, -13, -141, -30, -253, -6, -245, -157, -51, -187, -74, -38, -229, -245, -245, -60, -137, -118, -83, -96, -78, -60, -155, -54, -45, -159, -21, -42, -30, -151, -180, -49, -150, -219, -174, -112, -99, -167, -130, -78, -52, -94, -163, -250, -11, -78, -205, -36, -242, -93, -89, -14, -222, -53, -36, -45, -77, -220, -10, -217, -11, -125, -65, -146, -60, -132, -37, -153, -56, -20, -216, -147, -72, -242, -199, -58, -72, -21, -62, -67, -8, -219, -68, -242, -17, -55, -106, -48, -201, -232, -225, -180, -201, -155, -75, -37, -180, -155, -204, -0, -137, -245, -181, -173, -47, -72, -158, -82, -176, -112, -181, -89, -152, -175, -193, -184, -46, -159, -35, -137, -1, -134, -5, -46, -9, -175, -236, -12, -240, -28, -112, -68, -1, -221, -170, -192, -245, -152, -110, -225, -62, -96, -255, -8, -77, -7, -165, -105, -221, -72, -183, -142, -181, -173, -47, -168, -195, -0, -151, -96, -145, -193, -151, -23, -140, -78, -117, -219, -237, -139, -3, -106, -109, -164, -14, -249, -152, -139, -210, -165, -88, -36, -238, -22, -192, -187, -35, -52, -144, -150, -214, -173, -85, -235, -88, -13, -134, -74, -102, -128, -12, -205, -130, -152, -71, -111, -227, -47, -216, -219, -61, -154, -68, -79, -169, -190, -33, -245, -197, -57, -237, -12, -96, -231, -138, -250, -96, -112, -86, -175, -253, -137, -103, -39, -155, -157, -198, -206, -207, -63, -77, -119, -83, -79, -219, -12, -181, -16, -230, -15, -240, -44, -166, -8, -186, -22, -248, -65, -23, -245, -65, -13, -79, -41, -170, -125, -37, -219, -201, -75, -84, -231, -197, -249, -67, -140, -175, -168, -47, -207, -0, -69, -105, -221, -166, -147, -9, -65, -195, -28, -71, -186, -201, -98, -214, -54, -67, -157, -137, -169, -208, -215, -240, -247, -114, -15, -5, -89, -66, -18, -235, -131, -4, -79, -169, -204, -253, -42, -95, -201, -234, -188, -68, -41, -92, -82, -231, -197, -213, -96, -128, -148, -180, -110, -211, -128, -236, -246, -40, -221, -166, -177, -107, -155, -161, -166, -228, -126, -176, -131, -40, -200, -18, -146, -88, -31, -12, -94, -126, -70, -61, -165, -186, -69, -158, -91, -178, -38, -204, -89, -5, -101, -146, -236, -212, -12, -172, -34, -254, -140, -185, -92, -149, -249, -3, -252, -65, -210, -51, -178, -188, -185, -23, -73, -138, -249, -184, -223, -39, -219, -242, -165, -131, -85, -84, -226, -56, -82, -53, -36, -170, -125, -115, -235, -91, -101, -90, -194, -14, -158, -145, -45, -73, -219, -66, -52, -91, -56, -9, -70, -188, -50, -154, -65, -15, -29, -66, -88, -63, -132, -112, -91, -8, -97, -98, -8, -161, -200, -175, -44, -233, -197, -133, -16, -58, -46, -214, -219, -134, -16, -230, -13, -33, -148, -229, -34, -216, -222, -105, -198, -133, -16, -78, -8, -33, -196, -50, -127, -156, -39, -233, -176, -206, -212, -35, -233, -147, -178, -77, -160, -138, -112, -129, -164, -159, -73, -42, -218, -233, -35, -153, -161, -18, -231, -207, -71, -37, -45, -151, -57, -31, -39, -115, -254, -232, -6, -41, -158, -82, -79, -200, -156, -104, -86, -148, -169, -240, -99, -106, -234, -20, -26, -137, -180, -88, -185, -84, -59, -245, -252, -62, -140, -149, -234, -165, -243, -50, -64, -9, -93, -178, -117, -44, -5, -36, -154, -91, -157, -182, -114, -254, -4, -190, -128, -173, -96, -58, -66, -219, -100, -42, -194, -215, -43, -250, -135, -183, -187, -38, -176, -22, -240, -32, -240, -153, -138, -50, -149, -70, -188, -66, -26, -210, -99, -229, -82, -237, -212, -251, -49, -32, -20, -205, -78, -182, -156, -240, -236, -93, -129, -244, -229, -93, -219, -12, -53, -63, -38, -8, -62, -225, -245, -157, -22, -107, -183, -70, -125, -175, -99, -91, -249, -150, -102, -11, -39, -33, -114, -41, -133, -70, -164, -7, -85, -38, -189, -56, -10, -208, -232, -109, -212, -0, -195, -164, -47, -24, -46, -144, -96, -196, -75, -161, -17, -137, -177, -114, -35, -29, -140, -112, -125, -65, -219, -32, -193, -136, -87, -70, -147, -223, -147, -38, -101, -231, -142, -145, -142, -182, -189, -105, -251, -226, -158, -221, -5, -82, -140, -120, -213, -52, -36, -198, -202, -245, -27, -62, -4, -127, -25, -91, -103, -191, -72, -197, -14, -89, -140, -112, -125, -65, -219, -32, -193, -136, -151, -66, -35, -18, -99, -229, -250, -13, -224, -40, -108, -101, -50, -1, -75, -56, -89, -149, -76, -42, -105, -149, -82, -163, -253, -70, -12, -69, -130, -169, -25, -115, -72, -189, -39, -161, -174, -9, -254, -129, -150, -230, -17, -232, -26, -212, -216, -185, -131, -132, -240, -112, -224, -91, -153, -227, -111, -84, -220, -31, -162, -253, -243, -235, -183, -147, -176, -33, -99, -134, -62, -121, -121, -151, -88, -95, -35, -134, -34, -205, -212, -188, -31, -80, -169, -43, -192, -18, -64, -156, -76, -127, -54, -191, -170, -6, -105, -89, -179, -182, -0, -206, -247, -227, -205, -128, -239, -69, -104, -190, -207, -64, -98, -165, -243, -137, -120, -182, -96, -75, -160, -104, -218, -213, -130, -190, -13, -155, -190, -160, -87, -240, -15, -109, -124, -63, -219, -236, -26, -152, -143, -218, -134, -249, -227, -28, -205, -134, -157, -57, -221, -143, -127, -31, -161, -121, -53, -59, -4, -247, -27, -77, -24, -138, -244, -24, -139, -13, -128, -202, -116, -183, -206, -0, -133, -155, -89, -116, -131, -70, -95, -6, -105, -105, -216, -230, -41, -56, -46, -163, -139, -169, -139, -31, -80, -205, -45, -209, -219, -68, -8, -129, -16, -194, -151, -66, -8, -139, -251, -223, -137, -37, -241, -124, -29, -164, -169, -94, -165, -93, -53, -120, -197, -50, -8, -152, -95, -193, -129, -50, -27, -77, -105, -254, -162, -146, -58, -90, -221, -158, -166, -142, -198, -112, -171, -204, -20, -48, -123, -58, -200, -209, -124, -31, -216, -210, -143, -207, -39, -226, -64, -129, -69, -20, -61, -142, -185, -91, -173, -74, -65, -86, -210, -145, -10, -10, -84, -175, -192, -58, -152, -215, -210, -129, -37, -101, -193, -164, -247, -198, -35, -32, -169, -219, -211, -144, -184, -220, -162, -70, -118, -45, -50, -187, -112, -17, -17, -22, -169, -16, -18, -253, -250, -60, -152, -38, -110, -42, -166, -208, -24, -178, -153, -196, -72, -3, -105, -234, -217, -75, -171, -158, -5, -179, -104, -30, -139, -41, -233, -150, -232, -93, -143, -149, -190, -220, -98, -4, -106, -12, -201, -8, -138, -20, -8, -141, -62, -143, -79, -194, -86, -57, -189, -203, -185, -171, -100, -245, -236, -244, -148, -121, -29, -203, -23, -12, -176, -69, -131, -126, -108, -130, -173, -253, -241, -81, -180, -216, -199, -144, -196, -229, -22, -137, -217, -181, -250, -9, -127, -200, -45, -242, -199, -57, -154, -77, -129, -5, -48, -199, -147, -194, -36, -74, -88, -142, -223, -117, -75, -238, -167, -216, -223, -83, -212, -179, -47, -146, -152, -151, -209, -127, -192, -241, -41, -180, -145, -178, -99, -189, -124, -212, -16, -151, -21, -2, -87, -151, -84, -232, -114, -148, -193, -100, -89, -86, -139, -87, -178, -127, -77, -58, -215, -34, -158, -245, -191, -252, -241, -108, -132, -16, -110, -10, -33, -188, -44, -105, -99, -21, -36, -190, -192, -172, -109, -71, -75, -90, -172, -164, -173, -20, -1, -47, -69, -61, -123, -147, -164, -99, -48, -185, -102, -107, -224, -240, -146, -54, -123, -15, -18, -151, -91, -140, -64, -141, -33, -150, -24, -105, -217, -252, -113, -132, -110, -83, -204, -89, -51, -186, -247, -31, -3, -123, -238, -60, -133, -201, -28, -165, -31, -4, -197, -2, -94, -138, -122, -118, -101, -44, -170, -231, -37, -76, -183, -80, -168, -134, -247, -169, -235, -44, -26, -200, -1, -85, -35, -64, -150, -240, -30, -224, -184, -196, -74, -187, -218, -235, -151, -8, -34, -52, -233, -243, -87, -90, -155, -219, -96, -49, -244, -11, -39, -244, -173, -208, -157, -155, -97, -200, -28, -138, -233, -11, -254, -66, -131, -152, -196, -58, -12, -208, -183, -229, -150, -119, -104, -208, -190, -194, -5, -116, -105, -157, -79, -107, -243, -101, -204, -148, -59, -201, -255, -162, -158, -74, -9, -12, -80, -41, -224, -141, -36, -84, -189, -195, -172, -226, -229, -44, -153, -99, -227, -143, -37, -45, -33, -233, -247, -254, -215, -43, -188, -222, -79, -217, -33, -132, -208, -86, -82, -169, -141, -36, -237, -229, -123, -249, -172, -221, -82, -157, -195, -134, -217, -66, -96, -8, -97, -86, -8, -225, -216, -16, -194, -10, -178, -132, -77, -61, -223, -233, -123, -14, -69, -227, -32, -218, -57, -6, -192, -210, -68, -182, -119, -105, -177, -254, -74, -25, -192, -233, -42, -167, -0, -90, -206, -8, -134, -109, -206, -176, -101, -201, -253, -228, -32, -218, -132, -182, -160, -197, -192, -216, -130, -54, -234, -77, -163, -192, -95, -49, -19, -232, -39, -11, -238, -39, -101, -9, -199, -76, -161, -215, -3, -167, -71, -238, -181, -38, -3, -144, -184, -239, -79, -42, -48, -111, -222, -51, -129, -69, -128, -229, -170, -75, -116, -213, -86, -33, -3, -84, -49, -54, -166, -71, -184, -25, -216, -190, -164, -254, -77, -48, -33, -29, -103, -216, -238, -130, -77, -169, -145, -37, -28, -183, -153, -3, -255, -136, -220, -75, -226, -252, -218, -220, -91, -94, -87, -210, -22, -114, -152, -13, -99, -18, -230, -149, -219, -120, -107, -218, -196, -62, -149, -49, -64, -41, -99, -99, -91, -218, -126, -25, -75, -233, -51, -242, -224, -35, -197, -117, -196, -13, -69, -173, -48, -0, -17, -148, -212, -85, -26, -59, -55, -28, -72, -125, -15, -37, -229, -199, -151, -61, -115, -207, -224, -29, -239, -54, -244, -185, -235, -41, -32, -181, -158, -145, -138, -34, -6, -32, -81, -7, -50, -34, -25, -128, -52, -93, -121, -229, -151, -75, -194, -252, -149, -242, -5, -213, -25, -37, -218, -0, -53, -236, -239, -101, -253, -175, -98, -254, -12, -205, -235, -192, -129, -64, -163, -101, -110, -62, -89, -244, -78, -88, -182, -203, -87, -129, -235, -155, -84, -168, -4, -93, -121, -136, -32, -66, -115, -115, -8, -97, -5, -191, -189, -124, -8, -97, -200, -198, -201, -53, -176, -179, -6, -187, -187, -247, -18, -41, -1, -182, -173, -32, -132, -48, -69, -210, -30, -50, -29, -78, -101, -36, -114, -229, -71, -128, -237, -85, -123, -18, -182, -9, -65, -97, -182, -201, -178, -17, -32, -71, -215, -122, -194, -201, -72, -63, -170, -70, -146, -202, -81, -194, -233, -170, -178, -143, -125, -17, -91, -33, -188, -132, -173, -148, -186, -86, -2, -181, -48, -2, -44, -129, -153, -231, -143, -37, -109, -251, -219, -78, -220, -226, -154, -157, -107, -121, -129, -104, -5, -73, -215, -132, -16, -166, -135, -16, -158, -80, -3, -208, -255, -132, -147, -93, -127, -221, -164, -101, -31, -123, -70, -22, -145, -252, -14, -89, -100, -241, -144, -200, -228, -126, -79, -55, -146, -214, -145, -237, -168, -126, -86, -8, -225, -153, -42, -226, -16, -194, -164, -206, -223, -144, -155, -88, -98, -35, -112, -75, -88, -89, -69, -101, -35, -0, -125, -212, -149, -167, -124, -221, -189, -248, -81, -48, -7, -214, -162, -93, -77, -146, -133, -210, -22, -70, -128, -174, -133, -192, -172, -42, -120, -23, -63, -220, -221, -213, -193, -77, -177, -145, -164, -175, -135, -16, -238, -84, -129, -93, -29, -248, -33, -112, -35, -22, -199, -119, -66, -228, -254, -246, -126, -255, -111, -180, -227, -14, -93, -58, -74, -52, -96, -146, -247, -72, -122, -168, -224, -222, -235, -41, -126, -18, -12, -56, -210, -118, -19, -101, -212, -110, -144, -106, -217, -151, -157, -74, -71, -194, -46, -91, -192, -124, -254, -127, -94, -226, -249, -128, -110, -195, -20, -29, -75, -2, -255, -172, -232, -71, -233, -23, -87, -99, -148, -72, -250, -114, -125, -100, -123, -30, -216, -175, -97, -91, -203, -96, -94, -73, -39, -97, -171, -155, -104, -230, -175, -170, -17, -0, -155, -255, -191, -65, -133, -207, -66, -45, -164, -50, -64, -69, -29, -41, -206, -16, -159, -192, -66, -157, -174, -35, -238, -80, -49, -37, -118, -92, -208, -223, -210, -47, -183, -6, -3, -164, -102, -43, -189, -25, -248, -97, -23, -253, -153, -142, -169, -113, -175, -39, -18, -43, -145, -161, -171, -98, -128, -23, -48, -231, -150, -230, -249, -129, -11, -30, -160, -231, -217, -41, -49, -149, -236, -155, -253, -75, -24, -178, -124, -193, -166, -134, -37, -48, -245, -237, -109, -93, -182, -85, -249, -117, -215, -100, -128, -153, -148, -251, -18, -116, -173, -152, -162, -109, -29, -126, -141, -134, -251, -197, -0, -231, -96, -6, -167, -223, -19, -223, -36, -114, -107, -76, -6, -184, -145, -76, -166, -172, -134, -109, -165, -142, -18, -165, -52, -53, -218, -234, -169, -117, -175, -167, -232, -23, -3, -140, -52, -212, -249, -114, -49, -69, -217, -222, -37, -245, -204, -81, -12, -208, -52, -52, -44, -201, -178, -54, -135, -33, -73, -122, -87, -181, -228, -61, -95, -183, -83, -192, -136, -7, -213, -89, -41, -91, -217, -89, -188, -162, -15, -251, -249, -124, -220, -181, -16, -212, -214, -151, -91, -103, -42, -1, -62, -6, -252, -185, -219, -54, -11, -234, -190, -24, -184, -164, -23, -117, -167, -52, -222, -218, -206, -226, -37, -109, -28, -136, -45, -55, -95, -109, -145, -1, -250, -102, -85, -196, -18, -99, -79, -163, -100, -163, -7, -239, -199, -195, -192, -123, -234, -220, -243, -251, -189, -241, -232, -162, -69, -87, -109, -74, -60, -94, -170, -166, -24, -103, -176, -85, -48, -75, -216, -16, -6, -192, -118, -61, -123, -8, -243, -2, -62, -51, -161, -47, -201, -95, -110, -27, -240, -175, -191, -52, -49, -68, -83, -6, -160, -194, -163, -171, -107, -80, -189, -62, -77, -181, -101, -23, -122, -188, -144, -232, -188, -225, -109, -196, -24, -96, -77, -175, -127, -93, -224, -209, -212, -103, -235, -23, -176, -192, -208, -115, -170, -41, -251, -136, -178, -47, -50, -71, -151, -106, -167, -46, -165, -105, -3, -69, -12, -224, -247, -174, -195, -242, -23, -124, -164, -151, -125, -104, -2, -204, -234, -250, -209, -4, -58, -40, -214, -184, -22, -222, -171, -131, -236, -23, -118, -128, -164, -159, -43, -109, -227, -230, -86, -80, -244, -16, -109, -60, -92, -8, -97, -43, -73, -235, -75, -58, -173, -155, -122, -98, -160, -194, -233, -195, -251, -191, -62, -166, -210, -126, -58, -82, -197, -210, -50, -235, -226, -176, -99, -118, -96, -72, -8, -97, -150, -164, -163, -74, -104, -231, -24, -0, -43, -134, -16, -30, -149, -25, -163, -26, -167, -108, -47, -65, -138, -211, -199, -143, -37, -157, -44, -41, -230, -21, -20, -100, -73, -183, -135, -29, -35, -198, -65, -178, -101, -252, -10, -184, -79, -210, -197, -138, -4, -111, -96, -18, -255, -195, -46, -40, -78, -136, -220, -47, -253, -194, -19, -179, -170, -255, -44, -132, -240, -235, -16, -66, -76, -216, -251, -183, -164, -158, -239, -108, -78, -66, -130, -173, -178, -20, -238, -115, -44, -66, -8, -27, -87, -144, -156, -39, -105, -127, -73, -79, -75, -186, -66, -150, -218, -61, -139, -54, -220, -186, -162, -123, -47, -59, -110, -147, -57, -150, -244, -26, -209, -80, -249, -44, -230, -74, -6, -72, -192, -24, -217, -143, -60, -83, -17, -205, -94, -8, -33, -187, -55, -112, -211, -31, -170, -76, -155, -120, -165, -164, -126, -164, -154, -171, -100, -128, -236, -222, -193, -147, -128, -189, -122, -222, -165, -22, -225, -14, -163, -77, -172, -133, -31, -151, -244, -11, -73, -87, -169, -32, -190, -175, -45, -41, -187, -0, -23, -72, -90, -145, -18, -115, -112, -75, -72, -103, -0, -89, -186, -182, -170, -117, -247, -38, -146, -110, -240, -211, -235, -138, -214, -248, -35, -29, -33, -132, -203, -67, -8, -111, -247, -29, -74, -174, -168, -91, -30, -184, -149, -72, -196, -83, -141, -246, -159, -147, -116, -156, -164, -83, -154, -214, -145, -216, -206, -86, -77, -125, -59, -27, -131, -26, -182, -236, -94, -46, -3, -187, -69, -197, -26, -124, -34, -112, -107, -147, -178, -13, -250, -176, -89, -183, -245, -164, -54, -54, -29, -88, -186, -47, -141, -205, -1, -24, -78, -38, -196, -92, -225, -198, -99, -187, -169, -22, -186, -231, -183, -129, -172, -16, -56, -70, -115, -192, -254, -0, -48, -160, -167, -207, -7, -148, -0, -127, -146, -116, -73, -8, -225, -59, -125, -239, -88, -187, -120, -80, -210, -235, -146, -142, -239, -219, -16, -142, -5, -60, -12, -91, -74, -214, -84, -96, -134, -144, -29, -178, -140, -144, -185, -183, -9, -102, -101, -91, -40, -114, -111, -54, -18, -219, -25, -246, -105, -168, -31, -200, -239, -24, -18, -29, -1, -24, -65, -14, -32, -238, -172, -17, -219, -86, -78, -33, -132, -155, -37, -61, -37, -105, -136, -199, -174, -99, -130, -122, -31, -26, -150, -12, -103, -178, -174, -77, -207, -221, -48, -107, -18, -3, -168, -100, -15, -190, -178, -47, -203, -231, -178, -31, -3, -209, -31, -172, -71, -248, -179, -236, -135, -142, -225, -181, -94, -230, -37, -42, -250, -65, -49, -155, -192, -196, -94, -181, -219, -13, -146, -100, -128, -16, -194, -78, -37, -117, -148, -77, -27, -231, -200, -18, -77, -237, -89, -191, -107, -141, -113, -155, -164, -227, -187, -173, -36, -22, -176, -218, -5, -222, -144, -134, -238, -250, -57, -18, -208, -181, -16, -24, -141, -51, -27, -184, -183, -143, -36, -1, -63, -174, -223, -181, -198, -120, -70, -150, -237, -108, -196, -32, -132, -240, -238, -58, -244, -190, -196, -36, -132, -176, -97, -238, -250, -169, -146, -246, -13, -33, -188, -189, -173, -190, -205, -113, -171, -128, -4, -228, -183, -182, -157, -19, -81, -212, -255, -117, -36, -253, -178, -205, -134, -178, -230, -224, -57, -253, -165, -117, -176, -148, -70, -136, -173, -189, -10, -69, -239, -188, -100, -196, -120, -151, -164, -99, -218, -236, -195, -220, -104, -14, -126, -135, -76, -14, -72, -134, -11, -111, -255, -47, -114, -125, -68, -9, -111, -158, -48, -163, -219, -13, -169, -7, -161, -47, -12, -80, -177, -115, -120, -219, -216, -70, -102, -228, -169, -131, -55, -36, -197, -182, -100, -107, -69, -120, -115, -219, -65, -97, -144, -235, -112, -98, -142, -51, -7, -251, -50, -43, -154, -116, -194, -173, -107, -43, -202, -150, -173, -117, -240, -134, -164, -151, -242, -23, -235, -10, -111, -37, -24, -177, -211, -235, -28, -199, -0, -146, -94, -46, -185, -247, -37, -73, -159, -117, -107, -91, -12, -111, -2, -222, -28, -209, -5, -204, -82, -124, -4, -104, -5, -69, -140, -228, -186, -147, -5, -134, -115, -191, -133, -57, -142, -1, -202, -132, -213, -16, -194, -206, -21, -197, -255, -216, -33, -205, -93, -143, -142, -0, -255, -23, -48, -199, -49, -64, -83, -84, -172, -114, -138, -100, -128, -57, -2, -221, -172, -224, -230, -198, -85, -64, -19, -204, -82, -100, -4, -0, -78, -165, -96, -71, -180, -185, -5, -255, -103, -70, -128, -50, -132, -16, -22, -45, -184, -213, -186, -226, -101, -20, -35, -16, -20, -196, -252, -187, -103, -211, -26, -53, -234, -105, -197, -186, -215, -79, -140, -142, -0, -134, -34, -141, -92, -173, -108, -105, -115, -145, -54, -117, -20, -163, -24, -197, -40, -70, -49, -138, -81, -140, -98, -20, -163, -24, -197, -40, -70, -49, -138, -81, -140, -98, -20, -163, -24, -197, -40, -70, -49, -138, -81, -204, -37, -248, -255, -129, -51, -157, -250, -111, -139, -157, -153, -0, -0, -0, -0, -73, -69, -78, -68, -174, -66, -96, -130, -}; -/* clang-format on */ diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 86c7bda2b3..100fccc783 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1032,7 +1032,10 @@ void BaseMaterial3D::_update_shader() { if (features[FEATURE_REFRACTION]) { if (features[FEATURE_NORMAL_MAPPING]) { - code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMAL_MAP.x + BINORMAL * NORMAL_MAP.y + NORMAL * NORMAL_MAP.z,NORMAL_MAP_DEPTH) );\n"; + code += "\tvec3 unpacked_normal = NORMAL_MAP;\n"; + code += "\tunpacked_normal.xy = unpacked_normal.xy * 2.0 - 1.0;\n"; + code += "\tunpacked_normal.z = sqrt(max(0.0, 1.0 - dot(unpacked_normal.xy, unpacked_normal.xy)));\n"; + code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * unpacked_normal.x + BINORMAL * unpacked_normal.y + NORMAL * unpacked_normal.z,NORMAL_MAP_DEPTH) );\n"; } else { code += "\tvec3 ref_normal = NORMAL;\n"; } @@ -1757,7 +1760,8 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { if (orm) { if (property.name == "shading_mode") { - property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness. + // Vertex not supported in ORM mode, since no individual roughness. + property.hint_string = "Unshaded,Per-Pixel"; } if (property.name.begins_with("roughness") || property.name.begins_with("metallic") || property.name.begins_with("ao_texture")) { property.usage = 0; @@ -2384,18 +2388,18 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance); ADD_GROUP("Transparency", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth PrePass"), "set_transparency", "get_transparency"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass"), "set_transparency", "get_transparency"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST); ADD_GROUP("Shading", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,PerPixel,PerVertex"), "set_shading_mode", "get_shading_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,Per-Pixel,Per-Vertex"), "set_shading_mode", "get_shading_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT); @@ -2499,7 +2503,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Detail", "detail_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled"), "set_feature", "get_feature", FEATURE_DETAIL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK); - ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_detail_blend_mode", "get_detail_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply"), "set_detail_blend_mode", "get_detail_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_uv_layer", PROPERTY_HINT_ENUM, "UV1,UV2"), "set_detail_uv", "get_detail_uv"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL); diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 59e699326d..60d5566f08 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -1316,7 +1316,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); ADD_GROUP("Sub Emitter", "sub_emitter_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,AtEnd,AtCollision"), "set_sub_emitter_mode", "get_sub_emitter_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,At End,At Collision"), "set_sub_emitter_mode", "get_sub_emitter_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sub_emitter_frequency", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_sub_emitter_frequency", "get_sub_emitter_frequency"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_end", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_end", "get_sub_emitter_amount_at_end"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sub_emitter_keep_velocity"), "set_sub_emitter_keep_velocity", "get_sub_emitter_keep_velocity"); @@ -1391,7 +1391,7 @@ ParticlesMaterial::ParticlesMaterial() : set_sub_emitter_keep_velocity(false); set_attractor_interaction_enabled(true); - set_collision_enabled(true); + set_collision_enabled(false); set_collision_bounce(0.0); set_collision_friction(0.0); set_collision_use_scale(false); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index c3d84aeda2..64b43f82c6 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1133,7 +1133,7 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { Vector3 normal_left, normal_right; normal_left = Vector3(-size.y, size.x * left_to_right, 0.0); - normal_right = Vector3(size.y, size.x * left_to_right, 0.0); + normal_right = Vector3(size.y, size.x * (1.0 - left_to_right), 0.0); normal_left.normalize(); normal_right.normalize(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index f2751b7604..2414704a57 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -978,7 +978,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) } wf->store_32(0); //string table size, will not be in use - size_t ext_res_count_pos = wf->get_position(); + uint64_t ext_res_count_pos = wf->get_position(); wf->store_32(0); //zero ext resources, still parsing them @@ -1041,7 +1041,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) //now, save resources to a separate file, for now - size_t sub_res_count_pos = wf->get_position(); + uint64_t sub_res_count_pos = wf->get_position(); wf->store_32(0); //zero sub resources, still parsing them String temp_file = p_path + ".temp"; @@ -1050,8 +1050,8 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) return ERR_CANT_OPEN; } - Vector<size_t> local_offsets; - Vector<size_t> local_pointers_pos; + Vector<uint64_t> local_offsets; + Vector<uint64_t> local_pointers_pos; while (next_tag.name == "sub_resource" || next_tag.name == "resource") { String type; @@ -1089,7 +1089,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) wf->store_64(0); //temp local offset bs_save_unicode_string(wf2, type); - size_t propcount_ofs = wf2->get_position(); + uint64_t propcount_ofs = wf2->get_position(); wf2->store_32(0); int prop_count = 0; @@ -1159,7 +1159,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) local_offsets.push_back(wf2->get_position()); bs_save_unicode_string(wf2, "PackedScene"); - size_t propcount_ofs = wf2->get_position(); + uint64_t propcount_ofs = wf2->get_position(); wf2->store_32(0); int prop_count = 0; @@ -1185,7 +1185,7 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) wf2->close(); - size_t offset_from = wf->get_position(); + uint64_t offset_from = wf->get_position(); wf->seek(sub_res_count_pos); //plus one because the saved one wf->store_32(local_offsets.size()); diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index f50ee9c4c8..9d79c22159 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -193,7 +193,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "uniform float ground_energy = 1.0;\n\n"; code += "uniform float sun_angle_max = 1.74;\n"; code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n"; - code += "const float PI = 3.1415926535897932384626433833;\n\n"; code += "void sky() {\n"; code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n"; code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n"; @@ -499,7 +498,6 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "uniform sampler2D night_sky : hint_black;"; - code += "const float PI = 3.141592653589793238462643383279502884197169;\n"; code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n"; code += "// Sun constants\n"; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index ff682a40f4..f2143e683d 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -35,6 +35,7 @@ SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr; SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr; +SurfaceTool::SimplifyWithAttribFunc SurfaceTool::simplify_with_attrib_func = nullptr; SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr; SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr; diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 28addf2245..f5f3a95b14 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -78,6 +78,8 @@ public: static OptimizeVertexCacheFunc optimize_vertex_cache_func; typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_error); static SimplifyFunc simplify_func; + typedef size_t (*SimplifyWithAttribFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float *result_error, const float *attributes, const float *attribute_weights, size_t attribute_count); + static SimplifyWithAttribFunc simplify_with_attrib_func; typedef float (*SimplifyScaleFunc)(const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride); static SimplifyScaleFunc simplify_scale_func; typedef size_t (*SimplifySloppyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *out_result_error); diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index cf07003720..564c65adb9 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -55,10 +55,10 @@ Error TextFile::load_text(const String &p_path) { ERR_FAIL_COND_V_MSG(err, err, "Cannot open TextFile '" + p_path + "'."); - int len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); - int r = f->get_buffer(w, len); + uint64_t r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 925867a1f2..f1eff6e84f 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -74,7 +74,7 @@ void TextLine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextLine::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &TextLine::get_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida justification,Word justification,Trim edge spaces after justification,Justification only after last tab"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justify,Word Justify,Trim Edge Spaces After Justify,Justify Only After Last Tab"), "set_flags", "get_flags"); ClassDB::bind_method(D_METHOD("get_objects"), &TextLine::get_objects); ClassDB::bind_method(D_METHOD("get_object_rect", "key"), &TextLine::get_object_rect); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 341f5abd80..958c94fe31 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -72,7 +72,7 @@ void TextParagraph::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextParagraph::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &TextParagraph::get_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida justification,Word justification,Trim edge spaces after justification,Justification only after last tab,Break mandatory,Break words,Break graphemes"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justify,Word Justify,Trim Edge Spaces After Justify,Justify Only After Last Tab,Break Mandatory,Break Words,Break Graphemes"), "set_flags", "get_flags"); ClassDB::bind_method(D_METHOD("set_width", "width"), &TextParagraph::set_width); ClassDB::bind_method(D_METHOD("get_width"), &TextParagraph::get_width); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 624eae0411..4475179431 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -335,7 +335,7 @@ Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit //mipmaps need to be read independently, they will be later combined Vector<Ref<Image>> mipmap_images; - int total_size = 0; + uint64_t total_size = 0; bool first = true; @@ -490,7 +490,7 @@ Image::Format StreamTexture2D::get_format() const { return format; } -Error StreamTexture2D::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) { +Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) { alpha_cache.unref(); ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER); @@ -511,8 +511,8 @@ Error StreamTexture2D::_load_data(const String &p_path, int &tw, int &th, int &t memdelete(f); ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); } - tw_custom = f->get_32(); - th_custom = f->get_32(); + r_width = f->get_32(); + r_height = f->get_32(); uint32_t df = f->get_32(); //data format //skip reserved @@ -551,7 +551,7 @@ Error StreamTexture2D::_load_data(const String &p_path, int &tw, int &th, int &t } Error StreamTexture2D::load(const String &p_path) { - int lw, lh, lwc, lhc; + int lw, lh; Ref<Image> image; image.instance(); @@ -560,7 +560,7 @@ Error StreamTexture2D::load(const String &p_path) { bool request_roughness; int mipmap_limit; - Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness, mipmap_limit); + Error err = _load_data(p_path, lw, lh, image, request_3d, request_normal, request_roughness, mipmap_limit); if (err) { return err; } @@ -571,12 +571,12 @@ Error StreamTexture2D::load(const String &p_path) { } else { texture = RS::get_singleton()->texture_2d_create(image); } - if (lwc || lhc) { - RS::get_singleton()->texture_set_size_override(texture, lwc, lhc); + if (lw || lh) { + RS::get_singleton()->texture_set_size_override(texture, lw, lh); } - w = lwc ? lwc : lw; - h = lhc ? lhc : lh; + w = lw; + h = lh; path_to_file = p_path; format = image->get_format(); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 264d85d187..df8c00f8ff 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -158,7 +158,7 @@ public: }; private: - Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0); + Error _load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0); String path_to_file; mutable RID texture; Image::Format format = Image::FORMAT_MAX; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index e8b203417e..786a96501a 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -36,11 +36,11 @@ void Theme::_emit_theme_changed() { emit_changed(); } -Vector<String> Theme::_get_icon_list(const String &p_node_type) const { +Vector<String> Theme::_get_icon_list(const String &p_theme_type) const { Vector<String> ilret; List<StringName> il; - get_icon_list(p_node_type, &il); + get_icon_list(p_theme_type, &il); ilret.resize(il.size()); int i = 0; @@ -66,11 +66,11 @@ Vector<String> Theme::_get_icon_type_list() const { return ilret; } -Vector<String> Theme::_get_stylebox_list(const String &p_node_type) const { +Vector<String> Theme::_get_stylebox_list(const String &p_theme_type) const { Vector<String> ilret; List<StringName> il; - get_stylebox_list(p_node_type, &il); + get_stylebox_list(p_theme_type, &il); ilret.resize(il.size()); int i = 0; @@ -96,11 +96,11 @@ Vector<String> Theme::_get_stylebox_type_list() const { return ilret; } -Vector<String> Theme::_get_font_list(const String &p_node_type) const { +Vector<String> Theme::_get_font_list(const String &p_theme_type) const { Vector<String> ilret; List<StringName> il; - get_font_list(p_node_type, &il); + get_font_list(p_theme_type, &il); ilret.resize(il.size()); int i = 0; @@ -126,11 +126,11 @@ Vector<String> Theme::_get_font_type_list() const { return ilret; } -Vector<String> Theme::_get_font_size_list(const String &p_node_type) const { +Vector<String> Theme::_get_font_size_list(const String &p_theme_type) const { Vector<String> ilret; List<StringName> il; - get_font_size_list(p_node_type, &il); + get_font_size_list(p_theme_type, &il); ilret.resize(il.size()); int i = 0; @@ -156,11 +156,11 @@ Vector<String> Theme::_get_font_size_type_list() const { return ilret; } -Vector<String> Theme::_get_color_list(const String &p_node_type) const { +Vector<String> Theme::_get_color_list(const String &p_theme_type) const { Vector<String> ilret; List<StringName> il; - get_color_list(p_node_type, &il); + get_color_list(p_theme_type, &il); ilret.resize(il.size()); int i = 0; @@ -186,11 +186,11 @@ Vector<String> Theme::_get_color_type_list() const { return ilret; } -Vector<String> Theme::_get_constant_list(const String &p_node_type) const { +Vector<String> Theme::_get_constant_list(const String &p_theme_type) const { Vector<String> ilret; List<StringName> il; - get_constant_list(p_node_type, &il); + get_constant_list(p_theme_type, &il); ilret.resize(il.size()); int i = 0; @@ -216,20 +216,20 @@ Vector<String> Theme::_get_constant_type_list() const { return ilret; } -Vector<String> Theme::_get_theme_item_list(DataType p_data_type, const String &p_node_type) const { +Vector<String> Theme::_get_theme_item_list(DataType p_data_type, const String &p_theme_type) const { switch (p_data_type) { case DATA_TYPE_COLOR: - return _get_color_list(p_node_type); + return _get_color_list(p_theme_type); case DATA_TYPE_CONSTANT: - return _get_constant_list(p_node_type); + return _get_constant_list(p_theme_type); case DATA_TYPE_FONT: - return _get_font_list(p_node_type); + return _get_font_list(p_theme_type); case DATA_TYPE_FONT_SIZE: - return _get_font_size_list(p_node_type); + return _get_font_size_list(p_theme_type); case DATA_TYPE_ICON: - return _get_icon_list(p_node_type); + return _get_icon_list(p_theme_type); case DATA_TYPE_STYLEBOX: - return _get_stylebox_list(p_node_type); + return _get_stylebox_list(p_theme_type); case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } @@ -278,19 +278,19 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) { if (sname.find("/") != -1) { String type = sname.get_slicec('/', 1); - String node_type = sname.get_slicec('/', 0); + String theme_type = sname.get_slicec('/', 0); String name = sname.get_slicec('/', 2); if (type == "icons") { - set_icon(name, node_type, p_value); + set_icon(name, theme_type, p_value); } else if (type == "styles") { - set_stylebox(name, node_type, p_value); + set_stylebox(name, theme_type, p_value); } else if (type == "fonts") { - set_font(name, node_type, p_value); + set_font(name, theme_type, p_value); } else if (type == "colors") { - set_color(name, node_type, p_value); + set_color(name, theme_type, p_value); } else if (type == "constants") { - set_constant(name, node_type, p_value); + set_constant(name, theme_type, p_value); } else { return false; } @@ -306,31 +306,31 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const { if (sname.find("/") != -1) { String type = sname.get_slicec('/', 1); - String node_type = sname.get_slicec('/', 0); + String theme_type = sname.get_slicec('/', 0); String name = sname.get_slicec('/', 2); if (type == "icons") { - if (!has_icon(name, node_type)) { + if (!has_icon(name, theme_type)) { r_ret = Ref<Texture2D>(); } else { - r_ret = get_icon(name, node_type); + r_ret = get_icon(name, theme_type); } } else if (type == "styles") { - if (!has_stylebox(name, node_type)) { + if (!has_stylebox(name, theme_type)) { r_ret = Ref<StyleBox>(); } else { - r_ret = get_stylebox(name, node_type); + r_ret = get_stylebox(name, theme_type); } } else if (type == "fonts") { - if (!has_font(name, node_type)) { + if (!has_font(name, theme_type)) { r_ret = Ref<Font>(); } else { - r_ret = get_font(name, node_type); + r_ret = get_font(name, theme_type); } } else if (type == "colors") { - r_ret = get_color(name, node_type); + r_ret = get_color(name, theme_type); } else if (type == "constants") { - r_ret = get_constant(name, node_type); + r_ret = get_constant(name, theme_type); } else { return false; } @@ -477,17 +477,17 @@ void Theme::set_default_font_size(int p_font_size) { default_font_size = p_font_size; } -void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, const Ref<Texture2D> &p_icon) { - bool new_value = !icon_map.has(p_node_type) || !icon_map[p_node_type].has(p_name); +void Theme::set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon) { + bool new_value = !icon_map.has(p_theme_type) || !icon_map[p_theme_type].has(p_name); - if (icon_map[p_node_type].has(p_name) && icon_map[p_node_type][p_name].is_valid()) { - icon_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { + icon_map[p_theme_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - icon_map[p_node_type][p_name] = p_icon; + icon_map[p_theme_type][p_name] = p_icon; if (p_icon.is_valid()) { - icon_map[p_node_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); + icon_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) { @@ -496,64 +496,64 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, co } } -Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_node_type) const { - if (icon_map.has(p_node_type) && icon_map[p_node_type].has(p_name) && icon_map[p_node_type][p_name].is_valid()) { - return icon_map[p_node_type][p_name]; +Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { + return icon_map[p_theme_type][p_name]; } else { return default_icon; } } -bool Theme::has_icon(const StringName &p_name, const StringName &p_node_type) const { - return (icon_map.has(p_node_type) && icon_map[p_node_type].has(p_name) && icon_map[p_node_type][p_name].is_valid()); +bool Theme::has_icon(const StringName &p_name, const StringName &p_theme_type) const { + return (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()); } -bool Theme::has_icon_nocheck(const StringName &p_name, const StringName &p_node_type) const { - return (icon_map.has(p_node_type) && icon_map[p_node_type].has(p_name)); +bool Theme::has_icon_nocheck(const StringName &p_name, const StringName &p_theme_type) const { + return (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name)); } -void Theme::rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!icon_map.has(p_node_type), "Cannot rename the icon '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(icon_map[p_node_type].has(p_name), "Cannot rename the icon '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); - ERR_FAIL_COND_MSG(!icon_map[p_node_type].has(p_old_name), "Cannot rename the icon '" + String(p_old_name) + "' because it does not exist."); +void Theme::rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!icon_map.has(p_theme_type), "Cannot rename the icon '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(icon_map[p_theme_type].has(p_name), "Cannot rename the icon '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); + ERR_FAIL_COND_MSG(!icon_map[p_theme_type].has(p_old_name), "Cannot rename the icon '" + String(p_old_name) + "' because it does not exist."); - icon_map[p_node_type][p_name] = icon_map[p_node_type][p_old_name]; - icon_map[p_node_type].erase(p_old_name); + icon_map[p_theme_type][p_name] = icon_map[p_theme_type][p_old_name]; + icon_map[p_theme_type].erase(p_old_name); notify_property_list_changed(); emit_changed(); } -void Theme::clear_icon(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!icon_map.has(p_node_type), "Cannot clear the icon '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(!icon_map[p_node_type].has(p_name), "Cannot clear the icon '" + String(p_name) + "' because it does not exist."); +void Theme::clear_icon(const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!icon_map.has(p_theme_type), "Cannot clear the icon '" + String(p_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(!icon_map[p_theme_type].has(p_name), "Cannot clear the icon '" + String(p_name) + "' because it does not exist."); - if (icon_map[p_node_type][p_name].is_valid()) { - icon_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (icon_map[p_theme_type][p_name].is_valid()) { + icon_map[p_theme_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - icon_map[p_node_type].erase(p_name); + icon_map[p_theme_type].erase(p_name); notify_property_list_changed(); emit_changed(); } -void Theme::get_icon_list(StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_icon_list(StringName p_theme_type, List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!icon_map.has(p_node_type)) { + if (!icon_map.has(p_theme_type)) { return; } const StringName *key = nullptr; - while ((key = icon_map[p_node_type].next(key))) { + while ((key = icon_map[p_theme_type].next(key))) { p_list->push_back(*key); } } -void Theme::add_icon_type(const StringName &p_node_type) { - icon_map[p_node_type] = HashMap<StringName, Ref<Texture2D>>(); +void Theme::add_icon_type(const StringName &p_theme_type) { + icon_map[p_theme_type] = HashMap<StringName, Ref<Texture2D>>(); } void Theme::get_icon_type_list(List<StringName> *p_list) const { @@ -565,17 +565,17 @@ void Theme::get_icon_type_list(List<StringName> *p_list) const { } } -void Theme::set_stylebox(const StringName &p_name, const StringName &p_node_type, const Ref<StyleBox> &p_style) { - bool new_value = !style_map.has(p_node_type) || !style_map[p_node_type].has(p_name); +void Theme::set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style) { + bool new_value = !style_map.has(p_theme_type) || !style_map[p_theme_type].has(p_name); - if (style_map[p_node_type].has(p_name) && style_map[p_node_type][p_name].is_valid()) { - style_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { + style_map[p_theme_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - style_map[p_node_type][p_name] = p_style; + style_map[p_theme_type][p_name] = p_style; if (p_style.is_valid()) { - style_map[p_node_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); + style_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) { @@ -584,64 +584,64 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_node_type emit_changed(); } -Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_node_type) const { - if (style_map.has(p_node_type) && style_map[p_node_type].has(p_name) && style_map[p_node_type][p_name].is_valid()) { - return style_map[p_node_type][p_name]; +Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { + return style_map[p_theme_type][p_name]; } else { return default_style; } } -bool Theme::has_stylebox(const StringName &p_name, const StringName &p_node_type) const { - return (style_map.has(p_node_type) && style_map[p_node_type].has(p_name) && style_map[p_node_type][p_name].is_valid()); +bool Theme::has_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + return (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()); } -bool Theme::has_stylebox_nocheck(const StringName &p_name, const StringName &p_node_type) const { - return (style_map.has(p_node_type) && style_map[p_node_type].has(p_name)); +bool Theme::has_stylebox_nocheck(const StringName &p_name, const StringName &p_theme_type) const { + return (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name)); } -void Theme::rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!style_map.has(p_node_type), "Cannot rename the stylebox '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(style_map[p_node_type].has(p_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); - ERR_FAIL_COND_MSG(!style_map[p_node_type].has(p_old_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because it does not exist."); +void Theme::rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!style_map.has(p_theme_type), "Cannot rename the stylebox '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(style_map[p_theme_type].has(p_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); + ERR_FAIL_COND_MSG(!style_map[p_theme_type].has(p_old_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because it does not exist."); - style_map[p_node_type][p_name] = style_map[p_node_type][p_old_name]; - style_map[p_node_type].erase(p_old_name); + style_map[p_theme_type][p_name] = style_map[p_theme_type][p_old_name]; + style_map[p_theme_type].erase(p_old_name); notify_property_list_changed(); emit_changed(); } -void Theme::clear_stylebox(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!style_map.has(p_node_type), "Cannot clear the stylebox '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(!style_map[p_node_type].has(p_name), "Cannot clear the stylebox '" + String(p_name) + "' because it does not exist."); +void Theme::clear_stylebox(const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!style_map.has(p_theme_type), "Cannot clear the stylebox '" + String(p_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(!style_map[p_theme_type].has(p_name), "Cannot clear the stylebox '" + String(p_name) + "' because it does not exist."); - if (style_map[p_node_type][p_name].is_valid()) { - style_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (style_map[p_theme_type][p_name].is_valid()) { + style_map[p_theme_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - style_map[p_node_type].erase(p_name); + style_map[p_theme_type].erase(p_name); notify_property_list_changed(); emit_changed(); } -void Theme::get_stylebox_list(StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_stylebox_list(StringName p_theme_type, List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!style_map.has(p_node_type)) { + if (!style_map.has(p_theme_type)) { return; } const StringName *key = nullptr; - while ((key = style_map[p_node_type].next(key))) { + while ((key = style_map[p_theme_type].next(key))) { p_list->push_back(*key); } } -void Theme::add_stylebox_type(const StringName &p_node_type) { - style_map[p_node_type] = HashMap<StringName, Ref<StyleBox>>(); +void Theme::add_stylebox_type(const StringName &p_theme_type) { + style_map[p_theme_type] = HashMap<StringName, Ref<StyleBox>>(); } void Theme::get_stylebox_type_list(List<StringName> *p_list) const { @@ -653,17 +653,17 @@ void Theme::get_stylebox_type_list(List<StringName> *p_list) const { } } -void Theme::set_font(const StringName &p_name, const StringName &p_node_type, const Ref<Font> &p_font) { - bool new_value = !font_map.has(p_node_type) || !font_map[p_node_type].has(p_name); +void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font) { + bool new_value = !font_map.has(p_theme_type) || !font_map[p_theme_type].has(p_name); - if (font_map[p_node_type][p_name].is_valid()) { - font_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (font_map[p_theme_type][p_name].is_valid()) { + font_map[p_theme_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - font_map[p_node_type][p_name] = p_font; + font_map[p_theme_type][p_name] = p_font; if (p_font.is_valid()) { - font_map[p_node_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); + font_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) { @@ -672,9 +672,9 @@ void Theme::set_font(const StringName &p_name, const StringName &p_node_type, co } } -Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_node_type) const { - if (font_map.has(p_node_type) && font_map[p_node_type].has(p_name) && font_map[p_node_type][p_name].is_valid()) { - return font_map[p_node_type][p_name]; +Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_type) const { + if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) { + return font_map[p_theme_type][p_name]; } else if (default_theme_font.is_valid()) { return default_theme_font; } else { @@ -682,55 +682,55 @@ Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_node_typ } } -bool Theme::has_font(const StringName &p_name, const StringName &p_node_type) const { - return ((font_map.has(p_node_type) && font_map[p_node_type].has(p_name) && font_map[p_node_type][p_name].is_valid()) || default_theme_font.is_valid()); +bool Theme::has_font(const StringName &p_name, const StringName &p_theme_type) const { + return ((font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) || default_theme_font.is_valid()); } -bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_node_type) const { - return (font_map.has(p_node_type) && font_map[p_node_type].has(p_name)); +bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const { + return (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name)); } -void Theme::rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!font_map.has(p_node_type), "Cannot rename the font '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(font_map[p_node_type].has(p_name), "Cannot rename the font '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); - ERR_FAIL_COND_MSG(!font_map[p_node_type].has(p_old_name), "Cannot rename the font '" + String(p_old_name) + "' because it does not exist."); +void Theme::rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!font_map.has(p_theme_type), "Cannot rename the font '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(font_map[p_theme_type].has(p_name), "Cannot rename the font '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); + ERR_FAIL_COND_MSG(!font_map[p_theme_type].has(p_old_name), "Cannot rename the font '" + String(p_old_name) + "' because it does not exist."); - font_map[p_node_type][p_name] = font_map[p_node_type][p_old_name]; - font_map[p_node_type].erase(p_old_name); + font_map[p_theme_type][p_name] = font_map[p_theme_type][p_old_name]; + font_map[p_theme_type].erase(p_old_name); notify_property_list_changed(); emit_changed(); } -void Theme::clear_font(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!font_map.has(p_node_type), "Cannot clear the font '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(!font_map[p_node_type].has(p_name), "Cannot clear the font '" + String(p_name) + "' because it does not exist."); +void Theme::clear_font(const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!font_map.has(p_theme_type), "Cannot clear the font '" + String(p_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(!font_map[p_theme_type].has(p_name), "Cannot clear the font '" + String(p_name) + "' because it does not exist."); - if (font_map[p_node_type][p_name].is_valid()) { - font_map[p_node_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + if (font_map[p_theme_type][p_name].is_valid()) { + font_map[p_theme_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } - font_map[p_node_type].erase(p_name); + font_map[p_theme_type].erase(p_name); notify_property_list_changed(); emit_changed(); } -void Theme::get_font_list(StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_font_list(StringName p_theme_type, List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!font_map.has(p_node_type)) { + if (!font_map.has(p_theme_type)) { return; } const StringName *key = nullptr; - while ((key = font_map[p_node_type].next(key))) { + while ((key = font_map[p_theme_type].next(key))) { p_list->push_back(*key); } } -void Theme::add_font_type(const StringName &p_node_type) { - font_map[p_node_type] = HashMap<StringName, Ref<Font>>(); +void Theme::add_font_type(const StringName &p_theme_type) { + font_map[p_theme_type] = HashMap<StringName, Ref<Font>>(); } void Theme::get_font_type_list(List<StringName> *p_list) const { @@ -742,10 +742,10 @@ void Theme::get_font_type_list(List<StringName> *p_list) const { } } -void Theme::set_font_size(const StringName &p_name, const StringName &p_node_type, int p_font_size) { - bool new_value = !font_size_map.has(p_node_type) || !font_size_map[p_node_type].has(p_name); +void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size) { + bool new_value = !font_size_map.has(p_theme_type) || !font_size_map[p_theme_type].has(p_name); - font_size_map[p_node_type][p_name] = p_font_size; + font_size_map[p_theme_type][p_name] = p_font_size; if (new_value) { notify_property_list_changed(); @@ -753,9 +753,9 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_node_typ } } -int Theme::get_font_size(const StringName &p_name, const StringName &p_node_type) const { - if (font_size_map.has(p_node_type) && font_size_map[p_node_type].has(p_name) && (font_size_map[p_node_type][p_name] > 0)) { - return font_size_map[p_node_type][p_name]; +int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) { + return font_size_map[p_theme_type][p_name]; } else if (default_theme_font_size > 0) { return default_theme_font_size; } else { @@ -763,51 +763,51 @@ int Theme::get_font_size(const StringName &p_name, const StringName &p_node_type } } -bool Theme::has_font_size(const StringName &p_name, const StringName &p_node_type) const { - return ((font_size_map.has(p_node_type) && font_size_map[p_node_type].has(p_name) && (font_size_map[p_node_type][p_name] > 0)) || (default_theme_font_size > 0)); +bool Theme::has_font_size(const StringName &p_name, const StringName &p_theme_type) const { + return ((font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) || (default_theme_font_size > 0)); } -bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_node_type) const { - return (font_size_map.has(p_node_type) && font_size_map[p_node_type].has(p_name)); +bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const { + return (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name)); } -void Theme::rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!font_size_map.has(p_node_type), "Cannot rename the font size '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(font_size_map[p_node_type].has(p_name), "Cannot rename the font size '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); - ERR_FAIL_COND_MSG(!font_size_map[p_node_type].has(p_old_name), "Cannot rename the font size '" + String(p_old_name) + "' because it does not exist."); +void Theme::rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!font_size_map.has(p_theme_type), "Cannot rename the font size '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(font_size_map[p_theme_type].has(p_name), "Cannot rename the font size '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); + ERR_FAIL_COND_MSG(!font_size_map[p_theme_type].has(p_old_name), "Cannot rename the font size '" + String(p_old_name) + "' because it does not exist."); - font_size_map[p_node_type][p_name] = font_size_map[p_node_type][p_old_name]; - font_size_map[p_node_type].erase(p_old_name); + font_size_map[p_theme_type][p_name] = font_size_map[p_theme_type][p_old_name]; + font_size_map[p_theme_type].erase(p_old_name); notify_property_list_changed(); emit_changed(); } -void Theme::clear_font_size(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!font_size_map.has(p_node_type), "Cannot clear the font size '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(!font_size_map[p_node_type].has(p_name), "Cannot clear the font size '" + String(p_name) + "' because it does not exist."); +void Theme::clear_font_size(const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!font_size_map.has(p_theme_type), "Cannot clear the font size '" + String(p_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(!font_size_map[p_theme_type].has(p_name), "Cannot clear the font size '" + String(p_name) + "' because it does not exist."); - font_size_map[p_node_type].erase(p_name); + font_size_map[p_theme_type].erase(p_name); notify_property_list_changed(); emit_changed(); } -void Theme::get_font_size_list(StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_font_size_list(StringName p_theme_type, List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!font_size_map.has(p_node_type)) { + if (!font_size_map.has(p_theme_type)) { return; } const StringName *key = nullptr; - while ((key = font_size_map[p_node_type].next(key))) { + while ((key = font_size_map[p_theme_type].next(key))) { p_list->push_back(*key); } } -void Theme::add_font_size_type(const StringName &p_node_type) { - font_size_map[p_node_type] = HashMap<StringName, int>(); +void Theme::add_font_size_type(const StringName &p_theme_type) { + font_size_map[p_theme_type] = HashMap<StringName, int>(); } void Theme::get_font_size_type_list(List<StringName> *p_list) const { @@ -819,10 +819,10 @@ void Theme::get_font_size_type_list(List<StringName> *p_list) const { } } -void Theme::set_color(const StringName &p_name, const StringName &p_node_type, const Color &p_color) { - bool new_value = !color_map.has(p_node_type) || !color_map[p_node_type].has(p_name); +void Theme::set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color) { + bool new_value = !color_map.has(p_theme_type) || !color_map[p_theme_type].has(p_name); - color_map[p_node_type][p_name] = p_color; + color_map[p_theme_type][p_name] = p_color; if (new_value) { notify_property_list_changed(); @@ -830,59 +830,59 @@ void Theme::set_color(const StringName &p_name, const StringName &p_node_type, c } } -Color Theme::get_color(const StringName &p_name, const StringName &p_node_type) const { - if (color_map.has(p_node_type) && color_map[p_node_type].has(p_name)) { - return color_map[p_node_type][p_name]; +Color Theme::get_color(const StringName &p_name, const StringName &p_theme_type) const { + if (color_map.has(p_theme_type) && color_map[p_theme_type].has(p_name)) { + return color_map[p_theme_type][p_name]; } else { return Color(); } } -bool Theme::has_color(const StringName &p_name, const StringName &p_node_type) const { - return (color_map.has(p_node_type) && color_map[p_node_type].has(p_name)); +bool Theme::has_color(const StringName &p_name, const StringName &p_theme_type) const { + return (color_map.has(p_theme_type) && color_map[p_theme_type].has(p_name)); } -bool Theme::has_color_nocheck(const StringName &p_name, const StringName &p_node_type) const { - return (color_map.has(p_node_type) && color_map[p_node_type].has(p_name)); +bool Theme::has_color_nocheck(const StringName &p_name, const StringName &p_theme_type) const { + return (color_map.has(p_theme_type) && color_map[p_theme_type].has(p_name)); } -void Theme::rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!color_map.has(p_node_type), "Cannot rename the color '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(color_map[p_node_type].has(p_name), "Cannot rename the color '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); - ERR_FAIL_COND_MSG(!color_map[p_node_type].has(p_old_name), "Cannot rename the color '" + String(p_old_name) + "' because it does not exist."); +void Theme::rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!color_map.has(p_theme_type), "Cannot rename the color '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(color_map[p_theme_type].has(p_name), "Cannot rename the color '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); + ERR_FAIL_COND_MSG(!color_map[p_theme_type].has(p_old_name), "Cannot rename the color '" + String(p_old_name) + "' because it does not exist."); - color_map[p_node_type][p_name] = color_map[p_node_type][p_old_name]; - color_map[p_node_type].erase(p_old_name); + color_map[p_theme_type][p_name] = color_map[p_theme_type][p_old_name]; + color_map[p_theme_type].erase(p_old_name); notify_property_list_changed(); emit_changed(); } -void Theme::clear_color(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!color_map.has(p_node_type), "Cannot clear the color '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(!color_map[p_node_type].has(p_name), "Cannot clear the color '" + String(p_name) + "' because it does not exist."); +void Theme::clear_color(const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!color_map.has(p_theme_type), "Cannot clear the color '" + String(p_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(!color_map[p_theme_type].has(p_name), "Cannot clear the color '" + String(p_name) + "' because it does not exist."); - color_map[p_node_type].erase(p_name); + color_map[p_theme_type].erase(p_name); notify_property_list_changed(); emit_changed(); } -void Theme::get_color_list(StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_color_list(StringName p_theme_type, List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!color_map.has(p_node_type)) { + if (!color_map.has(p_theme_type)) { return; } const StringName *key = nullptr; - while ((key = color_map[p_node_type].next(key))) { + while ((key = color_map[p_theme_type].next(key))) { p_list->push_back(*key); } } -void Theme::add_color_type(const StringName &p_node_type) { - color_map[p_node_type] = HashMap<StringName, Color>(); +void Theme::add_color_type(const StringName &p_theme_type) { + color_map[p_theme_type] = HashMap<StringName, Color>(); } void Theme::get_color_type_list(List<StringName> *p_list) const { @@ -894,9 +894,9 @@ void Theme::get_color_type_list(List<StringName> *p_list) const { } } -void Theme::set_constant(const StringName &p_name, const StringName &p_node_type, int p_constant) { - bool new_value = !constant_map.has(p_node_type) || !constant_map[p_node_type].has(p_name); - constant_map[p_node_type][p_name] = p_constant; +void Theme::set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant) { + bool new_value = !constant_map.has(p_theme_type) || !constant_map[p_theme_type].has(p_name); + constant_map[p_theme_type][p_name] = p_constant; if (new_value) { notify_property_list_changed(); @@ -904,59 +904,59 @@ void Theme::set_constant(const StringName &p_name, const StringName &p_node_type } } -int Theme::get_constant(const StringName &p_name, const StringName &p_node_type) const { - if (constant_map.has(p_node_type) && constant_map[p_node_type].has(p_name)) { - return constant_map[p_node_type][p_name]; +int Theme::get_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (constant_map.has(p_theme_type) && constant_map[p_theme_type].has(p_name)) { + return constant_map[p_theme_type][p_name]; } else { return 0; } } -bool Theme::has_constant(const StringName &p_name, const StringName &p_node_type) const { - return (constant_map.has(p_node_type) && constant_map[p_node_type].has(p_name)); +bool Theme::has_constant(const StringName &p_name, const StringName &p_theme_type) const { + return (constant_map.has(p_theme_type) && constant_map[p_theme_type].has(p_name)); } -bool Theme::has_constant_nocheck(const StringName &p_name, const StringName &p_node_type) const { - return (constant_map.has(p_node_type) && constant_map[p_node_type].has(p_name)); +bool Theme::has_constant_nocheck(const StringName &p_name, const StringName &p_theme_type) const { + return (constant_map.has(p_theme_type) && constant_map[p_theme_type].has(p_name)); } -void Theme::rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!constant_map.has(p_node_type), "Cannot rename the constant '" + String(p_old_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(constant_map[p_node_type].has(p_name), "Cannot rename the constant '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); - ERR_FAIL_COND_MSG(!constant_map[p_node_type].has(p_old_name), "Cannot rename the constant '" + String(p_old_name) + "' because it does not exist."); +void Theme::rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!constant_map.has(p_theme_type), "Cannot rename the constant '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(constant_map[p_theme_type].has(p_name), "Cannot rename the constant '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); + ERR_FAIL_COND_MSG(!constant_map[p_theme_type].has(p_old_name), "Cannot rename the constant '" + String(p_old_name) + "' because it does not exist."); - constant_map[p_node_type][p_name] = constant_map[p_node_type][p_old_name]; - constant_map[p_node_type].erase(p_old_name); + constant_map[p_theme_type][p_name] = constant_map[p_theme_type][p_old_name]; + constant_map[p_theme_type].erase(p_old_name); notify_property_list_changed(); emit_changed(); } -void Theme::clear_constant(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND_MSG(!constant_map.has(p_node_type), "Cannot clear the constant '" + String(p_name) + "' because the node type '" + String(p_node_type) + "' does not exist."); - ERR_FAIL_COND_MSG(!constant_map[p_node_type].has(p_name), "Cannot clear the constant '" + String(p_name) + "' because it does not exist."); +void Theme::clear_constant(const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!constant_map.has(p_theme_type), "Cannot clear the constant '" + String(p_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); + ERR_FAIL_COND_MSG(!constant_map[p_theme_type].has(p_name), "Cannot clear the constant '" + String(p_name) + "' because it does not exist."); - constant_map[p_node_type].erase(p_name); + constant_map[p_theme_type].erase(p_name); notify_property_list_changed(); emit_changed(); } -void Theme::get_constant_list(StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_constant_list(StringName p_theme_type, List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!constant_map.has(p_node_type)) { + if (!constant_map.has(p_theme_type)) { return; } const StringName *key = nullptr; - while ((key = constant_map[p_node_type].next(key))) { + while ((key = constant_map[p_theme_type].next(key))) { p_list->push_back(*key); } } -void Theme::add_constant_type(const StringName &p_node_type) { - constant_map[p_node_type] = HashMap<StringName, int>(); +void Theme::add_constant_type(const StringName &p_theme_type) { + constant_map[p_theme_type] = HashMap<StringName, int>(); } void Theme::get_constant_type_list(List<StringName> *p_list) const { @@ -968,63 +968,63 @@ void Theme::get_constant_type_list(List<StringName> *p_list) const { } } -void Theme::set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type, const Variant &p_value) { +void Theme::set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type, const Variant &p_value) { switch (p_data_type) { case DATA_TYPE_COLOR: { ERR_FAIL_COND_MSG(p_value.get_type() != Variant::COLOR, "Theme item's data type (Color) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ")."); Color color_value = p_value; - set_color(p_name, p_node_type, color_value); + set_color(p_name, p_theme_type, color_value); } break; case DATA_TYPE_CONSTANT: { ERR_FAIL_COND_MSG(p_value.get_type() != Variant::INT, "Theme item's data type (int) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ")."); int constant_value = p_value; - set_constant(p_name, p_node_type, constant_value); + set_constant(p_name, p_theme_type, constant_value); } break; case DATA_TYPE_FONT: { ERR_FAIL_COND_MSG(p_value.get_type() != Variant::OBJECT, "Theme item's data type (Object) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ")."); Ref<Font> font_value = Object::cast_to<Font>(p_value.get_validated_object()); - set_font(p_name, p_node_type, font_value); + set_font(p_name, p_theme_type, font_value); } break; case DATA_TYPE_FONT_SIZE: { ERR_FAIL_COND_MSG(p_value.get_type() != Variant::INT, "Theme item's data type (int) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ")."); int font_size_value = p_value; - set_font_size(p_name, p_node_type, font_size_value); + set_font_size(p_name, p_theme_type, font_size_value); } break; case DATA_TYPE_ICON: { ERR_FAIL_COND_MSG(p_value.get_type() != Variant::OBJECT, "Theme item's data type (Object) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ")."); Ref<Texture2D> icon_value = Object::cast_to<Texture2D>(p_value.get_validated_object()); - set_icon(p_name, p_node_type, icon_value); + set_icon(p_name, p_theme_type, icon_value); } break; case DATA_TYPE_STYLEBOX: { ERR_FAIL_COND_MSG(p_value.get_type() != Variant::OBJECT, "Theme item's data type (Object) does not match Variant's type (" + Variant::get_type_name(p_value.get_type()) + ")."); Ref<StyleBox> stylebox_value = Object::cast_to<StyleBox>(p_value.get_validated_object()); - set_stylebox(p_name, p_node_type, stylebox_value); + set_stylebox(p_name, p_theme_type, stylebox_value); } break; case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } } -Variant Theme::get_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const { +Variant Theme::get_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const { switch (p_data_type) { case DATA_TYPE_COLOR: - return get_color(p_name, p_node_type); + return get_color(p_name, p_theme_type); case DATA_TYPE_CONSTANT: - return get_constant(p_name, p_node_type); + return get_constant(p_name, p_theme_type); case DATA_TYPE_FONT: - return get_font(p_name, p_node_type); + return get_font(p_name, p_theme_type); case DATA_TYPE_FONT_SIZE: - return get_font_size(p_name, p_node_type); + return get_font_size(p_name, p_theme_type); case DATA_TYPE_ICON: - return get_icon(p_name, p_node_type); + return get_icon(p_name, p_theme_type); case DATA_TYPE_STYLEBOX: - return get_stylebox(p_name, p_node_type); + return get_stylebox(p_name, p_theme_type); case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } @@ -1032,20 +1032,20 @@ Variant Theme::get_theme_item(DataType p_data_type, const StringName &p_name, co return Variant(); } -bool Theme::has_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const { +bool Theme::has_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const { switch (p_data_type) { case DATA_TYPE_COLOR: - return has_color(p_name, p_node_type); + return has_color(p_name, p_theme_type); case DATA_TYPE_CONSTANT: - return has_constant(p_name, p_node_type); + return has_constant(p_name, p_theme_type); case DATA_TYPE_FONT: - return has_font(p_name, p_node_type); + return has_font(p_name, p_theme_type); case DATA_TYPE_FONT_SIZE: - return has_font_size(p_name, p_node_type); + return has_font_size(p_name, p_theme_type); case DATA_TYPE_ICON: - return has_icon(p_name, p_node_type); + return has_icon(p_name, p_theme_type); case DATA_TYPE_STYLEBOX: - return has_stylebox(p_name, p_node_type); + return has_stylebox(p_name, p_theme_type); case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } @@ -1053,20 +1053,20 @@ bool Theme::has_theme_item(DataType p_data_type, const StringName &p_name, const return false; } -bool Theme::has_theme_item_nocheck(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const { +bool Theme::has_theme_item_nocheck(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const { switch (p_data_type) { case DATA_TYPE_COLOR: - return has_color_nocheck(p_name, p_node_type); + return has_color_nocheck(p_name, p_theme_type); case DATA_TYPE_CONSTANT: - return has_constant_nocheck(p_name, p_node_type); + return has_constant_nocheck(p_name, p_theme_type); case DATA_TYPE_FONT: - return has_font_nocheck(p_name, p_node_type); + return has_font_nocheck(p_name, p_theme_type); case DATA_TYPE_FONT_SIZE: - return has_font_size_nocheck(p_name, p_node_type); + return has_font_size_nocheck(p_name, p_theme_type); case DATA_TYPE_ICON: - return has_icon_nocheck(p_name, p_node_type); + return has_icon_nocheck(p_name, p_theme_type); case DATA_TYPE_STYLEBOX: - return has_stylebox_nocheck(p_name, p_node_type); + return has_stylebox_nocheck(p_name, p_theme_type); case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } @@ -1074,100 +1074,100 @@ bool Theme::has_theme_item_nocheck(DataType p_data_type, const StringName &p_nam return false; } -void Theme::rename_theme_item(DataType p_data_type, const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type) { +void Theme::rename_theme_item(DataType p_data_type, const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { switch (p_data_type) { case DATA_TYPE_COLOR: - rename_color(p_old_name, p_name, p_node_type); + rename_color(p_old_name, p_name, p_theme_type); break; case DATA_TYPE_CONSTANT: - rename_constant(p_old_name, p_name, p_node_type); + rename_constant(p_old_name, p_name, p_theme_type); break; case DATA_TYPE_FONT: - rename_font(p_old_name, p_name, p_node_type); + rename_font(p_old_name, p_name, p_theme_type); break; case DATA_TYPE_FONT_SIZE: - rename_font_size(p_old_name, p_name, p_node_type); + rename_font_size(p_old_name, p_name, p_theme_type); break; case DATA_TYPE_ICON: - rename_icon(p_old_name, p_name, p_node_type); + rename_icon(p_old_name, p_name, p_theme_type); break; case DATA_TYPE_STYLEBOX: - rename_stylebox(p_old_name, p_name, p_node_type); + rename_stylebox(p_old_name, p_name, p_theme_type); break; case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } } -void Theme::clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) { +void Theme::clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) { switch (p_data_type) { case DATA_TYPE_COLOR: - clear_color(p_name, p_node_type); + clear_color(p_name, p_theme_type); break; case DATA_TYPE_CONSTANT: - clear_constant(p_name, p_node_type); + clear_constant(p_name, p_theme_type); break; case DATA_TYPE_FONT: - clear_font(p_name, p_node_type); + clear_font(p_name, p_theme_type); break; case DATA_TYPE_FONT_SIZE: - clear_font_size(p_name, p_node_type); + clear_font_size(p_name, p_theme_type); break; case DATA_TYPE_ICON: - clear_icon(p_name, p_node_type); + clear_icon(p_name, p_theme_type); break; case DATA_TYPE_STYLEBOX: - clear_stylebox(p_name, p_node_type); + clear_stylebox(p_name, p_theme_type); break; case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } } -void Theme::get_theme_item_list(DataType p_data_type, StringName p_node_type, List<StringName> *p_list) const { +void Theme::get_theme_item_list(DataType p_data_type, StringName p_theme_type, List<StringName> *p_list) const { switch (p_data_type) { case DATA_TYPE_COLOR: - get_color_list(p_node_type, p_list); + get_color_list(p_theme_type, p_list); break; case DATA_TYPE_CONSTANT: - get_constant_list(p_node_type, p_list); + get_constant_list(p_theme_type, p_list); break; case DATA_TYPE_FONT: - get_font_list(p_node_type, p_list); + get_font_list(p_theme_type, p_list); break; case DATA_TYPE_FONT_SIZE: - get_font_size_list(p_node_type, p_list); + get_font_size_list(p_theme_type, p_list); break; case DATA_TYPE_ICON: - get_icon_list(p_node_type, p_list); + get_icon_list(p_theme_type, p_list); break; case DATA_TYPE_STYLEBOX: - get_stylebox_list(p_node_type, p_list); + get_stylebox_list(p_theme_type, p_list); break; case DATA_TYPE_MAX: break; // Can't happen, but silences warning. } } -void Theme::add_theme_item_type(DataType p_data_type, const StringName &p_node_type) { +void Theme::add_theme_item_type(DataType p_data_type, const StringName &p_theme_type) { switch (p_data_type) { case DATA_TYPE_COLOR: - add_color_type(p_node_type); + add_color_type(p_theme_type); break; case DATA_TYPE_CONSTANT: - add_constant_type(p_node_type); + add_constant_type(p_theme_type); break; case DATA_TYPE_FONT: - add_font_type(p_node_type); + add_font_type(p_theme_type); break; case DATA_TYPE_FONT_SIZE: - add_font_size_type(p_node_type); + add_font_size_type(p_theme_type); break; case DATA_TYPE_ICON: - add_icon_type(p_node_type); + add_icon_type(p_theme_type); break; case DATA_TYPE_STYLEBOX: - add_stylebox_type(p_node_type); + add_stylebox_type(p_theme_type); break; case DATA_TYPE_MAX: break; // Can't happen, but silences warning. @@ -1340,56 +1340,66 @@ void Theme::get_type_list(List<StringName> *p_list) const { } } +void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) { + ERR_FAIL_NULL(p_list); + + StringName class_name = p_theme_type; + while (class_name != StringName()) { + p_list->push_back(class_name); + class_name = ClassDB::get_parent_class_nocheck(class_name); + } +} + void Theme::reset_state() { clear(); } void Theme::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_icon", "name", "node_type", "texture"), &Theme::set_icon); - ClassDB::bind_method(D_METHOD("get_icon", "name", "node_type"), &Theme::get_icon); - ClassDB::bind_method(D_METHOD("has_icon", "name", "node_type"), &Theme::has_icon); - ClassDB::bind_method(D_METHOD("rename_icon", "old_name", "name", "node_type"), &Theme::rename_icon); - ClassDB::bind_method(D_METHOD("clear_icon", "name", "node_type"), &Theme::clear_icon); - ClassDB::bind_method(D_METHOD("get_icon_list", "node_type"), &Theme::_get_icon_list); + ClassDB::bind_method(D_METHOD("set_icon", "name", "theme_type", "texture"), &Theme::set_icon); + ClassDB::bind_method(D_METHOD("get_icon", "name", "theme_type"), &Theme::get_icon); + ClassDB::bind_method(D_METHOD("has_icon", "name", "theme_type"), &Theme::has_icon); + ClassDB::bind_method(D_METHOD("rename_icon", "old_name", "name", "theme_type"), &Theme::rename_icon); + ClassDB::bind_method(D_METHOD("clear_icon", "name", "theme_type"), &Theme::clear_icon); + ClassDB::bind_method(D_METHOD("get_icon_list", "theme_type"), &Theme::_get_icon_list); ClassDB::bind_method(D_METHOD("get_icon_type_list"), &Theme::_get_icon_type_list); - ClassDB::bind_method(D_METHOD("set_stylebox", "name", "node_type", "texture"), &Theme::set_stylebox); - ClassDB::bind_method(D_METHOD("get_stylebox", "name", "node_type"), &Theme::get_stylebox); - ClassDB::bind_method(D_METHOD("has_stylebox", "name", "node_type"), &Theme::has_stylebox); - ClassDB::bind_method(D_METHOD("rename_stylebox", "old_name", "name", "node_type"), &Theme::rename_stylebox); - ClassDB::bind_method(D_METHOD("clear_stylebox", "name", "node_type"), &Theme::clear_stylebox); - ClassDB::bind_method(D_METHOD("get_stylebox_list", "node_type"), &Theme::_get_stylebox_list); + ClassDB::bind_method(D_METHOD("set_stylebox", "name", "theme_type", "texture"), &Theme::set_stylebox); + ClassDB::bind_method(D_METHOD("get_stylebox", "name", "theme_type"), &Theme::get_stylebox); + ClassDB::bind_method(D_METHOD("has_stylebox", "name", "theme_type"), &Theme::has_stylebox); + ClassDB::bind_method(D_METHOD("rename_stylebox", "old_name", "name", "theme_type"), &Theme::rename_stylebox); + ClassDB::bind_method(D_METHOD("clear_stylebox", "name", "theme_type"), &Theme::clear_stylebox); + ClassDB::bind_method(D_METHOD("get_stylebox_list", "theme_type"), &Theme::_get_stylebox_list); ClassDB::bind_method(D_METHOD("get_stylebox_type_list"), &Theme::_get_stylebox_type_list); - ClassDB::bind_method(D_METHOD("set_font", "name", "node_type", "font"), &Theme::set_font); - ClassDB::bind_method(D_METHOD("get_font", "name", "node_type"), &Theme::get_font); - ClassDB::bind_method(D_METHOD("has_font", "name", "node_type"), &Theme::has_font); - ClassDB::bind_method(D_METHOD("rename_font", "old_name", "name", "node_type"), &Theme::rename_font); - ClassDB::bind_method(D_METHOD("clear_font", "name", "node_type"), &Theme::clear_font); - ClassDB::bind_method(D_METHOD("get_font_list", "node_type"), &Theme::_get_font_list); + ClassDB::bind_method(D_METHOD("set_font", "name", "theme_type", "font"), &Theme::set_font); + ClassDB::bind_method(D_METHOD("get_font", "name", "theme_type"), &Theme::get_font); + ClassDB::bind_method(D_METHOD("has_font", "name", "theme_type"), &Theme::has_font); + ClassDB::bind_method(D_METHOD("rename_font", "old_name", "name", "theme_type"), &Theme::rename_font); + ClassDB::bind_method(D_METHOD("clear_font", "name", "theme_type"), &Theme::clear_font); + ClassDB::bind_method(D_METHOD("get_font_list", "theme_type"), &Theme::_get_font_list); ClassDB::bind_method(D_METHOD("get_font_type_list"), &Theme::_get_font_type_list); - ClassDB::bind_method(D_METHOD("set_font_size", "name", "node_type", "font_size"), &Theme::set_font_size); - ClassDB::bind_method(D_METHOD("get_font_size", "name", "node_type"), &Theme::get_font_size); - ClassDB::bind_method(D_METHOD("has_font_size", "name", "node_type"), &Theme::has_font_size); - ClassDB::bind_method(D_METHOD("rename_font_size", "old_name", "name", "node_type"), &Theme::rename_font_size); - ClassDB::bind_method(D_METHOD("clear_font_size", "name", "node_type"), &Theme::clear_font_size); - ClassDB::bind_method(D_METHOD("get_font_size_list", "node_type"), &Theme::_get_font_size_list); + ClassDB::bind_method(D_METHOD("set_font_size", "name", "theme_type", "font_size"), &Theme::set_font_size); + ClassDB::bind_method(D_METHOD("get_font_size", "name", "theme_type"), &Theme::get_font_size); + ClassDB::bind_method(D_METHOD("has_font_size", "name", "theme_type"), &Theme::has_font_size); + ClassDB::bind_method(D_METHOD("rename_font_size", "old_name", "name", "theme_type"), &Theme::rename_font_size); + ClassDB::bind_method(D_METHOD("clear_font_size", "name", "theme_type"), &Theme::clear_font_size); + ClassDB::bind_method(D_METHOD("get_font_size_list", "theme_type"), &Theme::_get_font_size_list); ClassDB::bind_method(D_METHOD("get_font_size_type_list"), &Theme::_get_font_size_type_list); - ClassDB::bind_method(D_METHOD("set_color", "name", "node_type", "color"), &Theme::set_color); - ClassDB::bind_method(D_METHOD("get_color", "name", "node_type"), &Theme::get_color); - ClassDB::bind_method(D_METHOD("has_color", "name", "node_type"), &Theme::has_color); - ClassDB::bind_method(D_METHOD("rename_color", "old_name", "name", "node_type"), &Theme::rename_color); - ClassDB::bind_method(D_METHOD("clear_color", "name", "node_type"), &Theme::clear_color); - ClassDB::bind_method(D_METHOD("get_color_list", "node_type"), &Theme::_get_color_list); + ClassDB::bind_method(D_METHOD("set_color", "name", "theme_type", "color"), &Theme::set_color); + ClassDB::bind_method(D_METHOD("get_color", "name", "theme_type"), &Theme::get_color); + ClassDB::bind_method(D_METHOD("has_color", "name", "theme_type"), &Theme::has_color); + ClassDB::bind_method(D_METHOD("rename_color", "old_name", "name", "theme_type"), &Theme::rename_color); + ClassDB::bind_method(D_METHOD("clear_color", "name", "theme_type"), &Theme::clear_color); + ClassDB::bind_method(D_METHOD("get_color_list", "theme_type"), &Theme::_get_color_list); ClassDB::bind_method(D_METHOD("get_color_type_list"), &Theme::_get_color_type_list); - ClassDB::bind_method(D_METHOD("set_constant", "name", "node_type", "constant"), &Theme::set_constant); - ClassDB::bind_method(D_METHOD("get_constant", "name", "node_type"), &Theme::get_constant); - ClassDB::bind_method(D_METHOD("has_constant", "name", "node_type"), &Theme::has_constant); - ClassDB::bind_method(D_METHOD("rename_constant", "old_name", "name", "node_type"), &Theme::rename_constant); - ClassDB::bind_method(D_METHOD("clear_constant", "name", "node_type"), &Theme::clear_constant); - ClassDB::bind_method(D_METHOD("get_constant_list", "node_type"), &Theme::_get_constant_list); + ClassDB::bind_method(D_METHOD("set_constant", "name", "theme_type", "constant"), &Theme::set_constant); + ClassDB::bind_method(D_METHOD("get_constant", "name", "theme_type"), &Theme::get_constant); + ClassDB::bind_method(D_METHOD("has_constant", "name", "theme_type"), &Theme::has_constant); + ClassDB::bind_method(D_METHOD("rename_constant", "old_name", "name", "theme_type"), &Theme::rename_constant); + ClassDB::bind_method(D_METHOD("clear_constant", "name", "theme_type"), &Theme::clear_constant); + ClassDB::bind_method(D_METHOD("get_constant_list", "theme_type"), &Theme::_get_constant_list); ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list); ClassDB::bind_method(D_METHOD("clear"), &Theme::clear); @@ -1400,12 +1410,12 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size); ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size); - ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "node_type", "value"), &Theme::set_theme_item); - ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "node_type"), &Theme::get_theme_item); - ClassDB::bind_method(D_METHOD("has_theme_item", "data_type", "name", "node_type"), &Theme::has_theme_item); - ClassDB::bind_method(D_METHOD("rename_theme_item", "data_type", "old_name", "name", "node_type"), &Theme::rename_theme_item); - ClassDB::bind_method(D_METHOD("clear_theme_item", "data_type", "name", "node_type"), &Theme::clear_theme_item); - ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "node_type"), &Theme::_get_theme_item_list); + ClassDB::bind_method(D_METHOD("set_theme_item", "data_type", "name", "theme_type", "value"), &Theme::set_theme_item); + ClassDB::bind_method(D_METHOD("get_theme_item", "data_type", "name", "theme_type"), &Theme::get_theme_item); + ClassDB::bind_method(D_METHOD("has_theme_item", "data_type", "name", "theme_type"), &Theme::has_theme_item); + ClassDB::bind_method(D_METHOD("rename_theme_item", "data_type", "old_name", "name", "theme_type"), &Theme::rename_theme_item); + ClassDB::bind_method(D_METHOD("clear_theme_item", "data_type", "name", "theme_type"), &Theme::clear_theme_item); + ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "theme_type"), &Theme::_get_theme_item_list); ClassDB::bind_method(D_METHOD("get_theme_item_type_list", "data_type"), &Theme::_get_theme_item_type_list); ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 7e887b6343..4de1f065e1 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -62,20 +62,20 @@ private: HashMap<StringName, HashMap<StringName, Color>> color_map; HashMap<StringName, HashMap<StringName, int>> constant_map; - Vector<String> _get_icon_list(const String &p_node_type) const; + Vector<String> _get_icon_list(const String &p_theme_type) const; Vector<String> _get_icon_type_list() const; - Vector<String> _get_stylebox_list(const String &p_node_type) const; + Vector<String> _get_stylebox_list(const String &p_theme_type) const; Vector<String> _get_stylebox_type_list() const; - Vector<String> _get_font_list(const String &p_node_type) const; + Vector<String> _get_font_list(const String &p_theme_type) const; Vector<String> _get_font_type_list() const; - Vector<String> _get_font_size_list(const String &p_node_type) const; + Vector<String> _get_font_size_list(const String &p_theme_type) const; Vector<String> _get_font_size_type_list() const; - Vector<String> _get_color_list(const String &p_node_type) const; + Vector<String> _get_color_list(const String &p_theme_type) const; Vector<String> _get_color_type_list() const; - Vector<String> _get_constant_list(const String &p_node_type) const; + Vector<String> _get_constant_list(const String &p_theme_type) const; Vector<String> _get_constant_type_list() const; - Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_node_type) const; + Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_theme_type) const; Vector<String> _get_theme_item_type_list(DataType p_data_type) const; Vector<String> _get_type_list() const; @@ -116,77 +116,78 @@ public: void set_default_theme_font_size(int p_font_size); int get_default_theme_font_size() const; - void set_icon(const StringName &p_name, const StringName &p_node_type, const Ref<Texture2D> &p_icon); - Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_node_type) const; - bool has_icon(const StringName &p_name, const StringName &p_node_type) const; - bool has_icon_nocheck(const StringName &p_name, const StringName &p_node_type) const; - void rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_icon(const StringName &p_name, const StringName &p_node_type); - void get_icon_list(StringName p_node_type, List<StringName> *p_list) const; - void add_icon_type(const StringName &p_node_type); + void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const; + bool has_icon(const StringName &p_name, const StringName &p_theme_type) const; + bool has_icon_nocheck(const StringName &p_name, const StringName &p_theme_type) const; + void rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_icon(const StringName &p_name, const StringName &p_theme_type); + void get_icon_list(StringName p_theme_type, List<StringName> *p_list) const; + void add_icon_type(const StringName &p_theme_type); void get_icon_type_list(List<StringName> *p_list) const; - void set_stylebox(const StringName &p_name, const StringName &p_node_type, const Ref<StyleBox> &p_style); - Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_node_type) const; - bool has_stylebox(const StringName &p_name, const StringName &p_node_type) const; - bool has_stylebox_nocheck(const StringName &p_name, const StringName &p_node_type) const; - void rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_stylebox(const StringName &p_name, const StringName &p_node_type); - void get_stylebox_list(StringName p_node_type, List<StringName> *p_list) const; - void add_stylebox_type(const StringName &p_node_type); + void set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style); + Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const; + bool has_stylebox(const StringName &p_name, const StringName &p_theme_type) const; + bool has_stylebox_nocheck(const StringName &p_name, const StringName &p_theme_type) const; + void rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_stylebox(const StringName &p_name, const StringName &p_theme_type); + void get_stylebox_list(StringName p_theme_type, List<StringName> *p_list) const; + void add_stylebox_type(const StringName &p_theme_type); void get_stylebox_type_list(List<StringName> *p_list) const; - void set_font(const StringName &p_name, const StringName &p_node_type, const Ref<Font> &p_font); - Ref<Font> get_font(const StringName &p_name, const StringName &p_node_type) const; - bool has_font(const StringName &p_name, const StringName &p_node_type) const; - bool has_font_nocheck(const StringName &p_name, const StringName &p_node_type) const; - void rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_font(const StringName &p_name, const StringName &p_node_type); - void get_font_list(StringName p_node_type, List<StringName> *p_list) const; - void add_font_type(const StringName &p_node_type); + void set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font); + Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const; + bool has_font(const StringName &p_name, const StringName &p_theme_type) const; + bool has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const; + void rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_font(const StringName &p_name, const StringName &p_theme_type); + void get_font_list(StringName p_theme_type, List<StringName> *p_list) const; + void add_font_type(const StringName &p_theme_type); void get_font_type_list(List<StringName> *p_list) const; - void set_font_size(const StringName &p_name, const StringName &p_node_type, int p_font_size); - int get_font_size(const StringName &p_name, const StringName &p_node_type) const; - bool has_font_size(const StringName &p_name, const StringName &p_node_type) const; - bool has_font_size_nocheck(const StringName &p_name, const StringName &p_node_type) const; - void rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_font_size(const StringName &p_name, const StringName &p_node_type); - void get_font_size_list(StringName p_node_type, List<StringName> *p_list) const; - void add_font_size_type(const StringName &p_node_type); + void set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size); + int get_font_size(const StringName &p_name, const StringName &p_theme_type) const; + bool has_font_size(const StringName &p_name, const StringName &p_theme_type) const; + bool has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const; + void rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_font_size(const StringName &p_name, const StringName &p_theme_type); + void get_font_size_list(StringName p_theme_type, List<StringName> *p_list) const; + void add_font_size_type(const StringName &p_theme_type); void get_font_size_type_list(List<StringName> *p_list) const; - void set_color(const StringName &p_name, const StringName &p_node_type, const Color &p_color); - Color get_color(const StringName &p_name, const StringName &p_node_type) const; - bool has_color(const StringName &p_name, const StringName &p_node_type) const; - bool has_color_nocheck(const StringName &p_name, const StringName &p_node_type) const; - void rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_color(const StringName &p_name, const StringName &p_node_type); - void get_color_list(StringName p_node_type, List<StringName> *p_list) const; - void add_color_type(const StringName &p_node_type); + void set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color); + Color get_color(const StringName &p_name, const StringName &p_theme_type) const; + bool has_color(const StringName &p_name, const StringName &p_theme_type) const; + bool has_color_nocheck(const StringName &p_name, const StringName &p_theme_type) const; + void rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_color(const StringName &p_name, const StringName &p_theme_type); + void get_color_list(StringName p_theme_type, List<StringName> *p_list) const; + void add_color_type(const StringName &p_theme_type); void get_color_type_list(List<StringName> *p_list) const; - void set_constant(const StringName &p_name, const StringName &p_node_type, int p_constant); - int get_constant(const StringName &p_name, const StringName &p_node_type) const; - bool has_constant(const StringName &p_name, const StringName &p_node_type) const; - bool has_constant_nocheck(const StringName &p_name, const StringName &p_node_type) const; - void rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_constant(const StringName &p_name, const StringName &p_node_type); - void get_constant_list(StringName p_node_type, List<StringName> *p_list) const; - void add_constant_type(const StringName &p_node_type); + void set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant); + int get_constant(const StringName &p_name, const StringName &p_theme_type) const; + bool has_constant(const StringName &p_name, const StringName &p_theme_type) const; + bool has_constant_nocheck(const StringName &p_name, const StringName &p_theme_type) const; + void rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_constant(const StringName &p_name, const StringName &p_theme_type); + void get_constant_list(StringName p_theme_type, List<StringName> *p_list) const; + void add_constant_type(const StringName &p_theme_type); void get_constant_type_list(List<StringName> *p_list) const; - void set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type, const Variant &p_value); - Variant get_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const; - bool has_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const; - bool has_theme_item_nocheck(DataType p_data_type, const StringName &p_name, const StringName &p_node_type) const; - void rename_theme_item(DataType p_data_type, const StringName &p_old_name, const StringName &p_name, const StringName &p_node_type); - void clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_node_type); - void get_theme_item_list(DataType p_data_type, StringName p_node_type, List<StringName> *p_list) const; - void add_theme_item_type(DataType p_data_type, const StringName &p_node_type); + void set_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type, const Variant &p_value); + Variant get_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const; + bool has_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const; + bool has_theme_item_nocheck(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const; + void rename_theme_item(DataType p_data_type, const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type); + void clear_theme_item(DataType p_data_type, const StringName &p_name, const StringName &p_theme_type); + void get_theme_item_list(DataType p_data_type, StringName p_theme_type, List<StringName> *p_list) const; + void add_theme_item_type(DataType p_data_type, const StringName &p_theme_type); void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const; void get_type_list(List<StringName> *p_list) const; + static void get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list); void copy_default_theme(); void copy_theme(const Ref<Theme> &p_other); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index c4b8a56f54..59c1a4e915 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -106,15 +106,15 @@ void TileSet::_compute_next_source_id() { } // Sources management -int TileSet::add_source(Ref<TileSetAtlasSource> p_tile_atlas_source, int p_atlas_source_id_override) { - ERR_FAIL_COND_V(!p_tile_atlas_source.is_valid(), -1); +int TileSet::add_source(Ref<TileSetSource> p_tile_set_source, int p_atlas_source_id_override) { + ERR_FAIL_COND_V(!p_tile_set_source.is_valid(), -1); ERR_FAIL_COND_V_MSG(p_atlas_source_id_override >= 0 && (sources.has(p_atlas_source_id_override)), -1, vformat("Cannot create TileSet atlas source. Another atlas source exists with id %d.", p_atlas_source_id_override)); int new_source_id = p_atlas_source_id_override >= 0 ? p_atlas_source_id_override : next_source_id; - sources[new_source_id] = p_tile_atlas_source; + sources[new_source_id] = p_tile_set_source; source_ids.append(new_source_id); source_ids.sort(); - p_tile_atlas_source->set_tile_set(this); + p_tile_set_source->set_tile_set(this); _compute_next_source_id(); sources[new_source_id]->connect("changed", callable_mp(this, &TileSet::_source_changed)); @@ -668,8 +668,8 @@ void TileSet::reset_state() { custom_data_layers.clear(); } -const Vector2i TileSetAtlasSource::INVALID_ATLAS_COORDS = Vector2i(-1, -1); -const int TileSetAtlasSource::INVALID_TILE_ALTERNATIVE = -1; +const Vector2i TileSetSource::INVALID_ATLAS_COORDS = Vector2i(-1, -1); +const int TileSetSource::INVALID_TILE_ALTERNATIVE = -1; #ifndef DISABLE_DEPRECATED void TileSet::compatibility_conversion() { @@ -835,7 +835,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } else if (what == "tile_mode") { ctd->tile_mode = p_value; } else if (what.left(9) == "autotile") { - what = what.right(9); + what = what.substr(9); if (what == "bitmask_mode") { ctd->autotile_bitmask_mode = p_value; } else if (what == "icon_coordinate") { @@ -1086,7 +1086,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { return true; } } else if (components.size() == 2 && components[0] == "sources" && components[1].is_valid_integer()) { - // Create atlas if it does not exists. + // Create source only if it does not exists. int source_id = components[1].to_int(); if (!has_source(source_id)) { @@ -1290,7 +1290,7 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tile_skew", "skew"), &TileSet::set_tile_skew); ClassDB::bind_method(D_METHOD("get_tile_skew"), &TileSet::get_tile_skew); - ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_shape", PROPERTY_HINT_ENUM, "Square,Isometric,Half-offset square,Hexagon"), "set_tile_shape", "get_tile_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_shape", PROPERTY_HINT_ENUM, "Square,Isometric,Half-Offset Square,Hexagon"), "set_tile_shape", "get_tile_shape"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_layout", PROPERTY_HINT_ENUM, "Stacked,Stacked Offset,Stairs Right,Stairs Down,Diamond Right,Diamond Down"), "set_tile_layout", "get_tile_layout"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_offset_axis", PROPERTY_HINT_ENUM, "Horizontal Offset,Vertical Offset"), "set_tile_offset_axis", "get_tile_offset_axis"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "tile_size"), "set_tile_size", "get_tile_size"); @@ -1399,16 +1399,19 @@ void TileSet::_bind_methods() { TileSet::TileSet() { // Instanciatie and list all plugins. - tile_set_plugins_vector.append(memnew(TileSetAtlasPluginRendering)); - tile_set_plugins_vector.append(memnew(TileSetAtlasPluginPhysics)); - tile_set_plugins_vector.append(memnew(TileSetAtlasPluginTerrain)); - tile_set_plugins_vector.append(memnew(TileSetAtlasPluginNavigation)); + tile_set_plugins_vector.append(memnew(TileSetPluginAtlasRendering)); + tile_set_plugins_vector.append(memnew(TileSetPluginAtlasPhysics)); + tile_set_plugins_vector.append(memnew(TileSetPluginAtlasTerrain)); + tile_set_plugins_vector.append(memnew(TileSetPluginAtlasNavigation)); + tile_set_plugins_vector.append(memnew(TileSetPluginScenesCollections)); } TileSet::~TileSet() { +#ifndef DISABLE_DEPRECATED for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) { memdelete(E->get()); } +#endif // DISABLE_DEPRECATED while (!source_ids.is_empty()) { remove_source(source_ids[0]); } @@ -1530,13 +1533,13 @@ bool TileSetAtlasSource::_set(const StringName &p_name, const Variant &p_value) // Compute the vector2i if we have coordinates. Vector<String> coords_split = components[0].split(":"); - Vector2i coords = TileSetAtlasSource::INVALID_ATLAS_COORDS; + Vector2i coords = TileSetSource::INVALID_ATLAS_COORDS; if (coords_split.size() == 2 && coords_split[0].is_valid_integer() && coords_split[1].is_valid_integer()) { coords = Vector2i(coords_split[0].to_int(), coords_split[1].to_int()); } // Properties. - if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != TileSetSource::INVALID_ATLAS_COORDS) { // Create the tile if needed. if (!has_tile(coords)) { create_tile(coords); @@ -1549,7 +1552,7 @@ bool TileSetAtlasSource::_set(const StringName &p_name, const Variant &p_value) tiles[coords].next_alternative_id = p_value; } else if (components[1].is_valid_integer()) { int alternative_id = components[1].to_int(); - if (alternative_id != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) { + if (alternative_id != TileSetSource::INVALID_TILE_ALTERNATIVE) { // Create the alternative if needed ? if (!has_alternative_tile(coords, alternative_id)) { create_alternative_tile(coords, alternative_id); @@ -1594,7 +1597,7 @@ bool TileSetAtlasSource::_get(const StringName &p_name, Variant &r_ret) const { return true; } else if (components[1].is_valid_integer()) { int alternative_id = components[1].to_int(); - if (alternative_id != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE && tiles[coords].alternatives.has(alternative_id)) { + if (alternative_id != TileSetSource::INVALID_TILE_ALTERNATIVE && tiles[coords].alternatives.has(alternative_id)) { if (components.size() >= 3) { bool valid; r_ret = tiles[coords].alternatives[alternative_id]->get(components[2], &valid); @@ -1745,7 +1748,7 @@ int TileSetAtlasSource::get_tiles_count() const { } Vector2i TileSetAtlasSource::get_tile_id(int p_index) const { - ERR_FAIL_INDEX_V(p_index, tiles_ids.size(), TileSetAtlasSource::INVALID_ATLAS_COORDS); + ERR_FAIL_INDEX_V(p_index, tiles_ids.size(), TileSetSource::INVALID_ATLAS_COORDS); return tiles_ids[p_index]; } @@ -1798,7 +1801,7 @@ bool TileSetAtlasSource::can_move_tile_in_atlas(Vector2i p_atlas_coords, Vector2 for (int x = new_rect.position.x; x < new_rect.get_end().x; x++) { for (int y = new_rect.position.y; y < new_rect.get_end().y; y++) { Vector2i coords = get_tile_at_coords(Vector2i(x, y)); - if (coords != p_atlas_coords && coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) { + if (coords != p_atlas_coords && coords != TileSetSource::INVALID_ATLAS_COORDS) { return false; } } @@ -1880,7 +1883,7 @@ void TileSetAtlasSource::clear_tiles_outside_texture() { int TileSetAtlasSource::create_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_id_override) { ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), -1, vformat("TileSetAtlasSource has no tile at %s.", String(p_atlas_coords))); - ERR_FAIL_COND_V_MSG(p_alternative_id_override >= 0 && (tiles[p_atlas_coords].alternatives.has(p_alternative_id_override) || tiles[p_atlas_coords].alternatives.has(p_alternative_id_override)), -1, vformat("Cannot create alternative tile. Another alternative exists with id %d.", p_alternative_id_override)); + ERR_FAIL_COND_V_MSG(p_alternative_id_override >= 0 && tiles[p_atlas_coords].alternatives.has(p_alternative_id_override), -1, vformat("Cannot create alternative tile. Another alternative exists with id %d.", p_alternative_id_override)); int new_alternative_id = p_alternative_id_override >= 0 ? p_alternative_id_override : tiles[p_atlas_coords].next_alternative_id; @@ -2034,6 +2037,202 @@ void TileSetAtlasSource::_compute_next_alternative_id(const Vector2i p_atlas_coo }; } +/////////////////////////////// TileSetScenesCollectionSource ////////////////////////////////////// + +void TileSetScenesCollectionSource::_compute_next_alternative_id() { + while (scenes.has(next_scene_id)) { + next_scene_id = (next_scene_id % 1073741823) + 1; // 2 ** 30 + }; +} + +int TileSetScenesCollectionSource::get_tiles_count() const { + return 1; +} + +Vector2i TileSetScenesCollectionSource::get_tile_id(int p_tile_index) const { + ERR_FAIL_COND_V(p_tile_index != 0, TileSetSource::INVALID_ATLAS_COORDS); + return Vector2i(); +} + +bool TileSetScenesCollectionSource::has_tile(Vector2i p_atlas_coords) const { + return p_atlas_coords == Vector2i(); +} + +int TileSetScenesCollectionSource::get_alternative_tiles_count(const Vector2i p_atlas_coords) const { + return scenes_ids.size(); +} + +int TileSetScenesCollectionSource::get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const { + ERR_FAIL_COND_V(p_atlas_coords != Vector2i(), TileSetSource::INVALID_TILE_ALTERNATIVE); + ERR_FAIL_INDEX_V(p_index, scenes_ids.size(), TileSetSource::INVALID_TILE_ALTERNATIVE); + + return scenes_ids[p_index]; +} + +bool TileSetScenesCollectionSource::has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const { + ERR_FAIL_COND_V(p_atlas_coords != Vector2i(), false); + return scenes.has(p_alternative_tile); +} + +int TileSetScenesCollectionSource::create_scene_tile(Ref<PackedScene> p_packed_scene, int p_id_override) { + ERR_FAIL_COND_V_MSG(p_id_override >= 0 && scenes.has(p_id_override), -1, vformat("Cannot create scene tile. Another scene tile exists with id %d.", p_id_override)); + + int new_scene_id = p_id_override >= 0 ? p_id_override : next_scene_id; + + scenes[new_scene_id] = SceneData(); + scenes_ids.append(new_scene_id); + scenes_ids.sort(); + set_scene_tile_scene(new_scene_id, p_packed_scene); + _compute_next_alternative_id(); + + emit_signal("changed"); + + return new_scene_id; +} + +void TileSetScenesCollectionSource::set_scene_tile_id(int p_id, int p_new_id) { + ERR_FAIL_COND(p_new_id < 0); + ERR_FAIL_COND(!has_scene_tile_id(p_id)); + ERR_FAIL_COND(has_scene_tile_id(p_new_id)); + + scenes[p_new_id] = SceneData(); + scenes[p_new_id] = scenes[p_id]; + scenes_ids.append(p_new_id); + scenes_ids.sort(); + + _compute_next_alternative_id(); + + scenes.erase(p_id); + scenes_ids.erase(p_id); + + emit_signal("changed"); +} + +void TileSetScenesCollectionSource::set_scene_tile_scene(int p_id, Ref<PackedScene> p_packed_scene) { + ERR_FAIL_COND(!scenes.has(p_id)); + if (p_packed_scene.is_valid()) { + // Make sure we have a root node. Supposed to be at 0 index because find_node_by_path() does not seem to work. + ERR_FAIL_COND(!p_packed_scene->get_state().is_valid()); + ERR_FAIL_COND(p_packed_scene->get_state()->get_node_count() < 1); + + // Check if it extends CanvasItem. + String type = p_packed_scene->get_state()->get_node_type(0); + bool extends_correct_class = ClassDB::is_parent_class(type, "Control") || ClassDB::is_parent_class(type, "Node2D"); + ERR_FAIL_COND_MSG(!extends_correct_class, vformat("Invalid PackedScene for TileSetScenesCollectionSource: %s. Root node should extend Control or Node2D.", p_packed_scene->get_path())); + + scenes[p_id].scene = p_packed_scene; + } else { + scenes[p_id].scene = Ref<PackedScene>(); + } + emit_signal("changed"); +} + +Ref<PackedScene> TileSetScenesCollectionSource::get_scene_tile_scene(int p_id) const { + ERR_FAIL_COND_V(!scenes.has(p_id), Ref<PackedScene>()); + return scenes[p_id].scene; +} + +void TileSetScenesCollectionSource::set_scene_tile_display_placeholder(int p_id, bool p_display_placeholder) { + ERR_FAIL_COND(!scenes.has(p_id)); + + scenes[p_id].display_placeholder = p_display_placeholder; + + emit_signal("changed"); +} + +bool TileSetScenesCollectionSource::get_scene_tile_display_placeholder(int p_id) const { + ERR_FAIL_COND_V(!scenes.has(p_id), false); + return scenes[p_id].display_placeholder; +} + +void TileSetScenesCollectionSource::remove_scene_tile(int p_id) { + ERR_FAIL_COND(!scenes.has(p_id)); + + scenes.erase(p_id); + scenes_ids.erase(p_id); + emit_signal("changed"); +} + +int TileSetScenesCollectionSource::get_next_scene_tile_id() const { + return next_scene_id; +} + +bool TileSetScenesCollectionSource::_set(const StringName &p_name, const Variant &p_value) { + Vector<String> components = String(p_name).split("/", true, 2); + + if (components.size() >= 2 && components[0] == "scenes" && components[1].is_valid_integer()) { + int scene_id = components[1].to_int(); + if (components.size() >= 3 && components[2] == "scene") { + if (has_scene_tile_id(scene_id)) { + set_scene_tile_scene(scene_id, p_value); + } else { + create_scene_tile(p_value, scene_id); + } + return true; + } else if (components.size() >= 3 && components[2] == "display_placeholder") { + if (!has_scene_tile_id(scene_id)) { + create_scene_tile(p_value, scene_id); + } + + return true; + } + } + + return false; +} + +bool TileSetScenesCollectionSource::_get(const StringName &p_name, Variant &r_ret) const { + Vector<String> components = String(p_name).split("/", true, 2); + + if (components.size() >= 2 && components[0] == "scenes" && components[1].is_valid_integer() && scenes.has(components[1].to_int())) { + if (components.size() >= 3 && components[2] == "scene") { + r_ret = scenes[components[1].to_int()].scene; + return true; + } else if (components.size() >= 3 && components[2] == "display_placeholder") { + r_ret = scenes[components[1].to_int()].scene; + return true; + } + } + + return false; +} + +void TileSetScenesCollectionSource::_get_property_list(List<PropertyInfo> *p_list) const { + for (int i = 0; i < scenes_ids.size(); i++) { + p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("scenes/%d/scene", scenes_ids[i]), PROPERTY_HINT_RESOURCE_TYPE, "TileSetScenesCollectionSource")); + + PropertyInfo property_info = PropertyInfo(Variant::BOOL, vformat("scenes/%d/display_placeholder", scenes_ids[i])); + if (scenes[scenes_ids[i]].display_placeholder == false) { + property_info.usage ^= PROPERTY_USAGE_STORAGE; + } + p_list->push_back(property_info); + } +} + +void TileSetScenesCollectionSource::_bind_methods() { + // Base tiles + ClassDB::bind_method(D_METHOD("get_tiles_count"), &TileSetScenesCollectionSource::get_tiles_count); + ClassDB::bind_method(D_METHOD("get_tile_id", "index"), &TileSetScenesCollectionSource::get_tile_id); + ClassDB::bind_method(D_METHOD("has_tile", "atlas_coords"), &TileSetScenesCollectionSource::has_tile); + + // Alternative tiles + ClassDB::bind_method(D_METHOD("get_alternative_tiles_count", "atlas_coords"), &TileSetScenesCollectionSource::get_alternative_tiles_count); + ClassDB::bind_method(D_METHOD("get_alternative_tile_id", "atlas_coords", "index"), &TileSetScenesCollectionSource::get_alternative_tile_id); + ClassDB::bind_method(D_METHOD("has_alternative_tile", "atlas_coords", "alternative_tile"), &TileSetScenesCollectionSource::has_alternative_tile); + + ClassDB::bind_method(D_METHOD("get_scene_tiles_count"), &TileSetScenesCollectionSource::get_scene_tiles_count); + ClassDB::bind_method(D_METHOD("get_scene_tile_id", "index"), &TileSetScenesCollectionSource::get_scene_tile_id); + ClassDB::bind_method(D_METHOD("has_scene_tile_id", "id"), &TileSetScenesCollectionSource::has_scene_tile_id); + ClassDB::bind_method(D_METHOD("create_scene_tile", "packed_scene", "id_override"), &TileSetScenesCollectionSource::create_scene_tile, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("set_scene_tile_id", "id", "new_id"), &TileSetScenesCollectionSource::set_scene_tile_id); + ClassDB::bind_method(D_METHOD("set_scene_tile_scene", "id", "packed_scene"), &TileSetScenesCollectionSource::set_scene_tile_scene); + ClassDB::bind_method(D_METHOD("get_scene_tile_scene", "id"), &TileSetScenesCollectionSource::get_scene_tile_scene); + ClassDB::bind_method(D_METHOD("set_scene_tile_display_placeholder", "id", "display_placeholder"), &TileSetScenesCollectionSource::set_scene_tile_display_placeholder); + ClassDB::bind_method(D_METHOD("get_scene_tile_display_placeholder", "id"), &TileSetScenesCollectionSource::get_scene_tile_display_placeholder); + ClassDB::bind_method(D_METHOD("remove_scene_tile", "id"), &TileSetScenesCollectionSource::remove_scene_tile); + ClassDB::bind_method(D_METHOD("get_next_scene_tile_id"), &TileSetScenesCollectionSource::get_next_scene_tile_id); +} + /////////////////////////////// TileData ////////////////////////////////////// void TileData::set_tile_set(const TileSet *p_tile_set) { @@ -2154,11 +2353,11 @@ int TileData::get_z_index() const { return z_index; } -void TileData::set_y_sort_origin(Vector2i p_y_sort_origin) { +void TileData::set_y_sort_origin(int p_y_sort_origin) { y_sort_origin = p_y_sort_origin; emit_signal("changed"); } -Vector2i TileData::get_y_sort_origin() const { +int TileData::get_y_sort_origin() const { return y_sort_origin; } @@ -2823,7 +3022,7 @@ void TileData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "texture_offset"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index"), "set_z_index", "get_z_index"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "y_sort_origin"), "set_y_sort_origin", "get_y_sort_origin"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "y_sort_origin"), "set_y_sort_origin", "get_y_sort_origin"); ADD_GROUP("Terrains", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "terrain_set"), "set_terrain_set", "get_terrain_set"); @@ -2834,10 +3033,10 @@ void TileData::_bind_methods() { ADD_SIGNAL(MethodInfo("changed")); } -/////////////////////////////// TileSetAtlasPluginTerrain ////////////////////////////////////// +/////////////////////////////// TileSetPluginAtlasTerrain ////////////////////////////////////// // --- PLUGINS --- -void TileSetAtlasPluginTerrain::_draw_square_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { +void TileSetPluginAtlasTerrain::_draw_square_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { Rect2 bit_rect; bit_rect.size = Vector2(p_size) / 3; switch (p_bit) { @@ -2872,7 +3071,7 @@ void TileSetAtlasPluginTerrain::_draw_square_corner_or_side_terrain_bit(CanvasIt p_canvas_item->draw_rect(bit_rect, p_color); } -void TileSetAtlasPluginTerrain::_draw_square_corner_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { +void TileSetPluginAtlasTerrain::_draw_square_corner_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { PackedColorArray color_array; color_array.push_back(p_color); @@ -2919,7 +3118,7 @@ void TileSetAtlasPluginTerrain::_draw_square_corner_terrain_bit(CanvasItem *p_ca } } -void TileSetAtlasPluginTerrain::_draw_square_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { +void TileSetPluginAtlasTerrain::_draw_square_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { PackedColorArray color_array; color_array.push_back(p_color); @@ -2958,7 +3157,7 @@ void TileSetAtlasPluginTerrain::_draw_square_side_terrain_bit(CanvasItem *p_canv } } -void TileSetAtlasPluginTerrain::_draw_isometric_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { +void TileSetPluginAtlasTerrain::_draw_isometric_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { PackedColorArray color_array; color_array.push_back(p_color); @@ -3021,7 +3220,7 @@ void TileSetAtlasPluginTerrain::_draw_isometric_corner_or_side_terrain_bit(Canva } } -void TileSetAtlasPluginTerrain::_draw_isometric_corner_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { +void TileSetPluginAtlasTerrain::_draw_isometric_corner_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { PackedColorArray color_array; color_array.push_back(p_color); @@ -3068,7 +3267,7 @@ void TileSetAtlasPluginTerrain::_draw_isometric_corner_terrain_bit(CanvasItem *p } } -void TileSetAtlasPluginTerrain::_draw_isometric_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { +void TileSetPluginAtlasTerrain::_draw_isometric_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit) { PackedColorArray color_array; color_array.push_back(p_color); @@ -3107,7 +3306,7 @@ void TileSetAtlasPluginTerrain::_draw_isometric_side_terrain_bit(CanvasItem *p_c } } -void TileSetAtlasPluginTerrain::_draw_half_offset_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { +void TileSetPluginAtlasTerrain::_draw_half_offset_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { PackedColorArray color_array; color_array.push_back(p_color); @@ -3272,7 +3471,7 @@ void TileSetAtlasPluginTerrain::_draw_half_offset_corner_or_side_terrain_bit(Can } } -void TileSetAtlasPluginTerrain::_draw_half_offset_corner_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { +void TileSetPluginAtlasTerrain::_draw_half_offset_corner_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { PackedColorArray color_array; color_array.push_back(p_color); @@ -3383,7 +3582,7 @@ void TileSetAtlasPluginTerrain::_draw_half_offset_corner_terrain_bit(CanvasItem } } -void TileSetAtlasPluginTerrain::_draw_half_offset_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { +void TileSetPluginAtlasTerrain::_draw_half_offset_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) { PackedColorArray color_array; color_array.push_back(p_color); @@ -3498,7 +3697,7 @@ void TileSetAtlasPluginTerrain::_draw_half_offset_side_terrain_bit(CanvasItem *p } \ } -void TileSetAtlasPluginTerrain::draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, const TileData *p_tile_data) { +void TileSetPluginAtlasTerrain::draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, const TileData *p_tile_data) { ERR_FAIL_COND(!p_tile_set); ERR_FAIL_COND(!p_tile_data); @@ -3632,9 +3831,9 @@ void TileSetAtlasPluginTerrain::draw_terrains(CanvasItem *p_canvas_item, Transfo RenderingServer::get_singleton()->canvas_item_add_set_transform(p_canvas_item->get_canvas_item(), Transform2D()); } -/////////////////////////////// TileSetAtlasPluginRendering ////////////////////////////////////// +/////////////////////////////// TileSetPluginAtlasRendering ////////////////////////////////////// -void TileSetAtlasPluginRendering::tilemap_notification(TileMap *p_tile_map, int p_what) { +void TileSetPluginAtlasRendering::tilemap_notification(TileMap *p_tile_map, int p_what) { switch (p_what) { case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: { bool visible = p_tile_map->is_visible_in_tree(); @@ -3669,10 +3868,16 @@ void TileSetAtlasPluginRendering::tilemap_notification(TileMap *p_tile_map, int } } } break; + case CanvasItem::NOTIFICATION_DRAW: { + Ref<TileSet> tile_set = p_tile_map->get_tileset(); + if (tile_set.is_valid()) { + RenderingServer::get_singleton()->canvas_item_set_sort_children_by_y(p_tile_map->get_canvas_item(), tile_set->is_y_sorting()); + } + } break; } } -void TileSetAtlasPluginRendering::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, Color p_modulation) { +void TileSetPluginAtlasRendering::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, Color p_modulation) { ERR_FAIL_COND(!p_tile_set.is_valid()); ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id)); ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords)); @@ -3687,6 +3892,12 @@ void TileSetAtlasPluginRendering::draw_tile(RID p_canvas_item, Vector2i p_positi return; } + // Check if we are in the texture, return otherwise. + Vector2i grid_size = atlas_source->get_atlas_grid_size(); + if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) { + return; + } + // Get tile data. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile)); @@ -3724,7 +3935,7 @@ void TileSetAtlasPluginRendering::draw_tile(RID p_canvas_item, Vector2i p_positi } } -void TileSetAtlasPluginRendering::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { +void TileSetPluginAtlasRendering::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { ERR_FAIL_COND(!p_tile_map); ERR_FAIL_COND(!p_tile_map->is_inside_tree()); Ref<TileSet> tile_set = p_tile_map->get_tileset(); @@ -3775,7 +3986,11 @@ void TileSetAtlasPluginRendering::update_dirty_quadrants(TileMap *p_tile_map, Se int z_index = tile_data->get_z_index(); // Quandrant pos. - Vector2 position = p_tile_map->map_to_world(q.coords * p_tile_map->get_effective_quadrant_size()) - tile_set->get_tile_size() / 2; + Vector2 position = p_tile_map->map_to_world(q.coords * p_tile_map->get_effective_quadrant_size()); + if (tile_set->is_y_sorting()) { + // When Y-sorting, the quandrant size is sure to be 1, we can thus offset the CanvasItem. + position.y += tile_data->get_y_sort_origin(); + } // --- CanvasItems --- // Create two canvas items, for rendering and debug. @@ -3783,16 +3998,18 @@ void TileSetAtlasPluginRendering::update_dirty_quadrants(TileMap *p_tile_map, Se // Check if the material or the z_index changed. if (prev_canvas_item == RID() || prev_material != mat || prev_z_index != z_index) { + // If so, create a new CanvasItem. canvas_item = rs->canvas_item_create(); if (mat.is_valid()) { rs->canvas_item_set_material(canvas_item, mat->get_rid()); } rs->canvas_item_set_parent(canvas_item, p_tile_map->get_canvas_item()); rs->canvas_item_set_use_parent_material(canvas_item, p_tile_map->get_use_parent_material() || p_tile_map->get_material().is_valid()); + Transform2D xform; xform.set_origin(position); - rs->canvas_item_set_transform(canvas_item, xform); + rs->canvas_item_set_light_mask(canvas_item, p_tile_map->get_light_mask()); rs->canvas_item_set_z_index(canvas_item, z_index); @@ -3858,14 +4075,14 @@ void TileSetAtlasPluginRendering::update_dirty_quadrants(TileMap *p_tile_map, Se } } -void TileSetAtlasPluginRendering::create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasRendering::create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { Ref<TileSet> tile_set = p_tile_map->get_tileset(); ERR_FAIL_COND(!tile_set.is_valid()); quadrant_order_dirty = true; } -void TileSetAtlasPluginRendering::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasRendering::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { // Free the canvas items. for (List<RID>::Element *E = p_quadrant->canvas_items.front(); E; E = E->next()) { RenderingServer::get_singleton()->free(E->get()); @@ -3879,9 +4096,60 @@ void TileSetAtlasPluginRendering::cleanup_quadrant(TileMap *p_tile_map, TileMapQ p_quadrant->occluders.clear(); } -/////////////////////////////// TileSetAtlasPluginPhysics ////////////////////////////////////// +void TileSetPluginAtlasRendering::draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { + Ref<TileSet> tile_set = p_tile_map->get_tileset(); + ERR_FAIL_COND(!tile_set.is_valid()); + + if (!Engine::get_singleton()->is_editor_hint()) { + return; + } + + // Draw a placeholder for scenes needing one. + RenderingServer *rs = RenderingServer::get_singleton(); + Vector2 quadrant_pos = p_tile_map->map_to_world(p_quadrant->coords * p_tile_map->get_effective_quadrant_size()); + for (Set<Vector2i>::Element *E_cell = p_quadrant->cells.front(); E_cell; E_cell = E_cell->next()) { + const TileMapCell &c = p_tile_map->get_cell(E_cell->get()); + + TileSetSource *source; + if (tile_set->has_source(c.source_id)) { + source = *tile_set->get_source(c.source_id); + + if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) { + continue; + } -void TileSetAtlasPluginPhysics::tilemap_notification(TileMap *p_tile_map, int p_what) { + TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); + if (atlas_source) { + Vector2i grid_size = atlas_source->get_atlas_grid_size(); + if (!atlas_source->get_texture().is_valid() || c.get_atlas_coords().x >= grid_size.x || c.get_atlas_coords().y >= grid_size.y) { + // Generate a random color from the hashed values of the tiles. + Array to_hash; + to_hash.push_back(c.source_id); + to_hash.push_back(c.get_atlas_coords()); + to_hash.push_back(c.alternative_tile); + uint32_t hash = RandomPCG(to_hash.hash()).rand(); + + Color color; + color = color.from_hsv( + (float)((hash >> 24) & 0xFF) / 256.0, + Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0), + Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0), + 0.8); + + // Draw a placeholder tile. + Transform2D xform; + xform.set_origin(p_tile_map->map_to_world(E_cell->get()) - quadrant_pos); + rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); + rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color); + } + } + } + } +} + +/////////////////////////////// TileSetPluginAtlasPhysics ////////////////////////////////////// + +void TileSetPluginAtlasPhysics::tilemap_notification(TileMap *p_tile_map, int p_what) { switch (p_what) { case CanvasItem::NOTIFICATION_TRANSFORM_CHANGED: { // Update the bodies transforms. @@ -3905,7 +4173,7 @@ void TileSetAtlasPluginPhysics::tilemap_notification(TileMap *p_tile_map, int p_ } } -void TileSetAtlasPluginPhysics::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { +void TileSetPluginAtlasPhysics::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { ERR_FAIL_COND(!p_tile_map); ERR_FAIL_COND(!p_tile_map->is_inside_tree()); Ref<TileSet> tile_set = p_tile_map->get_tileset(); @@ -3971,7 +4239,7 @@ void TileSetAtlasPluginPhysics::update_dirty_quadrants(TileMap *p_tile_map, Self } } -void TileSetAtlasPluginPhysics::create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasPhysics::create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { Ref<TileSet> tile_set = p_tile_map->get_tileset(); ERR_FAIL_COND(!tile_set.is_valid()); @@ -4016,7 +4284,7 @@ void TileSetAtlasPluginPhysics::create_quadrant(TileMap *p_tile_map, TileMapQuad } } -void TileSetAtlasPluginPhysics::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasPhysics::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { // Remove a quadrant. for (int body_index = 0; body_index < p_quadrant->bodies.size(); body_index++) { PhysicsServer2D::get_singleton()->free(p_quadrant->bodies[body_index]); @@ -4024,7 +4292,7 @@ void TileSetAtlasPluginPhysics::cleanup_quadrant(TileMap *p_tile_map, TileMapQua p_quadrant->bodies.clear(); } -void TileSetAtlasPluginPhysics::draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasPhysics::draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { // Draw the debug collision shapes. Ref<TileSet> tile_set = p_tile_map->get_tileset(); ERR_FAIL_COND(!tile_set.is_valid()); @@ -4071,9 +4339,9 @@ void TileSetAtlasPluginPhysics::draw_quadrant_debug(TileMap *p_tile_map, TileMap } }; -/////////////////////////////// TileSetAtlasPluginNavigation ////////////////////////////////////// +/////////////////////////////// TileSetPluginAtlasNavigation ////////////////////////////////////// -void TileSetAtlasPluginNavigation::tilemap_notification(TileMap *p_tile_map, int p_what) { +void TileSetPluginAtlasNavigation::tilemap_notification(TileMap *p_tile_map, int p_what) { switch (p_what) { case CanvasItem::NOTIFICATION_TRANSFORM_CHANGED: { if (p_tile_map->is_inside_tree()) { @@ -4098,7 +4366,7 @@ void TileSetAtlasPluginNavigation::tilemap_notification(TileMap *p_tile_map, int } } -void TileSetAtlasPluginNavigation::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { +void TileSetPluginAtlasNavigation::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { ERR_FAIL_COND(!p_tile_map); ERR_FAIL_COND(!p_tile_map->is_inside_tree()); Ref<TileSet> tile_set = p_tile_map->get_tileset(); @@ -4169,7 +4437,7 @@ void TileSetAtlasPluginNavigation::update_dirty_quadrants(TileMap *p_tile_map, S } } -void TileSetAtlasPluginNavigation::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasNavigation::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { // Clear navigation shapes in the quadrant. for (Map<Vector2i, Vector<RID>>::Element *E = p_quadrant->navigation_regions.front(); E; E = E->next()) { for (int i = 0; i < E->get().size(); i++) { @@ -4183,7 +4451,7 @@ void TileSetAtlasPluginNavigation::cleanup_quadrant(TileMap *p_tile_map, TileMap p_quadrant->navigation_regions.clear(); } -void TileSetAtlasPluginNavigation::draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { +void TileSetPluginAtlasNavigation::draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { // Draw the debug collision shapes. Ref<TileSet> tile_set = p_tile_map->get_tileset(); ERR_FAIL_COND(!tile_set.is_valid()); @@ -4240,11 +4508,129 @@ void TileSetAtlasPluginNavigation::draw_quadrant_debug(TileMap *p_tile_map, Tile Vector<Color> colors; colors.push_back(random_variation_color); - RS::get_singleton()->canvas_item_add_polygon(p_quadrant->debug_canvas_item, vertices, colors); + rs->canvas_item_add_polygon(p_quadrant->debug_canvas_item, vertices, colors); + } + } + } + } + } + } +} + +/////////////////////////////// TileSetPluginScenesCollections ////////////////////////////////////// + +void TileSetPluginScenesCollections::update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) { + Ref<TileSet> tile_set = p_tile_map->get_tileset(); + ERR_FAIL_COND(!tile_set.is_valid()); + + SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first(); + while (q_list_element) { + TileMapQuadrant &q = *q_list_element->self(); + + // Clear the scenes. + for (Map<Vector2i, String>::Element *E = q.scenes.front(); E; E = E->next()) { + Node *node = p_tile_map->get_node(E->get()); + if (node) { + node->queue_delete(); + } + } + + q.scenes.clear(); + + // Recreate the scenes. + for (Set<Vector2i>::Element *E_cell = q.cells.front(); E_cell; E_cell = E_cell->next()) { + const TileMapCell &c = p_tile_map->get_cell(E_cell->get()); + + TileSetSource *source; + if (tile_set->has_source(c.source_id)) { + source = *tile_set->get_source(c.source_id); + + if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) { + continue; + } + + TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + if (scenes_collection_source) { + Ref<PackedScene> packed_scene = scenes_collection_source->get_scene_tile_scene(c.alternative_tile); + if (packed_scene.is_valid()) { + Node *scene = packed_scene->instance(); + p_tile_map->add_child(scene); + Control *scene_as_control = Object::cast_to<Control>(scene); + Node2D *scene_as_node2d = Object::cast_to<Node2D>(scene); + if (scene_as_control) { + scene_as_control->set_position(p_tile_map->map_to_world(E_cell->get()) + scene_as_control->get_position()); + } else if (scene_as_node2d) { + Transform2D xform; + xform.set_origin(p_tile_map->map_to_world(E_cell->get())); + scene_as_node2d->set_transform(xform * scene_as_node2d->get_transform()); } + q.scenes[E_cell->get()] = scene->get_name(); } } } } + + q_list_element = q_list_element->next(); + } +} + +void TileSetPluginScenesCollections::cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { + // Clear the scenes. + for (Map<Vector2i, String>::Element *E = p_quadrant->scenes.front(); E; E = E->next()) { + Node *node = p_tile_map->get_node(E->get()); + if (node) { + node->queue_delete(); + } + } + + p_quadrant->scenes.clear(); +} + +void TileSetPluginScenesCollections::draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) { + Ref<TileSet> tile_set = p_tile_map->get_tileset(); + ERR_FAIL_COND(!tile_set.is_valid()); + + if (!Engine::get_singleton()->is_editor_hint()) { + return; + } + + // Draw a placeholder for scenes needing one. + RenderingServer *rs = RenderingServer::get_singleton(); + Vector2 quadrant_pos = p_tile_map->map_to_world(p_quadrant->coords * p_tile_map->get_effective_quadrant_size()); + for (Set<Vector2i>::Element *E_cell = p_quadrant->cells.front(); E_cell; E_cell = E_cell->next()) { + const TileMapCell &c = p_tile_map->get_cell(E_cell->get()); + + TileSetSource *source; + if (tile_set->has_source(c.source_id)) { + source = *tile_set->get_source(c.source_id); + + if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) { + continue; + } + + TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source); + if (scenes_collection_source) { + if (!scenes_collection_source->get_scene_tile_scene(c.alternative_tile).is_valid() || scenes_collection_source->get_scene_tile_display_placeholder(c.alternative_tile)) { + // Generate a random color from the hashed values of the tiles. + Array to_hash; + to_hash.push_back(c.source_id); + to_hash.push_back(c.alternative_tile); + uint32_t hash = RandomPCG(to_hash.hash()).rand(); + + Color color; + color = color.from_hsv( + (float)((hash >> 24) & 0xFF) / 256.0, + Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0), + Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0), + 0.8); + + // Draw a placeholder tile. + Transform2D xform; + xform.set_origin(p_tile_map->map_to_world(E_cell->get()) - quadrant_pos); + rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); + rs->canvas_item_add_circle(p_quadrant->debug_canvas_item, Vector2(), MIN(tile_set->get_tile_size().x, tile_set->get_tile_size().y) / 4.0, color); + } + } + } } } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 20cf183a20..6cf4198f30 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -57,10 +57,10 @@ class TileData; // Forward-declare the plugins. class TileSetPlugin; -class TileSetAtlasPluginRendering; -class TileSetAtlasPluginPhysics; -class TileSetAtlasPluginNavigation; -class TileSetAtlasPluginTerrain; +class TileSetPluginAtlasRendering; +class TileSetPluginAtlasPhysics; +class TileSetPluginAtlasNavigation; +class TileSetPluginAtlasTerrain; class TileSet : public Resource { GDCLASS(TileSet, Resource); @@ -264,7 +264,7 @@ public: int get_next_source_id() const; int get_source_count() const; int get_source_id(int p_index) const; - int add_source(Ref<TileSetAtlasSource> p_tile_atlas_source, int p_source_id_override = -1); + int add_source(Ref<TileSetSource> p_tile_set_source, int p_source_id_override = -1); void set_source_id(int p_source_id, int p_new_id); void remove_source(int p_source_id); bool has_source(int p_source_id) const; @@ -338,6 +338,9 @@ protected: const TileSet *tile_set = nullptr; public: + static const Vector2i INVALID_ATLAS_COORDS; // Vector2i(-1, -1); + static const int INVALID_TILE_ALTERNATIVE; // -1; + // Not exposed. virtual void set_tile_set(const TileSet *p_tile_set); virtual void notify_tile_data_properties_should_change(){}; @@ -358,9 +361,6 @@ class TileSetAtlasSource : public TileSetSource { GDCLASS(TileSetAtlasSource, TileSetSource); public: - static const Vector2i INVALID_ATLAS_COORDS; // Vector2i(-1, -1); - static const int INVALID_TILE_ALTERNATIVE; // -1; - struct TileAlternativesData { Vector2i size_in_atlas = Vector2i(1, 1); Vector2i texture_offset; @@ -443,6 +443,52 @@ public: ~TileSetAtlasSource(); }; +class TileSetScenesCollectionSource : public TileSetSource { + GDCLASS(TileSetScenesCollectionSource, TileSetSource); + +private: + struct SceneData { + Ref<PackedScene> scene; + bool display_placeholder = false; + }; + Vector<int> scenes_ids; + Map<int, SceneData> scenes; + int next_scene_id = 1; + + void _compute_next_alternative_id(); + +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + static void _bind_methods(); + +public: + // Tiles. + int get_tiles_count() const override; + Vector2i get_tile_id(int p_tile_index) const override; + bool has_tile(Vector2i p_atlas_coords) const override; + + // Alternative tiles. + int get_alternative_tiles_count(const Vector2i p_atlas_coords) const override; + int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override; + bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override; + + // Scenes sccessors. Lot are similar to "Alternative tiles". + int get_scene_tiles_count() { return get_alternative_tiles_count(Vector2i()); } + int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); }; + bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); }; + int create_scene_tile(Ref<PackedScene> p_packed_scene = Ref<PackedScene>(), int p_id_override = -1); + void set_scene_tile_id(int p_id, int p_new_id); + void set_scene_tile_scene(int p_id, Ref<PackedScene> p_packed_scene); + Ref<PackedScene> get_scene_tile_scene(int p_id) const; + void set_scene_tile_display_placeholder(int p_id, bool p_packed_scene); + bool get_scene_tile_display_placeholder(int p_id) const; + void remove_scene_tile(int p_id); + int get_next_scene_tile_id() const; +}; + class TileData : public Object { GDCLASS(TileData, Object); @@ -458,7 +504,7 @@ private: Ref<ShaderMaterial> material = Ref<ShaderMaterial>(); Color modulate = Color(1.0, 1.0, 1.0, 1.0); int z_index = 0; - Vector2i y_sort_origin = Vector2i(); + int y_sort_origin = 0; Vector<Ref<OccluderPolygon2D>> occluders; // Physics @@ -517,8 +563,8 @@ public: Color get_modulate() const; void set_z_index(int p_z_index); int get_z_index() const; - void set_y_sort_origin(Vector2i p_y_sort_origin); - Vector2i get_y_sort_origin() const; + void set_y_sort_origin(int p_y_sort_origin); + int get_y_sort_origin() const; void set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon); Ref<OccluderPolygon2D> get_occluder(int p_layer_id) const; @@ -572,8 +618,8 @@ public: virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant){}; }; -class TileSetAtlasPluginRendering : public TileSetPlugin { - GDCLASS(TileSetAtlasPluginRendering, TileSetPlugin); +class TileSetPluginAtlasRendering : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasRendering, TileSetPlugin); private: static constexpr float fp_adjust = 0.00001; @@ -585,13 +631,14 @@ public: virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; virtual void create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; // Other. static void draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0)); }; -class TileSetAtlasPluginTerrain : public TileSetPlugin { - GDCLASS(TileSetAtlasPluginTerrain, TileSetPlugin); +class TileSetPluginAtlasTerrain : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasTerrain, TileSetPlugin); private: static void _draw_square_corner_or_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit); @@ -607,13 +654,11 @@ private: static void _draw_half_offset_side_terrain_bit(CanvasItem *p_canvas_item, Color p_color, Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis); public: - //virtual void tilemap_notification(const TileMap * p_tile_map, int p_what); - static void draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, TileSet *p_tile_set, const TileData *p_tile_data); }; -class TileSetAtlasPluginPhysics : public TileSetPlugin { - GDCLASS(TileSetAtlasPluginPhysics, TileSetPlugin); +class TileSetPluginAtlasPhysics : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasPhysics, TileSetPlugin); public: // Tilemap updates @@ -624,14 +669,23 @@ public: virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; }; -class TileSetAtlasPluginNavigation : public TileSetPlugin { - GDCLASS(TileSetAtlasPluginNavigation, TileSetPlugin); +class TileSetPluginAtlasNavigation : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasNavigation, TileSetPlugin); public: // Tilemap updates virtual void tilemap_notification(TileMap *p_tile_map, int p_what) override; virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; - //virtual void create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; +}; + +class TileSetPluginScenesCollections : public TileSetPlugin { + GDCLASS(TileSetPluginScenesCollections, TileSetPlugin); + +public: + // Tilemap updates + virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; }; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index b810f9562e..f37b1a3e8e 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -94,6 +94,52 @@ bool VisualShaderNode::is_generate_input_var(int p_port) const { return true; } +bool VisualShaderNode::is_output_port_expandable(int p_port) const { + return false; +} + +void VisualShaderNode::_set_output_ports_expanded(const Array &p_values) { + for (int i = 0; i < p_values.size(); i++) { + expanded_output_ports[p_values[i]] = true; + } + emit_changed(); +} + +Array VisualShaderNode::_get_output_ports_expanded() const { + Array arr; + for (int i = 0; i < get_output_port_count(); i++) { + if (_is_output_port_expanded(i)) { + arr.push_back(i); + } + } + return arr; +} + +void VisualShaderNode::_set_output_port_expanded(int p_port, bool p_expanded) { + expanded_output_ports[p_port] = p_expanded; + emit_changed(); +} + +bool VisualShaderNode::_is_output_port_expanded(int p_port) const { + if (expanded_output_ports.has(p_port)) { + return expanded_output_ports[p_port]; + } + return false; +} + +int VisualShaderNode::get_expanded_output_port_count() const { + int count = get_output_port_count(); + int count2 = count; + for (int i = 0; i < count; i++) { + if (is_output_port_expandable(i) && _is_output_port_expanded(i)) { + if (get_output_port_type(i) == PORT_TYPE_VECTOR) { + count2 += 3; + } + } + } + return count2; +} + bool VisualShaderNode::is_code_generated() const { return true; } @@ -106,6 +152,14 @@ bool VisualShaderNode::is_use_prop_slots() const { return false; } +bool VisualShaderNode::is_disabled() const { + return disabled; +} + +void VisualShaderNode::set_disabled(bool p_disabled) { + disabled = p_disabled; +} + Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { return Vector<VisualShader::DefaultTextureParam>(); } @@ -157,6 +211,12 @@ void VisualShaderNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview); ClassDB::bind_method(D_METHOD("get_output_port_for_preview"), &VisualShaderNode::get_output_port_for_preview); + ClassDB::bind_method(D_METHOD("_set_output_port_expanded", "port"), &VisualShaderNode::_set_output_port_expanded); + ClassDB::bind_method(D_METHOD("_is_output_port_expanded"), &VisualShaderNode::_is_output_port_expanded); + + ClassDB::bind_method(D_METHOD("_set_output_ports_expanded", "values"), &VisualShaderNode::_set_output_ports_expanded); + ClassDB::bind_method(D_METHOD("_get_output_ports_expanded"), &VisualShaderNode::_get_output_ports_expanded); + ClassDB::bind_method(D_METHOD("set_input_port_default_value", "port", "value"), &VisualShaderNode::set_input_port_default_value); ClassDB::bind_method(D_METHOD("get_input_port_default_value", "port"), &VisualShaderNode::get_input_port_default_value); @@ -165,6 +225,7 @@ void VisualShaderNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_default_input_values", "get_default_input_values"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "expanded_output_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_output_ports_expanded", "_get_output_ports_expanded"); ADD_SIGNAL(MethodInfo("editor_refresh_request")); BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR); @@ -576,7 +637,7 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po return false; } - if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count()) { + if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_expanded_output_port_count()) { return false; } @@ -617,7 +678,7 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from Graph *g = &graph[p_type]; ERR_FAIL_COND(!g->nodes.has(p_from_node)); - ERR_FAIL_INDEX(p_from_port, g->nodes[p_from_node].node->get_output_port_count()); + ERR_FAIL_INDEX(p_from_port, g->nodes[p_from_node].node->get_expanded_output_port_count()); ERR_FAIL_COND(!g->nodes.has(p_to_node)); ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count()); @@ -639,7 +700,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, Graph *g = &graph[p_type]; ERR_FAIL_COND_V(!g->nodes.has(p_from_node), ERR_INVALID_PARAMETER); - ERR_FAIL_INDEX_V(p_from_port, g->nodes[p_from_node].node->get_output_port_count(), ERR_INVALID_PARAMETER); + ERR_FAIL_INDEX_V(p_from_port, g->nodes[p_from_node].node->get_expanded_output_port_count(), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!g->nodes.has(p_to_node), ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_to_port, g->nodes[p_to_node].node->get_input_port_count(), ERR_INVALID_PARAMETER); @@ -790,7 +851,7 @@ bool VisualShader::is_text_shader() const { String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &default_tex_params) const { Ref<VisualShaderNode> node = get_node(p_type, p_node); ERR_FAIL_COND_V(!node.is_valid(), String()); - ERR_FAIL_COND_V(p_port < 0 || p_port >= node->get_output_port_count(), String()); + ERR_FAIL_COND_V(p_port < 0 || p_port >= node->get_expanded_output_port_count(), String()); ERR_FAIL_COND_V(node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_TRANSFORM, String()); StringBuilder global_code; @@ -1207,6 +1268,12 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const { const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node; + if (vsnode->is_disabled()) { + code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n"; + code += "\t// Node is disabled and code is not generated.\n"; + return OK; + } + //check inputs recursively first int input_count = vsnode->get_input_port_count(); for (int i = 0; i < input_count; i++) { @@ -1275,6 +1342,11 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui if (input_connections.has(ck)) { //connected to something, use that output int from_node = input_connections[ck]->get().from_node; + + if (graph[type].nodes[from_node].node->is_disabled()) { + continue; + } + int from_port = input_connections[ck]->get().from_port; VisualShaderNode::PortType in_type = vsnode->get_input_port_type(i); @@ -1362,13 +1434,30 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } int output_count = vsnode->get_output_port_count(); + int initial_output_count = output_count; + + Map<int, bool> expanded_output_ports; + + for (int i = 0; i < initial_output_count; i++) { + bool expanded = false; + + if (vsnode->is_output_port_expandable(i) && vsnode->_is_output_port_expanded(i)) { + expanded = true; + + if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) { + output_count += 3; + } + } + expanded_output_ports.insert(i, expanded); + } + Vector<String> output_vars; - output_vars.resize(vsnode->get_output_port_count()); + output_vars.resize(output_count); String *outputs = output_vars.ptrw(); if (vsnode->is_simple_decl()) { // less code to generate for some simple_decl nodes - for (int i = 0; i < output_count; i++) { - String var_name = "n_out" + itos(node) + "p" + itos(i); + for (int i = 0, j = 0; i < initial_output_count; i++, j++) { + String var_name = "n_out" + itos(node) + "p" + itos(j); switch (vsnode->get_output_port_type(i)) { case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; @@ -1388,35 +1477,84 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui default: { } } + if (expanded_output_ports[i]) { + if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) { + j += 3; + } + } } } else { - for (int i = 0; i < output_count; i++) { - outputs[i] = "n_out" + itos(node) + "p" + itos(i); + for (int i = 0, j = 0; i < initial_output_count; i++, j++) { + outputs[i] = "n_out" + itos(node) + "p" + itos(j); switch (vsnode->get_output_port_type(i)) { case VisualShaderNode::PORT_TYPE_SCALAR: - code += String() + "\tfloat " + outputs[i] + ";\n"; + code += "\tfloat " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_SCALAR_INT: - code += String() + "\tint " + outputs[i] + ";\n"; + code += "\tint " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_VECTOR: - code += String() + "\tvec3 " + outputs[i] + ";\n"; + code += "\tvec3 " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_BOOLEAN: - code += String() + "\tbool " + outputs[i] + ";\n"; + code += "\tbool " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_TRANSFORM: - code += String() + "\tmat4 " + outputs[i] + ";\n"; + code += "\tmat4 " + outputs[i] + ";\n"; break; default: { } } + if (expanded_output_ports[i]) { + if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) { + j += 3; + } + } } } code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); + for (int i = 0; i < output_count; i++) { + bool new_line_inserted = false; + if (expanded_output_ports[i]) { + if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) { + if (vsnode->is_output_port_connected(i + 1) || (for_preview && vsnode->get_output_port_for_preview() == (i + 1))) { // red-component + if (!new_line_inserted) { + code += "\n"; + new_line_inserted = true; + } + String r = "n_out" + itos(node) + "p" + itos(i + 1); + code += "\tfloat " + r + " = n_out" + itos(node) + "p" + itos(i) + ".r;\n"; + outputs[i + 1] = r; + } + + if (vsnode->is_output_port_connected(i + 2) || (for_preview && vsnode->get_output_port_for_preview() == (i + 2))) { // green-component + if (!new_line_inserted) { + code += "\n"; + new_line_inserted = true; + } + String g = "n_out" + itos(node) + "p" + itos(i + 2); + code += "\tfloat " + g + " = n_out" + itos(node) + "p" + itos(i) + ".g;\n"; + outputs[i + 2] = g; + } + + if (vsnode->is_output_port_connected(i + 3) || (for_preview && vsnode->get_output_port_for_preview() == (i + 3))) { // blue-component + if (!new_line_inserted) { + code += "\n"; + new_line_inserted = true; + } + String b = "n_out" + itos(node) + "p" + itos(i + 3); + code += "\tfloat " + b + " = n_out" + itos(node) + "p" + itos(i) + ".b;\n"; + outputs[i + 3] = b; + } + + i += 3; + } + } + } + code += "\n"; // processed.insert(node); @@ -2412,6 +2550,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_view_matrix", "MODELVIEW_MATRIX" }, + // Spatial, Fragment { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "albedo", "ALBEDO" }, @@ -2551,9 +2691,13 @@ String VisualShaderNodeOutput::get_output_port_name(int p_port) const { } bool VisualShaderNodeOutput::is_port_separator(int p_index) const { + if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_VERTEX) { + String name = get_input_port_name(p_index); + return bool(name == "Model View Matrix"); + } if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) { String name = get_input_port_name(p_index); - return (name == "Normal" || name == "Rim" || name == "Alpha Scissor Threshold"); + return bool(name == "Normal" || name == "Rim" || name == "Alpha Scissor Threshold"); } return false; } @@ -3148,11 +3292,11 @@ int VisualShaderNodeGroupBase::get_free_output_port_id() const { return output_ports.size(); } -void VisualShaderNodeGroupBase::set_control(Control *p_control, int p_index) { +void VisualShaderNodeGroupBase::set_ctrl_pressed(Control *p_control, int p_index) { controls[p_index] = p_control; } -Control *VisualShaderNodeGroupBase::get_control(int p_index) { +Control *VisualShaderNodeGroupBase::is_ctrl_pressed(int p_index) { ERR_FAIL_COND_V(!controls.has(p_index), nullptr); return controls[p_index]; } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 8af0fc9e44..aa7768751e 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -199,9 +199,12 @@ class VisualShaderNode : public Resource { Map<int, Variant> default_input_values; Map<int, bool> connected_input_ports; Map<int, int> connected_output_ports; + Map<int, bool> expanded_output_ports; protected: bool simple_decl = true; + bool disabled = false; + static void _bind_methods(); public: @@ -245,17 +248,28 @@ public: void set_input_port_connected(int p_port, bool p_connected); virtual bool is_generate_input_var(int p_port) const; + virtual bool is_output_port_expandable(int p_port) const; + void _set_output_ports_expanded(const Array &p_data); + Array _get_output_ports_expanded() const; + void _set_output_port_expanded(int p_port, bool p_expanded); + bool _is_output_port_expanded(int p_port) const; + int get_expanded_output_port_count() const; + virtual bool is_code_generated() const; virtual bool is_show_prop_names() const; virtual bool is_use_prop_slots() const; + bool is_disabled() const; + void set_disabled(bool p_disabled = true); + virtual Vector<StringName> get_editable_properties() const; virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const = 0; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + // If no output is connected, the output var passed will be empty. If no input is connected and input is NIL, the input var passed will be empty. + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const = 0; virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; @@ -610,8 +624,8 @@ public: int get_free_input_port_id() const; int get_free_output_port_id() const; - void set_control(Control *p_control, int p_index); - Control *get_control(int p_index); + void set_ctrl_pressed(Control *p_control, int p_index); + Control *is_ctrl_pressed(int p_index); void set_editable(bool p_enabled); bool is_editable() const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 7943b95177..e7cc78cb3a 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -242,6 +242,13 @@ String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const { return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port } +bool VisualShaderNodeColorConstant::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.r, constant.g, constant.b) + ";\n"; @@ -455,6 +462,13 @@ String VisualShaderNodeTexture::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +bool VisualShaderNodeTexture::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const { if (p_port == 0) { return "default"; @@ -775,7 +789,7 @@ void VisualShaderNodeTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_SCREEN); @@ -917,6 +931,13 @@ String VisualShaderNodeSample3D::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +bool VisualShaderNodeSample3D::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + String VisualShaderNodeSample3D::get_input_port_default_hint(int p_port) const { if (p_port == 0) { return "default"; @@ -1168,6 +1189,13 @@ String VisualShaderNodeCubemap::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } +bool VisualShaderNodeCubemap::is_output_port_expandable(int p_port) const { + if (p_port == 0) { + return true; + } + return false; +} + Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "cube"); @@ -1308,7 +1336,7 @@ void VisualShaderNodeCubemap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_PORT); @@ -1409,7 +1437,7 @@ void VisualShaderNodeFloatOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2,Step"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,ATan2,Step"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1506,7 +1534,7 @@ void VisualShaderNodeIntOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1615,7 +1643,7 @@ void VisualShaderNodeVectorOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Cross,Atan2,Reflect,Step"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,Cross,ATan2,Reflect,Step"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1785,7 +1813,7 @@ void VisualShaderNodeColorOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,SoftLight,HardLight"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,Soft Light,Hard Light"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_SCREEN); BIND_ENUM_CONSTANT(OP_DIFFERENCE); @@ -3899,7 +3927,7 @@ void VisualShaderNodeIntUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value); ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value); - ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range + Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step"); @@ -4487,7 +4515,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureUniform::set_color_default); ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureUniform::get_color_default); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap,Aniso"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White Default,Black Default"), "set_color_default", "get_color_default"); BIND_ENUM_CONSTANT(TYPE_DATA); @@ -5551,3 +5579,127 @@ VisualShaderNodeMultiplyAdd::VisualShaderNodeMultiplyAdd() { set_input_port_default_value(1, 0.0); set_input_port_default_value(2, 0.0); } + +////////////// Billboard + +String VisualShaderNodeBillboard::get_caption() const { + return "GetBillboardMatrix"; +} + +int VisualShaderNodeBillboard::get_input_port_count() const { + return 0; +} + +VisualShaderNodeBillboard::PortType VisualShaderNodeBillboard::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeBillboard::get_input_port_name(int p_port) const { + return ""; +} + +int VisualShaderNodeBillboard::get_output_port_count() const { + return 1; +} + +VisualShaderNodeBillboard::PortType VisualShaderNodeBillboard::get_output_port_type(int p_port) const { + return PORT_TYPE_TRANSFORM; +} + +String VisualShaderNodeBillboard::get_output_port_name(int p_port) const { + return "model_view_matrix"; +} + +String VisualShaderNodeBillboard::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + + switch (billboard_type) { + case BILLBOARD_TYPE_ENABLED: + code += "\t{\n"; + code += "\t\tmat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], CAMERA_MATRIX[1], CAMERA_MATRIX[2], WORLD_MATRIX[3]);\n"; + if (keep_scale) { + code += "\t\t__mvm = __mvm * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + } + code += "\t\t" + p_output_vars[0] + " = __mvm;\n"; + code += "\t}\n"; + break; + case BILLBOARD_TYPE_FIXED_Y: + code += "\t{\n"; + code += "\t\tmat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], WORLD_MATRIX[1], vec4(normalize(cross(CAMERA_MATRIX[0].xyz, WORLD_MATRIX[1].xyz)), 0.0), WORLD_MATRIX[3]);\n"; + if (keep_scale) { + code += "\t\t__mvm = __mvm * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + } else { + code += "\t\t__mvm = __mvm * mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0 / length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + } + code += "\t\t" + p_output_vars[0] + " = __mvm;\n"; + code += "\t}\n"; + break; + case BILLBOARD_TYPE_PARTICLES: + code += "\t{\n"; + code += "\t\tmat4 __wm = mat4(normalize(CAMERA_MATRIX[0]) * length(WORLD_MATRIX[0]), normalize(CAMERA_MATRIX[1]) * length(WORLD_MATRIX[0]), normalize(CAMERA_MATRIX[2]) * length(WORLD_MATRIX[2]), WORLD_MATRIX[3]);\n"; + code += "\t\t__wm = __wm * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += "\t\t" + p_output_vars[0] + " = INV_CAMERA_MATRIX * __wm;\n"; + code += "\t}\n"; + break; + default: + code += "\t" + p_output_vars[0] + " = mat4(1.0);\n"; + break; + } + + return code; +} + +bool VisualShaderNodeBillboard::is_show_prop_names() const { + return true; +} + +void VisualShaderNodeBillboard::set_billboard_type(BillboardType p_billboard_type) { + ERR_FAIL_INDEX((int)p_billboard_type, BILLBOARD_TYPE_MAX); + billboard_type = p_billboard_type; + simple_decl = bool(billboard_type == BILLBOARD_TYPE_DISABLED); + set_disabled(simple_decl); + emit_changed(); +} + +VisualShaderNodeBillboard::BillboardType VisualShaderNodeBillboard::get_billboard_type() const { + return billboard_type; +} + +void VisualShaderNodeBillboard::set_keep_scale_enabled(bool p_enabled) { + keep_scale = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeBillboard::is_keep_scale_enabled() const { + return keep_scale; +} + +Vector<StringName> VisualShaderNodeBillboard::get_editable_properties() const { + Vector<StringName> props; + props.push_back("billboard_type"); + if (billboard_type == BILLBOARD_TYPE_ENABLED || billboard_type == BILLBOARD_TYPE_FIXED_Y) { + props.push_back("keep_scale"); + } + return props; +} + +void VisualShaderNodeBillboard::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_billboard_type", "billboard_type"), &VisualShaderNodeBillboard::set_billboard_type); + ClassDB::bind_method(D_METHOD("get_billboard_type"), &VisualShaderNodeBillboard::get_billboard_type); + + ClassDB::bind_method(D_METHOD("set_keep_scale_enabled", "enabled"), &VisualShaderNodeBillboard::set_keep_scale_enabled); + ClassDB::bind_method(D_METHOD("is_keep_scale_enabled"), &VisualShaderNodeBillboard::is_keep_scale_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_type", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particles"), "set_billboard_type", "get_billboard_type"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_scale"), "set_keep_scale_enabled", "is_keep_scale_enabled"); + + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_DISABLED); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_ENABLED); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_FIXED_Y); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_PARTICLES); + BIND_ENUM_CONSTANT(BILLBOARD_TYPE_MAX); +} + +VisualShaderNodeBillboard::VisualShaderNodeBillboard() { + simple_decl = false; +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 594a494cf1..1c70459e3b 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -74,7 +74,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_constant(float p_value); float get_constant() const; @@ -104,7 +104,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_constant(int p_value); int get_constant() const; @@ -134,7 +134,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_constant(bool p_value); bool get_constant() const; @@ -163,8 +163,9 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool is_output_port_expandable(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_constant(Color p_value); Color get_constant() const; @@ -194,7 +195,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_constant(Vector3 p_value); Vector3 get_constant() const; @@ -224,7 +225,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_constant(Transform p_value); Transform get_constant() const; @@ -275,12 +276,13 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool is_output_port_expandable(int p_port) const override; virtual String get_input_port_default_hint(int p_port) const override; virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_source(Source p_source); Source get_source() const; @@ -323,7 +325,7 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_texture(Ref<CurveTexture> p_value); Ref<CurveTexture> get_texture() const; @@ -359,8 +361,9 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool is_output_port_expandable(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_source(Source p_source); Source get_source() const; @@ -452,10 +455,11 @@ public: virtual int get_output_port_count() const override; virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; + virtual bool is_output_port_expandable(int p_port) const override; virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_source(Source p_source); Source get_source() const; @@ -512,7 +516,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_operator(Operator p_op); Operator get_operator() const; @@ -554,7 +558,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_operator(Operator p_op); Operator get_operator() const; @@ -601,7 +605,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_operator(Operator p_op); Operator get_operator() const; @@ -647,7 +651,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_operator(Operator p_op); Operator get_operator() const; @@ -690,7 +694,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_operator(Operator p_op); Operator get_operator() const; @@ -733,7 +737,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_operator(Operator p_op); Operator get_operator() const; @@ -804,7 +808,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -846,7 +850,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -920,7 +924,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -961,7 +965,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -1002,7 +1006,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -1032,7 +1036,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeDotProduct(); }; @@ -1055,7 +1059,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeVectorLen(); }; @@ -1078,7 +1082,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeDeterminant(); }; @@ -1118,7 +1122,7 @@ public: virtual Vector<StringName> get_editable_properties() const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeClamp(); }; @@ -1155,7 +1159,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -1195,7 +1199,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -1225,7 +1229,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeFaceForward(); }; @@ -1248,7 +1252,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeOuterProduct(); }; @@ -1288,7 +1292,7 @@ public: virtual Vector<StringName> get_editable_properties() const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeStep(); }; @@ -1330,7 +1334,7 @@ public: virtual Vector<StringName> get_editable_properties() const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeSmoothStep(); }; @@ -1355,7 +1359,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeVectorDistance(); }; @@ -1378,7 +1382,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeVectorRefract(); }; @@ -1418,7 +1422,7 @@ public: virtual Vector<StringName> get_editable_properties() const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeMix(); }; @@ -1443,7 +1447,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeVectorCompose(); }; @@ -1464,7 +1468,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeTransformCompose(); }; @@ -1487,7 +1491,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeVectorDecompose(); }; @@ -1508,7 +1512,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeTransformDecompose(); }; @@ -1550,7 +1554,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_show_prop_names() const override; virtual bool is_use_prop_slots() const override; @@ -1616,7 +1620,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_show_prop_names() const override; virtual bool is_use_prop_slots() const override; @@ -1673,7 +1677,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_show_prop_names() const override; virtual bool is_use_prop_slots() const override; @@ -1716,7 +1720,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_show_prop_names() const override; @@ -1758,7 +1762,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_show_prop_names() const override; virtual bool is_use_prop_slots() const override; @@ -1801,7 +1805,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_show_prop_names() const override; virtual bool is_use_prop_slots() const override; @@ -1858,7 +1862,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; virtual bool is_code_generated() const override; @@ -1895,7 +1899,7 @@ public: virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeTextureUniformTriplanar(); }; @@ -1918,7 +1922,7 @@ public: virtual String get_input_port_default_hint(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeTexture2DArrayUniform(); }; @@ -1941,7 +1945,7 @@ public: virtual String get_input_port_default_hint(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeTexture3DUniform(); }; @@ -1964,7 +1968,7 @@ public: virtual String get_input_port_default_hint(int p_port) const override; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeCubemapUniform(); }; @@ -2092,7 +2096,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_function(Function p_func); Function get_function() const; @@ -2153,7 +2157,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_comparison_type(ComparisonType p_type); ComparisonType get_comparison_type() const; @@ -2201,7 +2205,7 @@ public: virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; - virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; void set_op_type(OpType p_type); OpType get_op_type() const; @@ -2213,4 +2217,51 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeMultiplyAdd::OpType) +class VisualShaderNodeBillboard : public VisualShaderNode { + GDCLASS(VisualShaderNodeBillboard, VisualShaderNode); + +public: + enum BillboardType { + BILLBOARD_TYPE_DISABLED, + BILLBOARD_TYPE_ENABLED, + BILLBOARD_TYPE_FIXED_Y, + BILLBOARD_TYPE_PARTICLES, + BILLBOARD_TYPE_MAX, + }; + +protected: + BillboardType billboard_type = BILLBOARD_TYPE_ENABLED; + bool keep_scale = false; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + virtual bool is_show_prop_names() const override; + + void set_billboard_type(BillboardType p_billboard_type); + BillboardType get_billboard_type() const; + + void set_keep_scale_enabled(bool p_enabled); + bool is_keep_scale_enabled() const; + + virtual Vector<StringName> get_editable_properties() const override; + + VisualShaderNodeBillboard(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeBillboard::BillboardType) + #endif // VISUAL_SHADER_NODES_H diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index ccdc5bebd0..0a0742753f 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -357,7 +357,7 @@ World2D::World2D() { // Create and configure space2D to be more friendly with pixels than meters space = PhysicsServer2D::get_singleton()->space_create(); PhysicsServer2D::get_singleton()->space_set_active(space, true); - PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98)); + PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 980.0)); PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1))); PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/2d/default_linear_damp", 0.1)); ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index 06d51776a3..5c076ca3fe 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -159,7 +159,7 @@ void AudioEffectDistortion::_bind_methods() { ClassDB::bind_method(D_METHOD("set_post_gain", "post_gain"), &AudioEffectDistortion::set_post_gain); ClassDB::bind_method(D_METHOD("get_post_gain"), &AudioEffectDistortion::get_post_gain); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,WaveShape"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,Wave Shape"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pre_gain", PROPERTY_HINT_RANGE, "-60,60,0.01"), "set_pre_gain", "get_pre_gain"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_keep_hf_hz", "get_keep_hf_hz"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drive", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drive", "get_drive"); diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp index 2123fe8548..7b0151b9c1 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.cpp +++ b/servers/audio/effects/audio_effect_pitch_shift.cpp @@ -326,12 +326,12 @@ int AudioEffectPitchShift::get_oversampling() const { return oversampling; } -void AudioEffectPitchShift::set_fft_size(FFT_Size p_fft_size) { +void AudioEffectPitchShift::set_fft_size(FFTSize p_fft_size) { ERR_FAIL_INDEX(p_fft_size, FFT_SIZE_MAX); fft_size = p_fft_size; } -AudioEffectPitchShift::FFT_Size AudioEffectPitchShift::get_fft_size() const { +AudioEffectPitchShift::FFTSize AudioEffectPitchShift::get_fft_size() const { return fft_size; } diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h index 18a9c33968..669943fa43 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.h +++ b/servers/audio/effects/audio_effect_pitch_shift.h @@ -89,7 +89,7 @@ class AudioEffectPitchShift : public AudioEffect { public: friend class AudioEffectPitchShiftInstance; - enum FFT_Size { + enum FFTSize { FFT_SIZE_256, FFT_SIZE_512, FFT_SIZE_1024, @@ -100,7 +100,7 @@ public: float pitch_scale; int oversampling; - FFT_Size fft_size; + FFTSize fft_size; float wet; float dry; bool filter; @@ -117,12 +117,12 @@ public: void set_oversampling(int p_oversampling); int get_oversampling() const; - void set_fft_size(FFT_Size); - FFT_Size get_fft_size() const; + void set_fft_size(FFTSize); + FFTSize get_fft_size() const; AudioEffectPitchShift(); }; -VARIANT_ENUM_CAST(AudioEffectPitchShift::FFT_Size); +VARIANT_ENUM_CAST(AudioEffectPitchShift::FFTSize); #endif // AUDIO_EFFECT_PITCH_SHIFT_H diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp index 3f7ab74a74..44b7f64d52 100644 --- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp +++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp @@ -245,12 +245,12 @@ float AudioEffectSpectrumAnalyzer::get_tap_back_pos() const { return tapback_pos; } -void AudioEffectSpectrumAnalyzer::set_fft_size(FFT_Size p_fft_size) { +void AudioEffectSpectrumAnalyzer::set_fft_size(FFTSize p_fft_size) { ERR_FAIL_INDEX(p_fft_size, FFT_SIZE_MAX); fft_size = p_fft_size; } -AudioEffectSpectrumAnalyzer::FFT_Size AudioEffectSpectrumAnalyzer::get_fft_size() const { +AudioEffectSpectrumAnalyzer::FFTSize AudioEffectSpectrumAnalyzer::get_fft_size() const { return fft_size; } diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.h b/servers/audio/effects/audio_effect_spectrum_analyzer.h index fba276e2bb..fc275446f0 100644 --- a/servers/audio/effects/audio_effect_spectrum_analyzer.h +++ b/servers/audio/effects/audio_effect_spectrum_analyzer.h @@ -71,7 +71,7 @@ class AudioEffectSpectrumAnalyzer : public AudioEffect { GDCLASS(AudioEffectSpectrumAnalyzer, AudioEffect); public: - enum FFT_Size { + enum FFTSize { FFT_SIZE_256, FFT_SIZE_512, FFT_SIZE_1024, @@ -84,7 +84,7 @@ public: friend class AudioEffectSpectrumAnalyzerInstance; float buffer_length; float tapback_pos; - FFT_Size fft_size; + FFTSize fft_size; protected: static void _bind_methods(); @@ -96,12 +96,12 @@ public: void set_tap_back_pos(float p_seconds); float get_tap_back_pos() const; - void set_fft_size(FFT_Size); - FFT_Size get_fft_size() const; + void set_fft_size(FFTSize); + FFTSize get_fft_size() const; AudioEffectSpectrumAnalyzer(); }; -VARIANT_ENUM_CAST(AudioEffectSpectrumAnalyzer::FFT_Size); +VARIANT_ENUM_CAST(AudioEffectSpectrumAnalyzer::FFTSize); #endif // AUDIO_EFFECT_SPECTRUM_ANALYZER_H diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 08c482553b..0e816fd4f8 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1164,6 +1164,9 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) { Bus::Effect bfx; bfx.effect = fx; bfx.enabled = p_bus_layout->buses[i].effects[j].enabled; +#if DEBUG_ENABLED + bfx.prof_time = 0; +#endif bus->effects.push_back(bfx); } } diff --git a/servers/display_server.h b/servers/display_server.h index f05aa1f59a..c108281aff 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -175,6 +175,9 @@ public: return scale; } virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + + // Keep the ScreenOrientation enum values in sync with the `display/window/handheld/orientation` + // project setting hint. enum ScreenOrientation { SCREEN_LANDSCAPE, SCREEN_PORTRAIT, diff --git a/servers/physics_2d/broad_phase_2d_basic.cpp b/servers/physics_2d/broad_phase_2d_basic.cpp deleted file mode 100644 index 17424629a9..0000000000 --- a/servers/physics_2d/broad_phase_2d_basic.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************/ -/* broad_phase_2d_basic.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "broad_phase_2d_basic.h" - -BroadPhase2DBasic::ID BroadPhase2DBasic::create(CollisionObject2DSW *p_object_, int p_subindex) { - current++; - - Element e; - e.owner = p_object_; - e._static = false; - e.subindex = p_subindex; - - element_map[current] = e; - return current; -} - -void BroadPhase2DBasic::move(ID p_id, const Rect2 &p_aabb) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - E->get().aabb = p_aabb; -} - -void BroadPhase2DBasic::set_static(ID p_id, bool p_static) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - E->get()._static = p_static; -} - -void BroadPhase2DBasic::remove(ID p_id) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - element_map.erase(E); -} - -CollisionObject2DSW *BroadPhase2DBasic::get_object(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, nullptr); - return E->get().owner; -} - -bool BroadPhase2DBasic::is_static(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, false); - return E->get()._static; -} - -int BroadPhase2DBasic::get_subindex(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, -1); - return E->get().subindex; -} - -int BroadPhase2DBasic::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; - - for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect2 aabb = E->get().aabb; - if (aabb.intersects_segment(p_from, p_to)) { - p_results[rc] = E->get().owner; - p_result_indices[rc] = E->get().subindex; - rc++; - if (rc >= p_max_results) { - break; - } - } - } - - return rc; -} - -int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; - - for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect2 aabb = E->get().aabb; - if (aabb.intersects(p_aabb)) { - p_results[rc] = E->get().owner; - p_result_indices[rc] = E->get().subindex; - rc++; - if (rc >= p_max_results) { - break; - } - } - } - - return rc; -} - -void BroadPhase2DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_userdata = p_userdata; - pair_callback = p_pair_callback; -} - -void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { - unpair_userdata = p_userdata; - unpair_callback = p_unpair_callback; -} - -void BroadPhase2DBasic::update() { - // recompute pairs - for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) { - for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) { - Element *elem_A = &I->get(); - Element *elem_B = &J->get(); - - if (elem_A->owner == elem_B->owner) { - continue; - } - - bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static); - - PairKey key(I->key(), J->key()); - - Map<PairKey, void *>::Element *E = pair_map.find(key); - - if (!pair_ok && E) { - if (unpair_callback) { - unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata); - } - pair_map.erase(key); - } - - if (pair_ok && !E) { - void *data = nullptr; - if (pair_callback) { - data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); - if (data) { - pair_map.insert(key, data); - } - } - } - } - } -} - -BroadPhase2DSW *BroadPhase2DBasic::_create() { - return memnew(BroadPhase2DBasic); -} - -BroadPhase2DBasic::BroadPhase2DBasic() { - current = 1; - unpair_callback = nullptr; - unpair_userdata = nullptr; - pair_callback = nullptr; - pair_userdata = nullptr; -} diff --git a/servers/physics_2d/broad_phase_2d_bvh.cpp b/servers/physics_2d/broad_phase_2d_bvh.cpp new file mode 100644 index 0000000000..5f53f4a012 --- /dev/null +++ b/servers/physics_2d/broad_phase_2d_bvh.cpp @@ -0,0 +1,116 @@ +/*************************************************************************/ +/* broad_phase_2d_bvh.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "broad_phase_2d_bvh.h" +#include "collision_object_2d_sw.h" + +BroadPhase2DSW::ID BroadPhase2DBVH::create(CollisionObject2DSW *p_object, int p_subindex, const Rect2 &p_aabb, bool p_static) { + ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? + return oid + 1; +} + +void BroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) { + bvh.move(p_id - 1, p_aabb); +} + +void BroadPhase2DBVH::set_static(ID p_id, bool p_static) { + CollisionObject2DSW *it = bvh.get(p_id - 1); + bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? +} + +void BroadPhase2DBVH::remove(ID p_id) { + bvh.erase(p_id - 1); +} + +CollisionObject2DSW *BroadPhase2DBVH::get_object(ID p_id) const { + CollisionObject2DSW *it = bvh.get(p_id - 1); + ERR_FAIL_COND_V(!it, nullptr); + return it; +} + +bool BroadPhase2DBVH::is_static(ID p_id) const { + return !bvh.is_pairable(p_id - 1); +} + +int BroadPhase2DBVH::get_subindex(ID p_id) const { + return bvh.get_subindex(p_id - 1); +} + +int BroadPhase2DBVH::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { + return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); +} + +int BroadPhase2DBVH::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { + return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); +} + +void *BroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, CollisionObject2DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject2DSW *p_object_B, int subindex_B) { + BroadPhase2DBVH *bpo = (BroadPhase2DBVH *)(self); + if (!bpo->pair_callback) { + return nullptr; + } + + return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata); +} + +void BroadPhase2DBVH::_unpair_callback(void *self, uint32_t p_A, CollisionObject2DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject2DSW *p_object_B, int subindex_B, void *pairdata) { + BroadPhase2DBVH *bpo = (BroadPhase2DBVH *)(self); + if (!bpo->unpair_callback) { + return; + } + + bpo->unpair_callback(p_object_A, subindex_A, p_object_B, subindex_B, pairdata, bpo->unpair_userdata); +} + +void BroadPhase2DBVH::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { + pair_callback = p_pair_callback; + pair_userdata = p_userdata; +} + +void BroadPhase2DBVH::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { + unpair_callback = p_unpair_callback; + unpair_userdata = p_userdata; +} + +void BroadPhase2DBVH::update() { + bvh.update(); +} + +BroadPhase2DSW *BroadPhase2DBVH::_create() { + return memnew(BroadPhase2DBVH); +} + +BroadPhase2DBVH::BroadPhase2DBVH() { + bvh.set_pair_callback(_pair_callback, this); + bvh.set_unpair_callback(_unpair_callback, this); + pair_callback = nullptr; + pair_userdata = nullptr; + unpair_userdata = nullptr; +} diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_bvh.h index ca1db360fb..6c11d2561b 100644 --- a/servers/physics_2d/broad_phase_2d_basic.h +++ b/servers/physics_2d/broad_phase_2d_bvh.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_2d_basic.h */ +/* broad_phase_2d_bvh.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,49 +28,19 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_2D_BASIC_H -#define BROAD_PHASE_2D_BASIC_H +#ifndef BROAD_PHASE_2D_BVH_H +#define BROAD_PHASE_2D_BVH_H -#include "core/templates/map.h" -#include "space_2d_sw.h" -class BroadPhase2DBasic : public BroadPhase2DSW { - struct Element { - CollisionObject2DSW *owner; - bool _static; - Rect2 aabb; - int subindex; - }; +#include "broad_phase_2d_sw.h" +#include "core/math/bvh.h" +#include "core/math/rect2.h" +#include "core/math/vector2.h" - Map<ID, Element> element_map; +class BroadPhase2DBVH : public BroadPhase2DSW { + BVH_Manager<CollisionObject2DSW, true, 128, Rect2, Vector2> bvh; - ID current; - - struct PairKey { - union { - struct { - ID a; - ID b; - }; - uint64_t key; - }; - - _FORCE_INLINE_ bool operator<(const PairKey &p_key) const { - return key < p_key.key; - } - - PairKey() { key = 0; } - PairKey(ID p_a, ID p_b) { - if (p_a > p_b) { - a = p_b; - b = p_a; - } else { - a = p_a; - b = p_b; - } - } - }; - - Map<PairKey, void *> pair_map; + static void *_pair_callback(void *, uint32_t, CollisionObject2DSW *, int, uint32_t, CollisionObject2DSW *, int); + static void _unpair_callback(void *, uint32_t, CollisionObject2DSW *, int, uint32_t, CollisionObject2DSW *, int, void *); PairCallback pair_callback; void *pair_userdata; @@ -79,7 +49,7 @@ class BroadPhase2DBasic : public BroadPhase2DSW { public: // 0 is an invalid ID - virtual ID create(CollisionObject2DSW *p_object_, int p_subindex = 0); + virtual ID create(CollisionObject2DSW *p_object, int p_subindex = 0, const Rect2 &p_aabb = Rect2(), bool p_static = false); virtual void move(ID p_id, const Rect2 &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); @@ -97,7 +67,7 @@ public: virtual void update(); static BroadPhase2DSW *_create(); - BroadPhase2DBasic(); + BroadPhase2DBVH(); }; -#endif // BROAD_PHASE_2D_BASIC_H +#endif // BROAD_PHASE_2D_BVH_H diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp deleted file mode 100644 index 35447c5389..0000000000 --- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/*************************************************************************/ -/* broad_phase_2d_hash_grid.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "broad_phase_2d_hash_grid.h" -#include "collision_object_2d_sw.h" -#include "core/config/project_settings.h" - -#define LARGE_ELEMENT_FI 1.01239812 - -void BroadPhase2DHashGrid::_pair_attempt(Element *p_elem, Element *p_with) { - if (p_elem->owner == p_with->owner) { - return; - } - if (!_test_collision_mask(p_elem->collision_mask, p_elem->collision_layer, p_with->collision_mask, p_with->collision_layer)) { - return; - } - Map<Element *, PairData *>::Element *E = p_elem->paired.find(p_with); - - ERR_FAIL_COND(p_elem->_static && p_with->_static); - - if (!E) { - PairData *pd = memnew(PairData); - p_elem->paired[p_with] = pd; - p_with->paired[p_elem] = pd; - } else { - E->get()->rc++; - } -} - -void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) { - if (p_elem->owner == p_with->owner) { - return; - } - if (!_test_collision_mask(p_elem->collision_mask, p_elem->collision_layer, p_with->collision_mask, p_with->collision_layer)) { - return; - } - Map<Element *, PairData *>::Element *E = p_elem->paired.find(p_with); - - ERR_FAIL_COND(!E); //this should really be paired.. - - E->get()->rc--; - - if (E->get()->rc == 0) { - if (E->get()->colliding) { - //uncollide - if (unpair_callback) { - unpair_callback(p_elem->owner, p_elem->subindex, p_with->owner, p_with->subindex, E->get()->ud, unpair_userdata); - } - } - - memdelete(E->get()); - p_elem->paired.erase(E); - p_with->paired.erase(p_elem); - } -} - -void BroadPhase2DHashGrid::_check_motion(Element *p_elem) { - for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) { - bool physical_collision = p_elem->aabb.intersects(E->key()->aabb); - bool logical_collision = p_elem->owner->test_collision_mask(E->key()->owner); - - if (physical_collision && logical_collision) { - if (!E->get()->colliding && pair_callback) { - E->get()->ud = pair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, pair_userdata); - } - E->get()->colliding = true; - } else { // No collision - if (E->get()->colliding && unpair_callback) { - unpair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, E->get()->ud, unpair_userdata); - E->get()->ud = nullptr; - } - E->get()->colliding = false; - } - } -} - -void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, bool p_static, bool p_force_enter) { - Vector2 sz = (p_rect.size / cell_size * LARGE_ELEMENT_FI); //use magic number to avoid floating point issues - if (sz.width * sz.height > large_object_min_surface) { - //large object, do not use grid, must check against all elements - for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - if (E->key() == p_elem->self) { - continue; // do not pair against itself - } - if (E->get()._static && p_static) { - continue; - } - - _pair_attempt(p_elem, &E->get()); - } - - large_elements[p_elem].inc(); - return; - } - - Point2i from = (p_rect.position / cell_size).floor(); - Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor(); - - for (int i = from.x; i <= to.x; i++) { - for (int j = from.y; j <= to.y; j++) { - PosKey pk; - pk.x = i; - pk.y = j; - - uint32_t idx = pk.hash() % hash_table_size; - PosBin *pb = hash_table[idx]; - - while (pb) { - if (pb->key == pk) { - break; - } - - pb = pb->next; - } - - bool entered = p_force_enter; - - if (!pb) { - //does not exist, create! - pb = memnew(PosBin); - pb->key = pk; - pb->next = hash_table[idx]; - hash_table[idx] = pb; - } - - if (p_static) { - if (pb->static_object_set[p_elem].inc() == 1) { - entered = true; - } - } else { - if (pb->object_set[p_elem].inc() == 1) { - entered = true; - } - } - - if (entered) { - for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) { - _pair_attempt(p_elem, E->key()); - } - - if (!p_static) { - for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) { - _pair_attempt(p_elem, E->key()); - } - } - } - } - } - - //pair separatedly with large elements - - for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - if (E->key() == p_elem) { - continue; // do not pair against itself - } - if (E->key()->_static && p_static) { - continue; - } - _pair_attempt(E->key(), p_elem); - } -} - -void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool p_static, bool p_force_exit) { - Vector2 sz = (p_rect.size / cell_size * LARGE_ELEMENT_FI); - if (sz.width * sz.height > large_object_min_surface) { - //unpair all elements, instead of checking all, just check what is already paired, so we at least save from checking static vs static - Map<Element *, PairData *>::Element *E = p_elem->paired.front(); - while (E) { - Map<Element *, PairData *>::Element *next = E->next(); - _unpair_attempt(p_elem, E->key()); - E = next; - } - - if (large_elements[p_elem].dec() == 0) { - large_elements.erase(p_elem); - } - return; - } - - Point2i from = (p_rect.position / cell_size).floor(); - Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor(); - - for (int i = from.x; i <= to.x; i++) { - for (int j = from.y; j <= to.y; j++) { - PosKey pk; - pk.x = i; - pk.y = j; - - uint32_t idx = pk.hash() % hash_table_size; - PosBin *pb = hash_table[idx]; - - while (pb) { - if (pb->key == pk) { - break; - } - - pb = pb->next; - } - - ERR_CONTINUE(!pb); //should exist!! - - bool exited = p_force_exit; - - if (p_static) { - if (pb->static_object_set[p_elem].dec() == 0) { - pb->static_object_set.erase(p_elem); - exited = true; - } - } else { - if (pb->object_set[p_elem].dec() == 0) { - pb->object_set.erase(p_elem); - exited = true; - } - } - - if (exited) { - for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) { - _unpair_attempt(p_elem, E->key()); - } - - if (!p_static) { - for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) { - _unpair_attempt(p_elem, E->key()); - } - } - } - - if (pb->object_set.is_empty() && pb->static_object_set.is_empty()) { - if (hash_table[idx] == pb) { - hash_table[idx] = pb->next; - } else { - PosBin *px = hash_table[idx]; - - while (px) { - if (px->next == pb) { - px->next = pb->next; - break; - } - - px = px->next; - } - - ERR_CONTINUE(!px); - } - - memdelete(pb); - } - } - } - - for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - if (E->key() == p_elem) { - continue; // do not pair against itself - } - if (E->key()->_static && p_static) { - continue; - } - - //unpair from large elements - _unpair_attempt(p_elem, E->key()); - } -} - -BroadPhase2DHashGrid::ID BroadPhase2DHashGrid::create(CollisionObject2DSW *p_object, int p_subindex) { - current++; - - Element e; - e.owner = p_object; - e._static = false; - e.collision_mask = p_object->get_collision_mask(); - e.collision_layer = p_object->get_collision_layer(); - e.subindex = p_subindex; - e.self = current; - e.pass = 0; - - element_map[current] = e; - return current; -} - -void BroadPhase2DHashGrid::move(ID p_id, const Rect2 &p_aabb) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - - Element &e = E->get(); - bool layer_changed = e.collision_mask != e.owner->get_collision_mask() || e.collision_layer != e.owner->get_collision_layer(); - - if (p_aabb != e.aabb || layer_changed) { - uint32_t old_mask = e.collision_mask; - uint32_t old_layer = e.collision_layer; - if (p_aabb != Rect2()) { - e.collision_mask = e.owner->get_collision_mask(); - e.collision_layer = e.owner->get_collision_layer(); - - _enter_grid(&e, p_aabb, e._static, layer_changed); - } - if (e.aabb != Rect2()) { - // Need _exit_grid to remove from cells based on the old layer values. - e.collision_mask = old_mask; - e.collision_layer = old_layer; - - _exit_grid(&e, e.aabb, e._static, layer_changed); - - e.collision_mask = e.owner->get_collision_mask(); - e.collision_layer = e.owner->get_collision_layer(); - } - e.aabb = p_aabb; - } - - _check_motion(&e); -} - -void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - - Element &e = E->get(); - - if (e._static == p_static) { - return; - } - - if (e.aabb != Rect2()) { - _exit_grid(&e, e.aabb, e._static, false); - } - - e._static = p_static; - - if (e.aabb != Rect2()) { - _enter_grid(&e, e.aabb, e._static, false); - _check_motion(&e); - } -} - -void BroadPhase2DHashGrid::remove(ID p_id) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - - Element &e = E->get(); - - if (e.aabb != Rect2()) { - _exit_grid(&e, e.aabb, e._static, false); - } - - element_map.erase(p_id); -} - -CollisionObject2DSW *BroadPhase2DHashGrid::get_object(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, nullptr); - return E->get().owner; -} - -bool BroadPhase2DHashGrid::is_static(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, false); - return E->get()._static; -} - -int BroadPhase2DHashGrid::get_subindex(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, -1); - return E->get().subindex; -} - -template <bool use_aabb, bool use_segment> -void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, const Point2 &p_from, const Point2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices, int &index) { - PosKey pk; - pk.x = p_cell.x; - pk.y = p_cell.y; - - uint32_t idx = pk.hash() % hash_table_size; - PosBin *pb = hash_table[idx]; - - while (pb) { - if (pb->key == pk) { - break; - } - - pb = pb->next; - } - - if (!pb) { - return; - } - - for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) { - if (index >= p_max_results) { - break; - } - if (E->key()->pass == pass) { - continue; - } - - E->key()->pass = pass; - - if (use_aabb && !p_aabb.intersects(E->key()->aabb)) { - continue; - } - - if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) { - continue; - } - - p_results[index] = E->key()->owner; - p_result_indices[index] = E->key()->subindex; - index++; - } - - for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) { - if (index >= p_max_results) { - break; - } - if (E->key()->pass == pass) { - continue; - } - - if (use_aabb && !p_aabb.intersects(E->key()->aabb)) { - continue; - } - - if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) { - continue; - } - - E->key()->pass = pass; - p_results[index] = E->key()->owner; - p_result_indices[index] = E->key()->subindex; - index++; - } -} - -int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - pass++; - - Vector2 dir = (p_to - p_from); - if (dir == Vector2()) { - return 0; - } - //avoid divisions by zero - dir.normalize(); - if (dir.x == 0.0) { - dir.x = 0.000001; - } - if (dir.y == 0.0) { - dir.y = 0.000001; - } - Vector2 delta = dir.abs(); - - delta.x = cell_size / delta.x; - delta.y = cell_size / delta.y; - - Point2i pos = (p_from / cell_size).floor(); - Point2i end = (p_to / cell_size).floor(); - - Point2i step = Vector2(SGN(dir.x), SGN(dir.y)); - - Vector2 max; - - if (dir.x < 0) { - max.x = (Math::floor((double)pos.x) * cell_size - p_from.x) / dir.x; - } else { - max.x = (Math::floor((double)pos.x + 1) * cell_size - p_from.x) / dir.x; - } - - if (dir.y < 0) { - max.y = (Math::floor((double)pos.y) * cell_size - p_from.y) / dir.y; - } else { - max.y = (Math::floor((double)pos.y + 1) * cell_size - p_from.y) / dir.y; - } - - int cullcount = 0; - _cull<false, true>(pos, Rect2(), p_from, p_to, p_results, p_max_results, p_result_indices, cullcount); - - bool reached_x = false; - bool reached_y = false; - - while (true) { - if (max.x < max.y) { - max.x += delta.x; - pos.x += step.x; - } else { - max.y += delta.y; - pos.y += step.y; - } - - if (step.x > 0) { - if (pos.x >= end.x) { - reached_x = true; - } - } else if (pos.x <= end.x) { - reached_x = true; - } - - if (step.y > 0) { - if (pos.y >= end.y) { - reached_y = true; - } - } else if (pos.y <= end.y) { - reached_y = true; - } - - _cull<false, true>(pos, Rect2(), p_from, p_to, p_results, p_max_results, p_result_indices, cullcount); - - if (reached_x && reached_y) { - break; - } - } - - for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - if (cullcount >= p_max_results) { - break; - } - if (E->key()->pass == pass) { - continue; - } - - E->key()->pass = pass; - - /* - if (use_aabb && !p_aabb.intersects(E->key()->aabb)) - continue; - */ - - if (!E->key()->aabb.intersects_segment(p_from, p_to)) { - continue; - } - - p_results[cullcount] = E->key()->owner; - p_result_indices[cullcount] = E->key()->subindex; - cullcount++; - } - - return cullcount; -} - -int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - pass++; - - Point2i from = (p_aabb.position / cell_size).floor(); - Point2i to = ((p_aabb.position + p_aabb.size) / cell_size).floor(); - int cullcount = 0; - - for (int i = from.x; i <= to.x; i++) { - for (int j = from.y; j <= to.y; j++) { - _cull<true, false>(Point2i(i, j), p_aabb, Point2(), Point2(), p_results, p_max_results, p_result_indices, cullcount); - } - } - - for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - if (cullcount >= p_max_results) { - break; - } - if (E->key()->pass == pass) { - continue; - } - - E->key()->pass = pass; - - if (!p_aabb.intersects(E->key()->aabb)) { - continue; - } - - /* - if (!E->key()->aabb.intersects_segment(p_from,p_to)) - continue; - */ - - p_results[cullcount] = E->key()->owner; - p_result_indices[cullcount] = E->key()->subindex; - cullcount++; - } - return cullcount; -} - -void BroadPhase2DHashGrid::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_callback = p_pair_callback; - pair_userdata = p_userdata; -} - -void BroadPhase2DHashGrid::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { - unpair_callback = p_unpair_callback; - unpair_userdata = p_userdata; -} - -void BroadPhase2DHashGrid::update() { -} - -BroadPhase2DSW *BroadPhase2DHashGrid::_create() { - return memnew(BroadPhase2DHashGrid); -} - -BroadPhase2DHashGrid::BroadPhase2DHashGrid() { - hash_table_size = GLOBAL_DEF("physics/2d/bp_hash_table_size", 4096); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/bp_hash_table_size", PropertyInfo(Variant::INT, "physics/2d/bp_hash_table_size", PROPERTY_HINT_RANGE, "0,8192,1,or_greater")); - hash_table_size = Math::larger_prime(hash_table_size); - hash_table = memnew_arr(PosBin *, hash_table_size); - - cell_size = GLOBAL_DEF("physics/2d/cell_size", 128); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/cell_size", PropertyInfo(Variant::INT, "physics/2d/cell_size", PROPERTY_HINT_RANGE, "0,512,1,or_greater")); - - large_object_min_surface = GLOBAL_DEF("physics/2d/large_object_surface_threshold_in_cells", 512); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/large_object_surface_threshold_in_cells", PropertyInfo(Variant::INT, "physics/2d/large_object_surface_threshold_in_cells", PROPERTY_HINT_RANGE, "0,1024,1,or_greater")); - - for (uint32_t i = 0; i < hash_table_size; i++) { - hash_table[i] = nullptr; - } - pass = 1; - - current = 0; -} - -BroadPhase2DHashGrid::~BroadPhase2DHashGrid() { - for (uint32_t i = 0; i < hash_table_size; i++) { - while (hash_table[i]) { - PosBin *pb = hash_table[i]; - hash_table[i] = pb->next; - memdelete(pb); - } - } - - memdelete_arr(hash_table); -} - -/* 3D version of voxel traversal: - -public IEnumerable<Point3D> GetCellsOnRay(Ray ray, int maxDepth) -{ - // Implementation is based on: - // "A Fast Voxel Traversal Algorithm for Ray Tracing" - // John Amanatides, Andrew Woo - // http://www.cse.yorku.ca/~amana/research/grid.pdf - // https://web.archive.org/web/20100616193049/http://www.devmaster.net/articles/raytracing_series/A%20faster%20voxel%20traversal%20algorithm%20for%20ray%20tracing.pdf - - // NOTES: - // * This code assumes that the ray's position and direction are in 'cell coordinates', which means - // that one unit equals one cell in all directions. - // * When the ray doesn't start within the voxel grid, calculate the first position at which the - // ray could enter the grid. If it never enters the grid, there is nothing more to do here. - // * Also, it is important to test when the ray exits the voxel grid when the grid isn't infinite. - // * The Point3D structure is a simple structure having three integer fields (X, Y and Z). - - // The cell in which the ray starts. - Point3D start = GetCellAt(ray.Position); // Rounds the position's X, Y and Z down to the nearest integer values. - int x = start.X; - int y = start.Y; - int z = start.Z; - - // Determine which way we go. - int stepX = Math.Sign(ray.Direction.X); - int stepY = Math.Sign(ray.Direction.Y); - int stepZ = Math.Sign(ray.Direction.Z); - - // Calculate cell boundaries. When the step (i.e. direction sign) is positive, - // the next boundary is AFTER our current position, meaning that we have to add 1. - // Otherwise, it is BEFORE our current position, in which case we add nothing. - Point3D cellBoundary = new Point3D( - x + (stepX > 0 ? 1 : 0), - y + (stepY > 0 ? 1 : 0), - z + (stepZ > 0 ? 1 : 0)); - - // NOTE: For the following calculations, the result will be Single.PositiveInfinity - // when ray.Direction.X, Y or Z equals zero, which is OK. However, when the left-hand - // value of the division also equals zero, the result is Single.NaN, which is not OK. - - // Determine how far we can travel along the ray before we hit a voxel boundary. - Vector3 tMax = new Vector3( - (cellBoundary.X - ray.Position.X) / ray.Direction.X, // Boundary is a plane on the YZ axis. - (cellBoundary.Y - ray.Position.Y) / ray.Direction.Y, // Boundary is a plane on the XZ axis. - (cellBoundary.Z - ray.Position.Z) / ray.Direction.Z); // Boundary is a plane on the XY axis. - if (Single.IsNaN(tMax.X)) tMax.X = Single.PositiveInfinity; - if (Single.IsNaN(tMax.Y)) tMax.Y = Single.PositiveInfinity; - if (Single.IsNaN(tMax.Z)) tMax.Z = Single.PositiveInfinity; - - // Determine how far we must travel along the ray before we have crossed a gridcell. - Vector3 tDelta = new Vector3( - stepX / ray.Direction.X, // Crossing the width of a cell. - stepY / ray.Direction.Y, // Crossing the height of a cell. - stepZ / ray.Direction.Z); // Crossing the depth of a cell. - if (Single.IsNaN(tDelta.X)) tDelta.X = Single.PositiveInfinity; - if (Single.IsNaN(tDelta.Y)) tDelta.Y = Single.PositiveInfinity; - if (Single.IsNaN(tDelta.Z)) tDelta.Z = Single.PositiveInfinity; - - // For each step, determine which distance to the next voxel boundary is lowest (i.e. - // which voxel boundary is nearest) and walk that way. - for (int i = 0; i < maxDepth; i++) - { - // Return it. - yield return new Point3D(x, y, z); - - // Do the next step. - if (tMax.X < tMax.Y && tMax.X < tMax.Z) - { - // tMax.X is the lowest, an YZ cell boundary plane is nearest. - x += stepX; - tMax.X += tDelta.X; - } - else if (tMax.Y < tMax.Z) - { - // tMax.Y is the lowest, an XZ cell boundary plane is nearest. - y += stepY; - tMax.Y += tDelta.Y; - } - else - { - // tMax.Z is the lowest, an XY cell boundary plane is nearest. - z += stepZ; - tMax.Z += tDelta.Z; - } - } - - */ diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h deleted file mode 100644 index bb7c03b989..0000000000 --- a/servers/physics_2d/broad_phase_2d_hash_grid.h +++ /dev/null @@ -1,194 +0,0 @@ -/*************************************************************************/ -/* broad_phase_2d_hash_grid.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef BROAD_PHASE_2D_HASH_GRID_H -#define BROAD_PHASE_2D_HASH_GRID_H - -#include "broad_phase_2d_sw.h" -#include "core/templates/map.h" - -class BroadPhase2DHashGrid : public BroadPhase2DSW { - struct PairData { - bool colliding; - int rc; - void *ud; - PairData() { - colliding = false; - rc = 1; - ud = nullptr; - } - }; - - struct Element { - ID self; - CollisionObject2DSW *owner; - bool _static; - Rect2 aabb; - // Owner's collision_mask/layer, used to detect changes in layers. - uint32_t collision_mask; - uint32_t collision_layer; - int subindex; - uint64_t pass; - Map<Element *, PairData *> paired; - }; - - struct RC { - int ref; - - _FORCE_INLINE_ int inc() { - ref++; - return ref; - } - _FORCE_INLINE_ int dec() { - ref--; - return ref; - } - - _FORCE_INLINE_ RC() { - ref = 0; - } - }; - - Map<ID, Element> element_map; - Map<Element *, RC> large_elements; - - ID current; - - uint64_t pass; - - struct PairKey { - union { - struct { - ID a; - ID b; - }; - uint64_t key; - }; - - _FORCE_INLINE_ bool operator<(const PairKey &p_key) const { - return key < p_key.key; - } - - PairKey() { key = 0; } - PairKey(ID p_a, ID p_b) { - if (p_a > p_b) { - a = p_b; - b = p_a; - } else { - a = p_a; - b = p_b; - } - } - }; - - Map<PairKey, PairData> pair_map; - - int cell_size; - int large_object_min_surface; - - PairCallback pair_callback; - void *pair_userdata; - UnpairCallback unpair_callback; - void *unpair_userdata; - - static _FORCE_INLINE_ bool _test_collision_mask(uint32_t p_mask1, uint32_t p_layer1, uint32_t p_mask2, uint32_t p_layer2) { - return p_mask1 & p_layer2 || p_mask2 & p_layer1; - } - - void _enter_grid(Element *p_elem, const Rect2 &p_rect, bool p_static, bool p_force_enter); - void _exit_grid(Element *p_elem, const Rect2 &p_rect, bool p_static, bool p_force_exit); - template <bool use_aabb, bool use_segment> - _FORCE_INLINE_ void _cull(const Point2i p_cell, const Rect2 &p_aabb, const Point2 &p_from, const Point2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices, int &index); - - struct PosKey { - union { - struct { - int32_t x; - int32_t y; - }; - uint64_t key; - }; - - _FORCE_INLINE_ uint32_t hash() const { - uint64_t k = key; - k = (~k) + (k << 18); // k = (k << 18) - k - 1; - k = k ^ (k >> 31); - k = k * 21; // k = (k + (k << 2)) + (k << 4); - k = k ^ (k >> 11); - k = k + (k << 6); - k = k ^ (k >> 22); - return k; - } - - bool operator==(const PosKey &p_key) const { return key == p_key.key; } - _FORCE_INLINE_ bool operator<(const PosKey &p_key) const { - return key < p_key.key; - } - }; - - struct PosBin { - PosKey key; - Map<Element *, RC> object_set; - Map<Element *, RC> static_object_set; - PosBin *next; - }; - - uint32_t hash_table_size; - PosBin **hash_table; - - void _pair_attempt(Element *p_elem, Element *p_with); - void _unpair_attempt(Element *p_elem, Element *p_with); - void _check_motion(Element *p_elem); - -public: - virtual ID create(CollisionObject2DSW *p_object, int p_subindex = 0); - virtual void move(ID p_id, const Rect2 &p_aabb); - virtual void set_static(ID p_id, bool p_static); - virtual void remove(ID p_id); - - virtual CollisionObject2DSW *get_object(ID p_id) const; - virtual bool is_static(ID p_id) const; - virtual int get_subindex(ID p_id) const; - - virtual int cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - virtual int cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices = nullptr); - - virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); - virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); - - virtual void update(); - - static BroadPhase2DSW *_create(); - - BroadPhase2DHashGrid(); - ~BroadPhase2DHashGrid(); -}; - -#endif // BROAD_PHASE_2D_HASH_GRID_H diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h index d17ee6e2d6..0f82f06b9c 100644 --- a/servers/physics_2d/broad_phase_2d_sw.h +++ b/servers/physics_2d/broad_phase_2d_sw.h @@ -48,7 +48,7 @@ public: typedef void (*UnpairCallback)(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_userdata); // 0 is an invalid ID - virtual ID create(CollisionObject2DSW *p_object_, int p_subindex = 0) = 0; + virtual ID create(CollisionObject2DSW *p_object_, int p_subindex = 0, const Rect2 &p_aabb = Rect2(), bool p_static = false) = 0; virtual void move(ID p_id, const Rect2 &p_aabb) = 0; virtual void set_static(ID p_id, bool p_static) = 0; virtual void remove(ID p_id) = 0; diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 7a2f312263..fa87dc1f3f 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -182,19 +182,19 @@ void CollisionObject2DSW::_update_shapes() { continue; } - if (s.bpid == 0) { - s.bpid = space->get_broadphase()->create(this, i); - space->get_broadphase()->set_static(s.bpid, _static); - } - //not quite correct, should compute the next matrix.. Rect2 shape_aabb = s.shape->get_aabb(); Transform2D xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); + shape_aabb.grow_by((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05); s.aabb_cache = shape_aabb; - s.aabb_cache = s.aabb_cache.grow((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05); - space->get_broadphase()->move(s.bpid, s.aabb_cache); + if (s.bpid == 0) { + s.bpid = space->get_broadphase()->create(this, i, shape_aabb, _static); + space->get_broadphase()->set_static(s.bpid, _static); + } + + space->get_broadphase()->move(s.bpid, shape_aabb); } } @@ -209,11 +209,6 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { continue; } - if (s.bpid == 0) { - s.bpid = space->get_broadphase()->create(this, i); - space->get_broadphase()->set_static(s.bpid, _static); - } - //not quite correct, should compute the next matrix.. Rect2 shape_aabb = s.shape->get_aabb(); Transform2D xform = transform * s.xform; @@ -221,6 +216,11 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { shape_aabb = shape_aabb.merge(Rect2(shape_aabb.position + p_motion, shape_aabb.size)); //use motion s.aabb_cache = shape_aabb; + if (s.bpid == 0) { + s.bpid = space->get_broadphase()->create(this, i, shape_aabb, _static); + space->get_broadphase()->set_static(s.bpid, _static); + } + space->get_broadphase()->move(s.bpid, shape_aabb); } } diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 6d64f4126c..1c2dca0259 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -30,8 +30,7 @@ #include "physics_server_2d_sw.h" -#include "broad_phase_2d_basic.h" -#include "broad_phase_2d_hash_grid.h" +#include "broad_phase_2d_bvh.h" #include "collision_solver_2d_sw.h" #include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" @@ -1238,6 +1237,10 @@ void PhysicsServer2DSW::set_active(bool p_active) { active = p_active; }; +void PhysicsServer2DSW::set_collision_iterations(int p_iterations) { + iterations = p_iterations; +}; + void PhysicsServer2DSW::init() { doing_sync = false; last_step = 0.001; @@ -1356,8 +1359,7 @@ PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr; PhysicsServer2DSW::PhysicsServer2DSW(bool p_using_threads) { singletonsw = this; - BroadPhase2DSW::create_func = BroadPhase2DHashGrid::_create; - //BroadPhase2DSW::create_func=BroadPhase2DBasic::_create; + BroadPhase2DSW::create_func = BroadPhase2DBVH::_create; active = true; island_count = 0; diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index efa0784245..f1eb78a776 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -288,6 +288,8 @@ public: virtual void end_sync() override; virtual void finish() override; + virtual void set_collision_iterations(int p_iterations) override; + virtual bool is_flushing_queries() const override { return flushing_queries; } int get_process_info(ProcessInfo p_info) override; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index 88ac742e40..c776641699 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -303,6 +303,7 @@ public: FUNC1(free, RID); FUNC1(set_active, bool); + FUNC1(set_collision_iterations, int); virtual void init() override; virtual void step(real_t p_step) override; diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp index 4357c474e4..e4f9548a61 100644 --- a/servers/physics_3d/body_3d_sw.cpp +++ b/servers/physics_3d/body_3d_sw.cpp @@ -65,16 +65,18 @@ void Body3DSW::update_inertias() { // We have to recompute the center of mass. center_of_mass_local.zero(); - for (int i = 0; i < get_shape_count(); i++) { - real_t area = get_shape_area(i); + if (total_area != 0.0) { + for (int i = 0; i < get_shape_count(); i++) { + real_t area = get_shape_area(i); - real_t mass = area * this->mass / total_area; + real_t mass = area * this->mass / total_area; - // NOTE: we assume that the shape origin is also its center of mass. - center_of_mass_local += mass * get_shape_transform(i).origin; - } + // NOTE: we assume that the shape origin is also its center of mass. + center_of_mass_local += mass * get_shape_transform(i).origin; + } - center_of_mass_local /= mass; + center_of_mass_local /= mass; + } // Recompute the inertia tensor. Basis inertia_tensor; @@ -86,12 +88,15 @@ void Body3DSW::update_inertias() { continue; } + real_t area = get_shape_area(i); + if (area == 0.0) { + continue; + } + inertia_set = true; const Shape3DSW *shape = get_shape(i); - real_t area = get_shape_area(i); - real_t mass = area * this->mass / total_area; Basis shape_inertia_tensor = shape->get_moment_of_inertia(mass).to_diagonal_matrix(); diff --git a/servers/physics_3d/broad_phase_3d_basic.cpp b/servers/physics_3d/broad_phase_3d_basic.cpp deleted file mode 100644 index b41c2530da..0000000000 --- a/servers/physics_3d/broad_phase_3d_basic.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/*************************************************************************/ -/* broad_phase_3d_basic.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "broad_phase_3d_basic.h" -#include "core/string/print_string.h" -#include "core/templates/list.h" - -BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int p_subindex) { - ERR_FAIL_COND_V(p_object == nullptr, 0); - - current++; - - Element e; - e.owner = p_object; - e._static = false; - e.subindex = p_subindex; - - element_map[current] = e; - return current; -} - -void BroadPhase3DBasic::move(ID p_id, const AABB &p_aabb) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - E->get().aabb = p_aabb; -} - -void BroadPhase3DBasic::set_static(ID p_id, bool p_static) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - E->get()._static = p_static; -} - -void BroadPhase3DBasic::remove(ID p_id) { - Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND(!E); - List<PairKey> to_erase; - //unpair must be done immediately on removal to avoid potential invalid pointers - for (Map<PairKey, void *>::Element *F = pair_map.front(); F; F = F->next()) { - if (F->key().a == p_id || F->key().b == p_id) { - if (unpair_callback) { - Element *elem_A = &element_map[F->key().a]; - Element *elem_B = &element_map[F->key().b]; - unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, F->get(), unpair_userdata); - } - to_erase.push_back(F->key()); - } - } - while (to_erase.size()) { - pair_map.erase(to_erase.front()->get()); - to_erase.pop_front(); - } - element_map.erase(E); -} - -CollisionObject3DSW *BroadPhase3DBasic::get_object(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, nullptr); - return E->get().owner; -} - -bool BroadPhase3DBasic::is_static(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, false); - return E->get()._static; -} - -int BroadPhase3DBasic::get_subindex(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); - ERR_FAIL_COND_V(!E, -1); - return E->get().subindex; -} - -int BroadPhase3DBasic::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; - - for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const AABB aabb = E->get().aabb; - if (aabb.has_point(p_point)) { - p_results[rc] = E->get().owner; - p_result_indices[rc] = E->get().subindex; - rc++; - if (rc >= p_max_results) { - break; - } - } - } - - return rc; -} - -int BroadPhase3DBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; - - for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const AABB aabb = E->get().aabb; - if (aabb.intersects_segment(p_from, p_to)) { - p_results[rc] = E->get().owner; - p_result_indices[rc] = E->get().subindex; - rc++; - if (rc >= p_max_results) { - break; - } - } - } - - return rc; -} - -int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; - - for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const AABB aabb = E->get().aabb; - if (aabb.intersects(p_aabb)) { - p_results[rc] = E->get().owner; - p_result_indices[rc] = E->get().subindex; - rc++; - if (rc >= p_max_results) { - break; - } - } - } - - return rc; -} - -void BroadPhase3DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_userdata = p_userdata; - pair_callback = p_pair_callback; -} - -void BroadPhase3DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { - unpair_userdata = p_userdata; - unpair_callback = p_unpair_callback; -} - -void BroadPhase3DBasic::update() { - // recompute pairs - for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) { - for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) { - Element *elem_A = &I->get(); - Element *elem_B = &J->get(); - - if (elem_A->owner == elem_B->owner) { - continue; - } - - bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static); - - PairKey key(I->key(), J->key()); - - Map<PairKey, void *>::Element *E = pair_map.find(key); - - if (!pair_ok && E) { - if (unpair_callback) { - unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata); - } - pair_map.erase(key); - } - - if (pair_ok && !E) { - void *data = nullptr; - if (pair_callback) { - data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); - if (data) { - pair_map.insert(key, data); - } - } - } - } - } -} - -BroadPhase3DSW *BroadPhase3DBasic::_create() { - return memnew(BroadPhase3DBasic); -} - -BroadPhase3DBasic::BroadPhase3DBasic() { - current = 1; - unpair_callback = nullptr; - unpair_userdata = nullptr; - pair_callback = nullptr; - pair_userdata = nullptr; -} diff --git a/servers/physics_3d/broad_phase_octree.cpp b/servers/physics_3d/broad_phase_3d_bvh.cpp index 11324fa4e4..f9f64f786d 100644 --- a/servers/physics_3d/broad_phase_octree.cpp +++ b/servers/physics_3d/broad_phase_3d_bvh.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_octree.cpp */ +/* broad_phase_3d_bvh.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,55 +28,55 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "broad_phase_octree.h" +#include "broad_phase_3d_bvh.h" #include "collision_object_3d_sw.h" -BroadPhase3DSW::ID BroadPhaseOctree::create(CollisionObject3DSW *p_object, int p_subindex) { - ID oid = octree.create(p_object, AABB(), p_subindex, false, 1 << p_object->get_type(), 0); - return oid; +BroadPhase3DBVH::ID BroadPhase3DBVH::create(CollisionObject3DSW *p_object, int p_subindex, const AABB &p_aabb, bool p_static) { + ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? + return oid + 1; } -void BroadPhaseOctree::move(ID p_id, const AABB &p_aabb) { - octree.move(p_id, p_aabb); +void BroadPhase3DBVH::move(ID p_id, const AABB &p_aabb) { + bvh.move(p_id - 1, p_aabb); } -void BroadPhaseOctree::set_static(ID p_id, bool p_static) { - CollisionObject3DSW *it = octree.get(p_id); - octree.set_pairable(p_id, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF); //pair everything, don't care 1? +void BroadPhase3DBVH::set_static(ID p_id, bool p_static) { + CollisionObject3DSW *it = bvh.get(p_id - 1); + bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? } -void BroadPhaseOctree::remove(ID p_id) { - octree.erase(p_id); +void BroadPhase3DBVH::remove(ID p_id) { + bvh.erase(p_id - 1); } -CollisionObject3DSW *BroadPhaseOctree::get_object(ID p_id) const { - CollisionObject3DSW *it = octree.get(p_id); +CollisionObject3DSW *BroadPhase3DBVH::get_object(ID p_id) const { + CollisionObject3DSW *it = bvh.get(p_id - 1); ERR_FAIL_COND_V(!it, nullptr); return it; } -bool BroadPhaseOctree::is_static(ID p_id) const { - return !octree.is_pairable(p_id); +bool BroadPhase3DBVH::is_static(ID p_id) const { + return !bvh.is_pairable(p_id - 1); } -int BroadPhaseOctree::get_subindex(ID p_id) const { - return octree.get_subindex(p_id); +int BroadPhase3DBVH::get_subindex(ID p_id) const { + return bvh.get_subindex(p_id - 1); } -int BroadPhaseOctree::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - return octree.cull_point(p_point, p_results, p_max_results, p_result_indices); +int BroadPhase3DBVH::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { + return bvh.cull_point(p_point, p_results, p_max_results, p_result_indices); } -int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); +int BroadPhase3DBVH::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { + return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); } -int BroadPhaseOctree::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - return octree.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); +int BroadPhase3DBVH::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { + return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); } -void *BroadPhaseOctree::_pair_callback(void *self, OctreeElementID p_A, CollisionObject3DSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObject3DSW *p_object_B, int subindex_B) { - BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self); +void *BroadPhase3DBVH::_pair_callback(void *self, uint32_t p_A, CollisionObject3DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject3DSW *p_object_B, int subindex_B) { + BroadPhase3DBVH *bpo = (BroadPhase3DBVH *)(self); if (!bpo->pair_callback) { return nullptr; } @@ -84,8 +84,8 @@ void *BroadPhaseOctree::_pair_callback(void *self, OctreeElementID p_A, Collisio return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata); } -void BroadPhaseOctree::_unpair_callback(void *self, OctreeElementID p_A, CollisionObject3DSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObject3DSW *p_object_B, int subindex_B, void *pairdata) { - BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self); +void BroadPhase3DBVH::_unpair_callback(void *self, uint32_t p_A, CollisionObject3DSW *p_object_A, int subindex_A, uint32_t p_B, CollisionObject3DSW *p_object_B, int subindex_B, void *pairdata) { + BroadPhase3DBVH *bpo = (BroadPhase3DBVH *)(self); if (!bpo->unpair_callback) { return; } @@ -93,27 +93,27 @@ void BroadPhaseOctree::_unpair_callback(void *self, OctreeElementID p_A, Collisi bpo->unpair_callback(p_object_A, subindex_A, p_object_B, subindex_B, pairdata, bpo->unpair_userdata); } -void BroadPhaseOctree::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { +void BroadPhase3DBVH::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { pair_callback = p_pair_callback; pair_userdata = p_userdata; } -void BroadPhaseOctree::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void BroadPhase3DBVH::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_callback = p_unpair_callback; unpair_userdata = p_userdata; } -void BroadPhaseOctree::update() { - // does.. not? +void BroadPhase3DBVH::update() { + bvh.update(); } -BroadPhase3DSW *BroadPhaseOctree::_create() { - return memnew(BroadPhaseOctree); +BroadPhase3DSW *BroadPhase3DBVH::_create() { + return memnew(BroadPhase3DBVH); } -BroadPhaseOctree::BroadPhaseOctree() { - octree.set_pair_callback(_pair_callback, this); - octree.set_unpair_callback(_unpair_callback, this); +BroadPhase3DBVH::BroadPhase3DBVH() { + bvh.set_pair_callback(_pair_callback, this); + bvh.set_unpair_callback(_unpair_callback, this); pair_callback = nullptr; pair_userdata = nullptr; unpair_userdata = nullptr; diff --git a/servers/physics_3d/broad_phase_octree.h b/servers/physics_3d/broad_phase_3d_bvh.h index ee681dda96..30b8b7f2aa 100644 --- a/servers/physics_3d/broad_phase_octree.h +++ b/servers/physics_3d/broad_phase_3d_bvh.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* broad_phase_octree.h */ +/* broad_phase_3d_bvh.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BROAD_PHASE_OCTREE_H -#define BROAD_PHASE_OCTREE_H +#ifndef BROAD_PHASE_3D_BVH_H +#define BROAD_PHASE_3D_BVH_H #include "broad_phase_3d_sw.h" -#include "core/math/octree.h" +#include "core/math/bvh.h" -class BroadPhaseOctree : public BroadPhase3DSW { - Octree<CollisionObject3DSW, true> octree; +class BroadPhase3DBVH : public BroadPhase3DSW { + BVH_Manager<CollisionObject3DSW, true, 128> bvh; - static void *_pair_callback(void *, OctreeElementID, CollisionObject3DSW *, int, OctreeElementID, CollisionObject3DSW *, int); - static void _unpair_callback(void *, OctreeElementID, CollisionObject3DSW *, int, OctreeElementID, CollisionObject3DSW *, int, void *); + static void *_pair_callback(void *, uint32_t, CollisionObject3DSW *, int, uint32_t, CollisionObject3DSW *, int); + static void _unpair_callback(void *, uint32_t, CollisionObject3DSW *, int, uint32_t, CollisionObject3DSW *, int, void *); PairCallback pair_callback; void *pair_userdata; @@ -47,7 +47,7 @@ class BroadPhaseOctree : public BroadPhase3DSW { public: // 0 is an invalid ID - virtual ID create(CollisionObject3DSW *p_object, int p_subindex = 0); + virtual ID create(CollisionObject3DSW *p_object, int p_subindex = 0, const AABB &p_aabb = AABB(), bool p_static = false); virtual void move(ID p_id, const AABB &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); @@ -66,7 +66,7 @@ public: virtual void update(); static BroadPhase3DSW *_create(); - BroadPhaseOctree(); + BroadPhase3DBVH(); }; -#endif // BROAD_PHASE_OCTREE_H +#endif // BROAD_PHASE_3D_BVH_H diff --git a/servers/physics_3d/broad_phase_3d_sw.h b/servers/physics_3d/broad_phase_3d_sw.h index 283c087b96..98313cb216 100644 --- a/servers/physics_3d/broad_phase_3d_sw.h +++ b/servers/physics_3d/broad_phase_3d_sw.h @@ -48,7 +48,7 @@ public: typedef void (*UnpairCallback)(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_userdata); // 0 is an invalid ID - virtual ID create(CollisionObject3DSW *p_object_, int p_subindex = 0) = 0; + virtual ID create(CollisionObject3DSW *p_object_, int p_subindex = 0, const AABB &p_aabb = AABB(), bool p_static = false) = 0; virtual void move(ID p_id, const AABB &p_aabb) = 0; virtual void set_static(ID p_id, bool p_static) = 0; virtual void remove(ID p_id) = 0; diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp index 293a7e6606..459deb1356 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/collision_object_3d_sw.cpp @@ -146,22 +146,23 @@ void CollisionObject3DSW::_update_shapes() { for (int i = 0; i < shapes.size(); i++) { Shape &s = shapes.write[i]; - if (s.bpid == 0) { - s.bpid = space->get_broadphase()->create(this, i); - space->get_broadphase()->set_static(s.bpid, _static); - } //not quite correct, should compute the next matrix.. AABB shape_aabb = s.shape->get_aabb(); Transform xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); + shape_aabb.grow_by((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05); s.aabb_cache = shape_aabb; - s.aabb_cache = s.aabb_cache.grow((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05); Vector3 scale = xform.get_basis().get_scale(); s.area_cache = s.shape->get_area() * scale.x * scale.y * scale.z; - space->get_broadphase()->move(s.bpid, s.aabb_cache); + if (s.bpid == 0) { + s.bpid = space->get_broadphase()->create(this, i, shape_aabb, _static); + space->get_broadphase()->set_static(s.bpid, _static); + } + + space->get_broadphase()->move(s.bpid, shape_aabb); } } @@ -172,18 +173,19 @@ void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) { for (int i = 0; i < shapes.size(); i++) { Shape &s = shapes.write[i]; - if (s.bpid == 0) { - s.bpid = space->get_broadphase()->create(this, i); - space->get_broadphase()->set_static(s.bpid, _static); - } //not quite correct, should compute the next matrix.. AABB shape_aabb = s.shape->get_aabb(); Transform xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); - shape_aabb = shape_aabb.merge(AABB(shape_aabb.position + p_motion, shape_aabb.size)); //use motion + shape_aabb.merge_with(AABB(shape_aabb.position + p_motion, shape_aabb.size)); //use motion s.aabb_cache = shape_aabb; + if (s.bpid == 0) { + s.bpid = space->get_broadphase()->create(this, i, shape_aabb, _static); + space->get_broadphase()->set_static(s.bpid, _static); + } + space->get_broadphase()->move(s.bpid, shape_aabb); } } diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index 9d5448dbfa..fcac0587b2 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -690,7 +690,7 @@ public: Vector3 axis = (p_point_B - p_point_A); real_t depth = axis.length(); - // Filter out bogus directions with a treshold and re-testing axis. + // Filter out bogus directions with a threshold and re-testing axis. if (separator->best_depth - depth > 0.001) { separator->test_axis(axis / depth); } diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index c08e2b5794..f3eb1ae48f 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -30,8 +30,7 @@ #include "physics_server_3d_sw.h" -#include "broad_phase_3d_basic.h" -#include "broad_phase_octree.h" +#include "broad_phase_3d_bvh.h" #include "core/debugger/engine_debugger.h" #include "core/os/os.h" #include "joints/cone_twist_joint_3d_sw.h" @@ -1755,7 +1754,8 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, int p_index_A, PhysicsServer3DSW *PhysicsServer3DSW::singletonsw = nullptr; PhysicsServer3DSW::PhysicsServer3DSW(bool p_using_threads) { singletonsw = this; - BroadPhase3DSW::create_func = BroadPhaseOctree::_create; + BroadPhase3DSW::create_func = BroadPhase3DBVH::_create; + island_count = 0; active_objects = 0; collision_pairs = 0; diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index ccd37ca742..ca7248993f 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -31,8 +31,8 @@ #include "shape_3d_sw.h" #include "core/io/image.h" +#include "core/math/convex_hull.h" #include "core/math/geometry_3d.h" -#include "core/math/quick_hull.h" #include "core/templates/sort_array.h" // HeightMapShape3DSW is based on Bullet btHeightfieldTerrainShape. @@ -1089,9 +1089,9 @@ Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { } void ConvexPolygonShape3DSW::_setup(const Vector<Vector3> &p_vertices) { - Error err = QuickHull::build(p_vertices, mesh); + Error err = ConvexHullComputer::convex_hull(p_vertices, mesh); if (err != OK) { - ERR_PRINT("Failed to build QuickHull"); + ERR_PRINT("Failed to build convex hull"); } AABB _aabb; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 384179f2c3..7c5761cc61 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -675,6 +675,8 @@ void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer2D::set_active); + ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer2D::set_collision_iterations); + ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer2D::get_process_info); BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index a5cf3f3a46..f2836961f2 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -589,6 +589,8 @@ public: virtual bool is_flushing_queries() const = 0; + virtual void set_collision_iterations(int iterations) = 0; + enum ProcessInfo { INFO_ACTIVE_OBJECTS, INFO_COLLISION_PAIRS, diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 7f3fc2f8f4..67003a6f64 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -923,10 +923,15 @@ void RendererCanvasCull::canvas_item_add_set_transform(RID p_item, const Transfo void RendererCanvasCull::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); + ERR_FAIL_COND(!p_mesh.is_valid()); Item::CommandMesh *m = canvas_item->alloc_command<Item::CommandMesh>(); ERR_FAIL_COND(!m); m->mesh = p_mesh; + if (canvas_item->skeleton.is_valid()) { + m->mesh_instance = RSG::storage->mesh_instance_create(p_mesh); + RSG::storage->mesh_instance_set_skeleton(m->mesh_instance, canvas_item->skeleton); + } m->texture = p_texture; @@ -996,8 +1001,30 @@ void RendererCanvasCull::canvas_item_set_z_as_relative_to_parent(RID p_item, boo void RendererCanvasCull::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); - + if (canvas_item->skeleton == p_skeleton) { + return; + } canvas_item->skeleton = p_skeleton; + + Item::Command *c = canvas_item->commands; + + while (c) { + if (c->type == Item::Command::TYPE_MESH) { + Item::CommandMesh *cm = static_cast<Item::CommandMesh *>(c); + if (canvas_item->skeleton.is_valid()) { + if (cm->mesh_instance.is_null()) { + cm->mesh_instance = RSG::storage->mesh_instance_create(cm->mesh); + } + RSG::storage->mesh_instance_set_skeleton(cm->mesh_instance, canvas_item->skeleton); + } else { + if (cm->mesh_instance.is_valid()) { + RSG::storage->free(cm->mesh_instance); + cm->mesh_instance = RID(); + } + } + } + c = c->next; + } } void RendererCanvasCull::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index f08986b021..0266e137c0 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -246,10 +246,16 @@ public: RID mesh; Transform2D transform; Color modulate; + RID mesh_instance; RID texture; CommandMesh() { type = TYPE_MESH; } + ~CommandMesh() { + if (mesh_instance.is_valid()) { + RendererStorage::base_singleton->free(mesh_instance); + } + } }; struct CommandMultiMesh : public Command { @@ -262,7 +268,6 @@ public: struct CommandParticles : public Command { RID particles; - RID texture; CommandParticles() { type = TYPE_PARTICLES; } @@ -415,7 +420,6 @@ public: if (found_xform) { r = xf.xform(r); - found_xform = false; } if (first) { diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index 919ae2c6da..41aaba0f4c 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -59,7 +59,22 @@ public: struct BlitToScreen { RID render_target; Rect2i rect; - //lens distorted parameters for VR should go here + + struct { + bool use_layer = false; + uint32_t layer = 0; + } multi_view; + + struct { + //lens distorted parameters for VR + bool apply = false; + Vector2 eye_center; + float k1 = 0.0; + float k2 = 0.0; + + float upscale = 1.0; + float aspect_ratio = 1.0; + } lens_distortion; }; virtual void prepare_for_blitting_render_targets() = 0; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index aadb7bac19..16c6273ff6 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -536,21 +536,21 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p } } -void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { - //CameraMatrix projection = p_cam_projection; +void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { + //CameraMatrix projection = p_render_data->cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; correction.set_depth_correction(p_flip_y); - CameraMatrix projection = correction * p_cam_projection; + CameraMatrix projection = correction * p_render_data->cam_projection; //store camera into ubo RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix); RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RendererStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix); - RendererStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); + RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix); + RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); - scene_state.ubo.z_far = p_zfar; - scene_state.ubo.z_near = p_znear; + scene_state.ubo.z_far = p_render_data->z_far; + scene_state.ubo.z_near = p_render_data->z_near; scene_state.ubo.pancake_shadows = p_pancake_shadows; @@ -568,17 +568,17 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y; - scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_cluster_size); - scene_state.ubo.max_cluster_element_count_div_32 = p_max_cluster_elements / 32; + scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_render_data->cluster_size); + scene_state.ubo.max_cluster_element_count_div_32 = p_render_data->cluster_max_elements / 32; { - uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_cluster_size + 1; - uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_cluster_size + 1; + uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_render_data->cluster_size + 1; + uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_render_data->cluster_size + 1; scene_state.ubo.cluster_type_size = cluster_screen_width * cluster_screen_height * (scene_state.ubo.max_cluster_element_count_div_32 + 32); scene_state.ubo.cluster_width = cluster_screen_width; } - if (p_shadow_atlas.is_valid()) { - Vector2 sas = shadow_atlas_get_size(p_shadow_atlas); + if (p_render_data->shadow_atlas.is_valid()) { + Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas); scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x; scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y; } @@ -594,22 +594,22 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ scene_state.ubo.volumetric_fog_enabled = false; scene_state.ubo.fog_enabled = false; - if (p_render_buffers.is_valid()) { - RenderBufferDataForwardClustered *render_buffers = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers); + if (p_render_data->render_buffers.is_valid()) { + RenderBufferDataForwardClustered *render_buffers = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) { scene_state.ubo.gi_upscale_for_msaa = true; } - if (render_buffers_has_volumetric_fog(p_render_buffers)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers)) { scene_state.ubo.volumetric_fog_enabled = true; - float fog_end = render_buffers_get_volumetric_fog_end(p_render_buffers); + float fog_end = render_buffers_get_volumetric_fog_end(p_render_data->render_buffers); if (fog_end > 0.0) { scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end; } else { scene_state.ubo.volumetric_fog_inv_length = 1.0; } - float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup + float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_data->render_buffers); //reverse lookup if (fog_detail_spread > 0.0) { scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread; } else { @@ -618,26 +618,26 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ } } #if 0 - if (p_render_buffers.is_valid() && render_buffers_is_sdfgi_enabled(p_render_buffers)) { - scene_state.ubo.sdfgi_cascade_count = render_buffers_get_sdfgi_cascade_count(p_render_buffers); - scene_state.ubo.sdfgi_probe_axis_size = render_buffers_get_sdfgi_cascade_probe_count(p_render_buffers); + if (p_render_data->render_buffers.is_valid() && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { + scene_state.ubo.sdfgi_cascade_count = render_buffers_get_sdfgi_cascade_count(p_render_data->render_buffers); + scene_state.ubo.sdfgi_probe_axis_size = render_buffers_get_sdfgi_cascade_probe_count(p_render_data->render_buffers); scene_state.ubo.sdfgi_cascade_probe_size[0] = scene_state.ubo.sdfgi_probe_axis_size - 1; //float version for performance scene_state.ubo.sdfgi_cascade_probe_size[1] = scene_state.ubo.sdfgi_probe_axis_size - 1; scene_state.ubo.sdfgi_cascade_probe_size[2] = scene_state.ubo.sdfgi_probe_axis_size - 1; - float csize = render_buffers_get_sdfgi_cascade_size(p_render_buffers); + float csize = render_buffers_get_sdfgi_cascade_size(p_render_data->render_buffers); scene_state.ubo.sdfgi_probe_to_uvw = 1.0 / float(scene_state.ubo.sdfgi_cascade_probe_size[0]); float occ_bias = 0.0; scene_state.ubo.sdfgi_occlusion_bias = occ_bias / csize; - scene_state.ubo.sdfgi_use_occlusion = render_buffers_is_sdfgi_using_occlusion(p_render_buffers); - scene_state.ubo.sdfgi_energy = render_buffers_get_sdfgi_energy(p_render_buffers); + scene_state.ubo.sdfgi_use_occlusion = render_buffers_is_sdfgi_using_occlusion(p_render_data->render_buffers); + scene_state.ubo.sdfgi_energy = render_buffers_get_sdfgi_energy(p_render_data->render_buffers); float cascade_voxel_size = (csize / scene_state.ubo.sdfgi_cascade_probe_size[0]); float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size; scene_state.ubo.sdfgi_occlusion_clamp[0] = occlusion_clamp; scene_state.ubo.sdfgi_occlusion_clamp[1] = occlusion_clamp; scene_state.ubo.sdfgi_occlusion_clamp[2] = occlusion_clamp; - scene_state.ubo.sdfgi_normal_bias = (render_buffers_get_sdfgi_normal_bias(p_render_buffers) / csize) * scene_state.ubo.sdfgi_cascade_probe_size[0]; + scene_state.ubo.sdfgi_normal_bias = (render_buffers_get_sdfgi_normal_bias(p_render_data->render_buffers) / csize) * scene_state.ubo.sdfgi_cascade_probe_size[0]; //vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) ); //vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx; @@ -658,14 +658,14 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ for (uint32_t i = 0; i < scene_state.ubo.sdfgi_cascade_count; i++) { SceneState::UBO::SDFGICascade &c = scene_state.ubo.sdfgi_cascades[i]; - Vector3 pos = render_buffers_get_sdfgi_cascade_offset(p_render_buffers, i); - pos -= p_cam_transform.origin; //make pos local to camera, to reduce numerical error + Vector3 pos = render_buffers_get_sdfgi_cascade_offset(p_render_data->render_buffers, i); + pos -= p_render_data->cam_transform.origin; //make pos local to camera, to reduce numerical error c.position[0] = pos.x; c.position[1] = pos.y; c.position[2] = pos.z; - c.to_probe = 1.0 / render_buffers_get_sdfgi_cascade_probe_size(p_render_buffers, i); + c.to_probe = 1.0 / render_buffers_get_sdfgi_cascade_probe_size(p_render_data->render_buffers, i); - Vector3i probe_ofs = render_buffers_get_sdfgi_cascade_probe_offset(p_render_buffers, i); + Vector3i probe_ofs = render_buffers_get_sdfgi_cascade_probe_offset(p_render_data->render_buffers, i); c.probe_world_offset[0] = probe_ofs.x; c.probe_world_offset[1] = probe_ofs.y; c.probe_world_offset[2] = probe_ofs.z; @@ -682,18 +682,18 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ scene_state.ubo.use_reflection_cubemap = false; scene_state.ubo.ssao_enabled = false; - } else if (is_environment(p_environment)) { - RS::EnvironmentBG env_bg = environment_get_background(p_environment); - RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment); + } else if (is_environment(p_render_data->environment)) { + RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); + RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = environment_get_bg_energy(p_environment); + float bg_energy = environment_get_bg_energy(p_render_data->environment); scene_state.ubo.ambient_light_color_energy[3] = bg_energy; - scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_environment); + scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment); + Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; @@ -702,15 +702,15 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = environment_get_ambient_light_energy(p_environment); - Color color = environment_get_ambient_light_color(p_environment); + float energy = environment_get_ambient_light_energy(p_render_data->environment); + Color color = environment_get_ambient_light_color(p_render_data->environment); color = color.to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; - Basis sky_transform = environment_get_sky_orientation(p_environment); - sky_transform = sky_transform.inverse() * p_cam_transform.basis; + Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); + sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; @@ -718,43 +718,43 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_ } //specular - RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_environment); + RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment); if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { scene_state.ubo.use_reflection_cubemap = true; } else { scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_environment); - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_environment); + scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment); + scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment); + scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment); - Color ao_color = environment_get_ao_color(p_environment).to_linear(); + Color ao_color = environment_get_ao_color(p_render_data->environment).to_linear(); scene_state.ubo.ao_color[0] = ao_color.r; scene_state.ubo.ao_color[1] = ao_color.g; scene_state.ubo.ao_color[2] = ao_color.b; scene_state.ubo.ao_color[3] = ao_color.a; - scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_environment); - scene_state.ubo.fog_density = environment_get_fog_density(p_environment); - scene_state.ubo.fog_height = environment_get_fog_height(p_environment); - scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_environment); + scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); + scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); + scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); if (scene_state.ubo.fog_height_density >= 0.0001) { scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density; } - scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_environment); + scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - Color fog_color = environment_get_fog_light_color(p_environment).to_linear(); - float fog_energy = environment_get_fog_light_energy(p_environment); + Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear(); + float fog_energy = environment_get_fog_light_energy(p_render_data->environment); scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment); + scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment); } else { - if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { + if (p_render_data->reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { scene_state.ubo.use_ambient_light = false; } else { scene_state.ubo.use_ambient_light = true; @@ -867,7 +867,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u } } -void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) { +void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) { if (p_render_list == RENDER_LIST_OPAQUE) { scene_state.used_sss = false; scene_state.used_screen_texture = false; @@ -876,9 +876,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con } uint32_t lightmap_captures_used = 0; - Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); - near_plane.d += p_cam_projection.get_z_near(); - float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near(); + Plane near_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z)); + near_plane.d += p_render_data->cam_projection.get_z_near(); + float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near(); RenderList *rl = &render_list[p_render_list]; _update_dirty_geometry_instances(); @@ -892,8 +892,8 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con //fill list - for (int i = 0; i < (int)p_instances.size(); i++) { - GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>(p_instances[i]); + for (int i = 0; i < (int)p_render_data->instances->size(); i++) { + GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>((*p_render_data->instances)[i]); Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal); inst->depth = near_plane.distance_to(support_min); @@ -987,13 +987,13 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con // LOD - if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) { + if (p_render_data->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) { //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal); + Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal); + Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal); - float distance_min = p_lod_plane.distance_to(lod_support_min); - float distance_max = p_lod_plane.distance_to(lod_support_max); + float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min); + float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max); float distance = 0.0; @@ -1006,7 +1006,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con distance = -distance_max; } - surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold); + surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); } else { surf->sort.lod_index = 0; } @@ -1090,28 +1090,21 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps } } -void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) { +void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) { RenderBufferDataForwardClustered *render_buffer = nullptr; - if (p_render_buffer.is_valid()) { - render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffer); + if (p_render_data->render_buffers.is_valid()) { + render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); } - RendererSceneEnvironmentRD *env = get_environment(p_environment); + RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); //first of all, make a new render pass //fill up ubo RENDER_TIMESTAMP("Setup 3D Scene"); - float lod_distance_multiplier = p_cam_projection.get_lod_multiplier(); - Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); - - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - p_screen_lod_threshold = 0.0; - } - //scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size; - Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); + Vector2 vp_he = p_render_data->cam_projection.get_viewport_half_extents(); scene_state.ubo.viewport_size[0] = vp_he.x; scene_state.ubo.viewport_size[1] = vp_he.y; scene_state.ubo.directional_light_count = 0; @@ -1136,29 +1129,29 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform opaque_framebuffer = render_buffer->color_fb; - if (p_gi_probes.size() > 0) { + if (p_render_data->gi_probes->size() > 0) { using_giprobe = true; } - if (!p_environment.is_valid() && using_giprobe) { + if (!p_render_data->environment.is_valid() && using_giprobe) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE; - } else if (p_environment.is_valid() && (environment_is_ssr_enabled(p_environment) || environment_is_sdfgi_enabled(p_environment) || using_giprobe)) { - if (environment_is_sdfgi_enabled(p_environment)) { + } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_giprobe)) { + if (environment_is_sdfgi_enabled(p_render_data->environment)) { depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also giprobe using_sdfgi = true; } else { depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } - if (environment_is_ssr_enabled(p_environment)) { + if (environment_is_ssr_enabled(p_render_data->environment)) { render_buffer->ensure_specular(); using_separate_specular = true; using_ssr = true; opaque_specular_framebuffer = render_buffer->color_specular_fb; } - } else if (p_environment.is_valid() && (environment_is_ssao_enabled(p_environment) || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) { + } else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } @@ -1183,17 +1176,18 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform } alpha_framebuffer = opaque_framebuffer; - } else if (p_reflection_probe.is_valid()) { - uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe); + } else if (p_render_data->reflection_probe.is_valid()) { + uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe); screen_size.x = resolution; screen_size.y = resolution; - opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_reflection_probe, p_reflection_probe_pass); - depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_reflection_probe, p_reflection_probe_pass); + opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass); + depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass); alpha_framebuffer = opaque_framebuffer; - if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { - p_environment = RID(); //no environment on interiors + if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { + p_render_data->environment = RID(); //no environment on interiors + env = nullptr; } reverse_cull = true; // for some reason our views are inverted @@ -1203,13 +1197,13 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform RD::get_singleton()->draw_command_begin_label("Render Setup"); - _setup_lightmaps(p_lightmaps, p_cam_transform); - _setup_giprobes(p_gi_probes); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + _setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform); + _setup_giprobes(*p_render_data->gi_probes); + _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(RENDER_LIST_OPAQUE, p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_giprobe); render_list[RENDER_LIST_OPAQUE].sort_by_key(); render_list[RENDER_LIST_ALPHA].sort_by_depth(); _fill_instance_data(RENDER_LIST_OPAQUE); @@ -1234,26 +1228,26 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black - } else if (is_environment(p_environment)) { - RS::EnvironmentBG bg_mode = environment_get_background(p_environment); - float bg_energy = environment_get_bg_energy(p_environment); + } else if (is_environment(p_render_data->environment)) { + RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment); + float bg_energy = environment_get_bg_energy(p_render_data->environment); switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { clear_color = p_default_bg_color; clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); } } break; case RS::ENV_BG_COLOR: { - clear_color = environment_get_bg_color(p_environment); + clear_color = environment_get_bg_color(p_render_data->environment); clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); } @@ -1273,21 +1267,21 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform } } // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - CameraMatrix projection = p_cam_projection; - if (p_reflection_probe.is_valid()) { + CameraMatrix projection = p_render_data->cam_projection; + if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; correction.set_depth_correction(true); - projection = correction * p_cam_projection; + projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_buffer, projection, p_cam_transform, screen_size, this); + sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this); RID sky_rid = env->sky; if (sky_rid.is_valid()) { - sky.update(env, projection, p_cam_transform, time); + sky.update(env, projection, p_render_data->cam_transform, time); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1303,11 +1297,11 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES; bool depth_pre_pass = depth_framebuffer.is_valid(); - bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment); + bool using_ssao = depth_pre_pass && p_render_data->render_buffers.is_valid() && p_render_data->environment.is_valid() && environment_is_ssao_enabled(p_render_data->environment); bool continue_depth = false; if (depth_pre_pass) { //depth pre pass - bool needs_pre_resolve = _needs_post_prepass_render(using_sdfgi || using_giprobe); + bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_giprobe); if (needs_pre_resolve) { RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)"); } else { @@ -1318,21 +1312,21 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear); RD::get_singleton()->draw_list_end(); //start compute processes here, so they run at the same time as depth pre-pass - _post_prepass_render(using_sdfgi || using_giprobe); + _post_prepass_render(p_render_data, using_sdfgi || using_giprobe); } RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); bool finish_depth = using_ssao || using_sdfgi || using_giprobe; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); RD::get_singleton()->draw_command_end_label(); if (needs_pre_resolve) { - _pre_resolve_render(using_sdfgi || using_giprobe); + _pre_resolve_render(p_render_data, using_sdfgi || using_giprobe); } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { @@ -1353,17 +1347,17 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform continue_depth = !finish_depth; } - _pre_opaque_render(using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID()); + _pre_opaque_render(p_render_data, using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID()); RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); - scene_state.ubo.directional_light_count = _get_render_state_directional_light_count(); + scene_state.ubo.directional_light_count = p_render_data->directional_light_count; - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid()); + _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, p_render_data->render_buffers.is_valid()); RENDER_TIMESTAMP("Render Opaque Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true); bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss; bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; @@ -1384,7 +1378,7 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform } RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used @@ -1402,11 +1396,11 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform CameraMatrix dc; dc.set_depth_correction(true); - CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse()); + CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); RD::get_singleton()->draw_command_begin_label("Debug GIProbes"); - for (int i = 0; i < (int)p_gi_probes.size(); i++) { - gi.debug_giprobe(p_gi_probes[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0); + for (int i = 0; i < (int)p_render_data->gi_probes->size(); i++) { + gi.debug_giprobe((*p_render_data->gi_probes)[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0); } RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_list_end(); @@ -1419,10 +1413,10 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform CameraMatrix dc; dc.set_depth_correction(true); - CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse()); + CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); RD::get_singleton()->draw_command_begin_label("Debug SDFGI"); - _debug_sdfgi_probes(p_render_buffer, draw_list, opaque_framebuffer, cm); + _debug_sdfgi_probes(p_render_data->render_buffers, draw_list, opaque_framebuffer, cm); RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_list_end(); } @@ -1430,14 +1424,14 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform if (draw_sky || draw_sky_fog_only) { RENDER_TIMESTAMP("Render Sky"); - CameraMatrix projection = p_cam_projection; - if (p_reflection_probe.is_valid()) { + CameraMatrix projection = p_render_data->cam_projection; + if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; correction.set_depth_correction(true); - projection = correction * p_cam_projection; + projection = correction * p_render_data->cam_projection; } RD::get_singleton()->draw_command_begin_label("Draw Sky"); - sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_cam_transform, time); + sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_render_data->cam_transform, time); RD::get_singleton()->draw_command_end_label(); } @@ -1456,14 +1450,14 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform if (using_sss) { RENDER_TIMESTAMP("Sub Surface Scattering"); RD::get_singleton()->draw_command_begin_label("Process Sub Surface Scattering"); - _process_sss(p_render_buffer, p_cam_projection); + _process_sss(p_render_data->render_buffers, p_render_data->cam_projection); RD::get_singleton()->draw_command_end_label(); } if (using_ssr) { RENDER_TIMESTAMP("Screen Space Reflection"); RD::get_singleton()->draw_command_begin_label("Process Screen Space Reflections"); - _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); + _process_ssr(p_render_data->render_buffers, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); RD::get_singleton()->draw_command_end_label(); } else { //just mix specular back @@ -1476,12 +1470,12 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); { - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } @@ -1509,18 +1503,31 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page SceneState::ShadowPass shadow_pass; + RenderDataRD render_data; + render_data.cam_projection = p_projection; + render_data.cam_transform = p_transform; + render_data.z_far = p_zfar; + render_data.z_near = 0.0; + render_data.cluster_size = 1; + render_data.cluster_max_elements = 32; + render_data.instances = &p_instances; + render_data.lod_camera_plane = p_camera_plane; + render_data.lod_distance_multiplier = p_lod_distance_multiplier; + scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index); + _setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - p_screen_lod_threshold = 0.0; + render_data.screen_lod_threshold = 0.0; + } else { + render_data.screen_lod_threshold = p_screen_lod_threshold; } PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, false, false, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, false, false, true); uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false); @@ -1539,8 +1546,8 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete shadow_pass.camera_plane = p_camera_plane; - shadow_pass.screen_lod_threshold = p_screen_lod_threshold; - shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier; + shadow_pass.screen_lod_threshold = render_data.screen_lod_threshold; + shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier; shadow_pass.framebuffer = p_framebuffer; shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE); @@ -1558,7 +1565,7 @@ void RenderForwardClustered::_render_shadow_process() { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { //render passes need to be configured after instance buffer is done, since they need the latest version SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>(), false, i); + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), false, i); } RD::get_singleton()->draw_command_end_label(); @@ -1583,18 +1590,27 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); + RenderDataRD render_data; + render_data.cam_projection = p_cam_projection; + render_data.cam_transform = p_cam_transform; + render_data.z_near = 0.0; + render_data.z_far = p_cam_projection.get_z_far(); + render_data.cluster_size = 1; + render_data.cluster_max_elements = 32; + render_data.instances = &p_instances; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false); + _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false); PassMode pass_mode = PASS_MODE_SHADOW; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); RENDER_TIMESTAMP("Render Collider Heightfield"); @@ -1611,19 +1627,26 @@ void RenderForwardClustered::_render_material(const Transform &p_cam_transform, RD::get_singleton()->draw_command_begin_label("Render Material"); + RenderDataRD render_data; + render_data.cam_projection = p_cam_projection; + render_data.cam_transform = p_cam_transform; + render_data.cluster_size = 1; + render_data.cluster_max_elements = 32; + render_data.instances = &p_instances; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = false; - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); + _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); RENDER_TIMESTAMP("Render Material"); @@ -1649,19 +1672,24 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RD::get_singleton()->draw_command_begin_label("Render UV2"); + RenderDataRD render_data; + render_data.cluster_size = 1; + render_data.cluster_max_elements = 32; + render_data.instances = &p_instances; + _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = true; - _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); + _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); RENDER_TIMESTAMP("Render Material"); @@ -1712,13 +1740,18 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel"); + RenderDataRD render_data; + render_data.cluster_size = 1; + render_data.cluster_max_elements = 32; + render_data.instances = &p_instances; + _update_render_base_uniform_set(); RenderBufferDataForwardClustered *render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers); ERR_FAIL_COND(!render_buffer); PassMode pass_mode = PASS_MODE_SDF; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); @@ -1750,28 +1783,26 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i fb_size.x = p_size[right_axis]; fb_size.y = p_size[up_axis]; - Transform cam_xform; - cam_xform.origin = center + axis * half_extents; - cam_xform.basis.set_axis(0, right); - cam_xform.basis.set_axis(1, up); - cam_xform.basis.set_axis(2, axis); + render_data.cam_transform.origin = center + axis * half_extents; + render_data.cam_transform.basis.set_axis(0, right); + render_data.cam_transform.basis.set_axis(1, up); + render_data.cam_transform.basis.set_axis(2, axis); - //print_line("pass: " + itos(i) + " xform " + cam_xform); + //print_line("pass: " + itos(i) + " xform " + render_data.cam_transform); float h_size = half_extents[right_axis]; float v_size = half_extents[up_axis]; float d_size = half_extents[i] * 2.0; - CameraMatrix camera_proj; - camera_proj.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size); + render_data.cam_projection.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size); //print_line("pass: " + itos(i) + " cam hsize: " + rtos(h_size) + " vsize: " + rtos(v_size) + " dsize " + rtos(d_size)); Transform to_bounds; to_bounds.origin = p_bounds.position; to_bounds.basis.scale(p_bounds.size); - RendererStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds); + RendererStorageRD::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds); - _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0); + _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); @@ -1921,13 +1952,13 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } } -RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) { +RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) { //there should always be enough uniform buffers for render passes, otherwise bugs ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID()); RenderBufferDataForwardClustered *rb = nullptr; - if (p_render_buffers.is_valid()) { - rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers); + if (p_render_data && p_render_data->render_buffers.is_valid()) { + rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); } //default render buffer and scene state uniform set @@ -1967,7 +1998,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } { - RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); + RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID(); RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; @@ -1984,8 +2015,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; - if (p_shadow_atlas.is_valid()) { - texture = shadow_atlas_get_texture(p_shadow_atlas); + if (p_render_data && p_render_data->shadow_atlas.is_valid()) { + texture = shadow_atlas_get_texture(p_render_data->shadow_atlas); } if (!texture.is_valid()) { texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); @@ -2011,8 +2042,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { - if (i < p_lightmaps.size()) { - RID base = lightmap_instance_get_lightmap(p_lightmaps[i]); + if (p_render_data && i < p_render_data->lightmaps->size()) { + RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); RID texture = storage->lightmap_get_texture(base); RID rd_texture = storage->texture_get_rd_texture(texture); u.ids.write[i] = rd_texture; @@ -2030,8 +2061,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_GI_PROBES; i++) { - if (i < (int)p_gi_probes.size()) { - RID tex = gi.gi_probe_instance_get_texture(p_gi_probes[i]); + if (p_render_data && i < (int)p_render_data->gi_probes->size()) { + RID tex = gi.gi_probe_instance_get_texture((*p_render_data->gi_probes)[i]); if (!tex.is_valid()) { tex = default_tex; } @@ -2048,7 +2079,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : scene_shader.default_vec4_xform_buffer; + RID cb = (p_render_data && p_render_data->cluster_buffer.is_valid()) ? p_render_data->cluster_buffer : scene_shader.default_vec4_xform_buffer; u.ids.push_back(cb); uniforms.push_back(u); } @@ -2065,7 +2096,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID(); + RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); @@ -2085,7 +2116,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID(); + RID aot = rb ? render_buffers_get_ao_texture(p_render_data->render_buffers) : RID(); RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); @@ -2095,7 +2126,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID(); + RID ambient_buffer = rb ? render_buffers_get_gi_ambient_texture(p_render_data->render_buffers) : RID(); RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); @@ -2105,7 +2136,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 14; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID(); + RID reflection_buffer = rb ? render_buffers_get_gi_reflection_texture(p_render_data->render_buffers) : RID(); RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); @@ -2115,8 +2146,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 15; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID t; - if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { - t = render_buffers_get_sdfgi_irradiance_probes(p_render_buffers); + if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { + t = render_buffers_get_sdfgi_irradiance_probes(p_render_data->render_buffers); } else { t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } @@ -2127,8 +2158,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 16; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { - u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers)); + if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { + u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers)); } else { u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } @@ -2138,7 +2169,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 17; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer()); + u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_data->render_buffers) : render_buffers_get_default_gi_probe_buffer()); uniforms.push_back(u); } { @@ -2146,8 +2177,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 18; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = RID(); - if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) { - vfog = render_buffers_get_volumetric_fog_texture(p_render_buffers); + if (rb && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) { + vfog = render_buffers_get_volumetric_fog_texture(p_render_data->render_buffers); if (vfog.is_null()) { vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 4b998a9e76..bed3c3b219 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -122,7 +122,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _update_render_base_uniform_set(); RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture); - RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0); enum PassMode { PASS_MODE_COLOR, @@ -349,7 +349,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { static RenderForwardClustered *singleton; - void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); + void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); void _setup_giprobes(const PagedArray<RID> &p_giprobes); void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform); @@ -373,7 +373,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _update_instance_data_buffer(RenderListType p_render_list); void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); - void _fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false); + void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); Map<Size2i, RID> sdfgi_framebuffer_size_cache; @@ -566,7 +566,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { RenderList render_list[RENDER_LIST_MAX]; protected: - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold); + virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color); virtual void _render_shadow_begin(); virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index f7ed0205af..5a26b5abbb 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -30,6 +30,7 @@ #include "scene_shader_forward_clustered.h" #include "core/config/project_settings.h" +#include "core/math/math_defs.h" #include "render_forward_clustered.h" using namespace RendererSceneRenderImplementation; @@ -608,6 +609,9 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin //builtins actions.renames["TIME"] = "scene_data.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; @@ -749,7 +753,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; actions.global_buffer_array_variable = "global_variables.data"; - actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs"; + actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs"; compiler.initialize(actions); } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 041476adf3..4e93fa5333 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -125,13 +125,13 @@ bool RenderForwardMobile::free(RID p_rid) { /* Render functions */ -RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) { +RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) { //there should always be enough uniform buffers for render passes, otherwise bugs ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID()); RenderBufferDataForwardMobile *rb = nullptr; - if (p_render_buffers.is_valid()) { - rb = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_buffers); + if (p_render_data && p_render_data->render_buffers.is_valid()) { + rb = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_data->render_buffers); } // default render buffer and scene state uniform set @@ -162,7 +162,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ } { - RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); + RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID(); RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; @@ -179,8 +179,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture; - if (p_shadow_atlas.is_valid()) { - texture = shadow_atlas_get_texture(p_shadow_atlas); + if (p_render_data && p_render_data->shadow_atlas.is_valid()) { + texture = shadow_atlas_get_texture(p_render_data->shadow_atlas); } if (!texture.is_valid()) { texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); @@ -208,8 +208,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { - if (i < p_lightmaps.size()) { - RID base = lightmap_instance_get_lightmap(p_lightmaps[i]); + if (p_render_data && i < p_render_data->lightmaps->size()) { + RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); RID texture = storage->lightmap_get_texture(base); RID rd_texture = storage->texture_get_rd_texture(texture); u.ids.write[i] = rd_texture; @@ -265,7 +265,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID(); + RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); u.ids.push_back(texture); uniforms.push_back(u); @@ -306,29 +306,16 @@ void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, c } } -void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) { - // These are UNUSED here and will not have data parsed from RendererSceneRenderRD: - // - p_gi_probes - // - p_cluster_buffer - // - p_cluster_size - // - p_cluster_max_elements - +void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) { RenderBufferDataForwardMobile *render_buffer = nullptr; - if (p_render_buffer.is_valid()) { - render_buffer = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_buffer); + if (p_render_data->render_buffers.is_valid()) { + render_buffer = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_data->render_buffers); } - RendererSceneEnvironmentRD *env = get_environment(p_environment); + RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); RENDER_TIMESTAMP("Setup 3D Scene"); - float lod_distance_multiplier = p_cam_projection.get_lod_multiplier(); - Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); - - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - p_screen_lod_threshold = 0.0; - } - - Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); + Vector2 vp_he = p_render_data->cam_projection.get_viewport_half_extents(); scene_state.ubo.viewport_size[0] = vp_he.x; scene_state.ubo.viewport_size[1] = vp_he.y; scene_state.ubo.directional_light_count = 0; @@ -349,16 +336,17 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ opaque_framebuffer = render_buffer->color_fb; alpha_framebuffer = opaque_framebuffer; - } else if (p_reflection_probe.is_valid()) { - uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe); + } else if (p_render_data->reflection_probe.is_valid()) { + uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe); screen_size.x = resolution; screen_size.y = resolution; - opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_reflection_probe, p_reflection_probe_pass); + opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass); alpha_framebuffer = opaque_framebuffer; - if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { - p_environment = RID(); //no environment on interiors + if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { + p_render_data->environment = RID(); //no environment on interiors + env = nullptr; } reverse_cull = true; @@ -368,12 +356,12 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ RD::get_singleton()->draw_command_begin_label("Render Setup"); - _setup_lightmaps(p_lightmaps, p_cam_transform); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + _setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform); + _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(RENDER_LIST_OPAQUE, p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR); render_list[RENDER_LIST_OPAQUE].sort_by_key(); render_list[RENDER_LIST_ALPHA].sort_by_depth(); @@ -395,9 +383,9 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black - } else if (is_environment(p_environment)) { - RS::EnvironmentBG bg_mode = environment_get_background(p_environment); - float bg_energy = environment_get_bg_energy(p_environment); + } else if (is_environment(p_render_data->environment)) { + RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment); + float bg_energy = environment_get_bg_energy(p_render_data->environment); switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { clear_color = p_default_bg_color; @@ -405,19 +393,19 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ clear_color.g *= bg_energy; clear_color.b *= bg_energy; /* - if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); } */ } break; case RS::ENV_BG_COLOR: { - clear_color = environment_get_bg_color(p_environment); + clear_color = environment_get_bg_color(p_render_data->environment); clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; /* - if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear())); } @@ -438,21 +426,21 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ } } // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - CameraMatrix projection = p_cam_projection; - if (p_reflection_probe.is_valid()) { + CameraMatrix projection = p_render_data->cam_projection; + if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; correction.set_depth_correction(true); - projection = correction * p_cam_projection; + projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_buffer, projection, p_cam_transform, screen_size, this); + sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this); RID sky_rid = env->sky; if (sky_rid.is_valid()) { - sky.update(env, projection, p_cam_transform, time); + sky.update(env, projection, p_render_data->cam_transform, time); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -468,17 +456,17 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ // !BAS! Look into this, seems most of the code in here related to clustered only, may want to move this code into ForwardClustered/RenderForwardMobile before calling it from here // does trigger shadow map rendering so kinda important - _pre_opaque_render(false, false, RID(), RID()); + _pre_opaque_render(p_render_data, false, false, RID(), RID()); RD::get_singleton()->draw_command_begin_label("Render Opaque Pass"); - scene_state.ubo.directional_light_count = _get_render_state_directional_light_count(); + scene_state.ubo.directional_light_count = p_render_data->directional_light_count; - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid()); + _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, p_render_data->render_buffers.is_valid()); RENDER_TIMESTAMP("Render Opaque Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_lightmaps, true); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true); bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss; bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; @@ -491,7 +479,7 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ Vector<Color> c; c.push_back(clear_color.to_linear()); - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, opaque_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); } @@ -500,14 +488,14 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ if (draw_sky || draw_sky_fog_only) { RENDER_TIMESTAMP("Render Sky"); - CameraMatrix projection = p_cam_projection; - if (p_reflection_probe.is_valid()) { + CameraMatrix projection = p_render_data->cam_projection; + if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; correction.set_depth_correction(true); - projection = correction * p_cam_projection; + projection = correction * p_render_data->cam_projection; } RD::get_singleton()->draw_command_begin_label("Draw Sky"); - sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_cam_transform, time); + sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_render_data->cam_transform, time); RD::get_singleton()->draw_command_end_label(); } @@ -529,12 +517,12 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_ RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_lightmaps, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true); - _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); + _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); { - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } @@ -564,18 +552,29 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr SceneState::ShadowPass shadow_pass; + RenderDataRD render_data; + render_data.cam_projection = p_projection; + render_data.cam_transform = p_transform; + render_data.z_near = 0.0; + render_data.z_far = p_zfar; + render_data.instances = &p_instances; + render_data.lod_camera_plane = p_camera_plane; + render_data.lod_distance_multiplier = p_lod_distance_multiplier; + scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index); + _setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { - p_screen_lod_threshold = 0.0; + render_data.screen_lod_threshold = 0.0; + } else { + render_data.screen_lod_threshold = p_screen_lod_threshold; } PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, true); uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false); @@ -594,8 +593,8 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete shadow_pass.camera_plane = p_camera_plane; - shadow_pass.screen_lod_threshold = p_screen_lod_threshold; - shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier; + shadow_pass.screen_lod_threshold = render_data.screen_lod_threshold; + shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier; shadow_pass.framebuffer = p_framebuffer; shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE); @@ -612,7 +611,7 @@ void RenderForwardMobile::_render_shadow_process() { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { //render passes need to be configured after instance buffer is done, since they need the latest version SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>(), false, i); + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), false, i); } RD::get_singleton()->draw_command_end_label(); @@ -645,14 +644,19 @@ void RenderForwardMobile::_render_material(const Transform &p_cam_transform, con scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = false; - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + RenderDataRD render_data; + render_data.cam_projection = p_cam_projection; + render_data.cam_transform = p_cam_transform; + render_data.instances = &p_instances; + + _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); RENDER_TIMESTAMP("Render Material"); @@ -683,14 +687,17 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in scene_state.ubo.dual_paraboloid_side = 0; scene_state.ubo.material_uv2_mode = true; - _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + RenderDataRD render_data; + render_data.instances = &p_instances; + + _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform()); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); RENDER_TIMESTAMP("Render Material"); @@ -747,15 +754,22 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const _update_render_base_uniform_set(); scene_state.ubo.dual_paraboloid_side = 0; - _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false); + RenderDataRD render_data; + render_data.cam_projection = p_cam_projection; + render_data.cam_transform = p_cam_transform; + render_data.z_near = 0.0; + render_data.z_far = p_cam_projection.get_z_far(); + render_data.instances = &p_instances; + + _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false); PassMode pass_mode = PASS_MODE_SHADOW; - _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); RENDER_TIMESTAMP("Render Collider Heightfield"); @@ -902,7 +916,7 @@ RID RenderForwardMobile::_render_buffers_get_normal_texture(RID p_render_buffers return RID(); } -void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) { +void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append) { if (p_render_list == RENDER_LIST_OPAQUE) { scene_state.used_sss = false; scene_state.used_screen_texture = false; @@ -911,9 +925,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const } uint32_t lightmap_captures_used = 0; - Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); - near_plane.d += p_cam_projection.get_z_near(); - float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near(); + Plane near_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z)); + near_plane.d += p_render_data->cam_projection.get_z_near(); + float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near(); RenderList *rl = &render_list[p_render_list]; @@ -929,8 +943,8 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const //fill list - for (int i = 0; i < (int)p_instances.size(); i++) { - GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>(p_instances[i]); + for (int i = 0; i < (int)p_render_data->instances->size(); i++) { + GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>((*p_render_data->instances)[i]); Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal); inst->depth = near_plane.distance_to(support_min); @@ -988,13 +1002,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const // LOD - if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) { + if (p_render_data->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) { //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal); + Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal); + Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal); - float distance_min = p_lod_plane.distance_to(lod_support_min); - float distance_max = p_lod_plane.distance_to(lod_support_max); + float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min); + float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max); float distance = 0.0; @@ -1007,7 +1021,7 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const distance = -distance_max; } - surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold); + surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold); } else { surf->lod_index = 0; } @@ -1058,25 +1072,25 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const } } -void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { +void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { //!BAS! need to go through this and find out what we don't need anymore // This populates our UBO with main scene data that is pushed into set 1 - //CameraMatrix projection = p_cam_projection; + //CameraMatrix projection = p_render_data->cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; correction.set_depth_correction(p_flip_y); - CameraMatrix projection = correction * p_cam_projection; + CameraMatrix projection = correction * p_render_data->cam_projection; //store camera into ubo RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix); RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); - RendererStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix); - RendererStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); + RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix); + RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); - scene_state.ubo.z_far = p_zfar; - scene_state.ubo.z_near = p_znear; + scene_state.ubo.z_far = p_render_data->z_far; + scene_state.ubo.z_near = p_render_data->z_near; scene_state.ubo.pancake_shadows = p_pancake_shadows; @@ -1094,19 +1108,8 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x; scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y; - /* - scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_cluster_size); - scene_state.ubo.max_cluster_element_count_div_32 = p_max_cluster_elements / 32; - { - uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_cluster_size + 1; - uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_cluster_size + 1; - scene_state.ubo.cluster_type_size = cluster_screen_width * cluster_screen_height * (scene_state.ubo.max_cluster_element_count_div_32 + 32); - scene_state.ubo.cluster_width = cluster_screen_width; - } - */ - - if (p_shadow_atlas.is_valid()) { - Vector2 sas = shadow_atlas_get_size(p_shadow_atlas); + if (p_render_data->shadow_atlas.is_valid()) { + Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas); scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x; scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y; } @@ -1124,22 +1127,22 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf scene_state.ubo.volumetric_fog_enabled = false; scene_state.ubo.fog_enabled = false; - if (p_render_buffers.is_valid()) { - RenderBufferDataForwardMobile *render_buffers = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_buffers); + if (p_render_data->render_buffers.is_valid()) { + RenderBufferDataForwardMobile *render_buffers = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_data->render_buffers); if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) { scene_state.ubo.gi_upscale_for_msaa = true; } - if (render_buffers_has_volumetric_fog(p_render_buffers)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers)) { scene_state.ubo.volumetric_fog_enabled = true; - float fog_end = render_buffers_get_volumetric_fog_end(p_render_buffers); + float fog_end = render_buffers_get_volumetric_fog_end(p_render_data->render_buffers); if (fog_end > 0.0) { scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end; } else { scene_state.ubo.volumetric_fog_inv_length = 1.0; } - float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup + float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_data->render_buffers); //reverse lookup if (fog_detail_spread > 0.0) { scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread; } else { @@ -1160,18 +1163,18 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf scene_state.ubo.use_reflection_cubemap = false; scene_state.ubo.ssao_enabled = false; - } else if (is_environment(p_environment)) { - RS::EnvironmentBG env_bg = environment_get_background(p_environment); - RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment); + } else if (is_environment(p_render_data->environment)) { + RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); + RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = environment_get_bg_energy(p_environment); + float bg_energy = environment_get_bg_energy(p_render_data->environment); scene_state.ubo.ambient_light_color_energy[3] = bg_energy; - scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_environment); + scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment); + Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; @@ -1180,15 +1183,15 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = environment_get_ambient_light_energy(p_environment); - Color color = environment_get_ambient_light_color(p_environment); + float energy = environment_get_ambient_light_energy(p_render_data->environment); + Color color = environment_get_ambient_light_color(p_render_data->environment); color = color.to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; - Basis sky_transform = environment_get_sky_orientation(p_environment); - sky_transform = sky_transform.inverse() * p_cam_transform.basis; + Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); + sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; @@ -1196,43 +1199,43 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf } //specular - RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_environment); + RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment); if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { scene_state.ubo.use_reflection_cubemap = true; } else { scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_environment); - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_environment); + scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment); + scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment); + scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment); - Color ao_color = environment_get_ao_color(p_environment).to_linear(); + Color ao_color = environment_get_ao_color(p_render_data->environment).to_linear(); scene_state.ubo.ao_color[0] = ao_color.r; scene_state.ubo.ao_color[1] = ao_color.g; scene_state.ubo.ao_color[2] = ao_color.b; scene_state.ubo.ao_color[3] = ao_color.a; - scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_environment); - scene_state.ubo.fog_density = environment_get_fog_density(p_environment); - scene_state.ubo.fog_height = environment_get_fog_height(p_environment); - scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_environment); + scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); + scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); + scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); if (scene_state.ubo.fog_height_density >= 0.0001) { scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density; } - scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_environment); + scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - Color fog_color = environment_get_fog_light_color(p_environment).to_linear(); - float fog_energy = environment_get_fog_light_energy(p_environment); + Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear(); + float fog_energy = environment_get_fog_light_energy(p_render_data->environment); scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment); + scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment); } else { - if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { + if (p_render_data->reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { scene_state.ubo.use_ambient_light = false; } else { scene_state.ubo.use_ambient_light = true; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 232ad0066b..bf911319f2 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -148,8 +148,8 @@ protected: } }; - RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0); - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0); + virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color); virtual void _render_shadow_begin(); virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); @@ -167,13 +167,13 @@ protected: void _update_render_base_uniform_set(); virtual RID _render_buffers_get_normal_texture(RID p_render_buffers); - void _fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false); + void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append = false); void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); // void _update_instance_data_buffer(RenderListType p_render_list); static RenderForwardMobile *singleton; - void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); + void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0); void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform); RID render_base_uniform_set; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index b9220cc514..883273c8a5 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -30,6 +30,7 @@ #include "scene_shader_forward_mobile.h" #include "core/config/project_settings.h" +#include "core/math/math_defs.h" #include "render_forward_mobile.h" using namespace RendererSceneRenderImplementation; @@ -625,6 +626,9 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p //builtins actions.renames["TIME"] = "scene_data.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 377b0fd72d..70c1705bff 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -31,8 +31,10 @@ #include "renderer_canvas_render_rd.h" #include "core/config/project_settings.h" #include "core/math/geometry_2d.h" +#include "core/math/math_defs.h" #include "core/math/math_funcs.h" #include "renderer_compositor_rd.h" +#include "servers/rendering/rendering_server_default.h" void RendererCanvasRenderRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { p_mat4[0] = p_transform.elements[0][0]; @@ -390,7 +392,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI r_last_texture = p_texture; } -void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { +void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { //create an empty push constant RS::CanvasItemTextureFilter current_filter = default_filter; @@ -705,286 +707,158 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, const Item case Item::Command::TYPE_MESH: case Item::Command::TYPE_MULTIMESH: case Item::Command::TYPE_PARTICLES: { - ERR_PRINT("FIXME: Mesh, MultiMesh and Particles render commands are unimplemented currently, they need to be ported to the 4.0 rendering architecture."); -#ifndef _MSC_VER -#warning Item::Command types for Mesh, MultiMesh and Particles need to be implemented. -#endif - // See #if 0'ed code below to port from GLES3. - } break; - -#if 0 - case Item::Command::TYPE_MESH: { - Item::CommandMesh *mesh = static_cast<Item::CommandMesh *>(c); - _set_texture_rect_mode(false); - - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mesh->texture, mesh->normal_map); - - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); + RID mesh; + RID mesh_instance; + RID texture; + Color modulate(1, 1, 1, 1); + float world_backup[6]; + int instance_count = 1; + + for (int j = 0; j < 6; j++) { + world_backup[j] = push_constant.world[j]; } - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform * mesh->transform); - - RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(mesh->mesh); - if (mesh_data) { - for (int j = 0; j < mesh_data->surfaces.size(); j++) { - RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j]; - // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing - glBindVertexArray(s->array_id); - - glVertexAttrib4f(RS::ARRAY_COLOR, mesh->modulate.r, mesh->modulate.g, mesh->modulate.b, mesh->modulate.a); - - if (s->index_array_len) { - glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); - } else { - glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); - } - - glBindVertexArray(0); + if (c->type == Item::Command::TYPE_MESH) { + const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(c); + mesh = m->mesh; + mesh_instance = m->mesh_instance; + texture = m->texture; + modulate = m->modulate; + _update_transform_2d_to_mat2x3(base_transform * m->transform, push_constant.world); + } else if (c->type == Item::Command::TYPE_MULTIMESH) { + const Item::CommandMultiMesh *mm = static_cast<const Item::CommandMultiMesh *>(c); + RID multimesh = mm->multimesh; + mesh = storage->multimesh_get_mesh(multimesh); + texture = mm->texture; + + if (storage->multimesh_get_transform_format(multimesh) != RS::MULTIMESH_TRANSFORM_2D) { + break; } - } - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform); - - } break; - case Item::Command::TYPE_MULTIMESH: { - Item::CommandMultiMesh *mmesh = static_cast<Item::CommandMultiMesh *>(c); - - RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.getornull(mmesh->multimesh); - - if (!multi_mesh) - break; - RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(multi_mesh->mesh); + instance_count = storage->multimesh_get_instances_to_draw(multimesh); - if (!mesh_data) - break; + RID uniform_set = storage->multimesh_get_2d_uniform_set(multimesh, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET); + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set, TRANSFORMS_UNIFORM_SET); + push_constant.flags |= 1; //multimesh, trails disabled + if (storage->multimesh_uses_colors(multimesh)) { + push_constant.flags |= FLAGS_INSTANCING_HAS_COLORS; + } + if (storage->multimesh_uses_custom_data(multimesh)) { + push_constant.flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA; + } + } else if (c->type == Item::Command::TYPE_PARTICLES) { + const Item::CommandParticles *pt = static_cast<const Item::CommandParticles *>(c); + ERR_BREAK(storage->particles_get_mode(pt->particles) != RS::PARTICLES_MODE_2D); + storage->particles_request_process(pt->particles); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mmesh->texture, mmesh->normal_map); + if (storage->particles_is_inactive(pt->particles)) { + break; + } - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, multi_mesh->custom_data_format != RS::MULTIMESH_CUSTOM_DATA_NONE); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true); - //reset shader and force rebind - state.using_texture_rect = true; - _set_texture_rect_mode(false); + RenderingServerDefault::redraw_request(); // active particles means redraw request - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - } + bool local_coords = true; + int dpc = storage->particles_get_draw_passes(pt->particles); + if (dpc == 0) { + break; //nothing to draw + } + uint32_t divisor = 1; + instance_count = storage->particles_get_amount(pt->particles, divisor); - int amount = MIN(multi_mesh->size, multi_mesh->visible_instances); + RID uniform_set = storage->particles_get_instance_buffer_uniform_set(pt->particles, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET); + RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set, TRANSFORMS_UNIFORM_SET); - if (amount == -1) { - amount = multi_mesh->size; - } + push_constant.flags |= divisor; + instance_count /= divisor; - for (int j = 0; j < mesh_data->surfaces.size(); j++) { - RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j]; - // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing - glBindVertexArray(s->instancing_array_id); + push_constant.flags |= FLAGS_INSTANCING_HAS_COLORS; + push_constant.flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA; - glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer + mesh = storage->particles_get_draw_pass_mesh(pt->particles, 0); //higher ones are ignored + texture = pt->texture; - int stride = (multi_mesh->xform_floats + multi_mesh->color_floats + multi_mesh->custom_data_floats) * 4; - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(0)); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(4 * 4)); - glVertexAttribDivisor(9, 1); + if (storage->particles_has_collision(pt->particles) && storage->render_target_is_sdf_enabled(p_render_target)) { + //pass collision information + Transform2D xform; + if (local_coords) { + xform = p_item->final_transform; + } else { + xform = p_canvas_transform_inverse; + } - int color_ofs; + RID sdf_texture = storage->render_target_get_sdf_texture(p_render_target); - if (multi_mesh->transform_format == RS::MULTIMESH_TRANSFORM_3D) { - glEnableVertexAttribArray(10); - glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(8 * 4)); - glVertexAttribDivisor(10, 1); - color_ofs = 12 * 4; - } else { - glDisableVertexAttribArray(10); - glVertexAttrib4f(10, 0, 0, 1, 0); - color_ofs = 8 * 4; - } - - int custom_data_ofs = color_ofs; - - switch (multi_mesh->color_format) { - case RS::MULTIMESH_COLOR_NONE: { - glDisableVertexAttribArray(11); - glVertexAttrib4f(11, 1, 1, 1, 1); - } break; - case RS::MULTIMESH_COLOR_8BIT: { - glEnableVertexAttribArray(11); - glVertexAttribPointer(11, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, CAST_INT_TO_UCHAR_PTR(color_ofs)); - glVertexAttribDivisor(11, 1); - custom_data_ofs += 4; - - } break; - case RS::MULTIMESH_COLOR_FLOAT: { - glEnableVertexAttribArray(11); - glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(color_ofs)); - glVertexAttribDivisor(11, 1); - custom_data_ofs += 4 * 4; - } break; - } + Rect2 to_screen; + { + Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_render_target); - switch (multi_mesh->custom_data_format) { - case RS::MULTIMESH_CUSTOM_DATA_NONE: { - glDisableVertexAttribArray(12); - glVertexAttrib4f(12, 1, 1, 1, 1); - } break; - case RS::MULTIMESH_CUSTOM_DATA_8BIT: { - glEnableVertexAttribArray(12); - glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, CAST_INT_TO_UCHAR_PTR(custom_data_ofs)); - glVertexAttribDivisor(12, 1); - - } break; - case RS::MULTIMESH_CUSTOM_DATA_FLOAT: { - glEnableVertexAttribArray(12); - glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(custom_data_ofs)); - glVertexAttribDivisor(12, 1); - } break; - } + to_screen.size = Vector2(1.0 / sdf_rect.size.width, 1.0 / sdf_rect.size.height); + to_screen.position = -sdf_rect.position * to_screen.size; + } - if (s->index_array_len) { - glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount); + storage->particles_set_canvas_sdf_collision(pt->particles, true, xform, to_screen, sdf_texture); } else { - glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount); + storage->particles_set_canvas_sdf_collision(pt->particles, false, Transform2D(), Rect2(), RID()); } + } - glBindVertexArray(0); + if (mesh.is_null()) { + break; } - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); - state.using_texture_rect = true; - _set_texture_rect_mode(false); + _bind_canvas_texture(p_draw_list, texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size); - } break; - case Item::Command::TYPE_PARTICLES: { - Item::CommandParticles *particles_cmd = static_cast<Item::CommandParticles *>(c); + uint32_t surf_count = storage->mesh_get_surface_count(mesh); + static const PipelineVariant variant[RS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP }; - RasterizerStorageGLES3::Particles *particles = storage->particles_owner.getornull(particles_cmd->particles); - if (!particles) - break; - - if (particles->inactive && !particles->emitting) - break; + push_constant.modulation[0] = base_color.r * modulate.r; + push_constant.modulation[1] = base_color.g * modulate.g; + push_constant.modulation[2] = base_color.b * modulate.b; + push_constant.modulation[3] = base_color.a * modulate.a; - glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1); //not used, so keep white + for (int j = 0; j < 4; j++) { + push_constant.src_rect[j] = 0; + push_constant.dst_rect[j] = 0; + push_constant.ninepatch_margins[j] = 0; + } - RenderingServerDefault::redraw_request(); + for (uint32_t j = 0; j < surf_count; j++) { + void *surface = storage->mesh_get_surface(mesh, j); - storage->particles_request_process(particles_cmd->particles); - //enable instancing + RS::PrimitiveType primitive = storage->mesh_surface_get_primitive(surface); + ERR_CONTINUE(primitive < 0 || primitive >= RS::PRIMITIVE_MAX); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, true); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PARTICLES, true); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true); - //reset shader and force rebind - state.using_texture_rect = true; - _set_texture_rect_mode(false); + uint32_t input_mask = pipeline_variants->variants[light_mode][variant[primitive]].get_vertex_input_mask(); - RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(particles_cmd->texture, particles_cmd->normal_map); + RID vertex_array; + RD::VertexFormatID vertex_format = RD::INVALID_FORMAT_ID; - if (texture) { - Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); - } else { - state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2(1.0, 1.0)); - } + if (mesh_instance.is_valid()) { + storage->mesh_instance_surface_get_vertex_arrays_and_format(mesh_instance, j, input_mask, vertex_array, vertex_format); + } else { + storage->mesh_surface_get_vertex_arrays_and_format(surface, input_mask, vertex_array, vertex_format); + } - if (!particles->use_local_coords) { - Transform2D inv_xf; - inv_xf.set_axis(0, Vector2(particles->emission_transform.basis.get_axis(0).x, particles->emission_transform.basis.get_axis(0).y)); - inv_xf.set_axis(1, Vector2(particles->emission_transform.basis.get_axis(1).x, particles->emission_transform.basis.get_axis(1).y)); - inv_xf.set_origin(Vector2(particles->emission_transform.get_origin().x, particles->emission_transform.get_origin().y)); - inv_xf.affine_invert(); + RID pipeline = pipeline_variants->variants[light_mode][variant[primitive]].get_render_pipeline(vertex_format, p_framebuffer_format); + RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); - state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform * inv_xf); - } + RID index_array = storage->mesh_surface_get_index_array(surface, 0); - glBindVertexArray(data.particle_quad_array); //use particle quad array - glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //bind particle buffer - - int stride = sizeof(float) * 4 * 6; - - int amount = particles->amount; - - if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_LIFETIME) { - glEnableVertexAttribArray(8); //xform x - glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 3)); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); //xform y - glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 4)); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(10); //xform z - glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 5)); - glVertexAttribDivisor(10, 1); - glEnableVertexAttribArray(11); //color - glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, nullptr); - glVertexAttribDivisor(11, 1); - glEnableVertexAttribArray(12); //custom - glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 2)); - glVertexAttribDivisor(12, 1); - - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, amount); - } else { - //split - int split = int(Math::ceil(particles->phase * particles->amount)); - - if (amount - split > 0) { - glEnableVertexAttribArray(8); //xform x - glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * split + sizeof(float) * 4 * 3)); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); //xform y - glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * split + sizeof(float) * 4 * 4)); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(10); //xform z - glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * split + sizeof(float) * 4 * 5)); - glVertexAttribDivisor(10, 1); - glEnableVertexAttribArray(11); //color - glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * split + 0)); - glVertexAttribDivisor(11, 1); - glEnableVertexAttribArray(12); //custom - glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * split + sizeof(float) * 4 * 2)); - glVertexAttribDivisor(12, 1); - - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, amount - split); + if (index_array.is_valid()) { + RD::get_singleton()->draw_list_bind_index_array(p_draw_list, index_array); } - if (split > 0) { - glEnableVertexAttribArray(8); //xform x - glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 3)); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); //xform y - glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 4)); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(10); //xform z - glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 5)); - glVertexAttribDivisor(10, 1); - glEnableVertexAttribArray(11); //color - glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, nullptr); - glVertexAttribDivisor(11, 1); - glEnableVertexAttribArray(12); //custom - glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * 2)); - glVertexAttribDivisor(12, 1); - - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, split); - } - } + RD::get_singleton()->draw_list_bind_vertex_array(p_draw_list, vertex_array); + RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant)); - glBindVertexArray(0); + RD::get_singleton()->draw_list_draw(p_draw_list, index_array.is_valid(), instance_count); + } - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PARTICLES, false); - state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); - state.using_texture_rect = true; - _set_texture_rect_mode(false); + for (int j = 0; j < 6; j++) { + push_constant.world[j] = world_backup[j]; + } } break; -#endif case Item::Command::TYPE_TRANSFORM: { const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); _update_transform_2d_to_mat2x3(base_transform * transform->xform, push_constant.world); @@ -1210,7 +1084,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co } } - _render_item(draw_list, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants); + _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants); prev_material = material; } @@ -1437,6 +1311,9 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p Item *canvas_group_owner = nullptr; + bool update_skeletons = false; + bool time_used = false; + while (ci) { if (ci->copy_back_buffer && canvas_group_owner == nullptr) { backbuffer_copy = true; @@ -1461,6 +1338,9 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p if (md->shader_data->uses_sdf) { r_sdf_used = true; } + if (md->shader_data->uses_time) { + time_used = true; + } if (md->last_frame != RendererCompositorRD::singleton->get_frame_number()) { md->last_frame = RendererCompositorRD::singleton->get_frame_number(); if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) { @@ -1472,9 +1352,27 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p } } + if (ci->skeleton.is_valid()) { + const Item::Command *c = ci->commands; + + while (c) { + if (c->type == Item::Command::TYPE_MESH) { + const Item::CommandMesh *cm = static_cast<const Item::CommandMesh *>(c); + if (cm->mesh_instance.is_valid()) { + storage->mesh_instance_check_for_update(cm->mesh_instance); + update_skeletons = true; + } + } + } + } + if (ci->canvas_group_owner != nullptr) { if (canvas_group_owner == nullptr) { //Canvas group begins here, render until before this item + if (update_skeletons) { + storage->update_mesh_instances(); + update_skeletons = false; + } _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); item_count = 0; @@ -1494,6 +1392,11 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p } if (ci == canvas_group_owner) { + if (update_skeletons) { + storage->update_mesh_instances(); + update_skeletons = false; + } + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, true); item_count = 0; @@ -1506,6 +1409,10 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p if (backbuffer_copy) { //render anything pending, including clearing if no items + if (update_skeletons) { + storage->update_mesh_instances(); + update_skeletons = false; + } _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); item_count = 0; @@ -1518,6 +1425,11 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p items[item_count++] = ci; if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) { + if (update_skeletons) { + storage->update_mesh_instances(); + update_skeletons = false; + } + _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); //then reset item_count = 0; @@ -1525,6 +1437,10 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p ci = ci->next; } + + if (time_used) { + RenderingServerDefault::redraw_request(); + } } RID RendererCanvasRenderRD::light_create() { @@ -2001,6 +1917,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { uniforms.clear(); uses_screen_texture = false; uses_sdf = false; + uses_time = false; if (code == String()) { return; //just invalid, but no error @@ -2025,6 +1942,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture; actions.usage_flag_pointers["texture_sdf"] = &uses_sdf; + actions.usage_flag_pointers["TIME"] = &uses_time; actions.uniforms = &uniforms; @@ -2491,6 +2409,9 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { actions.renames["CANVAS_MATRIX"] = "canvas_data.canvas_transform"; actions.renames["SCREEN_MATRIX"] = "canvas_data.screen_transform"; actions.renames["TIME"] = "canvas_data.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["AT_LIGHT_PASS"] = "false"; actions.renames["INSTANCE_CUSTOM"] = "instance_custom"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index cb947d7180..890a4e3649 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -67,12 +67,10 @@ class RendererCanvasRenderRD : public RendererCanvasRender { }; enum { - FLAGS_INSTANCING_STRIDE_MASK = 0xF, - FLAGS_INSTANCING_ENABLED = (1 << 4), - FLAGS_INSTANCING_HAS_COLORS = (1 << 5), - FLAGS_INSTANCING_COLOR_8BIT = (1 << 6), - FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 7), - FLAGS_INSTANCING_CUSTOM_DATA_8_BIT = (1 << 8), + + FLAGS_INSTANCING_MASK = 0x7F, + FLAGS_INSTANCING_HAS_COLORS = (1 << 7), + FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 8), FLAGS_CLIP_RECT_UV = (1 << 9), FLAGS_TRANSPOSE_RECT = (1 << 10), @@ -178,6 +176,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { bool uses_screen_texture = false; bool uses_sdf = false; + bool uses_time = false; virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); @@ -427,7 +426,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID _create_base_uniform_set(RID p_to_render_target, bool p_backbuffer); inline void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size); //recursive, so regular inline used instead. - void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants); + void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants); void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false); _FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4); diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index cb3e67e990..1337d36762 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -31,6 +31,7 @@ #include "renderer_compositor_rd.h" #include "core/config/project_settings.h" +#include "core/os/dir_access.h" void RendererCompositorRD::prepare_for_blitting_render_targets() { RD::get_singleton()->prepare_screen_for_drawing(); @@ -44,32 +45,40 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID ERR_CONTINUE(texture.is_null()); RID rd_texture = storage->texture_get_rd_texture(texture); ERR_CONTINUE(rd_texture.is_null()); + if (!render_target_descriptors.has(rd_texture) || !RD::get_singleton()->uniform_set_is_valid(render_target_descriptors[rd_texture])) { Vector<RD::Uniform> uniforms; RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(copy_viewports_sampler); + u.ids.push_back(blit.sampler); u.ids.push_back(rd_texture); uniforms.push_back(u); - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, copy_viewports_rd_shader, 0); + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0); render_target_descriptors[rd_texture] = uniform_set; } Size2 screen_size(RD::get_singleton()->screen_get_width(p_screen), RD::get_singleton()->screen_get_height(p_screen)); - - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_viewports_rd_pipeline); - RD::get_singleton()->draw_list_bind_index_array(draw_list, copy_viewports_rd_array); + BlitMode mode = p_render_targets[i].lens_distortion.apply ? BLIT_MODE_LENS : p_render_targets[i].multi_view.use_layer ? BLIT_MODE_USE_LAYER : + BLIT_MODE_NORMAL; + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[mode]); + RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_target_descriptors[rd_texture], 0); - float push_constant[4] = { - p_render_targets[i].rect.position.x / screen_size.width, - p_render_targets[i].rect.position.y / screen_size.height, - p_render_targets[i].rect.size.width / screen_size.width, - p_render_targets[i].rect.size.height / screen_size.height, - }; - RD::get_singleton()->draw_list_set_push_constant(draw_list, push_constant, 4 * sizeof(float)); + blit.push_constant.rect[0] = p_render_targets[i].rect.position.x / screen_size.width; + blit.push_constant.rect[1] = p_render_targets[i].rect.position.y / screen_size.height; + blit.push_constant.rect[2] = p_render_targets[i].rect.size.width / screen_size.width; + blit.push_constant.rect[3] = p_render_targets[i].rect.size.height / screen_size.height; + blit.push_constant.layer = p_render_targets[i].multi_view.layer; + blit.push_constant.eye_center[0] = p_render_targets[i].lens_distortion.eye_center.x; + blit.push_constant.eye_center[1] = p_render_targets[i].lens_distortion.eye_center.y; + blit.push_constant.k1 = p_render_targets[i].lens_distortion.k1; + blit.push_constant.k2 = p_render_targets[i].lens_distortion.k2; + blit.push_constant.upscale = p_render_targets[i].lens_distortion.upscale; + blit.push_constant.aspect_ratio = p_render_targets[i].lens_distortion.aspect_ratio; + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); } @@ -96,40 +105,22 @@ void RendererCompositorRD::end_frame(bool p_swap_buffers) { } void RendererCompositorRD::initialize() { - { //create framebuffer copy shader - RenderingDevice::ShaderStageData vert; - vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX; - vert.spir_v = RenderingDevice::get_singleton()->shader_compile_from_source(RenderingDevice::SHADER_STAGE_VERTEX, - "#version 450\n" - "layout(push_constant, binding = 0, std140) uniform Pos { vec4 dst_rect; } pos;\n" - "layout(location =0) out vec2 uv;\n" - "void main() { \n" - " vec2 base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));\n" - " uv = base_arr[gl_VertexIndex];\n" - " vec2 vtx = pos.dst_rect.xy+uv*pos.dst_rect.zw;\n" - " gl_Position = vec4(vtx * 2.0 - 1.0,0.0,1.0);\n" - "}\n"); - - RenderingDevice::ShaderStageData frag; - frag.shader_stage = RenderingDevice::SHADER_STAGE_FRAGMENT; - frag.spir_v = RenderingDevice::get_singleton()->shader_compile_from_source(RenderingDevice::SHADER_STAGE_FRAGMENT, - "#version 450\n" - "layout (location = 0) in vec2 uv;\n" - "layout (location = 0) out vec4 color;\n" - "layout (binding = 0) uniform sampler2D src_rt;\n" - "void main() { color=texture(src_rt,uv); }\n"); - - Vector<RenderingDevice::ShaderStageData> source; - source.push_back(vert); - source.push_back(frag); - String error; - copy_viewports_rd_shader = RD::get_singleton()->shader_create(source); - if (!copy_viewports_rd_shader.is_valid()) { - print_line("Failed compilation: " + error); + { + // Initialize blit + Vector<String> blit_modes; + blit_modes.push_back("\n"); + blit_modes.push_back("\n#define USE_LAYER\n"); + blit_modes.push_back("\n#define USE_LAYER\n#define APPLY_LENS_DISTORTION\n"); + + blit.shader.initialize(blit_modes); + + blit.shader_version = blit.shader.version_create(); + + for (int i = 0; i < BLIT_MODE_MAX; i++) { + blit.pipelines[i] = RD::get_singleton()->render_pipeline_create(blit.shader.version_get_shader(blit.shader_version, i), RD::get_singleton()->screen_get_framebuffer_format(), RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RenderingDevice::PipelineColorBlendState::create_disabled(), 0); } - } - { //create index array for copy shader + //create index array for copy shader Vector<uint8_t> pv; pv.resize(6 * 4); { @@ -142,15 +133,10 @@ void RendererCompositorRD::initialize() { p32[4] = 2; p32[5] = 3; } - copy_viewports_rd_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv); - copy_viewports_rd_array = RD::get_singleton()->index_array_create(copy_viewports_rd_index_buffer, 0, 6); - } + blit.index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv); + blit.array = RD::get_singleton()->index_array_create(blit.index_buffer, 0, 6); - { //pipeline - copy_viewports_rd_pipeline = RD::get_singleton()->render_pipeline_create(copy_viewports_rd_shader, RD::get_singleton()->screen_get_framebuffer_format(), RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RenderingDevice::PipelineColorBlendState::create_disabled(), 0); - } - { // sampler - copy_viewports_sampler = RD::get_singleton()->sampler_create(RD::SamplerState()); + blit.sampler = RD::get_singleton()->sampler_create(RD::SamplerState()); } } @@ -162,14 +148,51 @@ void RendererCompositorRD::finalize() { memdelete(storage); //only need to erase these, the rest are erased by cascade - RD::get_singleton()->free(copy_viewports_rd_index_buffer); - RD::get_singleton()->free(copy_viewports_rd_shader); - RD::get_singleton()->free(copy_viewports_sampler); + blit.shader.version_free(blit.shader_version); + RD::get_singleton()->free(blit.index_buffer); + RD::get_singleton()->free(blit.sampler); } RendererCompositorRD *RendererCompositorRD::singleton = nullptr; RendererCompositorRD::RendererCompositorRD() { + { + String shader_cache_dir = Engine::get_singleton()->get_shader_cache_path(); + if (shader_cache_dir == String()) { + shader_cache_dir = "user://"; + } + DirAccessRef da = DirAccess::open(shader_cache_dir); + if (!da) { + ERR_PRINT("Can't create shader cache folder, no shader caching will happen: " + shader_cache_dir); + } else { + Error err = da->change_dir("shader_cache"); + if (err != OK) { + err = da->make_dir("shader_cache"); + } + if (err != OK) { + ERR_PRINT("Can't create shader cache folder, no shader caching will happen: " + shader_cache_dir); + } else { + shader_cache_dir = shader_cache_dir.plus_file("shader_cache"); + + bool shader_cache_enabled = GLOBAL_GET("rendering/shader_compiler/shader_cache/enabled"); + if (!Engine::get_singleton()->is_editor_hint() && !shader_cache_enabled) { + shader_cache_dir = String(); //disable only if not editor + } + + if (shader_cache_dir != String()) { + bool compress = GLOBAL_GET("rendering/shader_compiler/shader_cache/compress"); + bool use_zstd = GLOBAL_GET("rendering/shader_compiler/shader_cache/use_zstd_compression"); + bool strip_debug = GLOBAL_GET("rendering/shader_compiler/shader_cache/strip_debug"); + + ShaderRD::set_shader_cache_dir(shader_cache_dir); + ShaderRD::set_shader_cache_save_compressed(compress); + ShaderRD::set_shader_cache_save_compressed_zstd(use_zstd); + ShaderRD::set_shader_cache_save_debug(!strip_debug); + } + } + } + } + singleton = this; time = 0; @@ -186,3 +209,7 @@ RendererCompositorRD::RendererCompositorRD() { scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered(storage)); } } + +RendererCompositorRD::~RendererCompositorRD() { + ShaderRD::set_shader_cache_dir(String()); +} diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index b3865de2bf..7a78322051 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -38,6 +38,7 @@ #include "servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h" #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" +#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h" class RendererCompositorRD : public RendererCompositor { protected: @@ -45,11 +46,35 @@ protected: RendererStorageRD *storage; RendererSceneRenderRD *scene; - RID copy_viewports_rd_shader; - RID copy_viewports_rd_pipeline; - RID copy_viewports_rd_index_buffer; - RID copy_viewports_rd_array; - RID copy_viewports_sampler; + enum BlitMode { + BLIT_MODE_NORMAL, + BLIT_MODE_USE_LAYER, + BLIT_MODE_LENS, + BLIT_MODE_MAX + }; + + struct BlitPushConstant { + float rect[4]; + + float eye_center[2]; + float k1; + float k2; + + float upscale; + float aspect_ratio; + uint32_t layer; + uint32_t pad1; + }; + + struct Blit { + BlitPushConstant push_constant; + BlitShaderRD shader; + RID shader_version; + RID pipelines[BLIT_MODE_MAX]; + RID index_buffer; + RID array; + RID sampler; + } blit; Map<RID, RID> render_target_descriptors; @@ -93,6 +118,6 @@ public: static RendererCompositorRD *singleton; RendererCompositorRD(); - ~RendererCompositorRD() {} + ~RendererCompositorRD(); }; #endif // RASTERIZER_RD_H diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index bc92e0b1ad..b289b17fad 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -1367,7 +1367,7 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr } } -void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform &p_transform, RendererSceneRenderRD *p_scene_render) { +void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) { /* Update general SDFGI Buffer */ SDFGIData sdfgi_data; diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h index df20011b23..59f5f374d1 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h @@ -48,7 +48,8 @@ #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" -// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound +// Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound +struct RenderDataRD; class RendererSceneRenderRD; class RendererSceneGIRD { @@ -529,7 +530,7 @@ public: void debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture); void debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform); - void pre_process_gi(const Transform &p_transform, RendererSceneRenderRD *p_scene_render); + void pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index d7a5d1211c..1f01de1333 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1731,13 +1731,13 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid); } -void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); +void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); //glow (if enabled) - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + CameraEffects *camfx = camera_effects_owner.getornull(p_render_data->camera_effects); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -1747,7 +1747,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_rende } float bokeh_size = camfx->dof_blur_amount * 64.0; - storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_projection.get_z_near(), p_projection.get_z_far(), p_projection.is_orthogonal()); + storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal); } if (can_use_effects && env && env->auto_exposure) { @@ -3459,13 +3459,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->prev_cam_transform = p_cam_transform; } -uint32_t RendererSceneRenderRD::_get_render_state_directional_light_count() const { - return render_state.directional_light_count; -} - -bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) { - if (render_state.render_buffers.is_valid()) { - RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); +bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { + if (p_render_data->render_buffers.is_valid()) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); if (rb->sdfgi != nullptr) { return true; } @@ -3473,34 +3469,34 @@ bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) { return false; } -void RendererSceneRenderRD::_post_prepass_render(bool p_use_gi) { - if (render_state.render_buffers.is_valid()) { +void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { + if (p_render_data->render_buffers.is_valid()) { if (p_use_gi) { - RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); + RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { return; } - RendererSceneEnvironmentRD *env = environment_owner.getornull(render_state.environment); + RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); rb->sdfgi->update_probes(env, sky.sky_owner.getornull(env->sky)); } } } -void RendererSceneRenderRD::_pre_resolve_render(bool p_use_gi) { - if (render_state.render_buffers.is_valid()) { +void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi) { + if (p_render_data->render_buffers.is_valid()) { if (p_use_gi) { RD::get_singleton()->compute_list_end(); } } } -void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) { +void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) { // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time - if (render_state.render_buffers.is_valid() && p_use_gi) { - RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers); + if (p_render_data->render_buffers.is_valid() && p_use_gi) { + RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { return; @@ -3513,8 +3509,8 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R render_state.shadows.clear(); render_state.directional_shadows.clear(); - Plane camera_plane(render_state.cam_transform.origin, -render_state.cam_transform.basis.get_axis(Vector3::AXIS_Z)); - float lod_distance_multiplier = render_state.cam_projection.get_lod_multiplier(); + Plane camera_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z)); + float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier(); { for (int i = 0; i < render_state.render_shadow_count; i++) { @@ -3531,7 +3527,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R //cube shadows are rendered in their own way for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, true, true, true); + _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, true, true, true); } if (render_state.directional_shadows.size()) { @@ -3545,7 +3541,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R // Render GI bool render_shadows = render_state.directional_shadows.size() || render_state.shadows.size(); - bool render_gi = render_state.render_buffers.is_valid() && p_use_gi; + bool render_gi = p_render_data->render_buffers.is_valid() && p_use_gi; if (render_shadows && render_gi) { RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)"); @@ -3561,11 +3557,11 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R //render directional shadows for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false); + _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false); } //render positional shadows for (uint32_t i = 0; i < render_state.shadows.size(); i++) { - _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true); + _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true); } _render_shadow_process(); @@ -3573,7 +3569,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R //start GI if (render_gi) { - gi.process_gi(render_state.render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, render_state.environment, render_state.cam_projection, render_state.cam_transform, *render_state.gi_probes, this); + gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->gi_probes, this); } //Do shadow rendering (in parallel with GI) @@ -3585,9 +3581,9 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier } - if (render_state.render_buffers.is_valid()) { + if (p_render_data->render_buffers.is_valid()) { if (p_use_ssao) { - _process_ssao(render_state.render_buffers, render_state.environment, p_normal_roughness_buffer, render_state.cam_projection); + _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection); } } @@ -3595,32 +3591,32 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); if (current_cluster_builder) { - current_cluster_builder->begin(render_state.cam_transform, render_state.cam_projection, !render_state.reflection_probe.is_valid()); + current_cluster_builder->begin(p_render_data->cam_transform, p_render_data->cam_projection, !p_render_data->reflection_probe.is_valid()); } bool using_shadows = true; - if (render_state.reflection_probe.is_valid()) { - if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(render_state.reflection_probe))) { + if (p_render_data->reflection_probe.is_valid()) { + if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { using_shadows = false; } } else { //do not render reflections when rendering a reflection probe - _setup_reflections(*render_state.reflection_probes, render_state.cam_transform.affine_inverse(), render_state.environment); + _setup_reflections(*p_render_data->reflection_probes, p_render_data->cam_transform.affine_inverse(), p_render_data->environment); } uint32_t directional_light_count = 0; uint32_t positional_light_count = 0; - _setup_lights(*render_state.lights, render_state.cam_transform, render_state.shadow_atlas, using_shadows, directional_light_count, positional_light_count); - _setup_decals(*render_state.decals, render_state.cam_transform.affine_inverse()); + _setup_lights(*p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count); + _setup_decals(*p_render_data->decals, p_render_data->cam_transform.affine_inverse()); - render_state.directional_light_count = directional_light_count; + p_render_data->directional_light_count = directional_light_count; if (current_cluster_builder) { current_cluster_builder->bake_cluster(); } - if (render_state.render_buffers.is_valid()) { + if (p_render_data->render_buffers.is_valid()) { bool directional_shadows = false; for (uint32_t i = 0; i < directional_light_count; i++) { if (cluster.directional_lights[i].shadow_enabled) { @@ -3629,7 +3625,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R } } if (is_volumetric_supported()) { - _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count); + _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count); } } } @@ -3643,24 +3639,37 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & } //assign render data + RenderDataRD render_data; { - render_state.render_buffers = p_render_buffers; - render_state.cam_transform = p_cam_transform; - render_state.cam_projection = p_cam_projection; - render_state.cam_ortogonal = p_cam_projection.is_orthogonal(); - render_state.instances = &p_instances; - render_state.lights = &p_lights; - render_state.reflection_probes = &p_reflection_probes; - render_state.gi_probes = &p_gi_probes; - render_state.decals = &p_decals; - render_state.lightmaps = &p_lightmaps; - render_state.environment = p_environment; - render_state.camera_effects = p_camera_effects; - render_state.shadow_atlas = p_shadow_atlas; - render_state.reflection_atlas = p_reflection_atlas; - render_state.reflection_probe = p_reflection_probe; - render_state.reflection_probe_pass = p_reflection_probe_pass; - render_state.screen_lod_threshold = p_screen_lod_threshold; + render_data.render_buffers = p_render_buffers; + + render_data.cam_transform = p_cam_transform; + render_data.cam_projection = p_cam_projection; + render_data.cam_ortogonal = p_cam_projection.is_orthogonal(); // !BAS! Shouldn't this be p_cam_ortogonal ? + render_data.z_near = p_cam_projection.get_z_near(); + render_data.z_far = p_cam_projection.get_z_far(); + + render_data.instances = &p_instances; + render_data.lights = &p_lights; + render_data.reflection_probes = &p_reflection_probes; + render_data.gi_probes = &p_gi_probes; + render_data.decals = &p_decals; + render_data.lightmaps = &p_lightmaps; + render_data.environment = p_environment; + render_data.camera_effects = p_camera_effects; + render_data.shadow_atlas = p_shadow_atlas; + render_data.reflection_atlas = p_reflection_atlas; + render_data.reflection_probe = p_reflection_probe; + render_data.reflection_probe_pass = p_reflection_probe_pass; + + render_data.lod_distance_multiplier = p_cam_projection.get_lod_multiplier(); + render_data.lod_camera_plane = Plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z)); + + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { + render_data.screen_lod_threshold = 0.0; + } else { + render_data.screen_lod_threshold = p_screen_lod_threshold; + } render_state.render_shadows = p_render_shadows; render_state.render_shadow_count = p_render_shadow_count; @@ -3672,9 +3681,9 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & PagedArray<RID> empty; if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - render_state.lights = ∅ - render_state.reflection_probes = ∅ - render_state.gi_probes = ∅ + render_data.lights = ∅ + render_data.reflection_probes = ∅ + render_data.gi_probes = ∅ } //sdfgi first @@ -3704,11 +3713,11 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & } } - if (render_buffers_owner.owns(render_state.render_buffers)) { - // render_state.render_buffers == p_render_buffers so we can use our already retrieved rb + if (render_buffers_owner.owns(render_data.render_buffers)) { + // render_data.render_buffers == p_render_buffers so we can use our already retrieved rb current_cluster_builder = rb->cluster_builder; - } else if (reflection_probe_instance_owner.owns(render_state.reflection_probe)) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_state.reflection_probe); + } else if (reflection_probe_instance_owner.owns(render_data.reflection_probe)) { + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_data.reflection_probe); ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas); if (!ra) { ERR_PRINT("reflection probe has no reflection atlas! Bug?"); @@ -3724,12 +3733,12 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & if (rb != nullptr && rb->sdfgi != nullptr) { rb->sdfgi->update_cascades(); - rb->sdfgi->pre_process_gi(p_cam_transform, this); + rb->sdfgi->pre_process_gi(p_cam_transform, &render_data, this); } render_state.gi_probe_count = 0; if (rb != nullptr && rb->sdfgi != nullptr) { - gi.setup_giprobes(render_state.render_buffers, render_state.cam_transform, *render_state.gi_probes, render_state.gi_probe_count, this); + gi.setup_giprobes(render_data.render_buffers, render_data.cam_transform, *render_data.gi_probes, render_state.gi_probe_count, this); rb->sdfgi->update_light(); } @@ -3737,11 +3746,13 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & render_state.depth_prepass_used = false; //calls _pre_opaque_render between depth pre-pass and opaque pass if (current_cluster_builder != nullptr) { - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, current_cluster_builder->get_cluster_buffer(), current_cluster_builder->get_cluster_size(), current_cluster_builder->get_max_cluster_elements(), p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold); - } else { - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, RID(), 0, 0, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold); + render_data.cluster_buffer = current_cluster_builder->get_cluster_buffer(); + render_data.cluster_size = current_cluster_builder->get_cluster_size(); + render_data.cluster_max_elements = current_cluster_builder->get_max_cluster_elements(); } + _render_scene(&render_data, clear_color); + if (p_render_buffers.is_valid()) { if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES) { ClusterBuilderRD::ElementType elem_type = ClusterBuilderRD::ELEMENT_TYPE_MAX; @@ -3768,7 +3779,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform & RENDER_TIMESTAMP("Tonemap"); - _render_buffers_post_process_and_tonemap(p_render_buffers, p_environment, p_camera_effects, p_cam_projection); + _render_buffers_post_process_and_tonemap(&render_data); _render_buffers_debug_draw(p_render_buffers, p_shadow_atlas, p_occluder_debug_tex); if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SDFGI && rb != nullptr && rb->sdfgi != nullptr) { rb->sdfgi->debug_draw(p_cam_projection, p_cam_transform, rb->width, rb->height, rb->render_target, rb->texture); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 7600d6823e..1f82ae6dec 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -43,6 +43,40 @@ #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" +struct RenderDataRD { + RID render_buffers = RID(); + + Transform cam_transform = Transform(); + CameraMatrix cam_projection = CameraMatrix(); + bool cam_ortogonal = false; + + float z_near = 0.0; + float z_far = 0.0; + + const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; + const PagedArray<RID> *lights = nullptr; + const PagedArray<RID> *reflection_probes = nullptr; + const PagedArray<RID> *gi_probes = nullptr; + const PagedArray<RID> *decals = nullptr; + const PagedArray<RID> *lightmaps = nullptr; + RID environment = RID(); + RID camera_effects = RID(); + RID shadow_atlas = RID(); + RID reflection_atlas = RID(); + RID reflection_probe = RID(); + int reflection_probe_pass = 0; + + float lod_distance_multiplier = 0.0; + Plane lod_camera_plane = Plane(); + float screen_lod_threshold = 0.0; + + RID cluster_buffer = RID(); + uint32_t cluster_size = 0; + uint32_t cluster_max_elements = 0; + + uint32_t directional_light_count = 0; +}; + class RendererSceneRenderRD : public RendererSceneRender { friend RendererSceneSkyRD; friend RendererSceneGIRD; @@ -62,7 +96,7 @@ protected: void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform); void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment); - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0; + virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; @@ -85,12 +119,11 @@ protected: void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive); void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera); - bool _needs_post_prepass_render(bool p_use_gi); - void _post_prepass_render(bool p_use_gi); - void _pre_resolve_render(bool p_use_gi); + bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi); + void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi); + void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi); - void _pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer); - uint32_t _get_render_state_directional_light_count() const; + void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer); // needed for a single argument calls (material and uv2) PagedArrayPool<GeometryInstance *> cull_argument_pool; @@ -445,7 +478,7 @@ private: void _allocate_luminance_textures(RenderBuffers *rb); void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer); - void _render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection); + void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data); /* Cluster */ @@ -592,38 +625,19 @@ private: } cluster; struct RenderState { - RID render_buffers; - Transform cam_transform; - CameraMatrix cam_projection; - bool cam_ortogonal = false; - const PagedArray<GeometryInstance *> *instances = nullptr; - const PagedArray<RID> *lights = nullptr; - const PagedArray<RID> *reflection_probes = nullptr; - const PagedArray<RID> *gi_probes = nullptr; - const PagedArray<RID> *decals = nullptr; - const PagedArray<RID> *lightmaps = nullptr; - RID environment; - RID camera_effects; - RID shadow_atlas; - RID reflection_atlas; - RID reflection_probe; - int reflection_probe_pass = 0; - float screen_lod_threshold = 0.0; - - const RenderShadowData *render_shadows = nullptr; + const RendererSceneRender::RenderShadowData *render_shadows = nullptr; int render_shadow_count = 0; - const RenderSDFGIData *render_sdfgi_regions = nullptr; + const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr; int render_sdfgi_region_count = 0; - const RenderSDFGIUpdateData *sdfgi_update_data = nullptr; + const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr; - uint32_t directional_light_count = 0; uint32_t gi_probe_count = 0; LocalVector<int> cube_shadows; LocalVector<int> shadows; LocalVector<int> directional_shadows; - bool depth_prepass_used; + bool depth_prepass_used; // this does not seem used anywhere... } render_state; struct VolumetricFog { diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 54c6e81110..966a1c6815 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -30,6 +30,7 @@ #include "renderer_scene_sky_rd.h" #include "core/config/project_settings.h" +#include "core/math/math_defs.h" #include "renderer_scene_render_rd.h" #include "servers/rendering/rendering_server_default.h" @@ -710,6 +711,9 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { actions.renames["SKY_COORDS"] = "panorama_coords"; actions.renames["SCREEN_UV"] = "uv"; actions.renames["TIME"] = "params.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["HALF_RES_COLOR"] = "half_res_color"; actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color"; actions.renames["RADIANCE"] = "radiance"; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 47b9e33ca6..7a26e40c0a 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/math/math_defs.h" #include "renderer_compositor_rd.h" #include "servers/rendering/shader_language.h" @@ -3873,6 +3874,18 @@ void RendererStorageRD::particles_initialize(RID p_rid) { particles_owner.initialize_rid(p_rid, Particles()); } +void RendererStorageRD::particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) { + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + if (particles->mode == p_mode) { + return; + } + + _particles_free_data(particles); + + particles->mode = p_mode; +} + void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); @@ -4293,6 +4306,15 @@ void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_partic particles->collisions.erase(p_particles_collision_instance); } +void RendererStorageRD::particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) { + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND(!particles); + particles->has_sdf_collision = p_enable; + particles->sdf_collision_transform = p_xform; + particles->sdf_collision_to_screen = p_to_screen; + particles->sdf_collision_texture = p_texture; +} + void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) { if (p_particles->particles_material_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_particles->particles_material_uniform_set)) { Vector<RD::Uniform> uniforms; @@ -4398,6 +4420,50 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta if (p_particles->use_local_coords) { to_particles = p_particles->emission_transform.affine_inverse(); } + + if (p_particles->has_sdf_collision && RD::get_singleton()->texture_is_valid(p_particles->sdf_collision_texture)) { + //2D collision + + Transform2D xform = p_particles->sdf_collision_transform; //will use dotproduct manually so invert beforehand + Transform2D revert = xform.affine_inverse(); + frame_params.collider_count = 1; + frame_params.colliders[0].transform[0] = xform.elements[0][0]; + frame_params.colliders[0].transform[1] = xform.elements[0][1]; + frame_params.colliders[0].transform[2] = 0; + frame_params.colliders[0].transform[3] = xform.elements[2][0]; + + frame_params.colliders[0].transform[4] = xform.elements[1][0]; + frame_params.colliders[0].transform[5] = xform.elements[1][1]; + frame_params.colliders[0].transform[6] = 0; + frame_params.colliders[0].transform[7] = xform.elements[2][1]; + + frame_params.colliders[0].transform[8] = revert.elements[0][0]; + frame_params.colliders[0].transform[9] = revert.elements[0][1]; + frame_params.colliders[0].transform[10] = 0; + frame_params.colliders[0].transform[11] = revert.elements[2][0]; + + frame_params.colliders[0].transform[12] = revert.elements[1][0]; + frame_params.colliders[0].transform[13] = revert.elements[1][1]; + frame_params.colliders[0].transform[14] = 0; + frame_params.colliders[0].transform[15] = revert.elements[2][1]; + + frame_params.colliders[0].extents[0] = p_particles->sdf_collision_to_screen.size.x; + frame_params.colliders[0].extents[1] = p_particles->sdf_collision_to_screen.size.y; + frame_params.colliders[0].extents[2] = p_particles->sdf_collision_to_screen.position.x; + frame_params.colliders[0].scale = p_particles->sdf_collision_to_screen.position.y; + frame_params.colliders[0].texture_index = 0; + frame_params.colliders[0].type = ParticlesFrameParams::COLLISION_TYPE_2D_SDF; + + collision_heightmap_texture = p_particles->sdf_collision_texture; + + //replace in all other history frames where used because parameters are no longer valid if screen moves + for (uint32_t i = 1; i < p_particles->frame_history.size(); i++) { + if (p_particles->frame_history[i].collider_count > 0 && p_particles->frame_history[i].colliders[0].type == ParticlesFrameParams::COLLISION_TYPE_2D_SDF) { + p_particles->frame_history[i].colliders[0] = frame_params.colliders[0]; + } + } + } + uint32_t collision_3d_textures_used = 0; for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) { ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get()); @@ -4645,6 +4711,8 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta ERR_FAIL_COND(!m); + p_particles->has_collision_cache = m->shader_data->uses_collision; + //todo should maybe compute all particle systems together? RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, m->shader_data->pipeline); @@ -4728,6 +4796,11 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & copy_push_constant.trail_total = 1; copy_push_constant.frame_delta = 0.0; } + + copy_push_constant.order_by_lifetime = (particles->draw_order == RS::PARTICLES_DRAW_ORDER_LIFETIME || particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME); + copy_push_constant.lifetime_split = MIN(particles->amount * particles->phase, particles->amount - 1); + copy_push_constant.lifetime_reverse = particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME; + copy_push_constant.frame_remainder = particles->interpolate ? particles->frame_remainder : 0.0; copy_push_constant.total_particles = particles->amount; @@ -4765,7 +4838,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & copy_push_constant.total_particles *= copy_push_constant.total_particles; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : ParticlesShader::COPY_MODE_FILL_INSTANCES]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : (particles->mode == RS::PARTICLES_MODE_2D ? ParticlesShader::COPY_MODE_FILL_INSTANCES_2D : ParticlesShader::COPY_MODE_FILL_INSTANCES)]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); if (do_sort) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); @@ -4785,8 +4858,12 @@ void RendererStorageRD::_particles_update_buffers(Particles *particles) { if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { total_amount *= particles->trail_bind_poses.size(); } + + uint32_t xform_size = particles->mode == RS::PARTICLES_MODE_2D ? 2 : 3; + particles->particle_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticleData) * total_amount); - particles->particle_instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(float) * 4 * (3 + 1 + 1) * total_amount); + + particles->particle_instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(float) * 4 * (xform_size + 1 + 1) * total_amount); //needs to clear it { @@ -5003,8 +5080,12 @@ void RendererStorageRD::update_particles() { copy_push_constant.frame_delta = 0.0; } + copy_push_constant.order_by_lifetime = (particles->draw_order == RS::PARTICLES_DRAW_ORDER_LIFETIME || particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME); + copy_push_constant.lifetime_split = MIN(particles->amount * particles->phase, particles->amount - 1); + copy_push_constant.lifetime_reverse = particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME; + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_INSTANCES]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[particles->mode == RS::PARTICLES_MODE_2D ? ParticlesShader::COPY_MODE_FILL_INSTANCES_2D : ParticlesShader::COPY_MODE_FILL_INSTANCES]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->trail_bind_pose_uniform_set, 2); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); @@ -5033,6 +5114,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { valid = false; ubo_size = 0; uniforms.clear(); + uses_collision = false; if (code == String()) { return; //just invalid, but no error @@ -5052,6 +5134,8 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["TIME"] = &uses_time; */ + actions.usage_flag_pointers["COLLIDED"] = &uses_collision; + actions.uniforms = &uniforms; Error err = base_singleton->particles_shader.compiler.compile(RS::SHADER_PARTICLES, code, &actions, path, gen_code); @@ -7117,6 +7201,20 @@ Rect2i RendererStorageRD::render_target_get_sdf_rect(RID p_render_target) const return _render_target_get_sdf_rect(rt); } +void RendererStorageRD::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + rt->sdf_enabled = p_enabled; +} + +bool RendererStorageRD::render_target_is_sdf_enabled(RID p_render_target) const { + const RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND_V(!rt, false); + + return rt->sdf_enabled; +} + RID RendererStorageRD::render_target_get_sdf_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); @@ -7184,7 +7282,7 @@ void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { rt->process_size.x = MAX(rt->process_size.x, 1); rt->process_size.y = MAX(rt->process_size.y, 1); - tformat.format = RD::DATA_FORMAT_R16G16_UINT; + tformat.format = RD::DATA_FORMAT_R16G16_SINT; tformat.width = rt->process_size.width; tformat.height = rt->process_size.height; tformat.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; @@ -7192,7 +7290,7 @@ void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { rt->sdf_buffer_process[0] = RD::get_singleton()->texture_create(tformat, RD::TextureView()); rt->sdf_buffer_process[1] = RD::get_singleton()->texture_create(tformat, RD::TextureView()); - tformat.format = RD::DATA_FORMAT_R16_UNORM; + tformat.format = RD::DATA_FORMAT_R16_SNORM; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView()); @@ -9128,6 +9226,9 @@ RendererStorageRD::RendererStorageRD() { actions.renames["CUSTOM"] = "PARTICLE.custom"; actions.renames["TRANSFORM"] = "PARTICLE.xform"; actions.renames["TIME"] = "FRAME.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["LIFETIME"] = "params.lifetime"; actions.renames["DELTA"] = "local_delta"; actions.renames["NUMBER"] = "particle_number"; @@ -9220,6 +9321,7 @@ RendererStorageRD::RendererStorageRD() { { Vector<String> copy_modes; copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n"); + copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define MODE_2D\n"); copy_modes.push_back("\n#define MODE_FILL_SORT_BUFFER\n#define USE_SORT_BUFFER\n"); copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define USE_SORT_BUFFER\n"); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 961bdfb178..67fbeb3008 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -580,6 +580,7 @@ private: RID buffer; //storage buffer RID uniform_set_3d; + RID uniform_set_2d; bool dirty = false; MultiMesh *dirty_list = nullptr; @@ -637,7 +638,9 @@ private: COLLISION_TYPE_SPHERE, COLLISION_TYPE_BOX, COLLISION_TYPE_SDF, - COLLISION_TYPE_HEIGHT_FIELD + COLLISION_TYPE_HEIGHT_FIELD, + COLLISION_TYPE_2D_SDF, + }; struct Collider { @@ -696,6 +699,7 @@ private: }; struct Particles { + RS::ParticlesMode mode = RS::PARTICLES_MODE_3D; bool inactive = true; float inactive_time = 0.0; bool emitting = false; @@ -708,6 +712,13 @@ private: bool restart_request = false; AABB custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)); bool use_local_coords = true; + bool has_collision_cache = false; + + bool has_sdf_collision = false; + Transform2D sdf_collision_transform; + Rect2 sdf_collision_to_screen; + RID sdf_collision_texture; + RID process_material; uint32_t frame_counter = 0; RS::ParticlesTransformAlign transform_align = RS::PARTICLES_TRANSFORM_ALIGN_DISABLED; @@ -818,10 +829,16 @@ private: float align_up[3]; uint32_t align_mode; + + uint32_t order_by_lifetime; + uint32_t lifetime_split; + uint32_t lifetime_reverse; + uint32_t pad; }; enum { COPY_MODE_FILL_INSTANCES, + COPY_MODE_FILL_INSTANCES_2D, COPY_MODE_FILL_SORT_BUFFER, COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER, COPY_MODE_MAX, @@ -840,6 +857,7 @@ private: struct ParticlesShaderData : public ShaderData { bool valid; RID version; + bool uses_collision = false; //PipelineCacheRD pipelines[SKY_VERSION_MAX]; Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; @@ -1117,6 +1135,8 @@ private: bool flags[RENDER_TARGET_FLAG_MAX]; + bool sdf_enabled = false; + RID backbuffer; //used for effects RID backbuffer_fb; RID backbuffer_mipmap0; @@ -1699,6 +1719,21 @@ public: return multimesh->uniform_set_3d; } + _FORCE_INLINE_ RID multimesh_get_2d_uniform_set(RID p_multimesh, RID p_shader, uint32_t p_set) const { + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + if (!multimesh->uniform_set_2d.is_valid()) { + Vector<RD::Uniform> uniforms; + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 0; + u.ids.push_back(multimesh->buffer); + uniforms.push_back(u); + multimesh->uniform_set_2d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); + } + + return multimesh->uniform_set_2d; + } + /* IMMEDIATE API */ RID immediate_allocate() { return RID(); } @@ -2093,6 +2128,7 @@ public: RID particles_allocate(); void particles_initialize(RID p_particles_collision); + void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode); void particles_set_emitting(RID p_particles, bool p_emitting); void particles_set_amount(RID p_particles, int p_amount); void particles_set_lifetime(RID p_particles, float p_lifetime); @@ -2137,6 +2173,12 @@ public: virtual bool particles_is_inactive(RID p_particles) const; + _FORCE_INLINE_ RS::ParticlesMode particles_get_mode(RID p_particles) { + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, RS::PARTICLES_MODE_2D); + return particles->mode; + } + _FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, 0); @@ -2150,6 +2192,13 @@ public: return particles->amount * r_trail_divisor; } + _FORCE_INLINE_ bool particles_has_collision(RID p_particles) { + Particles *particles = particles_owner.getornull(p_particles); + ERR_FAIL_COND_V(!particles, 0); + + return particles->has_collision_cache; + } + _FORCE_INLINE_ uint32_t particles_is_using_local_coords(RID p_particles) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND_V(!particles, false); @@ -2181,6 +2230,7 @@ public: virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance); virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance); + virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture); /* PARTICLES COLLISION */ @@ -2255,6 +2305,8 @@ public: RID render_target_get_sdf_framebuffer(RID p_render_target); void render_target_sdf_process(RID p_render_target); virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const; + void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled); + bool render_target_is_sdf_enabled(RID p_render_target) const; Size2 render_target_get_size(RID p_render_target); RID render_target_get_rd_framebuffer(RID p_render_target); diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 24ac85bb35..7deedb80c3 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -369,17 +369,24 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S ERR_FAIL_COND(fidx == -1); + Vector<StringName> uses_functions; + for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { - if (added.has(E->get())) { + uses_functions.push_back(E->get()); + } + uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced + + for (int k = 0; k < uses_functions.size(); k++) { + if (added.has(uses_functions[k])) { continue; //was added already } - _dump_function_deps(p_node, E->get(), p_func_code, r_to_add, added); + _dump_function_deps(p_node, uses_functions[k], p_func_code, r_to_add, added); SL::FunctionNode *fnode = nullptr; for (int i = 0; i < p_node->functions.size(); i++) { - if (p_node->functions[i].name == E->get()) { + if (p_node->functions[i].name == uses_functions[k]) { fnode = p_node->functions[i].function; break; } @@ -391,10 +398,21 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S String header; if (fnode->return_type == SL::TYPE_STRUCT) { - header = _mkid(fnode->return_struct_name) + " " + _mkid(fnode->name) + "("; + header = _mkid(fnode->return_struct_name); } else { - header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "("; + header = _typestr(fnode->return_type); } + + if (fnode->return_array_size > 0) { + header += "["; + header += itos(fnode->return_array_size); + header += "]"; + } + + header += " "; + header += _mkid(fnode->name); + header += "("; + for (int i = 0; i < fnode->arguments.size(); i++) { if (i > 0) { header += ", "; @@ -407,13 +425,18 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S } else { header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name); } + if (fnode->arguments[i].array_size > 0) { + header += "["; + header += itos(fnode->arguments[i].array_size); + header += "]"; + } } header += ")\n"; r_to_add += header; - r_to_add += p_func_code[E->get()]; + r_to_add += p_func_code[uses_functions[k]]; - added.insert(E->get()); + added.insert(uses_functions[k]); } } @@ -565,63 +588,74 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uniform_defines.resize(max_uniforms); bool uses_uniforms = false; + Vector<StringName> uniform_names; + for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { + uniform_names.push_back(E->key()); + } + + uniform_names.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced + + for (int k = 0; k < uniform_names.size(); k++) { + StringName uniform_name = uniform_names[k]; + const SL::ShaderNode::Uniform &uniform = pnode->uniforms[uniform_name]; + String ucode; - if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { + if (uniform.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { //insert, but don't generate any code. - p_actions.uniforms->insert(E->key(), E->get()); + p_actions.uniforms->insert(uniform_name, uniform); continue; //instances are indexed directly, dont need index uniforms } - if (SL::is_sampler_type(E->get().type)) { - ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + E->get().texture_order) + ") uniform "; + if (SL::is_sampler_type(uniform.type)) { + ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_order) + ") uniform "; } - bool is_buffer_global = !SL::is_sampler_type(E->get().type) && E->get().scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL; + bool is_buffer_global = !SL::is_sampler_type(uniform.type) && uniform.scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL; if (is_buffer_global) { //this is an integer to index the global table ucode += _typestr(ShaderLanguage::TYPE_UINT); } else { - ucode += _prestr(E->get().precision); - ucode += _typestr(E->get().type); + ucode += _prestr(uniform.precision); + ucode += _typestr(uniform.type); } - ucode += " " + _mkid(E->key()); + ucode += " " + _mkid(uniform_name); ucode += ";\n"; - if (SL::is_sampler_type(E->get().type)) { + if (SL::is_sampler_type(uniform.type)) { for (int j = 0; j < STAGE_MAX; j++) { r_gen_code.stage_globals[j] += ucode; } GeneratedCode::Texture texture; - texture.name = E->key(); - texture.hint = E->get().hint; - texture.type = E->get().type; - texture.filter = E->get().filter; - texture.repeat = E->get().repeat; - texture.global = E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL; + texture.name = uniform_name; + texture.hint = uniform.hint; + texture.type = uniform.type; + texture.filter = uniform.filter; + texture.repeat = uniform.repeat; + texture.global = uniform.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL; if (texture.global) { r_gen_code.uses_global_textures = true; } - r_gen_code.texture_uniforms.write[E->get().texture_order] = texture; + r_gen_code.texture_uniforms.write[uniform.texture_order] = texture; } else { if (!uses_uniforms) { uses_uniforms = true; } - uniform_defines.write[E->get().order] = ucode; + uniform_defines.write[uniform.order] = ucode; if (is_buffer_global) { //globals are indices into the global table - uniform_sizes.write[E->get().order] = _get_datatype_size(ShaderLanguage::TYPE_UINT); - uniform_alignments.write[E->get().order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT); + uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT); + uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT); } else { - uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type); - uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type); + uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type); + uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type); } } - p_actions.uniforms->insert(E->key(), E->get()); + p_actions.uniforms->insert(uniform_name, uniform); } for (int i = 0; i < max_uniforms; i++) { @@ -688,21 +722,32 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light; + Vector<StringName> varying_names; + for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { - if (E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) { - var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(E->key(), E->get())); - fragment_varyings.insert(E->key()); + varying_names.push_back(E->key()); + } + + varying_names.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced + + for (int k = 0; k < varying_names.size(); k++) { + StringName varying_name = varying_names[k]; + const SL::ShaderNode::Varying &varying = pnode->varyings[varying_name]; + + if (varying.stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || varying.stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) { + var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(varying_name, varying)); + fragment_varyings.insert(varying_name); continue; } String vcode; - String interp_mode = _interpstr(E->get().interpolation); - vcode += _prestr(E->get().precision); - vcode += _typestr(E->get().type); - vcode += " " + _mkid(E->key()); - if (E->get().array_size > 0) { + String interp_mode = _interpstr(varying.interpolation); + vcode += _prestr(varying.precision); + vcode += _typestr(varying.type); + vcode += " " + _mkid(varying_name); + if (varying.array_size > 0) { vcode += "["; - vcode += itos(E->get().array_size); + vcode += itos(varying.array_size); vcode += "]"; } vcode += ";\n"; @@ -959,25 +1004,30 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge declaration += itos(adnode->declarations[i].size); } declaration += "]"; - int sz = adnode->declarations[i].initializer.size(); - if (sz > 0) { + if (adnode->declarations[i].single_expression) { declaration += "="; - if (adnode->datatype == SL::TYPE_STRUCT) { - declaration += _mkid(adnode->struct_name); - } else { - declaration += _typestr(adnode->datatype); - } - declaration += "["; - declaration += itos(sz); - declaration += "]"; - declaration += "("; - for (int j = 0; j < sz; j++) { - declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (j != sz - 1) { - declaration += ", "; + declaration += _dump_node_code(adnode->declarations[i].initializer[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } else { + int sz = adnode->declarations[i].initializer.size(); + if (sz > 0) { + declaration += "="; + if (adnode->datatype == SL::TYPE_STRUCT) { + declaration += _mkid(adnode->struct_name); + } else { + declaration += _typestr(adnode->datatype); } + declaration += "["; + declaration += itos(sz); + declaration += "]"; + declaration += "("; + for (int j = 0; j < sz; j++) { + declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + if (j != sz - 1) { + declaration += ", "; + } + } + declaration += ")"; } - declaration += ")"; } } @@ -988,7 +1038,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge bool use_fragment_varying = false; if (!(p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX)) { - if (anode->assign_expression != nullptr) { + if (anode->assign_expression != nullptr && shader->varyings.has(anode->name)) { use_fragment_varying = true; } else { if (p_assigning) { @@ -1280,6 +1330,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } else if (mnode->assign_expression != nullptr) { code += "="; code += _dump_node_code(mnode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false); + } else if (mnode->call_expression != nullptr) { + code += "."; + code += _dump_node_code(mnode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false); } } break; } diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index f7242a2b17..6f29ff42bc 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -30,8 +30,12 @@ #include "shader_rd.h" +#include "core/io/compression.h" +#include "core/os/dir_access.h" +#include "core/os/file_access.h" #include "renderer_compositor_rd.h" #include "servers/rendering/rendering_device.h" +#include "thirdparty/misc/smolv.h" void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) { Vector<String> lines = String(p_code).split("\n"); @@ -97,6 +101,7 @@ void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) { void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) { name = p_name; + if (p_compute_code) { _add_stage(p_compute_code, STAGE_TYPE_COMPUTE); is_compute = true; @@ -109,6 +114,18 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con _add_stage(p_fragment_code, STAGE_TYPE_FRAGMENT); } } + + StringBuilder tohash; + tohash.append("[VersionKey]"); + tohash.append(RenderingDevice::get_singleton()->shader_get_cache_key()); + tohash.append("[Vertex]"); + tohash.append(p_vertex_code ? p_vertex_code : ""); + tohash.append("[Fragment]"); + tohash.append(p_fragment_code ? p_fragment_code : ""); + tohash.append("[Compute]"); + tohash.append(p_compute_code ? p_compute_code : ""); + + base_sha256 = tohash.as_string().sha256_text(); } RID ShaderRD::version_create() { @@ -131,6 +148,9 @@ void ShaderRD::_clear_version(Version *p_version) { } memdelete_arr(p_version->variants); + if (p_version->variant_stages) { + memdelete_arr(p_version->variant_stages); + } p_version->variants = nullptr; } } @@ -183,7 +203,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { return; //variant is disabled, return } - Vector<RD::ShaderStageData> stages; + Vector<RD::ShaderStageData> &stages = p_version->variant_stages[p_variant]; String error; String current_source; @@ -313,6 +333,197 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio return source_code; } +String ShaderRD::_version_get_sha1(Version *p_version) const { + StringBuilder hash_build; + + hash_build.append("[uniforms]"); + hash_build.append(p_version->uniforms.get_data()); + hash_build.append("[vertex_globals]"); + hash_build.append(p_version->vertex_globals.get_data()); + hash_build.append("[fragment_globals]"); + hash_build.append(p_version->fragment_globals.get_data()); + hash_build.append("[compute_globals]"); + hash_build.append(p_version->compute_globals.get_data()); + + Vector<StringName> code_sections; + for (Map<StringName, CharString>::Element *E = p_version->code_sections.front(); E; E = E->next()) { + code_sections.push_back(E->key()); + } + code_sections.sort_custom<StringName::AlphCompare>(); + + for (int i = 0; i < code_sections.size(); i++) { + hash_build.append(String("[code:") + String(code_sections[i]) + "]"); + hash_build.append(p_version->code_sections[code_sections[i]].get_data()); + } + for (int i = 0; i < p_version->custom_defines.size(); i++) { + hash_build.append("[custom_defines:" + itos(i) + "]"); + hash_build.append(p_version->custom_defines[i].get_data()); + } + + return hash_build.as_string().sha1_text(); +} + +static const char *shader_file_header = "GDSC"; +static const uint32_t cache_file_version = 1; + +bool ShaderRD::_load_from_cache(Version *p_version) { + String sha1 = _version_get_sha1(p_version); + String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; + + uint64_t time_from = OS::get_singleton()->get_ticks_usec(); + + FileAccessRef f = FileAccess::open(path, FileAccess::READ); + if (!f) { + return false; + } + + char header[5] = { 0, 0, 0, 0, 0 }; + f->get_buffer((uint8_t *)header, 4); + ERR_FAIL_COND_V(header != String(shader_file_header), false); + + uint32_t file_version = f->get_32(); + if (file_version != cache_file_version) { + return false; // wrong version + } + + uint32_t variant_count = f->get_32(); + + ERR_FAIL_COND_V(variant_count != (uint32_t)variant_defines.size(), false); //should not happen but check + + bool success = true; + for (uint32_t i = 0; i < variant_count; i++) { + uint32_t stage_count = f->get_32(); + p_version->variant_stages[i].resize(stage_count); + for (uint32_t j = 0; j < stage_count; j++) { + p_version->variant_stages[i].write[j].shader_stage = RD::ShaderStage(f->get_32()); + + int compression = f->get_32(); + uint32_t length = f->get_32(); + + if (compression == 0) { + Vector<uint8_t> data; + data.resize(length); + + f->get_buffer(data.ptrw(), length); + + p_version->variant_stages[i].write[j].spir_v = data; + } else { + Vector<uint8_t> data; + + if (compression == 2) { + //zstd + int smol_length = f->get_32(); + Vector<uint8_t> zstd_data; + + zstd_data.resize(smol_length); + f->get_buffer(zstd_data.ptrw(), smol_length); + + data.resize(length); + Compression::decompress(data.ptrw(), data.size(), zstd_data.ptr(), zstd_data.size(), Compression::MODE_ZSTD); + + } else { + data.resize(length); + f->get_buffer(data.ptrw(), length); + } + + Vector<uint8_t> spirv; + uint32_t spirv_size = smolv::GetDecodedBufferSize(data.ptr(), data.size()); + spirv.resize(spirv_size); + if (!smolv::Decode(data.ptr(), data.size(), spirv.ptrw(), spirv_size)) { + ERR_PRINT("Malformed smolv input uncompressing shader " + name + ", variant #" + itos(i) + " stage :" + itos(j)); + success = false; + break; + } + p_version->variant_stages[i].write[j].spir_v = spirv; + } + } + } + + if (!success) { + for (uint32_t i = 0; i < variant_count; i++) { + p_version->variant_stages[i].resize(0); + } + return false; + } + + float time_ms = double(OS::get_singleton()->get_ticks_usec() - time_from) / 1000.0; + + print_verbose("Shader cache load success '" + path + "' " + rtos(time_ms) + "ms."); + + for (uint32_t i = 0; i < variant_count; i++) { + RID shader = RD::get_singleton()->shader_create(p_version->variant_stages[i]); + { + MutexLock lock(variant_set_mutex); + p_version->variants[i] = shader; + } + } + + memdelete_arr(p_version->variant_stages); //clear stages + p_version->variant_stages = nullptr; + p_version->valid = true; + return true; +} + +void ShaderRD::_save_to_cache(Version *p_version) { + String sha1 = _version_get_sha1(p_version); + String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; + + FileAccessRef f = FileAccess::open(path, FileAccess::WRITE); + ERR_FAIL_COND(!f); + f->store_buffer((const uint8_t *)shader_file_header, 4); + f->store_32(cache_file_version); //file version + uint32_t variant_count = variant_defines.size(); + f->store_32(variant_count); //variant count + + for (uint32_t i = 0; i < variant_count; i++) { + f->store_32(p_version->variant_stages[i].size()); //stage count + for (int j = 0; j < p_version->variant_stages[i].size(); j++) { + f->store_32(p_version->variant_stages[i][j].shader_stage); //stage count + Vector<uint8_t> spirv = p_version->variant_stages[i][j].spir_v; + + bool save_uncompressed = true; + if (shader_cache_save_compressed) { + smolv::ByteArray smolv; + bool strip_debug = !shader_cache_save_debug; + if (!smolv::Encode(spirv.ptr(), spirv.size(), smolv, strip_debug ? smolv::kEncodeFlagStripDebugInfo : 0)) { + ERR_PRINT("Error compressing shader " + name + ", variant #" + itos(i) + " stage :" + itos(i)); + } else { + bool compress_zstd = shader_cache_save_compressed_zstd; + + if (compress_zstd) { + Vector<uint8_t> zstd; + zstd.resize(Compression::get_max_compressed_buffer_size(smolv.size(), Compression::MODE_ZSTD)); + int dst_size = Compression::compress(zstd.ptrw(), &smolv[0], smolv.size(), Compression::MODE_ZSTD); + if (dst_size >= 0 && (uint32_t)dst_size < smolv.size()) { + f->store_32(2); //compressed zstd + f->store_32(smolv.size()); //size of smolv buffer + f->store_32(dst_size); //size of smolv buffer + f->store_buffer(zstd.ptr(), dst_size); //smolv buffer + } else { + compress_zstd = false; + } + } + + if (!compress_zstd) { + f->store_32(1); //compressed + f->store_32(smolv.size()); //size of smolv buffer + f->store_buffer(&smolv[0], smolv.size()); //smolv buffer + } + save_uncompressed = false; + } + } + + if (save_uncompressed) { + f->store_32(0); //uncompressed + f->store_32(spirv.size()); //stage count + f->store_buffer(spirv.ptr(), spirv.size()); //stage count + } + } + } + + f->close(); +} + void ShaderRD::_compile_version(Version *p_version) { _clear_version(p_version); @@ -320,6 +531,15 @@ void ShaderRD::_compile_version(Version *p_version) { p_version->dirty = false; p_version->variants = memnew_arr(RID, variant_defines.size()); + typedef Vector<RD::ShaderStageData> ShaderStageArray; + p_version->variant_stages = memnew_arr(ShaderStageArray, variant_defines.size()); + + if (shader_cache_dir_valid) { + if (_load_from_cache(p_version)) { + return; + } + } + #if 1 RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); @@ -351,10 +571,20 @@ void ShaderRD::_compile_version(Version *p_version) { } } memdelete_arr(p_version->variants); + if (p_version->variant_stages) { + memdelete_arr(p_version->variant_stages); + } p_version->variants = nullptr; + p_version->variant_stages = nullptr; return; + } else if (shader_cache_dir_valid) { + //save shader cache + _save_to_cache(p_version); } + memdelete_arr(p_version->variant_stages); //clear stages + p_version->variant_stages = nullptr; + p_version->valid = true; } @@ -443,6 +673,8 @@ bool ShaderRD::is_variant_enabled(int p_variant) const { return variants_enabled[p_variant]; } +bool ShaderRD::shader_cache_cleanup_on_start = false; + ShaderRD::ShaderRD() { // Do not feel forced to use this, in most cases it makes little to no difference. bool use_32_threads = false; @@ -469,8 +701,64 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String variant_defines.push_back(p_variant_defines[i].utf8()); variants_enabled.push_back(true); } + + if (shader_cache_dir != String()) { + StringBuilder hash_build; + + hash_build.append("[base_hash]"); + hash_build.append(base_sha256); + hash_build.append("[general_defines]"); + hash_build.append(general_defines.get_data()); + for (int i = 0; i < variant_defines.size(); i++) { + hash_build.append("[variant_defines:" + itos(i) + "]"); + hash_build.append(variant_defines[i].get_data()); + } + + base_sha256 = hash_build.as_string().sha256_text(); + + DirAccessRef d = DirAccess::open(shader_cache_dir); + ERR_FAIL_COND(!d); + if (d->change_dir(name) != OK) { + Error err = d->make_dir(name); + ERR_FAIL_COND(err != OK); + d->change_dir(name); + } + + //erase other versions? + if (shader_cache_cleanup_on_start) { + } + // + if (d->change_dir(base_sha256) != OK) { + Error err = d->make_dir(base_sha256); + ERR_FAIL_COND(err != OK); + } + shader_cache_dir_valid = true; + + print_verbose("Shader '" + name + "' SHA256: " + base_sha256); + } +} + +void ShaderRD::set_shader_cache_dir(const String &p_dir) { + shader_cache_dir = p_dir; +} + +void ShaderRD::set_shader_cache_save_compressed(bool p_enable) { + shader_cache_save_compressed = p_enable; } +void ShaderRD::set_shader_cache_save_compressed_zstd(bool p_enable) { + shader_cache_save_compressed_zstd = p_enable; +} + +void ShaderRD::set_shader_cache_save_debug(bool p_enable) { + shader_cache_save_debug = p_enable; +} + +String ShaderRD::shader_cache_dir; +bool ShaderRD::shader_cache_save_compressed = true; +bool ShaderRD::shader_cache_save_compressed_zstd = true; +bool ShaderRD::shader_cache_save_debug = true; + ShaderRD::~ShaderRD() { List<RID> remaining; version_owner.get_owned_list(&remaining); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index f20d539621..9a68e02007 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -59,7 +59,8 @@ class ShaderRD { Map<StringName, CharString> code_sections; Vector<CharString> custom_defines; - RID *variants; //same size as version defines + Vector<RD::ShaderStageData> *variant_stages = nullptr; + RID *variants = nullptr; //same size as version defines bool valid; bool dirty; @@ -96,10 +97,19 @@ class ShaderRD { bool is_compute = false; - const char *name; + String name; CharString base_compute_defines; + String base_sha256; + + static String shader_cache_dir; + static bool shader_cache_cleanup_on_start; + static bool shader_cache_save_compressed; + static bool shader_cache_save_compressed_zstd; + static bool shader_cache_save_debug; + bool shader_cache_dir_valid = false; + enum StageType { STAGE_TYPE_VERTEX, STAGE_TYPE_FRAGMENT, @@ -113,6 +123,10 @@ class ShaderRD { void _add_stage(const char *p_code, StageType p_stage_type); + String _version_get_sha1(Version *p_version) const; + bool _load_from_cache(Version *p_version); + void _save_to_cache(Version *p_version); + protected: ShaderRD(); void setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name); @@ -148,6 +162,11 @@ public: void set_variant_enabled(int p_variant, bool p_enabled); bool is_variant_enabled(int p_variant) const; + static void set_shader_cache_dir(const String &p_dir); + static void set_shader_cache_save_compressed(bool p_enable); + static void set_shader_cache_save_compressed_zstd(bool p_enable); + static void set_shader_cache_save_debug(bool p_enable); + RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version); void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = ""); diff --git a/servers/rendering/renderer_rd/shaders/blit.glsl b/servers/rendering/renderer_rd/shaders/blit.glsl new file mode 100644 index 0000000000..967da1e6e4 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/blit.glsl @@ -0,0 +1,95 @@ +#[vertex] + +#version 450 + +#VERSION_DEFINES + +layout(push_constant, binding = 0, std140) uniform Pos { + vec4 dst_rect; + + vec2 eye_center; + float k1; + float k2; + + float upscale; + float aspect_ratio; + uint layer; + uint pad1; +} +data; + +layout(location = 0) out vec2 uv; + +void main() { + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv = base_arr[gl_VertexIndex]; + vec2 vtx = data.dst_rect.xy + uv * data.dst_rect.zw; + gl_Position = vec4(vtx * 2.0 - 1.0, 0.0, 1.0); +} + +#[fragment] + +#version 450 + +#VERSION_DEFINES + +layout(push_constant, binding = 0, std140) uniform Pos { + vec4 dst_rect; + + vec2 eye_center; + float k1; + float k2; + + float upscale; + float aspect_ratio; + uint layer; + uint pad1; +} +data; + +layout(location = 0) in vec2 uv; + +layout(location = 0) out vec4 color; + +#ifdef USE_LAYER +layout(binding = 0) uniform sampler2DArray src_rt; +#else +layout(binding = 0) uniform sampler2D src_rt; +#endif + +void main() { +#ifdef APPLY_LENS_DISTORTION + vec2 coords = uv * 2.0 - 1.0; + vec2 offset = coords - data.eye_center; + + // take aspect ratio into account + offset.y /= data.aspect_ratio; + + // distort + vec2 offset_sq = offset * offset; + float radius_sq = offset_sq.x + offset_sq.y; + float radius_s4 = radius_sq * radius_sq; + float distortion_scale = 1.0 + (data.k1 * radius_sq) + (data.k2 * radius_s4); + offset *= distortion_scale; + + // reapply aspect ratio + offset.y *= data.aspect_ratio; + + // add our eye center back in + coords = offset + data.eye_center; + coords /= data.upscale; + + // and check our color + if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) { + color = vec4(0.0, 0.0, 0.0, 1.0); + } else { + // layer is always used here + coords = (coords + vec2(1.0)) / vec2(2.0); + color = texture(src_rt, vec3(coords, data.layer)); + } +#elif defined(USE_LAYER) + color = texture(src_rt, vec3(uv, data.layer)); +#else + color = texture(src_rt, uv); +#endif +} diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 8b97ec119f..2186bd174b 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -84,40 +84,82 @@ void main() { mat4 world_matrix = mat4(vec4(draw_data.world_x, 0.0, 0.0), vec4(draw_data.world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data.world_ofs, 0.0, 1.0)); -#if 0 - if (draw_data.flags & FLAGS_INSTANCING_ENABLED) { - uint offset = draw_data.flags & FLAGS_INSTANCING_STRIDE_MASK; - offset *= gl_InstanceIndex; - mat4 instance_xform = mat4( - vec4(texelFetch(instancing_buffer, offset + 0), texelFetch(instancing_buffer, offset + 1), 0.0, texelFetch(instancing_buffer, offset + 3)), - vec4(texelFetch(instancing_buffer, offset + 4), texelFetch(instancing_buffer, offset + 5), 0.0, texelFetch(instancing_buffer, offset + 7)), - vec4(0.0, 0.0, 1.0, 0.0), - vec4(0.0, 0.0, 0.0, 1.0)); - offset += 8; - if (draw_data.flags & FLAGS_INSTANCING_HAS_COLORS) { - vec4 instance_color; - if (draw_data.flags & FLAGS_INSTANCING_COLOR_8_BIT) { - uint bits = floatBitsToUint(texelFetch(instancing_buffer, offset)); - instance_color = unpackUnorm4x8(bits); - offset += 1; - } else { - instance_color = vec4(texelFetch(instancing_buffer, offset + 0), texelFetch(instancing_buffer, offset + 1), texelFetch(instancing_buffer, offset + 2), texelFetch(instancing_buffer, offset + 3)); - offset += 4; - } +#define FLAGS_INSTANCING_MASK 0x7F +#define FLAGS_INSTANCING_HAS_COLORS (1 << 7) +#define FLAGS_INSTANCING_HAS_CUSTOM_DATA (1 << 8) + + uint instancing = draw_data.flags & FLAGS_INSTANCING_MASK; + +#ifdef USE_ATTRIBUTES + + if (instancing > 1) { + // trails - color *= instance_color; + uint stride = 2 + 1 + 1; //particles always uses this format + + uint trail_size = instancing; + + uint offset = trail_size * stride * gl_InstanceIndex; + + vec4 pcolor; + vec2 new_vertex; + { + uint boffset = offset + bone_attrib.x * stride; + new_vertex = (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.x; + pcolor = transforms.data[boffset + 2] * weight_attrib.x; } - if (draw_data.flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA) { - if (draw_data.flags & FLAGS_INSTANCING_CUSTOM_DATA_8_BIT) { - uint bits = floatBitsToUint(texelFetch(instancing_buffer, offset)); - instance_custom = unpackUnorm4x8(bits); - } else { - instance_custom = vec4(texelFetch(instancing_buffer, offset + 0), texelFetch(instancing_buffer, offset + 1), texelFetch(instancing_buffer, offset + 2), texelFetch(instancing_buffer, offset + 3)); + if (weight_attrib.y > 0.001) { + uint boffset = offset + bone_attrib.y * stride; + new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.y; + pcolor += transforms.data[boffset + 2] * weight_attrib.y; + } + if (weight_attrib.z > 0.001) { + uint boffset = offset + bone_attrib.z * stride; + new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.z; + pcolor += transforms.data[boffset + 2] * weight_attrib.z; + } + if (weight_attrib.w > 0.001) { + uint boffset = offset + bone_attrib.w * stride; + new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.w; + pcolor += transforms.data[boffset + 2] * weight_attrib.w; + } + + instance_custom = transforms.data[offset + 3]; + + vertex = new_vertex; + color *= pcolor; + + } else +#endif // USE_ATTRIBUTES + + if (instancing == 1) { + uint stride = 2; + { + if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_COLORS)) { + stride += 1; + } + if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) { + stride += 1; } } - } -#endif + uint offset = stride * gl_InstanceIndex; + + mat4 matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); + offset += 2; + + if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_COLORS)) { + color *= transforms.data[offset]; + offset += 1; + } + + if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) { + instance_custom = transforms.data[offset]; + } + + matrix = transpose(matrix); + world_matrix = world_matrix * matrix; + } #if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE) if (bool(draw_data.flags & FLAGS_USING_PARTICLES)) { @@ -239,7 +281,7 @@ vec2 screen_uv_to_sdf(vec2 p_uv) { float texture_sdf(vec2 p_sdf) { vec2 uv = p_sdf * canvas_data.sdf_to_tex.xy + canvas_data.sdf_to_tex.zw; float d = texture(sampler2D(sdf_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv).r; - d = d * SDF_MAX_LENGTH - 1.0; + d *= SDF_MAX_LENGTH; return d * canvas_data.tex_to_sdf; } diff --git a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl index 65a554e839..2bdfbabfcf 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl @@ -7,7 +7,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; layout(r8, set = 0, binding = 1) uniform restrict readonly image2D src_pixels; -layout(r16, set = 0, binding = 2) uniform restrict writeonly image2D dst_sdf; +layout(r16_snorm, set = 0, binding = 2) uniform restrict writeonly image2D dst_sdf; layout(rg16i, set = 0, binding = 3) uniform restrict readonly iimage2D src_process; layout(rg16i, set = 0, binding = 4) uniform restrict writeonly iimage2D dst_process; @@ -32,7 +32,7 @@ void main() { #ifdef MODE_LOAD bool solid = imageLoad(src_pixels, pos).r > 0.5; - imageStore(dst_process, pos, solid ? ivec4(pos, 0, 0) : ivec4(ivec2(32767), 0, 0)); + imageStore(dst_process, pos, solid ? ivec4(ivec2(-32767), 0, 0) : ivec4(ivec2(32767), 0, 0)); #endif #ifdef MODE_LOAD_SHRINK @@ -43,6 +43,8 @@ void main() { ivec2 rel = ivec2(32767); float d = 1e20; + int found = 0; + int solid_found = 0; for (int i = 0; i < s; i++) { for (int j = 0; j < s; j++) { ivec2 src_pos = base + ivec2(i, j); @@ -56,10 +58,17 @@ void main() { d = dist; rel = src_pos; } + solid_found++; } + found++; } } + if (solid_found == found) { + //mark solid only if all are solid + rel = ivec2(-32767); + } + imageStore(dst_process, pos, ivec4(rel, 0, 0)); #endif @@ -70,6 +79,12 @@ void main() { ivec2 rel = imageLoad(src_process, pos).xy; + bool solid = rel.x < 0; + + if (solid) { + rel = -rel - ivec2(1); + } + if (center != rel) { //only process if it does not point to itself const int ofs_table_size = 8; @@ -92,6 +107,15 @@ void main() { continue; } ivec2 src_rel = imageLoad(src_process, src_pos).xy; + bool src_solid = src_rel.x < 0; + if (src_solid) { + src_rel = -src_rel - ivec2(1); + } + + if (src_solid != solid) { + src_rel = ivec2(src_pos << params.shift); //point to itself if of different type + } + float src_dist = length(vec2(src_rel - center)); if (src_dist < dist) { dist = src_dist; @@ -100,18 +124,31 @@ void main() { } } + if (solid) { + rel = -rel - ivec2(1); + } + imageStore(dst_process, pos, ivec4(rel, 0, 0)); #endif #ifdef MODE_STORE ivec2 rel = imageLoad(src_process, pos).xy; + + bool solid = rel.x < 0; + + if (solid) { + rel = -rel - ivec2(1); + } + float d = length(vec2(rel - pos)); - if (d > 0.01) { - d += 1.0; //make it signed + + if (solid) { + d = -d; } + d /= SDF_MAX_LENGTH; - d = clamp(d, 0.0, 1.0); + d = clamp(d, -1.0, 1.0); imageStore(dst_sdf, pos, vec4(d)); #endif @@ -122,13 +159,20 @@ void main() { ivec2 center = base + ivec2(params.shift); ivec2 rel = imageLoad(src_process, pos).xy; + + bool solid = rel.x < 0; + + if (solid) { + rel = -rel - ivec2(1); + } + float d = length(vec2(rel - center)); - if (d > 0.01) { - d += 1.0; //make it signed + if (solid) { + d = -d; } d /= SDF_MAX_LENGTH; - d = clamp(d, 0.0, 1.0); + d = clamp(d, -1.0, 1.0); imageStore(dst_sdf, pos, vec4(d)); #endif diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index cf7678ea31..451f9b0089 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -5,12 +5,10 @@ #define SDF_MAX_LENGTH 16384.0 -#define FLAGS_INSTANCING_STRIDE_MASK 0xF -#define FLAGS_INSTANCING_ENABLED (1 << 4) -#define FLAGS_INSTANCING_HAS_COLORS (1 << 5) -#define FLAGS_INSTANCING_COLOR_8BIT (1 << 6) -#define FLAGS_INSTANCING_HAS_CUSTOM_DATA (1 << 7) -#define FLAGS_INSTANCING_CUSTOM_DATA_8_BIT (1 << 8) +//1 means enabled, 2+ means trails in use +#define FLAGS_INSTANCING_MASK 0x7F +#define FLAGS_INSTANCING_HAS_COLORS (1 << 7) +#define FLAGS_INSTANCING_HAS_CUSTOM_DATA (1 << 8) #define FLAGS_CLIP_RECT_UV (1 << 9) #define FLAGS_TRANSPOSE_RECT (1 << 10) diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index beaff10793..9f8410fd8a 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -19,6 +19,8 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; #define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT 10 #define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11 +#define SDF_MAX_LENGTH 16384.0 + /* SET 0: GLOBAL DATA */ layout(set = 0, binding = 1) uniform sampler material_samplers[12]; @@ -54,6 +56,7 @@ struct Attractor { #define COLLIDER_TYPE_BOX 1 #define COLLIDER_TYPE_SDF 2 #define COLLIDER_TYPE_HEIGHT_FIELD 3 +#define COLLIDER_TYPE_2D_SDF 4 struct Collider { mat4 transform; @@ -452,128 +455,167 @@ void main() { #endif - for (uint i = 0; i < FRAME.collider_count; i++) { - vec3 normal; - float depth; - bool col = false; + if (FRAME.collider_count == 1 && FRAME.colliders[0].type == COLLIDER_TYPE_2D_SDF) { + //2D collision - vec3 rel_vec = PARTICLE.xform[3].xyz - FRAME.colliders[i].transform[3].xyz; - vec3 local_pos = rel_vec * mat3(FRAME.colliders[i].transform); + vec2 pos = PARTICLE.xform[3].xy; + vec4 to_sdf_x = FRAME.colliders[0].transform[0]; + vec4 to_sdf_y = FRAME.colliders[0].transform[1]; + vec2 sdf_pos = vec2(dot(vec4(pos, 0, 1), to_sdf_x), dot(vec4(pos, 0, 1), to_sdf_y)); - switch (FRAME.colliders[i].type) { - case COLLIDER_TYPE_SPHERE: { - float d = length(rel_vec) - (particle_size + FRAME.colliders[i].extents.x); + vec4 sdf_to_screen = vec4(FRAME.colliders[0].extents, FRAME.colliders[0].scale); - if (d < 0.0) { - col = true; - depth = -d; - normal = normalize(rel_vec); - } + vec2 uv_pos = sdf_pos * sdf_to_screen.xy + sdf_to_screen.zw; - } break; - case COLLIDER_TYPE_BOX: { - vec3 abs_pos = abs(local_pos); - vec3 sgn_pos = sign(local_pos); + if (all(greaterThan(uv_pos, vec2(0.0))) && all(lessThan(uv_pos, vec2(1.0)))) { + vec2 pos2 = pos + vec2(0, particle_size); + vec2 sdf_pos2 = vec2(dot(vec4(pos2, 0, 1), to_sdf_x), dot(vec4(pos2, 0, 1), to_sdf_y)); + float sdf_particle_size = distance(sdf_pos, sdf_pos2); + + float d = texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv_pos).r * SDF_MAX_LENGTH; + + d -= sdf_particle_size; + + if (d < 0.0) { + const float EPSILON = 0.001; + vec2 n = normalize(vec2( + texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv_pos + vec2(EPSILON, 0.0)).r - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv_pos - vec2(EPSILON, 0.0)).r, + texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv_pos + vec2(0.0, EPSILON)).r - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv_pos - vec2(0.0, EPSILON)).r)); + + collided = true; + sdf_pos2 = sdf_pos + n * d; + pos2 = vec2(dot(vec4(sdf_pos2, 0, 1), FRAME.colliders[0].transform[2]), dot(vec4(sdf_pos2, 0, 1), FRAME.colliders[0].transform[3])); + + n = pos - pos2; + + collision_normal = normalize(vec3(n, 0.0)); + collision_depth = length(n); + } + } + + } else { + for (uint i = 0; i < FRAME.collider_count; i++) { + vec3 normal; + float depth; + bool col = false; - if (any(greaterThan(abs_pos, FRAME.colliders[i].extents))) { - //point outside box + vec3 rel_vec = PARTICLE.xform[3].xyz - FRAME.colliders[i].transform[3].xyz; + vec3 local_pos = rel_vec * mat3(FRAME.colliders[i].transform); - vec3 closest = min(abs_pos, FRAME.colliders[i].extents); - vec3 rel = abs_pos - closest; - depth = length(rel) - particle_size; - if (depth < 0.0) { + switch (FRAME.colliders[i].type) { + case COLLIDER_TYPE_SPHERE: { + float d = length(rel_vec) - (particle_size + FRAME.colliders[i].extents.x); + + if (d < 0.0) { col = true; - normal = mat3(FRAME.colliders[i].transform) * (normalize(rel) * sgn_pos); - depth = -depth; + depth = -d; + normal = normalize(rel_vec); } - } else { - //point inside box - vec3 axis_len = FRAME.colliders[i].extents - abs_pos; - // there has to be a faster way to do this? - if (all(lessThan(axis_len.xx, axis_len.yz))) { - normal = vec3(1, 0, 0); - } else if (all(lessThan(axis_len.yy, axis_len.xz))) { - normal = vec3(0, 1, 0); + + } break; + case COLLIDER_TYPE_BOX: { + vec3 abs_pos = abs(local_pos); + vec3 sgn_pos = sign(local_pos); + + if (any(greaterThan(abs_pos, FRAME.colliders[i].extents))) { + //point outside box + + vec3 closest = min(abs_pos, FRAME.colliders[i].extents); + vec3 rel = abs_pos - closest; + depth = length(rel) - particle_size; + if (depth < 0.0) { + col = true; + normal = mat3(FRAME.colliders[i].transform) * (normalize(rel) * sgn_pos); + depth = -depth; + } } else { - normal = vec3(0, 0, 1); + //point inside box + vec3 axis_len = FRAME.colliders[i].extents - abs_pos; + // there has to be a faster way to do this? + if (all(lessThan(axis_len.xx, axis_len.yz))) { + normal = vec3(1, 0, 0); + } else if (all(lessThan(axis_len.yy, axis_len.xz))) { + normal = vec3(0, 1, 0); + } else { + normal = vec3(0, 0, 1); + } + + col = true; + depth = dot(normal * axis_len, vec3(1)) + particle_size; + normal = mat3(FRAME.colliders[i].transform) * (normal * sgn_pos); } - col = true; - depth = dot(normal * axis_len, vec3(1)) + particle_size; - normal = mat3(FRAME.colliders[i].transform) * (normal * sgn_pos); - } + } break; + case COLLIDER_TYPE_SDF: { + vec3 apos = abs(local_pos); + float extra_dist = 0.0; + if (any(greaterThan(apos, FRAME.colliders[i].extents))) { //outside + vec3 mpos = min(apos, FRAME.colliders[i].extents); + extra_dist = distance(mpos, apos); + } - } break; - case COLLIDER_TYPE_SDF: { - vec3 apos = abs(local_pos); - float extra_dist = 0.0; - if (any(greaterThan(apos, FRAME.colliders[i].extents))) { //outside - vec3 mpos = min(apos, FRAME.colliders[i].extents); - extra_dist = distance(mpos, apos); - } + if (extra_dist > particle_size) { + continue; + } - if (extra_dist > particle_size) { - continue; - } + vec3 uvw_pos = (local_pos / FRAME.colliders[i].extents) * 0.5 + 0.5; + float s = texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).r; + s *= FRAME.colliders[i].scale; + s += extra_dist; + if (s < particle_size) { + col = true; + depth = particle_size - s; + const float EPSILON = 0.001; + normal = mat3(FRAME.colliders[i].transform) * + normalize( + vec3( + texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos - vec3(EPSILON, 0.0, 0.0)).r, + texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos - vec3(0.0, EPSILON, 0.0)).r, + texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos - vec3(0.0, 0.0, EPSILON)).r)); + } - vec3 uvw_pos = (local_pos / FRAME.colliders[i].extents) * 0.5 + 0.5; - float s = texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).r; - s *= FRAME.colliders[i].scale; - s += extra_dist; - if (s < particle_size) { - col = true; - depth = particle_size - s; - const float EPSILON = 0.001; - normal = mat3(FRAME.colliders[i].transform) * - normalize( - vec3( - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos - vec3(EPSILON, 0.0, 0.0)).r, - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos - vec3(0.0, EPSILON, 0.0)).r, - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_vec_textures[FRAME.colliders[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos - vec3(0.0, 0.0, EPSILON)).r)); - } + } break; + case COLLIDER_TYPE_HEIGHT_FIELD: { + vec3 local_pos_bottom = local_pos; + local_pos_bottom.y -= particle_size; - } break; - case COLLIDER_TYPE_HEIGHT_FIELD: { - vec3 local_pos_bottom = local_pos; - local_pos_bottom.y -= particle_size; + if (any(greaterThan(abs(local_pos_bottom), FRAME.colliders[i].extents))) { + continue; + } + const float DELTA = 1.0 / 8192.0; - if (any(greaterThan(abs(local_pos_bottom), FRAME.colliders[i].extents))) { - continue; - } + vec3 uvw_pos = vec3(local_pos_bottom / FRAME.colliders[i].extents) * 0.5 + 0.5; - const float DELTA = 1.0 / 8192.0; + float y = 1.0 - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos.xz).r; - vec3 uvw_pos = vec3(local_pos_bottom / FRAME.colliders[i].extents) * 0.5 + 0.5; + if (y > uvw_pos.y) { + //inside heightfield - float y = 1.0 - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos.xz).r; + vec3 pos1 = (vec3(uvw_pos.x, y, uvw_pos.z) * 2.0 - 1.0) * FRAME.colliders[i].extents; + vec3 pos2 = (vec3(uvw_pos.x + DELTA, 1.0 - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos.xz + vec2(DELTA, 0)).r, uvw_pos.z) * 2.0 - 1.0) * FRAME.colliders[i].extents; + vec3 pos3 = (vec3(uvw_pos.x, 1.0 - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos.xz + vec2(0, DELTA)).r, uvw_pos.z + DELTA) * 2.0 - 1.0) * FRAME.colliders[i].extents; - if (y > uvw_pos.y) { - //inside heightfield + normal = normalize(cross(pos1 - pos2, pos1 - pos3)); + float local_y = (vec3(local_pos / FRAME.colliders[i].extents) * 0.5 + 0.5).y; - vec3 pos1 = (vec3(uvw_pos.x, y, uvw_pos.z) * 2.0 - 1.0) * FRAME.colliders[i].extents; - vec3 pos2 = (vec3(uvw_pos.x + DELTA, 1.0 - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos.xz + vec2(DELTA, 0)).r, uvw_pos.z) * 2.0 - 1.0) * FRAME.colliders[i].extents; - vec3 pos3 = (vec3(uvw_pos.x, 1.0 - texture(sampler2D(height_field_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos.xz + vec2(0, DELTA)).r, uvw_pos.z + DELTA) * 2.0 - 1.0) * FRAME.colliders[i].extents; + col = true; + depth = dot(normal, pos1) - dot(normal, local_pos_bottom); + } - normal = normalize(cross(pos1 - pos2, pos1 - pos3)); - float local_y = (vec3(local_pos / FRAME.colliders[i].extents) * 0.5 + 0.5).y; + } break; + } - col = true; - depth = dot(normal, pos1) - dot(normal, local_pos_bottom); + if (col) { + if (!collided) { + collided = true; + collision_normal = normal; + collision_depth = depth; + } else { + vec3 c = collision_normal * collision_depth; + c += normal * max(0.0, depth - dot(normal, c)); + collision_normal = normalize(c); + collision_depth = length(c); } - - } break; - } - - if (col) { - if (!collided) { - collided = true; - collision_normal = normal; - collision_depth = depth; - } else { - vec3 c = collision_normal * collision_depth; - c += normal * max(0.0, depth - dot(normal, c)); - collision_normal = normalize(c); - collision_depth = length(c); } } } diff --git a/servers/rendering/renderer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index 7804d66d1c..4dceeea995 100644 --- a/servers/rendering/renderer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl @@ -53,6 +53,11 @@ layout(push_constant, binding = 0, std430) uniform Params { vec3 align_up; uint align_mode; + + bool order_by_lifetime; + uint lifetime_split; + bool lifetime_reverse; + uint pad; } params; @@ -80,7 +85,6 @@ void main() { #ifdef MODE_FILL_INSTANCES uint particle = gl_GlobalInvocationID.x; - uint write_offset = gl_GlobalInvocationID.x * (3 + 1 + 1); //xform + color + custom if (particle >= params.total_particles) { return; //discard @@ -93,7 +97,41 @@ void main() { } else { particle = uint(sort_buffer.data[particle].y); //use index from sort buffer } -#endif +#else + if (params.order_by_lifetime) { + if (params.trail_size > 1) { + uint limit = (params.total_particles / params.trail_size) - params.lifetime_split; + + uint base_index = particle / params.trail_size; + uint base_offset = particle % params.trail_size; + + if (params.lifetime_reverse) { + base_index = (params.total_particles / params.trail_size) - base_index - 1; + } + + if (base_index < limit) { + base_index = params.lifetime_split + base_index; + } else { + base_index -= limit; + } + + particle = base_index * params.trail_size + base_offset; + + } else { + uint limit = params.total_particles - params.lifetime_split; + + if (params.lifetime_reverse) { + particle = params.total_particles - particle - 1; + } + + if (particle < limit) { + particle = params.lifetime_split + particle; + } else { + particle -= limit; + } + } + } +#endif // USE_SORT_BUFFER mat4 txform; @@ -163,11 +201,25 @@ void main() { txform = mat4(vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); //zero scale, becomes invisible } +#ifdef MODE_2D + + uint write_offset = gl_GlobalInvocationID.x * (2 + 1 + 1); //xform + color + custom + + instances.data[write_offset + 0] = txform[0]; + instances.data[write_offset + 1] = txform[1]; + instances.data[write_offset + 2] = particles.data[particle].color; + instances.data[write_offset + 3] = particles.data[particle].custom; + +#else + + uint write_offset = gl_GlobalInvocationID.x * (3 + 1 + 1); //xform + color + custom + instances.data[write_offset + 0] = txform[0]; instances.data[write_offset + 1] = txform[1]; instances.data[write_offset + 2] = txform[2]; instances.data[write_offset + 3] = particles.data[particle].color; instances.data[write_offset + 4] = particles.data[particle].custom; +#endif //MODE_2D #endif } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 1d67a3f1df..e09b8f15be 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -662,7 +662,7 @@ void main() { #endif #ifdef ALPHA_ANTIALIASING_EDGE_USED -// If alpha scissor is used, we must further the edge threshold, otherwise we wont get any edge feather +// If alpha scissor is used, we must further the edge threshold, otherwise we won't get any edge feather #ifdef ALPHA_SCISSOR_USED alpha_antialiasing_edge = clamp(alpha_scissor_threshold + alpha_antialiasing_edge, 0.0, 1.0); #endif diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index b38b8d803d..d488c99b6d 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -622,7 +622,7 @@ void main() { #endif #ifdef ALPHA_ANTIALIASING_EDGE_USED -// If alpha scissor is used, we must further the edge threshold, otherwise we wont get any edge feather +// If alpha scissor is used, we must further the edge threshold, otherwise we won't get any edge feather #ifdef ALPHA_SCISSOR_USED alpha_antialiasing_edge = clamp(alpha_scissor_threshold + alpha_antialiasing_edge, 0.0, 1.0); #endif diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index 669ffc961d..b831005256 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -74,6 +74,53 @@ void main() { #ifdef MODE_2D vec2 vertex = uintBitsToFloat(uvec2(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1])); + + if (params.has_blend_shape) { + float blend_total = 0.0; + vec2 blend_vertex = vec2(0.0); + + for (uint i = 0; i < params.blend_shape_count; i++) { + float w = blend_shape_weights.data[i]; + if (abs(w) > 0.0001) { + uint base_offset = (params.vertex_count * i + index) * params.vertex_stride; + + blend_vertex += uintBitsToFloat(uvec2(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1])) * w; + + base_offset += 2; + + blend_total += w; + } + } + + if (params.normalized_blend_shapes) { + vertex = (1.0 - blend_total) * vertex; + } + + vertex += blend_vertex; + } + + if (params.has_skeleton) { + uint skin_offset = params.skin_stride * index; + + uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); + uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset + uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3; + + skin_offset += params.skin_weight_offset; + + uvec2 weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); + + vec2 weights_01 = unpackUnorm2x16(weights.x); + vec2 weights_23 = unpackUnorm2x16(weights.y); + + mat4 m = mat4(bone_transforms.data[bones_01.x], bone_transforms.data[bones_01.x + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.x; + m += mat4(bone_transforms.data[bones_01.y], bone_transforms.data[bones_01.y + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.y; + m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.x; + m += mat4(bone_transforms.data[bones_23.y], bone_transforms.data[bones_23.y + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y; + + //reverse order because its transposed + vertex = (vec4(vertex, 0.0, 1.0) * m).xy; + } #else vec3 vertex; vec3 normal; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index a61b04afc8..930ac0df70 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -845,7 +845,7 @@ public: RID_PtrOwner<Instance, true> instance_owner; - uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered + uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecessary on clustered virtual RID instance_allocate(); virtual void instance_initialize(RID p_rid); diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 15d99c038e..75975e909d 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -484,6 +484,7 @@ public: virtual RID particles_allocate() = 0; virtual void particles_initialize(RID p_rid) = 0; + virtual void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) = 0; virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0; virtual bool particles_get_emitting(RID p_particles) = 0; @@ -533,6 +534,8 @@ public: virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0; virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0; + virtual void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) = 0; + virtual void update_particles() = 0; /* PARTICLES COLLISION */ @@ -602,6 +605,7 @@ public: virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0; virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0; + virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0; virtual RS::InstanceType get_base_type(RID p_rid) const = 0; virtual bool free(RID p_rid) = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index f7be6c6c60..f97e24947d 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -186,8 +186,11 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_ } RSG::canvas_render->render_sdf(p_viewport->render_target, occluders); + RSG::storage->render_target_mark_sdf_enabled(p_viewport->render_target, true); p_viewport->sdf_active = false; // if used, gets set active again + } else { + RSG::storage->render_target_mark_sdf_enabled(p_viewport->render_target, false); } Rect2 shadow_rect; @@ -322,7 +325,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_ Vector2 point = clip_rect.position + clip_rect.size * signs[j]; if (sign_cmp == light_dir_sign) { - //both point in same direction, plot offseted + //both point in same direction, plot offsetted points[point_count++] = point + light_dir * cull_distance; } else if (sign_cmp.x == light_dir_sign.x || sign_cmp.y == light_dir_sign.y) { int next_j = (j + 1) % 4; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index e6ad001807..056cec4c1f 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -40,6 +40,7 @@ RenderingDevice *RenderingDevice::get_singleton() { RenderingDevice::ShaderCompileFunction RenderingDevice::compile_function = nullptr; RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = nullptr; +RenderingDevice::ShaderGetCacheKeyFunction RenderingDevice::get_cache_key_function = nullptr; void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) { compile_function = p_function; @@ -49,6 +50,10 @@ void RenderingDevice::shader_set_cache_function(ShaderCacheFunction p_function) cache_function = p_function; } +void RenderingDevice::shader_set_get_cache_key_function(ShaderGetCacheKeyFunction p_function) { + get_cache_key_function = p_function; +} + Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, bool p_allow_cache) { if (p_allow_cache && cache_function) { Vector<uint8_t> cache = cache_function(p_stage, p_source_code, p_language); @@ -62,6 +67,13 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, return compile_function(p_stage, p_source_code, p_language, r_error, &device_capabilities); } +String RenderingDevice::shader_get_cache_key() const { + if (get_cache_key_function) { + return get_cache_key_function(&device_capabilities); + } + return String(); +} + RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) { ERR_FAIL_COND_V(p_format.is_null(), RID()); ERR_FAIL_COND_V(p_view.is_null(), RID()); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index d86c44a206..4dcb9b963e 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -103,12 +103,14 @@ public: bool supports_multiview = false; // If true this device supports multiview options }; + typedef String (*ShaderGetCacheKeyFunction)(const Capabilities *p_capabilities); typedef Vector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities); typedef Vector<uint8_t> (*ShaderCacheFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language); private: static ShaderCompileFunction compile_function; static ShaderCacheFunction cache_function; + static ShaderGetCacheKeyFunction get_cache_key_function; static RenderingDevice *singleton; @@ -635,9 +637,11 @@ public: const Capabilities *get_device_capabilities() const { return &device_capabilities; }; virtual Vector<uint8_t> shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = nullptr, bool p_allow_cache = true); + virtual String shader_get_cache_key() const; static void shader_set_compile_function(ShaderCompileFunction p_function); static void shader_set_cache_function(ShaderCacheFunction p_function); + static void shader_set_get_cache_key_function(ShaderGetCacheKeyFunction p_function); struct ShaderStageData { ShaderStage shader_stage; @@ -982,7 +986,7 @@ public: enum InitialAction { INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params) INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params) - INITIAL_ACTION_CLEAR_REGION_CONTINUE, //countinue rendering and clear the framebuffer in the specified region (supply params) + INITIAL_ACTION_CLEAR_REGION_CONTINUE, //continue rendering and clear the framebuffer in the specified region (supply params) INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared) INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously) diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index c76ae1bb34..bf47d497b6 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -478,6 +478,7 @@ public: FUNCRIDSPLIT(particles) + FUNC2(particles_set_mode, RID, ParticlesMode) FUNC2(particles_set_emitting, RID, bool) FUNC1R(bool, particles_get_emitting, RID) FUNC2(particles_set_amount, RID, int) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index a81306b97d..14b21e1f42 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -33,6 +33,8 @@ #include "core/string/print_string.h" #include "servers/rendering_server.h" +#define HAS_WARNING(flag) (warning_flags & flag) + static bool _is_text_char(char32_t c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } @@ -901,6 +903,8 @@ bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) { void ShaderLanguage::clear() { current_function = StringName(); + last_name = StringName(); + last_type = IDENTIFIER_MAX; completion_type = COMPLETION_NONE; completion_block = nullptr; @@ -908,12 +912,22 @@ void ShaderLanguage::clear() { completion_class = SubClassTag::TAG_GLOBAL; completion_struct = StringName(); +#ifdef DEBUG_ENABLED + used_constants.clear(); + used_varyings.clear(); + used_uniforms.clear(); + used_functions.clear(); + used_structs.clear(); + warnings.clear(); +#endif // DEBUG_ENABLED + error_line = 0; tk_line = 1; char_idx = 0; error_set = false; error_str = ""; last_const = false; + pass_array = false; while (nodes) { Node *n = nodes; nodes = nodes->next; @@ -921,6 +935,35 @@ void ShaderLanguage::clear() { } } +#ifdef DEBUG_ENABLED +void ShaderLanguage::_parse_used_identifier(const StringName &p_identifier, IdentifierType p_type) { + switch (p_type) { + case IdentifierType::IDENTIFIER_CONSTANT: + if (HAS_WARNING(ShaderWarning::UNUSED_CONSTANT_FLAG) && used_constants.has(p_identifier)) { + used_constants[p_identifier].used = true; + } + break; + case IdentifierType::IDENTIFIER_VARYING: + if (HAS_WARNING(ShaderWarning::UNUSED_VARYING_FLAG) && used_varyings.has(p_identifier)) { + used_varyings[p_identifier].used = true; + } + break; + case IdentifierType::IDENTIFIER_UNIFORM: + if (HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG) && used_uniforms.has(p_identifier)) { + used_uniforms[p_identifier].used = true; + } + break; + case IdentifierType::IDENTIFIER_FUNCTION: + if (HAS_WARNING(ShaderWarning::UNUSED_FUNCTION_FLAG) && used_functions.has(p_identifier)) { + used_functions[p_identifier].used = true; + } + break; + default: + break; + } +} +#endif // DEBUG_ENABLED + bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name, ConstantNode::Value *r_constant_value) { if (p_function_info.built_ins.has(p_identifier)) { if (r_data_type) { @@ -932,7 +975,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_type) { *r_type = IDENTIFIER_BUILTIN_VAR; } - return true; } @@ -946,7 +988,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_type) { *r_type = IDENTIFIER_FUNCTION; } - return true; } @@ -963,16 +1004,15 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_array_size) { *r_array_size = p_block->variables[p_identifier].array_size; } - if (r_type) { - *r_type = IDENTIFIER_LOCAL_VAR; - } if (r_struct_name) { *r_struct_name = p_block->variables[p_identifier].struct_name; } if (r_constant_value) { *r_constant_value = p_block->variables[p_identifier].value; } - + if (r_type) { + *r_type = IDENTIFIER_LOCAL_VAR; + } return true; } @@ -994,15 +1034,18 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_data_type) { *r_data_type = function->arguments[i].type; } - if (r_type) { - *r_type = IDENTIFIER_FUNCTION_ARGUMENT; - } if (r_struct_name) { *r_struct_name = function->arguments[i].type_str; } + if (r_array_size) { + *r_array_size = function->arguments[i].array_size; + } if (r_is_const) { *r_is_const = function->arguments[i].is_const; } + if (r_type) { + *r_type = IDENTIFIER_FUNCTION_ARGUMENT; + } return true; } } @@ -1041,9 +1084,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_array_size) { *r_array_size = shader->constants[p_identifier].array_size; } - if (r_type) { - *r_type = IDENTIFIER_CONSTANT; - } if (r_struct_name) { *r_struct_name = shader->constants[p_identifier].type_str; } @@ -1052,6 +1092,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea *r_constant_value = shader->constants[p_identifier].initializer->values[0]; } } + if (r_type) { + *r_type = IDENTIFIER_CONSTANT; + } return true; } @@ -1064,6 +1107,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_data_type) { *r_data_type = shader->functions[i].function->return_type; } + if (r_array_size) { + *r_array_size = shader->functions[i].function->return_array_size; + } if (r_type) { *r_type = IDENTIFIER_FUNCTION; } @@ -1074,13 +1120,18 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea return false; } -bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) { +bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type, int *r_ret_size) { bool valid = false; DataType ret_type = TYPE_VOID; + int ret_size = 0; switch (p_op->op) { case OP_EQUAL: case OP_NOT_EQUAL: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); valid = na == nb; @@ -1090,6 +1141,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_LESS_EQUAL: case OP_GREATER: case OP_GREATER_EQUAL: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1099,6 +1154,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } break; case OP_AND: case OP_OR: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1107,6 +1166,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } break; case OP_NOT: { + if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); valid = na == TYPE_BOOL; ret_type = TYPE_BOOL; @@ -1117,6 +1180,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_POST_INCREMENT: case OP_POST_DECREMENT: case OP_NEGATE: { + if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); valid = na > TYPE_BOOL && na < TYPE_MAT2; ret_type = na; @@ -1125,6 +1192,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_SUB: case OP_MUL: case OP_DIV: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1193,6 +1264,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type * component-wise. */ + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1245,6 +1320,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_ASSIGN_SHIFT_RIGHT: case OP_SHIFT_LEFT: case OP_SHIFT_RIGHT: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1293,6 +1372,18 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } break; case OP_ASSIGN: { + int sa = 0; + int sb = 0; + if (!p_op->arguments[0]->is_indexed()) { + sa = p_op->arguments[0]->get_array_size(); + } + if (!p_op->arguments[1]->is_indexed()) { + sb = p_op->arguments[1]->get_array_size(); + } + if (sa != sb) { + break; // don't accept arrays if their sizes are not equal + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); if (na == TYPE_STRUCT || nb == TYPE_STRUCT) { @@ -1301,11 +1392,24 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type valid = na == nb; } ret_type = na; + ret_size = sa; } break; case OP_ASSIGN_ADD: case OP_ASSIGN_SUB: case OP_ASSIGN_MUL: case OP_ASSIGN_DIV: { + int sa = 0; + int sb = 0; + if (!p_op->arguments[0]->is_indexed()) { + sa = p_op->arguments[0]->get_array_size(); + } + if (!p_op->arguments[1]->is_indexed()) { + sb = p_op->arguments[1]->get_array_size(); + } + if (sa > 0 || sb > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1373,6 +1477,18 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type * must match. */ + int sa = 0; + int sb = 0; + if (!p_op->arguments[0]->is_indexed()) { + sa = p_op->arguments[0]->get_array_size(); + } + if (!p_op->arguments[1]->is_indexed()) { + sb = p_op->arguments[1]->get_array_size(); + } + if (sa > 0 || sb > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1427,17 +1543,34 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } break; case OP_BIT_INVERT: { //unaries + if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); valid = na >= TYPE_INT && na < TYPE_FLOAT; ret_type = na; } break; case OP_SELECT_IF: { + int sa = 0; + int sb = 0; + if (!p_op->arguments[1]->is_indexed()) { + sa = p_op->arguments[1]->get_array_size(); + } + if (!p_op->arguments[2]->is_indexed()) { + sb = p_op->arguments[2]->get_array_size(); + } + if (sa != sb) { + break; // don't accept arrays if their sizes are not equal + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); DataType nc = p_op->arguments[2]->get_datatype(); valid = na == TYPE_BOOL && (nb == nc); ret_type = nb; + ret_size = sa; } break; default: { ERR_FAIL_V(false); @@ -1447,6 +1580,9 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type if (r_ret_type) { *r_ret_type = ret_type; } + if (r_ret_size) { + *r_ret_size = ret_size; + } return valid; } @@ -2182,6 +2318,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI Vector<DataType> args; Vector<StringName> args2; + Vector<int> args3; ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::TYPE_VARIABLE, false); @@ -2190,6 +2327,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI for (int i = 1; i < p_func->arguments.size(); i++) { args.push_back(p_func->arguments[i]->get_datatype()); args2.push_back(p_func->arguments[i]->get_datatype_name()); + args3.push_back(p_func->arguments[i]->get_array_size()); } int argcount = args.size(); @@ -2457,6 +2595,11 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI } else { func_arg_name = get_datatype_name(pfunc->arguments[j].type); } + if (pfunc->arguments[j].array_size > 0) { + func_arg_name += "["; + func_arg_name += itos(pfunc->arguments[j].array_size); + func_arg_name += "]"; + } arg_list += func_arg_name; } } @@ -2469,21 +2612,32 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI bool fail = false; for (int j = 0; j < args.size(); j++) { - if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { + if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && args3[j] == 0 && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { //all good, but it needs implicit conversion later - } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str)) { + } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str) || args3[j] != pfunc->arguments[j].array_size) { String func_arg_name; if (pfunc->arguments[j].type == TYPE_STRUCT) { func_arg_name = pfunc->arguments[j].type_str; } else { func_arg_name = get_datatype_name(pfunc->arguments[j].type); } + if (pfunc->arguments[j].array_size > 0) { + func_arg_name += "["; + func_arg_name += itos(pfunc->arguments[j].array_size); + func_arg_name += "]"; + } String arg_name; if (args[j] == TYPE_STRUCT) { arg_name = args2[j]; } else { arg_name = get_datatype_name(args[j]); } + if (args3[j] > 0) { + arg_name += "["; + arg_name += itos(args3[j]); + arg_name += "]"; + } + _set_error(vformat("Invalid argument for \"%s(%s)\" function: argument %s should be %s but is %s.", String(name), arg_list, j + 1, func_arg_name, arg_name)); fail = true; break; @@ -2529,16 +2683,45 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI return false; } -bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const { - if (a->get_datatype() != b->get_datatype()) { - return false; +bool ShaderLanguage::_compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b) { + bool result = true; + + if (p_datatype_a == TYPE_STRUCT || p_datatype_b == TYPE_STRUCT) { + if (p_datatype_name_a != p_datatype_name_b) { + result = false; + } + } else { + if (p_datatype_a != p_datatype_b) { + result = false; + } } - if (a->get_datatype() == TYPE_STRUCT || b->get_datatype() == TYPE_STRUCT) { - if (a->get_datatype_name() != b->get_datatype_name()) { - return false; + + if (p_array_size_a != p_array_size_b) { + result = false; + } + + if (!result) { + String type_name = p_datatype_a == TYPE_STRUCT ? p_datatype_name_a : get_datatype_name(p_datatype_a); + if (p_array_size_a > 0) { + type_name += "["; + type_name += itos(p_array_size_a); + type_name += "]"; + } + + String type_name2 = p_datatype_b == TYPE_STRUCT ? p_datatype_name_b : get_datatype_name(p_datatype_b); + if (p_array_size_b > 0) { + type_name2 += "["; + type_name2 += itos(p_array_size_b); + type_name2 += "]"; } + + _set_error("Invalid assignment of '" + type_name2 + "' to '" + type_name + "'"); } - return true; + return result; +} + +bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) { + return _compare_datatypes(a->get_datatype(), a->get_datatype_name(), a->get_array_size(), b->get_datatype(), b->get_datatype_name(), b->get_array_size()); } bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg) { @@ -3186,7 +3369,7 @@ bool ShaderLanguage::_check_node_constness(const Node *p_node) const { switch (p_node->type) { case Node::TYPE_OPERATOR: { OperatorNode *op_node = (OperatorNode *)p_node; - for (int i = (1 ? op_node->op == OP_CALL : 0); i < op_node->arguments.size(); i++) { + for (int i = int(op_node->op == OP_CALL); i < op_node->arguments.size(); i++) { if (!_check_node_constness(op_node->arguments[i])) { return false; } @@ -3349,11 +3532,12 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa ERR_FAIL_V(false); //bug? function not found } -ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) { +ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info) { DataType type = TYPE_VOID; String struct_name = ""; int array_size = 0; bool auto_size = false; + bool undefined_size = false; Token tk = _get_token(); if (tk.type == TK_CURLY_BRACKET_OPEN) { @@ -3374,6 +3558,137 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc TkPos pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_BRACKET_CLOSE) { + undefined_size = true; + tk = _get_token(); + } else { + _set_tkpos(pos); + + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { + _set_error("Expected single integer constant > 0"); + return nullptr; + } + + ConstantNode *cnode = (ConstantNode *)n; + if (cnode->values.size() == 1) { + array_size = cnode->values[0].sint; + if (array_size <= 0) { + _set_error("Expected single integer constant > 0"); + return nullptr; + } + } else { + _set_error("Expected single integer constant > 0"); + return nullptr; + } + + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return nullptr; + } else { + tk = _get_token(); + } + } + } else { + _set_error("Expected '['"); + return nullptr; + } + } + + ArrayConstructNode *an = alloc_node<ArrayConstructNode>(); + + if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization + int idx = 0; + while (true) { + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n) { + return nullptr; + } + + // define type by using the first member + if (auto_size && idx == 0) { + type = n->get_datatype(); + if (type == TYPE_STRUCT) { + struct_name = n->get_datatype_name(); + } + } else { + if (!_compare_datatypes(type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { + return nullptr; + } + } + + tk = _get_token(); + if (tk.type == TK_COMMA) { + an->initializer.push_back(n); + } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) { + an->initializer.push_back(n); + break; + } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) { + an->initializer.push_back(n); + break; + } else { + if (auto_size) { + _set_error("Expected '}' or ','"); + } else { + _set_error("Expected ')' or ','"); + } + return nullptr; + } + idx++; + } + if (!auto_size && !undefined_size && an->initializer.size() != array_size) { + _set_error("Array size mismatch"); + return nullptr; + } + } else { + _set_error("Expected array initialization!"); + return nullptr; + } + + an->datatype = type; + an->struct_name = struct_name; + return an; +} + +ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) { + DataType type = TYPE_VOID; + String struct_name = ""; + int array_size = 0; + bool auto_size = false; + TkPos prev_pos = _get_tkpos(); + Token tk = _get_token(); + + if (tk.type == TK_CURLY_BRACKET_OPEN) { + auto_size = true; + } else { + if (shader->structs.has(tk.text)) { + type = TYPE_STRUCT; + struct_name = tk.text; + } else { + if (!is_token_variable_datatype(tk.type)) { + _set_tkpos(prev_pos); + + pass_array = true; + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + pass_array = false; + + if (!n) { + _set_error("Invalid data type for array"); + return nullptr; + } + + if (!_compare_datatypes(p_type, p_struct_name, p_array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { + return nullptr; + } + return n; + } + type = get_token_datatype(tk.type); + } + tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + TkPos pos = _get_tkpos(); + tk = _get_token(); + if (tk.type == TK_BRACKET_CLOSE) { array_size = p_array_size; tk = _get_token(); } else { @@ -3445,8 +3760,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc return nullptr; } - if (p_type != n->get_datatype() || p_struct_name != n->get_datatype_name()) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'"); + if (!_compare_datatypes(p_type, p_struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { return nullptr; } @@ -3546,50 +3860,73 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //make sure void is not used in expression _set_error("Void value not allowed in Expression"); return nullptr; - } else if (is_token_nonvoid_datatype(tk.type)) { - //basic type constructor + } else if (is_token_nonvoid_datatype(tk.type) || tk.type == TK_CURLY_BRACKET_OPEN) { + if (tk.type == TK_CURLY_BRACKET_OPEN) { + //array constructor - OperatorNode *func = alloc_node<OperatorNode>(); - func->op = OP_CONSTRUCT; + _set_tkpos(prepos); + expr = _parse_array_constructor(p_block, p_function_info); + } else { + DataType datatype; + DataPrecision precision; + bool precision_defined = false; - if (is_token_precision(tk.type)) { - func->return_precision_cache = get_token_precision(tk.type); + if (is_token_precision(tk.type)) { + precision = get_token_precision(tk.type); + precision_defined = true; + tk = _get_token(); + } + + datatype = get_token_datatype(tk.type); tk = _get_token(); - } - VariableNode *funcname = alloc_node<VariableNode>(); - funcname->name = get_datatype_name(get_token_datatype(tk.type)); - func->arguments.push_back(funcname); + if (tk.type == TK_BRACKET_OPEN) { + //array constructor - tk = _get_token(); - if (tk.type != TK_PARENTHESIS_OPEN) { - _set_error("Expected '(' after type name"); - return nullptr; - } + _set_tkpos(prepos); + expr = _parse_array_constructor(p_block, p_function_info); + } else { + if (tk.type != TK_PARENTHESIS_OPEN) { + _set_error("Expected '(' after type name"); + return nullptr; + } + //basic type constructor - int carg = -1; + OperatorNode *func = alloc_node<OperatorNode>(); + func->op = OP_CONSTRUCT; - bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); + if (precision_defined) { + func->return_precision_cache = precision; + } - if (carg >= 0) { - completion_type = COMPLETION_CALL_ARGUMENTS; - completion_line = tk_line; - completion_block = p_block; - completion_function = funcname->name; - completion_argument = carg; - } + VariableNode *funcname = alloc_node<VariableNode>(); + funcname->name = get_datatype_name(datatype); + func->arguments.push_back(funcname); - if (!ok) { - return nullptr; - } + int carg = -1; - if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) { - _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); - return nullptr; - } + bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); + + if (carg >= 0) { + completion_type = COMPLETION_CALL_ARGUMENTS; + completion_line = tk_line; + completion_block = p_block; + completion_function = funcname->name; + completion_argument = carg; + } + + if (!ok) { + return nullptr; + } - expr = _reduce_expression(p_block, func); + if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) { + _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); + return nullptr; + } + expr = _reduce_expression(p_block, func); + } + } } else if (tk.type == TK_IDENTIFIER) { _set_tkpos(prepos); @@ -3602,6 +3939,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (shader->structs.has(identifier)) { pstruct = shader->structs[identifier].shader_struct; +#ifdef DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(identifier)) { + used_structs[identifier].used = true; + } +#endif // DEBUG_ENABLED struct_init = true; } @@ -3632,11 +3974,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (!nexpr) { return nullptr; } - Node *node = pstruct->members[i]; if (!_compare_datatypes_in_nodes(pstruct->members[i], nexpr)) { - String type_name = nexpr->get_datatype() == TYPE_STRUCT ? nexpr->get_datatype_name() : get_datatype_name(nexpr->get_datatype()); - String type_name2 = node->get_datatype() == TYPE_STRUCT ? node->get_datatype_name() : get_datatype_name(node->get_datatype()); - _set_error("Invalid assignment of '" + type_name + "' to '" + type_name2 + "'"); return nullptr; } } @@ -3658,7 +3996,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = func; - } else { //a function + } else { //a function call const StringName &name = identifier; @@ -3670,7 +4008,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons int carg = -1; + pass_array = true; bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); + pass_array = false; // Check if block has a variable with the same name as function to prevent shader crash. ShaderLanguage::BlockNode *bnode = p_block; @@ -3723,6 +4063,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons FunctionNode *call_function = shader->functions[function_index].function; if (call_function) { + func->return_cache = call_function->get_datatype(); + func->struct_name = call_function->get_datatype_name(); + func->return_array_size = call_function->get_array_size(); + //get current base function FunctionNode *base_function = nullptr; { @@ -3825,11 +4169,17 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } expr = func; +#ifdef DEBUG_ENABLED + if (check_warnings) { + _parse_used_identifier(name, IdentifierType::IDENTIFIER_FUNCTION); + } +#endif // DEBUG_ENABLED } } else { //an identifier - last_const = false; + last_name = identifier; + last_type = IDENTIFIER_MAX; _set_tkpos(pos); DataType data_type; @@ -3874,12 +4224,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } } - last_const = is_const; if (ident_type == IDENTIFIER_FUNCTION) { _set_error("Can't use function as identifier: " + String(identifier)); return nullptr; } + if (is_const) { + last_type = IDENTIFIER_CONSTANT; + } else { + last_type = ident_type; + } } Node *index_expression = nullptr; @@ -3887,60 +4241,61 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *assign_expression = nullptr; if (array_size > 0) { - tk = _get_token(); - - if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) { - _set_error("Expected '[','.' or '='"); - return nullptr; - } + if (!pass_array) { + tk = _get_token(); - if (tk.type == TK_OP_ASSIGN) { - if (is_const) { - _set_error("Constants cannot be modified."); - return nullptr; - } - assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); - if (!assign_expression) { - return nullptr; - } - } else if (tk.type == TK_PERIOD) { - completion_class = TAG_ARRAY; - p_block->block_tag = SubClassTag::TAG_ARRAY; - call_expression = _parse_and_reduce_expression(p_block, p_function_info); - p_block->block_tag = SubClassTag::TAG_GLOBAL; - if (!call_expression) { + if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) { + _set_error("Expected '[','.' or '='"); return nullptr; } - data_type = call_expression->get_datatype(); - } else { // indexing - index_expression = _parse_and_reduce_expression(p_block, p_function_info); - if (!index_expression) { - return nullptr; - } + if (tk.type == TK_OP_ASSIGN) { + if (is_const) { + _set_error("Constants cannot be modified."); + return nullptr; + } + assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); + if (!assign_expression) { + return nullptr; + } + } else if (tk.type == TK_PERIOD) { + completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; + call_expression = _parse_and_reduce_expression(p_block, p_function_info); + p_block->block_tag = SubClassTag::TAG_GLOBAL; + if (!call_expression) { + return nullptr; + } + data_type = call_expression->get_datatype(); + } else { // indexing + index_expression = _parse_and_reduce_expression(p_block, p_function_info); + if (!index_expression) { + return nullptr; + } - if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { - _set_error("Only integer expressions are allowed for indexing"); - return nullptr; - } + if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { + _set_error("Only integer expressions are allowed for indexing"); + return nullptr; + } - if (index_expression->type == Node::TYPE_CONSTANT) { - ConstantNode *cnode = (ConstantNode *)index_expression; - if (cnode) { - if (!cnode->values.is_empty()) { - int value = cnode->values[0].sint; - if (value < 0 || value >= array_size) { - _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); - return nullptr; + if (index_expression->type == Node::TYPE_CONSTANT) { + ConstantNode *cnode = (ConstantNode *)index_expression; + if (cnode) { + if (!cnode->values.is_empty()) { + int value = cnode->values[0].sint; + if (value < 0 || value >= array_size) { + _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); + return nullptr; + } } } } - } - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return nullptr; + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return nullptr; + } } } @@ -3952,8 +4307,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons arrname->call_expression = call_expression; arrname->assign_expression = assign_expression; arrname->is_const = is_const; + arrname->array_size = array_size; expr = arrname; - } else { VariableNode *varname = alloc_node<VariableNode>(); varname->name = identifier; @@ -3962,6 +4317,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons varname->struct_name = struct_name; expr = varname; } +#ifdef DEBUG_ENABLED + if (check_warnings) { + _parse_used_identifier(identifier, ident_type); + } +#endif // DEBUG_ENABLED } } else if (tk.type == TK_OP_ADD) { continue; //this one does nothing @@ -4012,6 +4372,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons DataType dt = expr->get_datatype(); String st = expr->get_datatype_name(); + if (!expr->is_indexed() && expr->get_array_size() > 0) { + completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; + Node *call_expression = _parse_and_reduce_expression(p_block, p_function_info); + p_block->block_tag = SubClassTag::TAG_GLOBAL; + if (!call_expression) { + return nullptr; + } + expr = call_expression; + break; + } + StringName identifier; if (_get_completable_identifier(p_block, dt == TYPE_STRUCT ? COMPLETION_STRUCT : COMPLETION_INDEX, identifier)) { if (dt == TYPE_STRUCT) { @@ -4288,10 +4660,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons mn->has_swizzling_duplicates = repeated; if (array_size > 0) { + TkPos prev_pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { - if (last_const) { - last_const = false; + if (last_type == IDENTIFIER_CONSTANT) { _set_error("Constants cannot be modified."); return nullptr; } @@ -4301,8 +4673,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } mn->assign_expression = assign_expression; } else if (tk.type == TK_PERIOD) { - _set_error("Nested array length() is not yet implemented"); - return nullptr; + completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; + Node *call_expression = _parse_and_reduce_expression(p_block, p_function_info); + p_block->block_tag = SubClassTag::TAG_GLOBAL; + if (!call_expression) { + return nullptr; + } + mn->datatype = call_expression->get_datatype(); + mn->call_expression = call_expression; } else if (tk.type == TK_BRACKET_OPEN) { Node *index_expression = _parse_and_reduce_expression(p_block, p_function_info); if (!index_expression) { @@ -4333,13 +4712,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons return nullptr; } mn->index_expression = index_expression; - } else { - _set_error("Expected '[','.' or '='"); - return nullptr; + if (!pass_array) { + _set_error("Expected '[','.' or '='"); + return nullptr; + } + _set_tkpos(prev_pos); } } - expr = mn; //todo @@ -4364,117 +4744,130 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } DataType member_type = TYPE_VOID; + String member_struct_name; - switch (expr->get_datatype()) { - case TYPE_BVEC2: - case TYPE_VEC2: - case TYPE_IVEC2: - case TYPE_UVEC2: - case TYPE_MAT2: - if (index->type == Node::TYPE_CONSTANT) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= 2) { - _set_error("Index out of range (0-1)"); - return nullptr; + if (expr->get_array_size() > 0) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= (uint32_t)expr->get_array_size()) { + _set_error(vformat("Index [%s] out of range [%s..%s]", index_constant, 0, expr->get_array_size() - 1)); + return nullptr; + } + member_type = expr->get_datatype(); + if (member_type == TYPE_STRUCT) { + member_struct_name = expr->get_datatype_name(); + } + } else { + switch (expr->get_datatype()) { + case TYPE_BVEC2: + case TYPE_VEC2: + case TYPE_IVEC2: + case TYPE_UVEC2: + case TYPE_MAT2: + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= 2) { + _set_error("Index out of range (0-1)"); + return nullptr; + } } - } - switch (expr->get_datatype()) { - case TYPE_BVEC2: - member_type = TYPE_BOOL; - break; - case TYPE_VEC2: - member_type = TYPE_FLOAT; - break; - case TYPE_IVEC2: - member_type = TYPE_INT; - break; - case TYPE_UVEC2: - member_type = TYPE_UINT; - break; - case TYPE_MAT2: - member_type = TYPE_VEC2; - break; - default: - break; - } + switch (expr->get_datatype()) { + case TYPE_BVEC2: + member_type = TYPE_BOOL; + break; + case TYPE_VEC2: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC2: + member_type = TYPE_INT; + break; + case TYPE_UVEC2: + member_type = TYPE_UINT; + break; + case TYPE_MAT2: + member_type = TYPE_VEC2; + break; + default: + break; + } - break; - case TYPE_BVEC3: - case TYPE_VEC3: - case TYPE_IVEC3: - case TYPE_UVEC3: - case TYPE_MAT3: - if (index->type == Node::TYPE_CONSTANT) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= 3) { - _set_error("Index out of range (0-2)"); - return nullptr; + break; + case TYPE_BVEC3: + case TYPE_VEC3: + case TYPE_IVEC3: + case TYPE_UVEC3: + case TYPE_MAT3: + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= 3) { + _set_error("Index out of range (0-2)"); + return nullptr; + } } - } - switch (expr->get_datatype()) { - case TYPE_BVEC3: - member_type = TYPE_BOOL; - break; - case TYPE_VEC3: - member_type = TYPE_FLOAT; - break; - case TYPE_IVEC3: - member_type = TYPE_INT; - break; - case TYPE_UVEC3: - member_type = TYPE_UINT; - break; - case TYPE_MAT3: - member_type = TYPE_VEC3; - break; - default: - break; - } - break; - case TYPE_BVEC4: - case TYPE_VEC4: - case TYPE_IVEC4: - case TYPE_UVEC4: - case TYPE_MAT4: - if (index->type == Node::TYPE_CONSTANT) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= 4) { - _set_error("Index out of range (0-3)"); - return nullptr; + switch (expr->get_datatype()) { + case TYPE_BVEC3: + member_type = TYPE_BOOL; + break; + case TYPE_VEC3: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC3: + member_type = TYPE_INT; + break; + case TYPE_UVEC3: + member_type = TYPE_UINT; + break; + case TYPE_MAT3: + member_type = TYPE_VEC3; + break; + default: + break; + } + break; + case TYPE_BVEC4: + case TYPE_VEC4: + case TYPE_IVEC4: + case TYPE_UVEC4: + case TYPE_MAT4: + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= 4) { + _set_error("Index out of range (0-3)"); + return nullptr; + } } - } - switch (expr->get_datatype()) { - case TYPE_BVEC4: - member_type = TYPE_BOOL; - break; - case TYPE_VEC4: - member_type = TYPE_FLOAT; - break; - case TYPE_IVEC4: - member_type = TYPE_INT; - break; - case TYPE_UVEC4: - member_type = TYPE_UINT; - break; - case TYPE_MAT4: - member_type = TYPE_VEC4; - break; - default: - break; + switch (expr->get_datatype()) { + case TYPE_BVEC4: + member_type = TYPE_BOOL; + break; + case TYPE_VEC4: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC4: + member_type = TYPE_INT; + break; + case TYPE_UVEC4: + member_type = TYPE_UINT; + break; + case TYPE_MAT4: + member_type = TYPE_VEC4; + break; + default: + break; + } + break; + default: { + _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed"); + return nullptr; } - break; - default: { - _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed"); - return nullptr; } } - OperatorNode *op = alloc_node<OperatorNode>(); op->op = OP_INDEX; op->return_cache = member_type; + op->struct_name = member_struct_name; op->arguments.push_back(expr); op->arguments.push_back(index); expr = op; @@ -4490,7 +4883,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT; op->arguments.push_back(expr); - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { _set_error("Invalid base type for increment/decrement operator"); return nullptr; } @@ -4641,9 +5034,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons bool unary = false; bool ternary = false; + Operator op = expression[i].op; int priority; - switch (expression[i].op) { + switch (op) { case OP_EQUAL: priority = 8; break; @@ -4764,6 +5158,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ERR_FAIL_V(nullptr); //unexpected operator } +#if DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::FLOAT_COMPARISON_FLAG) && (op == OP_EQUAL || op == OP_NOT_EQUAL) && expression[i - 1].node->get_datatype() == TYPE_FLOAT && expression[i + 1].node->get_datatype() == TYPE_FLOAT) { + _add_line_warning(ShaderWarning::FLOAT_COMPARISON); + } +#endif // DEBUG_ENABLED + if (priority < min_priority) { // < is used for left to right (default) // <= is used for right to left @@ -4801,13 +5201,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[i].is_op = false; expression.write[i].node = op; - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { String at; for (int j = 0; j < op->arguments.size(); j++) { if (j > 0) { at += " and "; } at += get_datatype_name(op->arguments[j]->get_datatype()); + if (!op->arguments[j]->is_indexed() && op->arguments[j]->get_array_size() > 0) { + at += "["; + at += itos(op->arguments[j]->get_array_size()); + at += "]"; + } } _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at); return nullptr; @@ -4834,13 +5239,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[next_op - 1].is_op = false; expression.write[next_op - 1].node = op; - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { String at; for (int i = 0; i < op->arguments.size(); i++) { if (i > 0) { at += " and "; } at += get_datatype_name(op->arguments[i]->get_datatype()); + if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) { + at += "["; + at += itos(op->arguments[i]->get_array_size()); + at += "]"; + } } _set_error("Invalid argument to ternary ?: operator: " + at); return nullptr; @@ -4887,7 +5297,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //replace all 3 nodes by this operator and make it an expression - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { String at; for (int i = 0; i < op->arguments.size(); i++) { if (i > 0) { @@ -4898,6 +5308,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } else { at += get_datatype_name(op->arguments[i]->get_datatype()); } + if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) { + at += "["; + at += itos(op->arguments[i]->get_array_size()); + at += "]"; + } } _set_error("Invalid arguments to operator '" + get_operator_text(op->op) + "' :" + at); return nullptr; @@ -5154,6 +5569,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun ArrayDeclarationNode::Declaration decl; decl.name = name; decl.size = 0U; + decl.single_expression = false; pos = _get_tkpos(); tk = _get_token(); @@ -5220,179 +5636,205 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } + TkPos prev_pos = _get_tkpos(); tk = _get_token(); - if (tk.type != TK_CURLY_BRACKET_OPEN) { - if (unknown_size) { - _set_error("Expected '{'"); - return ERR_PARSE_ERROR; - } - - full_def = true; + if (tk.type == TK_IDENTIFIER) { // a function call array initialization + _set_tkpos(prev_pos); + pass_array = true; + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + pass_array = false; - DataPrecision precision2 = PRECISION_DEFAULT; - if (is_token_precision(tk.type)) { - precision2 = get_token_precision(tk.type); - tk = _get_token(); - if (shader->structs.has(tk.text)) { - _set_error("Precision modifier cannot be used on structs."); - return ERR_PARSE_ERROR; + if (!n) { + _set_error("Expected correct array initializer!"); + return ERR_PARSE_ERROR; + } else { + if (unknown_size) { + decl.size = n->get_array_size(); + var.array_size = n->get_array_size(); } - if (!is_token_nonvoid_datatype(tk.type)) { - _set_error("Expected datatype after precision"); + + if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { return ERR_PARSE_ERROR; } - } - DataType type2; - StringName struct_name2 = ""; + decl.single_expression = true; + decl.initializer.push_back(n); + } - if (shader->structs.has(tk.text)) { - type2 = TYPE_STRUCT; - struct_name2 = tk.text; - } else { - if (!is_token_variable_datatype(tk.type)) { - _set_error("Invalid data type for array"); + tk = _get_token(); + } else { + if (tk.type != TK_CURLY_BRACKET_OPEN) { + if (unknown_size) { + _set_error("Expected '{'"); return ERR_PARSE_ERROR; } - type2 = get_token_datatype(tk.type); - } - int array_size2 = 0; + full_def = true; - tk = _get_token(); - if (tk.type == TK_BRACKET_OPEN) { - TkPos pos2 = _get_tkpos(); - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { - array_size2 = var.array_size; + DataPrecision precision2 = PRECISION_DEFAULT; + if (is_token_precision(tk.type)) { + precision2 = get_token_precision(tk.type); tk = _get_token(); - } else { - _set_tkpos(pos2); - - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { - _set_error("Expected single integer constant > 0"); + if (shader->structs.has(tk.text)) { + _set_error("Precision modifier cannot be used on structs."); return ERR_PARSE_ERROR; } + if (!is_token_nonvoid_datatype(tk.type)) { + _set_error("Expected datatype after precision"); + return ERR_PARSE_ERROR; + } + } - ConstantNode *cnode = (ConstantNode *)n; - if (cnode->values.size() == 1) { - array_size2 = cnode->values[0].sint; - if (array_size2 <= 0) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - } else { - _set_error("Expected single integer constant > 0"); + DataType type2; + StringName struct_name2 = ""; + + if (shader->structs.has(tk.text)) { + type2 = TYPE_STRUCT; + struct_name2 = tk.text; + } else { + if (!is_token_variable_datatype(tk.type)) { + _set_error("Invalid data type for array"); return ERR_PARSE_ERROR; } + type2 = get_token_datatype(tk.type); + } + int array_size2 = 0; + + tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + TkPos pos2 = _get_tkpos(); tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; + if (tk.type == TK_BRACKET_CLOSE) { + array_size2 = var.array_size; + tk = _get_token(); } else { + _set_tkpos(pos2); + + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + + ConstantNode *cnode = (ConstantNode *)n; + if (cnode->values.size() == 1) { + array_size2 = cnode->values[0].sint; + if (array_size2 <= 0) { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + } else { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } else { + tk = _get_token(); + } } - } - } else { - _set_error("Expected '['"); - return ERR_PARSE_ERROR; - } - - if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) { - String error_str = "Cannot convert from '"; - if (precision2 != PRECISION_DEFAULT) { - error_str += get_precision_name(precision2); - error_str += " "; - } - if (type2 == TYPE_STRUCT) { - error_str += struct_name2; } else { - error_str += get_datatype_name(type2); - } - error_str += "["; - error_str += itos(array_size2); - error_str += "]'"; - error_str += " to '"; - if (precision != PRECISION_DEFAULT) { - error_str += get_precision_name(precision); - error_str += " "; + _set_error("Expected '['"); + return ERR_PARSE_ERROR; } - if (type == TYPE_STRUCT) { - error_str += struct_name; - } else { - error_str += get_datatype_name(type); + + if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) { + String error_str = "Cannot convert from '"; + if (precision2 != PRECISION_DEFAULT) { + error_str += get_precision_name(precision2); + error_str += " "; + } + if (type2 == TYPE_STRUCT) { + error_str += struct_name2; + } else { + error_str += get_datatype_name(type2); + } + error_str += "["; + error_str += itos(array_size2); + error_str += "]'"; + error_str += " to '"; + if (precision != PRECISION_DEFAULT) { + error_str += get_precision_name(precision); + error_str += " "; + } + if (type == TYPE_STRUCT) { + error_str += struct_name; + } else { + error_str += get_datatype_name(type); + } + error_str += "["; + error_str += itos(var.array_size); + error_str += "]'"; + _set_error(error_str); + return ERR_PARSE_ERROR; } - error_str += "["; - error_str += itos(var.array_size); - error_str += "]'"; - _set_error(error_str); - return ERR_PARSE_ERROR; } - } - bool curly = tk.type == TK_CURLY_BRACKET_OPEN; + bool curly = tk.type == TK_CURLY_BRACKET_OPEN; - if (unknown_size) { - if (!curly) { - _set_error("Expected '{'"); - return ERR_PARSE_ERROR; - } - } else { - if (full_def) { - if (curly) { - _set_error("Expected '('"); + if (unknown_size) { + if (!curly) { + _set_error("Expected '{'"); return ERR_PARSE_ERROR; } + } else { + if (full_def) { + if (curly) { + _set_error("Expected '('"); + return ERR_PARSE_ERROR; + } + } } - } - if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization - while (true) { - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n) { - return ERR_PARSE_ERROR; - } + if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization + while (true) { + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n) { + return ERR_PARSE_ERROR; + } - if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { - _set_error("Expected constant expression"); - return ERR_PARSE_ERROR; - } + if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { + _set_error("Expected constant expression"); + return ERR_PARSE_ERROR; + } - if (var.type != n->get_datatype() || struct_name != n->get_datatype_name()) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (var.type == TYPE_STRUCT ? struct_name : get_datatype_name(var.type)) + "'"); - return ERR_PARSE_ERROR; - } + if (!_compare_datatypes(var.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { + return ERR_PARSE_ERROR; + } - tk = _get_token(); - if (tk.type == TK_COMMA) { - decl.initializer.push_back(n); - continue; - } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) { - decl.initializer.push_back(n); - break; - } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) { - decl.initializer.push_back(n); - break; - } else { - if (curly) { - _set_error("Expected '}' or ','"); + tk = _get_token(); + if (tk.type == TK_COMMA) { + decl.initializer.push_back(n); + continue; + } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) { + decl.initializer.push_back(n); + break; + } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) { + decl.initializer.push_back(n); + break; } else { - _set_error("Expected ')' or ','"); + if (curly) { + _set_error("Expected '}' or ','"); + } else { + _set_error("Expected ')' or ','"); + } + return ERR_PARSE_ERROR; } + } + if (unknown_size) { + decl.size = decl.initializer.size(); + var.array_size = decl.initializer.size(); + } else if (decl.initializer.size() != var.array_size) { + _set_error("Array size mismatch"); return ERR_PARSE_ERROR; } + tk = _get_token(); } - if (unknown_size) { - decl.size = decl.initializer.size(); - var.array_size = decl.initializer.size(); - } else if (decl.initializer.size() != var.array_size) { - _set_error("Array size mismatch"); - return ERR_PARSE_ERROR; - } - tk = _get_token(); } } else { if (unknown_size) { @@ -5445,8 +5887,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } - if (var.type == TYPE_STRUCT ? (var.struct_name != n->get_datatype_name()) : (var.type != n->get_datatype())) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (var.type == TYPE_STRUCT ? String(var.struct_name) : get_datatype_name(var.type)) + "'"); + if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { return ERR_PARSE_ERROR; } tk = _get_token(); @@ -5476,7 +5917,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun p_block->statements.push_back(vardecl); p_block->variables[name] = var; - if (tk.type == TK_COMMA) { if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR) { _set_error("Multiple declarations in 'for' loop are not implemented yet."); @@ -5908,6 +6348,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } String return_struct_name = String(b->parent_function->return_struct_name); + String array_size_string; + + if (b->parent_function->return_array_size > 0) { + array_size_string = "[" + itos(b->parent_function->return_array_size) + "]"; + } ControlFlowNode *flow = alloc_node<ControlFlowNode>(); flow->flow_op = FLOW_OP_RETURN; @@ -5917,18 +6362,27 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (tk.type == TK_SEMICOLON) { //all is good if (b->parent_function->return_type != TYPE_VOID) { - _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'"); + _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'"); return ERR_PARSE_ERROR; } } else { _set_tkpos(pos); //rollback, wants expression + + pass_array = true; Node *expr = _parse_and_reduce_expression(p_block, p_function_info); if (!expr) { return ERR_PARSE_ERROR; } + pass_array = false; - if (b->parent_function->return_type != expr->get_datatype() || return_struct_name != expr->get_datatype_name()) { - _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'"); + bool array_size_incorrect = false; + + if (b->parent_function->return_array_size > 0 && b->parent_function->return_array_size != expr->get_array_size()) { + array_size_incorrect = true; + } + + if (b->parent_function->return_type != expr->get_datatype() || array_size_incorrect || return_struct_name != expr->get_datatype_name()) { + _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'"); return ERR_PARSE_ERROR; } @@ -6306,7 +6760,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } shader->structs[st.name] = st; shader->vstructs.push_back(st); // struct's order is important! - +#ifdef DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG)) { + used_structs.insert(st.name, Usage(tk_line)); + } +#endif // DEBUG_ENABLED } break; case TK_GLOBAL: { tk = _get_token(); @@ -6653,6 +7111,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } shader->uniforms[name] = uniform2; +#ifdef DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG)) { + used_uniforms.insert(name, Usage(tk_line)); + } +#endif // DEBUG_ENABLED + //reset scope for next uniform uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL; @@ -6696,6 +7160,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } shader->varyings[name] = varying; +#ifdef DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_VARYING_FLAG)) { + used_varyings.insert(name, Usage(tk_line)); + } +#endif // DEBUG_ENABLED } } break; @@ -6708,6 +7177,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct DataPrecision precision = PRECISION_DEFAULT; DataType type; StringName name; + int return_array_size = 0; if (tk.type == TK_CONST) { is_constant = true; @@ -6745,10 +7215,33 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } TkPos prev_pos = _get_tkpos(); tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { - _set_error("Cannot use arrays as return types"); - return ERR_PARSE_ERROR; + bool error = false; + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT) { + return_array_size = (int)tk.constant; + if (return_array_size > 0) { + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + error = true; + } + } else { + error = true; + } + if (error) { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + + prev_pos = _get_tkpos(); } + _set_tkpos(prev_pos); _get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name); @@ -6962,8 +7455,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - if (constant.type != n->get_datatype() || n->get_datatype_name() != struct_name) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (is_struct ? String(struct_name) : get_datatype_name(constant.type)) + "'"); + if (!_compare_datatypes(constant.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { return ERR_PARSE_ERROR; } @@ -7024,8 +7516,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct constant.initializer = static_cast<ConstantNode *>(expr); - if (type != expr->get_datatype() || expr->get_datatype_name() != struct_name) { - _set_error("Invalid assignment of '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' to '" + (is_struct ? String(struct_name) : get_datatype_name(type)) + "'"); + if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), 0)) { return ERR_PARSE_ERROR; } } @@ -7042,6 +7533,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct shader->constants[name] = constant; shader->vconstants.push_back(constant); +#ifdef DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_CONSTANT_FLAG)) { + used_constants.insert(name, Usage(tk_line)); + } +#endif // DEBUG_ENABLED if (tk.type == TK_COMMA) { tk = _get_token(); @@ -7100,9 +7596,16 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct func_node->return_type = type; func_node->return_struct_name = struct_name; func_node->return_precision = precision; + func_node->return_array_size = return_array_size; if (p_functions.has(name)) { func_node->can_discard = p_functions[name].can_discard; + } else { +#ifdef DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_FUNCTION_FLAG)) { + used_functions.insert(name, Usage(tk_line)); + } +#endif // DEBUG_ENABLED } func_node->body = alloc_node<BlockNode>(); @@ -7147,6 +7650,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct StringName param_struct_name; DataPrecision pprecision = PRECISION_DEFAULT; bool use_precision = false; + int array_size = 0; if (is_token_precision(tk.type)) { pprecision = get_token_precision(tk.type); @@ -7193,8 +7697,29 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - _set_error("Arrays as parameters are not implemented yet"); - return ERR_PARSE_ERROR; + bool error = false; + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT) { + array_size = (int)tk.constant; + + if (array_size > 0) { + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + error = true; + } + } else { + error = true; + } + if (error) { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); } if (tk.type != TK_IDENTIFIER) { _set_error("Expected identifier for argument name"); @@ -7228,14 +7753,41 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct arg.tex_argument_repeat = REPEAT_DEFAULT; arg.is_const = is_const; - func_node->arguments.push_back(arg); - tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - _set_error("Arrays as parameters are not implemented yet"); - return ERR_PARSE_ERROR; + if (array_size > 0) { + _set_error("Array size is already defined!"); + return ERR_PARSE_ERROR; + } + bool error = false; + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT) { + array_size = (int)tk.constant; + + if (array_size > 0) { + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + error = true; + } + } else { + error = true; + } + + if (error) { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); } + arg.array_size = array_size; + func_node->arguments.push_back(arg); + if (tk.type == TK_COMMA) { tk = _get_token(); //do none and go on @@ -7436,6 +7988,33 @@ String ShaderLanguage::get_shader_type(const String &p_code) { return String(); } +#ifdef DEBUG_ENABLED +void ShaderLanguage::_check_warning_accums() { + for (Map<ShaderWarning::Code, Map<StringName, Usage> *>::Element *E = warnings_check_map.front(); E; E = E->next()) { + for (const Map<StringName, Usage>::Element *U = (*E->get()).front(); U; U = U->next()) { + if (!U->get().used) { + _add_warning(E->key(), U->get().decl_line, U->key()); + } + } + } +} +List<ShaderWarning>::Element *ShaderLanguage::get_warnings_ptr() { + return warnings.front(); +} +void ShaderLanguage::enable_warning_checking(bool p_enabled) { + check_warnings = p_enabled; +} +bool ShaderLanguage::is_warning_checking_enabled() const { + return check_warnings; +} +void ShaderLanguage::set_warning_flags(uint32_t p_flags) { + warning_flags = p_flags; +} +uint32_t ShaderLanguage::get_warning_flags() const { + return warning_flags; +} +#endif // DEBUG_ENABLED + Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { clear(); @@ -7448,6 +8027,12 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi shader = alloc_node<ShaderNode>(); Error err = _parse_shader(p_functions, p_render_modes, p_shader_types); +#ifdef DEBUG_ENABLED + if (check_warnings) { + _check_warning_accums(); + } +#endif // DEBUG_ENABLED + if (err != OK) { return err; } @@ -7625,6 +8210,13 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct String calltip; calltip += get_datatype_name(shader->functions[i].function->return_type); + + if (shader->functions[i].function->return_array_size > 0) { + calltip += "["; + calltip += itos(shader->functions[i].function->return_array_size); + calltip += "]"; + } + calltip += " "; calltip += shader->functions[i].name; calltip += "("; @@ -7656,6 +8248,12 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct calltip += " "; calltip += shader->functions[i].function->arguments[j].name; + if (shader->functions[i].function->arguments[j].array_size > 0) { + calltip += "["; + calltip += itos(shader->functions[i].function->arguments[j].array_size); + calltip += "]"; + } + if (j == completion_argument) { calltip += char32_t(0xFFFF); } @@ -7857,6 +8455,14 @@ ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() { ShaderLanguage::ShaderLanguage() { nodes = nullptr; completion_class = TAG_GLOBAL; + +#if DEBUG_ENABLED + warnings_check_map.insert(ShaderWarning::UNUSED_CONSTANT, &used_constants); + warnings_check_map.insert(ShaderWarning::UNUSED_FUNCTION, &used_functions); + warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs); + warnings_check_map.insert(ShaderWarning::UNUSED_UNIFORM, &used_uniforms); + warnings_check_map.insert(ShaderWarning::UNUSED_VARYING, &used_varyings); +#endif // DEBUG_ENABLED } ShaderLanguage::~ShaderLanguage() { diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index e00f4dce19..af66e32e06 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -39,6 +39,10 @@ #include "core/typedefs.h" #include "core/variant/variant.h" +#ifdef DEBUG_ENABLED +#include "shader_warnings.h" +#endif // DEBUG_ENABLED + class ShaderLanguage { public: struct TkPos { @@ -365,6 +369,8 @@ public: virtual DataType get_datatype() const { return TYPE_VOID; } virtual String get_datatype_name() const { return ""; } + virtual int get_array_size() const { return 0; } + virtual bool is_indexed() const { return false; } Node(Type t) : type(t) {} @@ -384,11 +390,15 @@ public: struct OperatorNode : public Node { DataType return_cache = TYPE_VOID; DataPrecision return_precision_cache = PRECISION_DEFAULT; + int return_array_size = 0; Operator op = OP_EQUAL; StringName struct_name; Vector<Node *> arguments; - virtual DataType get_datatype() const { return return_cache; } - virtual String get_datatype_name() const { return String(struct_name); } + + virtual DataType get_datatype() const override { return return_cache; } + virtual String get_datatype_name() const override { return String(struct_name); } + virtual int get_array_size() const override { return return_array_size; } + virtual bool is_indexed() const override { return op == OP_INDEX; } OperatorNode() : Node(TYPE_OPERATOR) {} @@ -398,10 +408,11 @@ public: DataType datatype_cache = TYPE_VOID; StringName name; StringName struct_name; - virtual DataType get_datatype() const { return datatype_cache; } - virtual String get_datatype_name() const { return String(struct_name); } bool is_const = false; + virtual DataType get_datatype() const override { return datatype_cache; } + virtual String get_datatype_name() const override { return String(struct_name); } + VariableNode() : Node(TYPE_VARIABLE) {} }; @@ -416,9 +427,9 @@ public: StringName name; Node *initializer; }; - Vector<Declaration> declarations; - virtual DataType get_datatype() const { return datatype; } + + virtual DataType get_datatype() const override { return datatype; } VariableDeclarationNode() : Node(TYPE_VARIABLE_DECLARATION) {} @@ -432,9 +443,12 @@ public: Node *call_expression = nullptr; Node *assign_expression = nullptr; bool is_const = false; + int array_size = 0; - virtual DataType get_datatype() const { return datatype_cache; } - virtual String get_datatype_name() const { return String(struct_name); } + virtual DataType get_datatype() const override { return datatype_cache; } + virtual String get_datatype_name() const override { return String(struct_name); } + virtual int get_array_size() const override { return array_size; } + virtual bool is_indexed() const override { return index_expression != nullptr; } ArrayNode() : Node(TYPE_ARRAY) {} @@ -445,6 +459,10 @@ public: String struct_name; Vector<Node *> initializer; + virtual DataType get_datatype() const override { return datatype; } + virtual String get_datatype_name() const override { return struct_name; } + virtual int get_array_size() const override { return initializer.size(); } + ArrayConstructNode() : Node(TYPE_ARRAY_CONSTRUCT) {} }; @@ -460,10 +478,11 @@ public: StringName name; uint32_t size; Vector<Node *> initializer; + bool single_expression; }; - Vector<Declaration> declarations; - virtual DataType get_datatype() const { return datatype; } + + virtual DataType get_datatype() const override { return datatype; } ArrayDeclarationNode() : Node(TYPE_ARRAY_DECLARATION) {} @@ -483,8 +502,10 @@ public: Vector<Value> values; Vector<ArrayDeclarationNode::Declaration> array_declarations; - virtual DataType get_datatype() const { return datatype; } - virtual String get_datatype_name() const { return struct_name; } + + virtual DataType get_datatype() const override { return datatype; } + virtual String get_datatype_name() const override { return struct_name; } + virtual int get_array_size() const override { return array_size; } ConstantNode() : Node(TYPE_CONSTANT) {} @@ -546,10 +567,13 @@ public: Node *owner = nullptr; Node *index_expression = nullptr; Node *assign_expression = nullptr; + Node *call_expression = nullptr; bool has_swizzling_duplicates = false; - virtual DataType get_datatype() const { return datatype; } - virtual String get_datatype_name() const { return String(struct_name); } + virtual DataType get_datatype() const override { return datatype; } + virtual String get_datatype_name() const override { return String(struct_name); } + virtual int get_array_size() const override { return array_size; } + virtual bool is_indexed() const override { return index_expression != nullptr || call_expression != nullptr; } MemberNode() : Node(TYPE_MEMBER) {} @@ -575,6 +599,7 @@ public: bool tex_builtin_check; StringName tex_builtin; bool is_const; + int array_size; Map<StringName, Set<int>> tex_argument_connect; }; @@ -583,10 +608,15 @@ public: DataType return_type = TYPE_VOID; StringName return_struct_name; DataPrecision return_precision = PRECISION_DEFAULT; + int return_array_size = 0; Vector<Argument> arguments; BlockNode *body = nullptr; bool can_discard = false; + virtual DataType get_datatype() const override { return return_type; } + virtual String get_datatype_name() const override { return String(return_struct_name); } + virtual int get_array_size() const override { return return_array_size; } + FunctionNode() : Node(TYPE_FUNCTION) {} }; @@ -802,12 +832,44 @@ private: String error_str; int error_line; +#ifdef DEBUG_ENABLED + struct Usage { + int decl_line; + bool used = false; + Usage(int p_decl_line = -1) { + decl_line = p_decl_line; + } + }; + + Map<StringName, Usage> used_constants; + Map<StringName, Usage> used_varyings; + Map<StringName, Usage> used_uniforms; + Map<StringName, Usage> used_functions; + Map<StringName, Usage> used_structs; + Map<ShaderWarning::Code, Map<StringName, Usage> *> warnings_check_map; + + List<ShaderWarning> warnings; + + bool check_warnings = false; + uint32_t warning_flags; + + void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "") { + warnings.push_back(ShaderWarning(p_code, tk_line, p_subject)); + } + void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "") { + warnings.push_back(ShaderWarning(p_code, p_line, p_subject)); + } + void _check_warning_accums(); +#endif // DEBUG_ENABLED + String code; int char_idx; int tk_line; StringName current_function; bool last_const = false; + bool pass_array = false; + StringName last_name; VaryingFunctionNames varying_function_names; @@ -848,12 +910,18 @@ private: IDENTIFIER_LOCAL_VAR, IDENTIFIER_BUILTIN_VAR, IDENTIFIER_CONSTANT, + IDENTIFIER_MAX, }; + IdentifierType last_type = IDENTIFIER_MAX; + bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr, ConstantNode::Value *r_constant_value = nullptr); +#ifdef DEBUG_ENABLED + void _parse_used_identifier(const StringName &p_identifier, IdentifierType p_type); +#endif // DEBUG_ENABLED bool _is_operator_assign(Operator p_op) const; bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr); - bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr); + bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr, int *r_ret_size = nullptr); struct BuiltinFuncDef { enum { MAX_ARGS = 5 }; @@ -884,7 +952,8 @@ private: static const BuiltinFuncOutArgs builtin_func_out_args[]; Error _validate_datatype(DataType p_type); - bool _compare_datatypes_in_nodes(Node *a, Node *b) const; + bool _compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b); + bool _compare_datatypes_in_nodes(Node *a, Node *b); bool _validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str); bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr); @@ -895,6 +964,7 @@ private: bool _check_node_constness(const Node *p_node) const; Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info); + Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size); ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node); @@ -909,6 +979,16 @@ private: Error _find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op); public: +#ifdef DEBUG_ENABLED + List<ShaderWarning>::Element *get_warnings_ptr(); + + void enable_warning_checking(bool p_enabled); + bool is_warning_checking_enabled() const; + + void set_warning_flags(uint32_t p_flags); + uint32_t get_warning_flags() const; +#endif // DEBUG_ENABLED + //static void get_keyword_list(ShaderType p_type,List<String> *p_keywords); void clear(); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 0bf68b9e0f..a1e892498b 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "shader_types.h" +#include "core/math/math_defs.h" const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) { return shader_modes[p_mode].functions; @@ -54,6 +55,9 @@ ShaderTypes::ShaderTypes() { /*************** SPATIAL ***********************/ shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; @@ -120,11 +124,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO_LIGHT_AFFECT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_ROUGHNESS_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_ROUGHNESS_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); @@ -227,6 +231,9 @@ ShaderTypes::ShaderTypes() { /************ CANVAS ITEM **************************/ shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; @@ -317,6 +324,9 @@ ShaderTypes::ShaderTypes() { /************ PARTICLES **************************/ shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3; @@ -381,6 +391,9 @@ ShaderTypes::ShaderTypes() { /************ SKY **************************/ shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL); diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp new file mode 100644 index 0000000000..aa11b4e397 --- /dev/null +++ b/servers/rendering/shader_warnings.cpp @@ -0,0 +1,131 @@ +/*************************************************************************/ +/* shader_warnings.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "shader_warnings.h" +#include "core/variant/variant.h" + +#ifdef DEBUG_ENABLED + +ShaderWarning::Code ShaderWarning::get_code() const { + return code; +} + +int ShaderWarning::get_line() const { + return line; +} + +const StringName &ShaderWarning::get_subject() const { + return subject; +} + +String ShaderWarning::get_message() const { + switch (code) { + case FLOAT_COMPARISON: + return vformat("Direct floating-point comparison (this may not evaluate to `true` as you expect). Instead, use `abs(a - b) < 0.0001` for an approximate but predictable comparison."); + case UNUSED_CONSTANT: + return vformat("The const '%s' is declared but never used.", subject); + case UNUSED_FUNCTION: + return vformat("The function '%s' is declared but never used.", subject); + case UNUSED_STRUCT: + return vformat("The struct '%s' is declared but never used.", subject); + case UNUSED_UNIFORM: + return vformat("The uniform '%s' is declared but never used.", subject); + case UNUSED_VARYING: + return vformat("The varying '%s' is declared but never used.", subject); + default: + break; + } + return String(); +} + +String ShaderWarning::get_name() const { + return get_name_from_code(code); +} + +String ShaderWarning::get_name_from_code(Code p_code) { + ERR_FAIL_INDEX_V(p_code, WARNING_MAX, String()); + + static const char *names[] = { + "FLOAT_COMPARISON", + "UNUSED_CONSTANT", + "UNUSED_FUNCTION", + "UNUSED_STRUCT", + "UNUSED_UNIFORM", + "UNUSED_VARYING", + }; + + static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names."); + + return names[(int)p_code]; +} + +ShaderWarning::Code ShaderWarning::get_code_from_name(const String &p_name) { + for (int i = 0; i < WARNING_MAX; i++) { + if (get_name_from_code((Code)i) == p_name) { + return (Code)i; + } + } + + ERR_FAIL_V_MSG(WARNING_MAX, "Invalid shader warning name: " + p_name); +} + +static Map<int, uint32_t> *code_to_flags_map = nullptr; + +static void init_code_to_flags_map() { + code_to_flags_map = memnew((Map<int, uint32_t>)); + code_to_flags_map->insert(ShaderWarning::FLOAT_COMPARISON, ShaderWarning::FLOAT_COMPARISON_FLAG); + code_to_flags_map->insert(ShaderWarning::UNUSED_CONSTANT, ShaderWarning::UNUSED_CONSTANT_FLAG); + code_to_flags_map->insert(ShaderWarning::UNUSED_FUNCTION, ShaderWarning::UNUSED_FUNCTION_FLAG); + code_to_flags_map->insert(ShaderWarning::UNUSED_STRUCT, ShaderWarning::UNUSED_STRUCT_FLAG); + code_to_flags_map->insert(ShaderWarning::UNUSED_UNIFORM, ShaderWarning::UNUSED_UNIFORM_FLAG); + code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG); +} + +ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) { + uint32_t result = 0U; + + if (code_to_flags_map == nullptr) { + init_code_to_flags_map(); + } + + for (Map<Code, bool>::Element *E = p_map.front(); E; E = E->next()) { + if (E->get()) { + ERR_FAIL_COND_V(!code_to_flags_map->has((int)E->key()), ShaderWarning::NONE_FLAG); + result |= (*code_to_flags_map)[(int)E->key()]; + } + } + return (CodeFlags)result; +} + +ShaderWarning::ShaderWarning(Code p_code, int p_line, const StringName &p_subject) : + code(p_code), line(p_line), subject(p_subject) { +} + +#endif // DEBUG_ENABLED diff --git a/platform/javascript/javascript_eval.cpp b/servers/rendering/shader_warnings.h index cb19dd20d4..c40aeefa2d 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/servers/rendering/shader_warnings.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* javascript_eval.cpp */ +/* shader_warnings.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,52 +28,56 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef JAVASCRIPT_EVAL_ENABLED +#ifndef SHADER_WARNINGS +#define SHADER_WARNINGS -#include "api/javascript_eval.h" -#include "emscripten.h" +#ifdef DEBUG_ENABLED -extern "C" { -union js_eval_ret { - uint32_t b; - double d; - char *s; -}; +#include "core/string/string_name.h" +#include "core/templates/list.h" +#include "core/templates/map.h" + +class ShaderWarning { +public: + enum Code { + FLOAT_COMPARISON, + UNUSED_CONSTANT, + UNUSED_FUNCTION, + UNUSED_STRUCT, + UNUSED_UNIFORM, + UNUSED_VARYING, + WARNING_MAX, + }; -extern int godot_js_eval(const char *p_js, int p_use_global_ctx, union js_eval_ret *p_union_ptr, void *p_byte_arr, void *p_byte_arr_write, void *(*p_callback)(void *p_ptr, void *p_ptr2, int p_len)); -} + enum CodeFlags : uint32_t { + NONE_FLAG = 0U, + FLOAT_COMPARISON_FLAG = 1U, + UNUSED_CONSTANT_FLAG = 2U, + UNUSED_FUNCTION_FLAG = 4U, + UNUSED_STRUCT_FLAG = 8U, + UNUSED_UNIFORM_FLAG = 16U, + UNUSED_VARYING_FLAG = 32U, + }; -void *resize_PackedByteArray_and_open_write(void *p_arr, void *r_write, int p_len) { - PackedByteArray *arr = (PackedByteArray *)p_arr; - VectorWriteProxy<uint8_t> *write = (VectorWriteProxy<uint8_t> *)r_write; - arr->resize(p_len); - *write = arr->write; - return arr->ptrw(); -} +private: + Code code; + int line; + StringName subject; -Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { - union js_eval_ret js_data; - PackedByteArray arr; - VectorWriteProxy<uint8_t> arr_write; +public: + Code get_code() const; + int get_line() const; + const StringName &get_subject() const; + String get_message() const; + String get_name() const; - Variant::Type return_type = static_cast<Variant::Type>(godot_js_eval(p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write, resize_PackedByteArray_and_open_write)); + static String get_name_from_code(Code p_code); + static Code get_code_from_name(const String &p_name); + static CodeFlags get_flags_from_codemap(const Map<Code, bool> &p_map); + + ShaderWarning(Code p_code = WARNING_MAX, int p_line = -1, const StringName &p_subject = ""); +}; - switch (return_type) { - case Variant::BOOL: - return js_data.b; - case Variant::FLOAT: - return js_data.d; - case Variant::STRING: { - String str = String::utf8(js_data.s); - free(js_data.s); // Must free the string allocated in JS. - return str; - } - case Variant::PACKED_BYTE_ARRAY: - arr_write = VectorWriteProxy<uint8_t>(); - return arr; - default: - return Variant(); - } -} +#endif // DEBUG_ENABLED -#endif // JAVASCRIPT_EVAL_ENABLED +#endif // SHADER_WARNINGS diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a9154603ee..4741e90a81 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -858,8 +858,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa case Variant::PACKED_VECTOR2_ARRAY: { Vector<Vector2> v2 = p_arrays[i]; array_len = v2.size(); + format |= ARRAY_FLAG_USE_2D_VERTICES; } break; case Variant::PACKED_VECTOR3_ARRAY: { + ERR_FAIL_COND_V(p_compress_format & ARRAY_FLAG_USE_2D_VERTICES, ERR_INVALID_PARAMETER); Vector<Vector3> v3 = p_arrays[i]; array_len = v3.size(); } break; @@ -871,10 +873,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } else if (i == RS::ARRAY_BONES) { switch (p_arrays[i].get_type()) { case Variant::PACKED_INT32_ARRAY: { - Vector<Vector3> vertexes = p_arrays[RS::ARRAY_VERTEX]; + Vector<Vector3> vertices = p_arrays[RS::ARRAY_VERTEX]; Vector<int32_t> bones = p_arrays[i]; int32_t bone_8_group_count = bones.size() / (ARRAY_WEIGHTS_SIZE * 2); - int32_t vertex_count = vertexes.size(); + int32_t vertex_count = vertices.size(); if (vertex_count == bone_8_group_count) { format |= RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS; } @@ -2304,6 +2306,12 @@ RenderingServer::RenderingServer() { "rendering/vulkan/rendering/back_end", PROPERTY_HINT_ENUM, "ForwardClustered,ForwardMobile")); + GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true); + GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true); + GLOBAL_DEF("rendering/shader_compiler/shader_cache/use_zstd_compression", true); + GLOBAL_DEF("rendering/shader_compiler/shader_cache/strip_debug", false); + GLOBAL_DEF("rendering/shader_compiler/shader_cache/strip_debug.release", true); + GLOBAL_DEF("rendering/reflections/sky_reflections/roughness_layers", 8); GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections", true); GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections.mobile", false); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index ad965e9690..a9ab4928c4 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -618,6 +618,12 @@ public: virtual RID particles_create() = 0; + enum ParticlesMode { + PARTICLES_MODE_2D, + PARTICLES_MODE_3D + }; + virtual void particles_set_mode(RID p_particles, ParticlesMode p_mode) = 0; + virtual void particles_set_emitting(RID p_particles, bool p_enable) = 0; virtual bool particles_get_emitting(RID p_particles) = 0; virtual void particles_set_amount(RID p_particles, int p_amount) = 0; @@ -666,6 +672,7 @@ public: enum ParticlesDrawOrder { PARTICLES_DRAW_ORDER_INDEX, PARTICLES_DRAW_ORDER_LIFETIME, + PARTICLES_DRAW_ORDER_REVERSE_LIFETIME, PARTICLES_DRAW_ORDER_VIEW_DEPTH, }; diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 8b03565291..daed612b02 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -987,7 +987,7 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, while (i < ranges.size()) { int j = i + 1; while (j < ranges.size()) { - if (Math::is_equal_approx(ranges[i].y, ranges[j].x, UNIT_EPSILON)) { + if (Math::is_equal_approx(ranges[i].y, ranges[j].x, (real_t)UNIT_EPSILON)) { ranges.write[i].y = ranges[j].y; ranges.remove(j); continue; diff --git a/tests/test_color.h b/tests/test_color.h index eb8d7dcbd4..ad4a7cd3f2 100644 --- a/tests/test_color.h +++ b/tests/test_color.h @@ -101,13 +101,13 @@ TEST_CASE("[Color] Reading methods") { const Color dark_blue = Color(0, 0, 0.5, 0.4); CHECK_MESSAGE( - Math::is_equal_approx(dark_blue.get_h(), 240 / 360.0), + Math::is_equal_approx(dark_blue.get_h(), 240.0f / 360.0f), "The returned HSV hue should match the expected value."); CHECK_MESSAGE( - Math::is_equal_approx(dark_blue.get_s(), 1), + Math::is_equal_approx(dark_blue.get_s(), 1.0f), "The returned HSV saturation should match the expected value."); CHECK_MESSAGE( - Math::is_equal_approx(dark_blue.get_v(), 0.5), + Math::is_equal_approx(dark_blue.get_v(), 0.5f), "The returned HSV value should match the expected value."); } diff --git a/tests/test_curve.h b/tests/test_curve.h index 019941a7ce..3055cfd97b 100644 --- a/tests/test_curve.h +++ b/tests/test_curve.h @@ -83,13 +83,13 @@ TEST_CASE("[Curve] Custom curve with free tangents") { Math::is_equal_approx(curve->interpolate(-0.1), 0), "Custom free curve should return the expected value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.1), 0.352), + Math::is_equal_approx(curve->interpolate(0.1), (real_t)0.352), "Custom free curve should return the expected value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.4), 0.352), + Math::is_equal_approx(curve->interpolate(0.4), (real_t)0.352), "Custom free curve should return the expected value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.7), 0.896), + Math::is_equal_approx(curve->interpolate(0.7), (real_t)0.896), "Custom free curve should return the expected value at offset 0.1."); CHECK_MESSAGE( Math::is_equal_approx(curve->interpolate(1), 1), @@ -102,13 +102,13 @@ TEST_CASE("[Curve] Custom curve with free tangents") { Math::is_equal_approx(curve->interpolate_baked(-0.1), 0), "Custom free curve should return the expected baked value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.1), 0.352), + Math::is_equal_approx(curve->interpolate_baked(0.1), (real_t)0.352), "Custom free curve should return the expected baked value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.4), 0.352), + Math::is_equal_approx(curve->interpolate_baked(0.4), (real_t)0.352), "Custom free curve should return the expected baked value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.7), 0.896), + Math::is_equal_approx(curve->interpolate_baked(0.7), (real_t)0.896), "Custom free curve should return the expected baked value at offset 0.1."); CHECK_MESSAGE( Math::is_equal_approx(curve->interpolate_baked(1), 1), @@ -172,13 +172,13 @@ TEST_CASE("[Curve] Custom curve with linear tangents") { Math::is_equal_approx(curve->interpolate(-0.1), 0), "Custom linear curve should return the expected value at offset -0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.1), 0.4), + Math::is_equal_approx(curve->interpolate(0.1), (real_t)0.4), "Custom linear curve should return the expected value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.4), 0.4), + Math::is_equal_approx(curve->interpolate(0.4), (real_t)0.4), "Custom linear curve should return the expected value at offset 0.4."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.7), 0.8), + Math::is_equal_approx(curve->interpolate(0.7), (real_t)0.8), "Custom linear curve should return the expected value at offset 0.7."); CHECK_MESSAGE( Math::is_equal_approx(curve->interpolate(1), 1), @@ -191,13 +191,13 @@ TEST_CASE("[Curve] Custom curve with linear tangents") { Math::is_equal_approx(curve->interpolate_baked(-0.1), 0), "Custom linear curve should return the expected baked value at offset -0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.1), 0.4), + Math::is_equal_approx(curve->interpolate_baked(0.1), (real_t)0.4), "Custom linear curve should return the expected baked value at offset 0.1."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.4), 0.4), + Math::is_equal_approx(curve->interpolate_baked(0.4), (real_t)0.4), "Custom linear curve should return the expected baked value at offset 0.4."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.7), 0.8), + Math::is_equal_approx(curve->interpolate_baked(0.7), (real_t)0.8), "Custom linear curve should return the expected baked value at offset 0.7."); CHECK_MESSAGE( Math::is_equal_approx(curve->interpolate_baked(1), 1), @@ -210,10 +210,10 @@ TEST_CASE("[Curve] Custom curve with linear tangents") { curve->remove_point(10); ERR_PRINT_ON; CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate(0.7), 0.8), + Math::is_equal_approx(curve->interpolate(0.7), (real_t)0.8), "Custom free curve should return the expected value at offset 0.7 after removing point at invalid index 10."); CHECK_MESSAGE( - Math::is_equal_approx(curve->interpolate_baked(0.7), 0.8), + Math::is_equal_approx(curve->interpolate_baked(0.7), (real_t)0.8), "Custom free curve should return the expected baked value at offset 0.7 after removing point at invalid index 10."); } } // namespace TestCurve diff --git a/tests/test_expression.h b/tests/test_expression.h index 0ef60d1a19..cb1d29389f 100644 --- a/tests/test_expression.h +++ b/tests/test_expression.h @@ -83,42 +83,42 @@ TEST_CASE("[Expression] Floating-point arithmetic") { expression.parse("-123.456") == OK, "Float identity should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), -123.456), + Math::is_equal_approx(double(expression.execute()), -123.456), "Float identity should return the expected result."); CHECK_MESSAGE( expression.parse("2.0 + 3.0") == OK, "Float addition should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 5), + Math::is_equal_approx(double(expression.execute()), 5), "Float addition should return the expected result."); CHECK_MESSAGE( expression.parse("3.0 / 10") == OK, "Float / integer division should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 0.3), + Math::is_equal_approx(double(expression.execute()), 0.3), "Float / integer division should return the expected result."); CHECK_MESSAGE( expression.parse("3 / 10.0") == OK, "Basic integer / float division should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 0.3), + Math::is_equal_approx(double(expression.execute()), 0.3), "Basic integer / float division should return the expected result."); CHECK_MESSAGE( expression.parse("3.0 / 10.0") == OK, "Float / float division should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 0.3), + Math::is_equal_approx(double(expression.execute()), 0.3), "Float / float division should return the expected result."); CHECK_MESSAGE( expression.parse("2.5 * (6.0 + 14.25) / 2.0 - 5.12345") == OK, "Float multiplication-addition-subtraction-division should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 20.18905), + Math::is_equal_approx(double(expression.execute()), 20.18905), "Float multiplication-addition-subtraction-division should return the expected result."); } @@ -129,7 +129,7 @@ TEST_CASE("[Expression] Scientific notation") { expression.parse("2.e5") == OK, "The expression should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 200'000), + Math::is_equal_approx(double(expression.execute()), 200'000), "The expression should return the expected result."); // The middle "e" is ignored here. @@ -137,14 +137,14 @@ TEST_CASE("[Expression] Scientific notation") { expression.parse("2e5") == OK, "The expression should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 25), + Math::is_equal_approx(double(expression.execute()), 25), "The expression should return the expected result."); CHECK_MESSAGE( expression.parse("2e.5") == OK, "The expression should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 2), + Math::is_equal_approx(double(expression.execute()), 2), "The expression should return the expected result."); } @@ -176,14 +176,14 @@ TEST_CASE("[Expression] Built-in functions") { expression.parse("snapped(sin(0.5), 0.01)") == OK, "The expression should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(float(expression.execute()), 0.48), + Math::is_equal_approx(double(expression.execute()), 0.48), "`snapped(sin(0.5), 0.01)` should return the expected result."); CHECK_MESSAGE( expression.parse("pow(2.0, -2500)") == OK, "The expression should parse successfully."); CHECK_MESSAGE( - Math::is_zero_approx(float(expression.execute())), + Math::is_zero_approx(double(expression.execute())), "`pow(2.0, -2500)` should return the expected result (asymptotically zero)."); } @@ -410,7 +410,7 @@ TEST_CASE("[Expression] Unusual expressions") { "The expression should parse successfully."); ERR_PRINT_OFF; CHECK_MESSAGE( - Math::is_inf(float(expression.execute())), + Math::is_inf(double(expression.execute())), "`-25.4 / 0` should return inf."); ERR_PRINT_ON; diff --git a/tests/test_geometry_2d.h b/tests/test_geometry_2d.h index c9313f3625..32d4114a1c 100644 --- a/tests/test_geometry_2d.h +++ b/tests/test_geometry_2d.h @@ -50,7 +50,7 @@ TEST_CASE("[Geometry2D] Point in circle") { CHECK(Geometry2D::is_point_in_circle(Vector2(7, -42), Vector2(4, -40), 3.7)); CHECK_FALSE(Geometry2D::is_point_in_circle(Vector2(7, -42), Vector2(4, -40), 3.5)); - // This tests points on the edge of the circle. They are treated as beeing inside the circle. + // This tests points on the edge of the circle. They are treated as being inside the circle. // In `is_point_in_triangle` and `is_point_in_polygon` they are treated as being outside, so in order the make // the behaviour consistent this may change in the future (see issue #44717 and PR #44274). CHECK(Geometry2D::is_point_in_circle(Vector2(1.0, 0.0), Vector2(0, 0), 1.0)); @@ -65,7 +65,7 @@ TEST_CASE("[Geometry2D] Point in triangle") { CHECK(Geometry2D::is_point_in_triangle(Vector2(-3, -2.5), Vector2(-1, -4), Vector2(-3, -2), Vector2(-5, -4))); CHECK_FALSE(Geometry2D::is_point_in_triangle(Vector2(0, 0), Vector2(1, 4), Vector2(3, 2), Vector2(5, 4))); - // This tests points on the edge of the triangle. They are treated as beeing outside the triangle. + // This tests points on the edge of the triangle. They are treated as being outside the triangle. // In `is_point_in_circle` they are treated as being inside, so in order the make // the behaviour consistent this may change in the future (see issue #44717 and PR #44274). CHECK_FALSE(Geometry2D::is_point_in_triangle(Vector2(1, 1), Vector2(-1, 1), Vector2(0, -1), Vector2(1, 1))); @@ -95,7 +95,7 @@ TEST_CASE("[Geometry2D] Point in polygon") { CHECK(Geometry2D::is_point_in_polygon(Vector2(370, 55), p)); CHECK(Geometry2D::is_point_in_polygon(Vector2(-160, 190), p)); - // This tests points on the edge of the polygon. They are treated as beeing outside the polygon. + // This tests points on the edge of the polygon. They are treated as being outside the polygon. // In `is_point_in_circle` they are treated as being inside, so in order the make // the behaviour consistent this may change in the future (see issue #44717 and PR #44274). CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(68, 112), p)); @@ -227,7 +227,7 @@ TEST_CASE("[Geometry2D] Polygon intersection") { CHECK(r[0][2].is_equal_approx(Point2(160.52632, 92.63157))); } - SUBCASE("[Geometry2D] Intersection with one polygon beeing completly inside the other polygon") { + SUBCASE("[Geometry2D] Intersection with one polygon being completely inside the other polygon") { b.push_back(Point2(80, 100)); b.push_back(Point2(50, 50)); b.push_back(Point2(150, 50)); diff --git a/tests/test_image.h b/tests/test_image.h index d73717f5b7..99c2a9380d 100644 --- a/tests/test_image.h +++ b/tests/test_image.h @@ -101,8 +101,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_bmp = memnew(Image()); FileAccessRef f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err); PackedByteArray data_bmp; - data_bmp.resize(f_bmp->get_len() + 1); - f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_len()); + data_bmp.resize(f_bmp->get_length() + 1); + f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_length()); CHECK_MESSAGE( image_bmp->load_bmp_from_buffer(data_bmp) == OK, "The BMP image should load successfully."); @@ -111,8 +111,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_jpg = memnew(Image()); FileAccessRef f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err); PackedByteArray data_jpg; - data_jpg.resize(f_jpg->get_len() + 1); - f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_len()); + data_jpg.resize(f_jpg->get_length() + 1); + f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_length()); CHECK_MESSAGE( image_jpg->load_jpg_from_buffer(data_jpg) == OK, "The JPG image should load successfully."); @@ -121,8 +121,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_webp = memnew(Image()); FileAccessRef f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err); PackedByteArray data_webp; - data_webp.resize(f_webp->get_len() + 1); - f_webp->get_buffer(data_webp.ptrw(), f_webp->get_len()); + data_webp.resize(f_webp->get_length() + 1); + f_webp->get_buffer(data_webp.ptrw(), f_webp->get_length()); CHECK_MESSAGE( image_webp->load_webp_from_buffer(data_webp) == OK, "The WEBP image should load successfully."); @@ -131,8 +131,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_png = memnew(Image()); FileAccessRef f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err); PackedByteArray data_png; - data_png.resize(f_png->get_len() + 1); - f_png->get_buffer(data_png.ptrw(), f_png->get_len()); + data_png.resize(f_png->get_length() + 1); + f_png->get_buffer(data_png.ptrw(), f_png->get_length()); CHECK_MESSAGE( image_png->load_png_from_buffer(data_png) == OK, "The PNG image should load successfully."); @@ -141,8 +141,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_tga = memnew(Image()); FileAccessRef f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err); PackedByteArray data_tga; - data_tga.resize(f_tga->get_len() + 1); - f_tga->get_buffer(data_tga.ptrw(), f_tga->get_len()); + data_tga.resize(f_tga->get_length() + 1); + f_tga->get_buffer(data_tga.ptrw(), f_tga->get_length()); CHECK_MESSAGE( image_tga->load_tga_from_buffer(data_tga) == OK, "The TGA image should load successfully."); diff --git a/tests/test_json.h b/tests/test_json.h index e652a8fced..f1cb4799dc 100644 --- a/tests/test_json.h +++ b/tests/test_json.h @@ -80,7 +80,7 @@ TEST_CASE("[JSON] Parsing single data types") { err_line == 0, "Parsing an integer number as JSON should parse successfully."); CHECK_MESSAGE( - Math::is_equal_approx(result, 123'456), + (int)result == 123'456, "Parsing an integer number as JSON should return the expected value."); json.parse("0.123456", result, err_str, err_line); @@ -155,7 +155,7 @@ TEST_CASE("[JSON] Parsing objects (dictionaries)") { dictionary["bugs"] == Variant(), "The parsed JSON should contain the expected values."); CHECK_MESSAGE( - Math::is_equal_approx(Dictionary(dictionary["apples"])["blue"], -20), + (int)Dictionary(dictionary["apples"])["blue"] == -20, "The parsed JSON should contain the expected values."); CHECK_MESSAGE( dictionary["empty_object"].hash() == Dictionary().hash(), diff --git a/tests/test_main.cpp b/tests/test_main.cpp index d06d604532..54327caf3d 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -74,8 +74,10 @@ #include "test_shader_lang.h" #include "test_string.h" #include "test_text_server.h" +#include "test_translation.h" #include "test_validate_testing.h" #include "test_variant.h" +#include "test_vector.h" #include "test_xml_parser.h" #include "modules/modules_tests.gen.h" @@ -119,24 +121,27 @@ int test_main(int argc, char *argv[]) { test_args.push_back(arg); } } - // Convert Godot command line arguments back to standard arguments. - char **doctest_args = new char *[test_args.size()]; - for (int x = 0; x < test_args.size(); x++) { - // Operation to convert Godot string to non wchar string. - CharString cs = test_args[x].utf8(); - const char *str = cs.get_data(); - // Allocate the string copy. - doctest_args[x] = new char[strlen(str) + 1]; - // Copy this into memory. - memcpy(doctest_args[x], str, strlen(str) + 1); - } - test_context.applyCommandLine(test_args.size(), doctest_args); + if (test_args.size() > 0) { + // Convert Godot command line arguments back to standard arguments. + char **doctest_args = new char *[test_args.size()]; + for (int x = 0; x < test_args.size(); x++) { + // Operation to convert Godot string to non wchar string. + CharString cs = test_args[x].utf8(); + const char *str = cs.get_data(); + // Allocate the string copy. + doctest_args[x] = new char[strlen(str) + 1]; + // Copy this into memory. + memcpy(doctest_args[x], str, strlen(str) + 1); + } + + test_context.applyCommandLine(test_args.size(), doctest_args); - for (int x = 0; x < test_args.size(); x++) { - delete[] doctest_args[x]; + for (int x = 0; x < test_args.size(); x++) { + delete[] doctest_args[x]; + } + delete[] doctest_args; } - delete[] doctest_args; return test_context.run(); } diff --git a/tests/test_math.cpp b/tests/test_math.cpp index 26c2aa2088..88c32713ed 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -529,8 +529,8 @@ MainLoop *test() { ERR_FAIL_COND_V_MSG(!fa, nullptr, "Could not open file: " + test); Vector<uint8_t> buf; - int flen = fa->get_len(); - buf.resize(fa->get_len() + 1); + uint64_t flen = fa->get_length(); + buf.resize(fa->get_length() + 1); fa->get_buffer(buf.ptrw(), flen); buf.write[flen] = 0; diff --git a/tests/test_pck_packer.h b/tests/test_pck_packer.h index 8e4721b821..06e4e64963 100644 --- a/tests/test_pck_packer.h +++ b/tests/test_pck_packer.h @@ -62,10 +62,10 @@ TEST_CASE("[PCKPacker] Pack an empty PCK file") { err == OK, "The generated empty PCK file should be opened successfully."); CHECK_MESSAGE( - f->get_len() >= 100, + f->get_length() >= 100, "The generated empty PCK file shouldn't be too small (it should have the PCK header)."); CHECK_MESSAGE( - f->get_len() <= 500, + f->get_length() <= 500, "The generated empty PCK file shouldn't be too large."); } @@ -103,10 +103,10 @@ TEST_CASE("[PCKPacker] Pack a PCK file with some files and directories") { err == OK, "The generated non-empty PCK file should be opened successfully."); CHECK_MESSAGE( - f->get_len() >= 25000, + f->get_length() >= 25000, "The generated non-empty PCK file should be large enough to actually hold the contents specified above."); CHECK_MESSAGE( - f->get_len() <= 35000, + f->get_length() <= 35000, "The generated non-empty PCK file shouldn't be too large."); } } // namespace TestPCKPacker diff --git a/tests/test_physics_2d.cpp b/tests/test_physics_2d.cpp index 25b2871890..a9e2e92b34 100644 --- a/tests/test_physics_2d.cpp +++ b/tests/test_physics_2d.cpp @@ -320,7 +320,7 @@ public: ps->space_set_active(space, true); ps->set_active(true); ps->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, Vector2(0, 1)); - ps->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, 98); + ps->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, 980); { RID vp = vs->viewport_create(); diff --git a/tests/test_physics_3d.cpp b/tests/test_physics_3d.cpp index ac8078a0a8..727c44b3ac 100644 --- a/tests/test_physics_3d.cpp +++ b/tests/test_physics_3d.cpp @@ -30,8 +30,8 @@ #include "test_physics_3d.h" +#include "core/math/convex_hull.h" #include "core/math/math_funcs.h" -#include "core/math/quick_hull.h" #include "core/os/main_loop.h" #include "core/os/os.h" #include "core/string/print_string.h" @@ -169,7 +169,7 @@ protected: RID convex_mesh = vs->mesh_create(); Geometry3D::MeshData convex_data = Geometry3D::build_convex_mesh(convex_planes); - QuickHull::build(convex_data.vertices, convex_data); + ConvexHullComputer::convex_hull(convex_data.vertices, convex_data); vs->mesh_add_surface_from_mesh_data(convex_mesh, convex_data); type_mesh_map[PhysicsServer3D::SHAPE_CONVEX_POLYGON] = convex_mesh; diff --git a/tests/test_rect2.h b/tests/test_rect2.h index b94a8b7d05..821aa69970 100644 --- a/tests/test_rect2.h +++ b/tests/test_rect2.h @@ -144,7 +144,7 @@ TEST_CASE("[Rect2] Absolute coordinates") { "abs() should return the expected Rect2."); } -TEST_CASE("[Rect2] Intersecton") { +TEST_CASE("[Rect2] Intersection") { CHECK_MESSAGE( Rect2(0, 100, 1280, 720).intersection(Rect2(0, 300, 100, 100)).is_equal_approx(Rect2(0, 300, 100, 100)), "intersection() with fully enclosed Rect2 should return the expected result."); @@ -312,19 +312,19 @@ TEST_CASE("[Rect2i] Basic setters") { TEST_CASE("[Rect2i] Area getters") { CHECK_MESSAGE( - Math::is_equal_approx(Rect2i(0, 100, 1280, 720).get_area(), 921'600), + Rect2i(0, 100, 1280, 720).get_area() == 921'600, "get_area() should return the expected value."); CHECK_MESSAGE( - Math::is_equal_approx(Rect2i(0, 100, -1280, -720).get_area(), 921'600), + Rect2i(0, 100, -1280, -720).get_area() == 921'600, "get_area() should return the expected value."); CHECK_MESSAGE( - Math::is_equal_approx(Rect2i(0, 100, 1280, -720).get_area(), -921'600), + Rect2i(0, 100, 1280, -720).get_area() == -921'600, "get_area() should return the expected value."); CHECK_MESSAGE( - Math::is_equal_approx(Rect2i(0, 100, -1280, 720).get_area(), -921'600), + Rect2i(0, 100, -1280, 720).get_area() == -921'600, "get_area() should return the expected value."); CHECK_MESSAGE( - Math::is_zero_approx(Rect2i(0, 100, 0, 720).get_area()), + Rect2i(0, 100, 0, 720).get_area() == 0, "get_area() should return the expected value."); CHECK_MESSAGE( diff --git a/tests/test_render.cpp b/tests/test_render.cpp index 72b2840098..9737fd03f3 100644 --- a/tests/test_render.cpp +++ b/tests/test_render.cpp @@ -30,8 +30,8 @@ #include "test_render.h" +#include "core/math/convex_hull.h" #include "core/math/math_funcs.h" -#include "core/math/quick_hull.h" #include "core/os/keyboard.h" #include "core/os/main_loop.h" #include "core/os/os.h" @@ -118,7 +118,7 @@ public: vts.push_back(Vector3(-1, -1, -1)); Geometry3D::MeshData md; - Error err = QuickHull::build(vts, md); + Error err = ConvexHullComputer::convex_hull(vts, md); print_line("ERR: " + itos(err)); test_cube = vs->mesh_create(); vs->mesh_add_surface_from_mesh_data(test_cube, md); diff --git a/tests/test_string.h b/tests/test_string.h index 486c17dbbd..6e214574af 100644 --- a/tests/test_string.h +++ b/tests/test_string.h @@ -299,6 +299,7 @@ TEST_CASE("[String] hex_encode_buffer") { TEST_CASE("[String] Substr") { String s = "Killer Baby"; CHECK(s.substr(3, 4) == "ler "); + CHECK(s.substr(3) == "ler Baby"); } TEST_CASE("[String] Find") { @@ -1252,8 +1253,10 @@ TEST_CASE("[String] Trim") { TEST_CASE("[String] Right/Left") { String s = "aaaTestbbb"; // ^ - CHECK(s.right(6) == "tbbb"); + CHECK(s.right(6) == "estbbb"); + CHECK(s.right(-6) == "tbbb"); CHECK(s.left(6) == "aaaTes"); + CHECK(s.left(-6) == "aaaT"); } TEST_CASE("[String] Repeat") { diff --git a/tests/test_translation.h b/tests/test_translation.h new file mode 100644 index 0000000000..52ff49bf9b --- /dev/null +++ b/tests/test_translation.h @@ -0,0 +1,150 @@ +/*************************************************************************/ +/* test_translation.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_TRANSLATION_H +#define TEST_TRANSLATION_H + +#include "core/string/optimized_translation.h" +#include "core/string/translation.h" +#include "core/string/translation_po.h" + +#include "thirdparty/doctest/doctest.h" + +namespace TestTranslation { + +TEST_CASE("[Translation] Messages") { + Ref<Translation> translation = memnew(Translation); + translation->set_locale("fr"); + translation->add_message("Hello", "Bonjour"); + CHECK(translation->get_message("Hello") == "Bonjour"); + + translation->erase_message("Hello"); + // The message no longer exists, so it returns an empty string instead. + CHECK(translation->get_message("Hello") == ""); + + List<StringName> messages; + translation->get_message_list(&messages); + CHECK(translation->get_message_count() == 0); + CHECK(messages.size() == 0); + + translation->add_message("Hello2", "Bonjour2"); + translation->add_message("Hello3", "Bonjour3"); + messages.clear(); + translation->get_message_list(&messages); + CHECK(translation->get_message_count() == 2); + CHECK(messages.size() == 2); + // Messages are stored in a Map, don't assume ordering. + CHECK(messages.find("Hello2")); + CHECK(messages.find("Hello3")); +} + +TEST_CASE("[TranslationPO] Messages with context") { + Ref<TranslationPO> translation = memnew(TranslationPO); + translation->set_locale("fr"); + translation->add_message("Hello", "Bonjour"); + translation->add_message("Hello", "Salut", "friendly"); + CHECK(translation->get_message("Hello") == "Bonjour"); + CHECK(translation->get_message("Hello", "friendly") == "Salut"); + CHECK(translation->get_message("Hello", "nonexistent_context") == ""); + + // Only remove the message for the default context, not the "friendly" context. + translation->erase_message("Hello"); + // The message no longer exists, so it returns an empty string instead. + CHECK(translation->get_message("Hello") == ""); + CHECK(translation->get_message("Hello", "friendly") == "Salut"); + CHECK(translation->get_message("Hello", "nonexistent_context") == ""); + + List<StringName> messages; + translation->get_message_list(&messages); + + // `get_message_count()` takes all contexts into account. + CHECK(translation->get_message_count() == 1); + // Only the default context is taken into account. + // Since "Hello" is now only present in a non-default context, it is not counted in the list of messages. + CHECK(messages.size() == 0); + + translation->add_message("Hello2", "Bonjour2"); + translation->add_message("Hello2", "Salut2", "friendly"); + translation->add_message("Hello3", "Bonjour3"); + messages.clear(); + translation->get_message_list(&messages); + + // `get_message_count()` takes all contexts into account. + CHECK(translation->get_message_count() == 4); + // Only the default context is taken into account. + CHECK(messages.size() == 2); + // Messages are stored in a Map, don't assume ordering. + CHECK(messages.find("Hello2")); + CHECK(messages.find("Hello3")); +} + +TEST_CASE("[TranslationPO] Plural messages") { + Ref<TranslationPO> translation = memnew(TranslationPO); + translation->set_locale("fr"); + translation->set_plural_rule("Plural-Forms: nplurals=2; plural=(n >= 2);"); + CHECK(translation->get_plural_forms() == 2); + + PackedStringArray plurals; + plurals.push_back("Il y a %d pomme"); + plurals.push_back("Il y a %d pommes"); + translation->add_plural_message("There are %d apples", plurals); + ERR_PRINT_OFF; + // This is invalid, as the number passed to `get_plural_message()` may not be negative. + CHECK(vformat(translation->get_plural_message("There are %d apples", "", -1), -1) == ""); + ERR_PRINT_ON; + CHECK(vformat(translation->get_plural_message("There are %d apples", "", 0), 0) == "Il y a 0 pomme"); + CHECK(vformat(translation->get_plural_message("There are %d apples", "", 1), 1) == "Il y a 1 pomme"); + CHECK(vformat(translation->get_plural_message("There are %d apples", "", 2), 2) == "Il y a 2 pommes"); +} + +TEST_CASE("[OptimizedTranslation] Generate from Translation and read messages") { + Ref<Translation> translation = memnew(Translation); + translation->set_locale("fr"); + translation->add_message("Hello", "Bonjour"); + translation->add_message("Hello2", "Bonjour2"); + translation->add_message("Hello3", "Bonjour3"); + + Ref<OptimizedTranslation> optimized_translation = memnew(OptimizedTranslation); + optimized_translation->generate(translation); + CHECK(optimized_translation->get_message("Hello") == "Bonjour"); + CHECK(optimized_translation->get_message("Hello2") == "Bonjour2"); + CHECK(optimized_translation->get_message("Hello3") == "Bonjour3"); + CHECK(optimized_translation->get_message("DoesNotExist") == ""); + + List<StringName> messages; + // `get_message_list()` can't return the list of messages stored in an OptimizedTranslation. + optimized_translation->get_message_list(&messages); + CHECK(optimized_translation->get_message_count() == 0); + CHECK(messages.size() == 0); +} + +} // namespace TestTranslation + +#endif // TEST_TRANSLATION_H diff --git a/tests/test_vector.h b/tests/test_vector.h new file mode 100644 index 0000000000..02c56e59f6 --- /dev/null +++ b/tests/test_vector.h @@ -0,0 +1,496 @@ +/*************************************************************************/ +/* test_vector.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_VECTOR_H +#define TEST_VECTOR_H + +#include "core/templates/vector.h" + +#include "tests/test_macros.h" + +namespace TestVector { + +TEST_CASE("[Vector] Push back and append") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + // Alias for `push_back`. + vector.append(4); + + CHECK(vector[0] == 0); + CHECK(vector[1] == 1); + CHECK(vector[2] == 2); + CHECK(vector[3] == 3); + CHECK(vector[4] == 4); +} + +TEST_CASE("[Vector] Append array") { + Vector<int> vector; + vector.push_back(1); + vector.push_back(2); + + Vector<int> vector_other; + vector_other.push_back(128); + vector_other.push_back(129); + vector.append_array(vector_other); + + CHECK(vector.size() == 4); + CHECK(vector[0] == 1); + CHECK(vector[1] == 2); + CHECK(vector[2] == 128); + CHECK(vector[3] == 129); +} + +TEST_CASE("[Vector] Insert") { + Vector<int> vector; + vector.insert(0, 2); + vector.insert(0, 8); + vector.insert(2, 5); + vector.insert(1, 5); + vector.insert(0, -2); + + CHECK(vector.size() == 5); + CHECK(vector[0] == -2); + CHECK(vector[1] == 8); + CHECK(vector[2] == 5); + CHECK(vector[3] == 2); + CHECK(vector[4] == 5); +} + +TEST_CASE("[Vector] Ordered insert") { + Vector<int> vector; + vector.ordered_insert(2); + vector.ordered_insert(8); + vector.ordered_insert(5); + vector.ordered_insert(5); + vector.ordered_insert(-2); + + CHECK(vector.size() == 5); + CHECK(vector[0] == -2); + CHECK(vector[1] == 2); + CHECK(vector[2] == 5); + CHECK(vector[3] == 5); + CHECK(vector[4] == 8); +} + +TEST_CASE("[Vector] Insert + Ordered insert") { + Vector<int> vector; + vector.ordered_insert(2); + vector.ordered_insert(8); + vector.insert(0, 5); + vector.ordered_insert(5); + vector.insert(1, -2); + + CHECK(vector.size() == 5); + CHECK(vector[0] == 5); + CHECK(vector[1] == -2); + CHECK(vector[2] == 2); + CHECK(vector[3] == 5); + CHECK(vector[4] == 8); +} + +TEST_CASE("[Vector] Fill large array and modify it") { + Vector<int> vector; + vector.resize(1'000'000); + vector.fill(0x60d07); + + vector.write[200] = 0; + CHECK(vector.size() == 1'000'000); + CHECK(vector[0] == 0x60d07); + CHECK(vector[200] == 0); + CHECK(vector[499'999] == 0x60d07); + CHECK(vector[999'999] == 0x60d07); + vector.remove(200); + CHECK(vector[200] == 0x60d07); + + vector.clear(); + CHECK(vector.size() == 0); +} + +TEST_CASE("[Vector] Copy creation") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + Vector<int> vector_other = Vector<int>(vector); + vector_other.remove(0); + CHECK(vector_other[0] == 1); + CHECK(vector_other[1] == 2); + CHECK(vector_other[2] == 3); + CHECK(vector_other[3] == 4); + + // Make sure the original vector isn't modified. + CHECK(vector[0] == 0); + CHECK(vector[1] == 1); + CHECK(vector[2] == 2); + CHECK(vector[3] == 3); + CHECK(vector[4] == 4); +} + +TEST_CASE("[Vector] Duplicate") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + Vector<int> vector_other = vector.duplicate(); + vector_other.remove(0); + CHECK(vector_other[0] == 1); + CHECK(vector_other[1] == 2); + CHECK(vector_other[2] == 3); + CHECK(vector_other[3] == 4); + + // Make sure the original vector isn't modified. + CHECK(vector[0] == 0); + CHECK(vector[1] == 1); + CHECK(vector[2] == 2); + CHECK(vector[3] == 3); + CHECK(vector[4] == 4); +} + +TEST_CASE("[Vector] Get, set") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + CHECK(vector.get(0) == 0); + CHECK(vector.get(1) == 1); + vector.set(2, 256); + CHECK(vector.get(2) == 256); + CHECK(vector.get(3) == 3); + + ERR_PRINT_OFF; + // Invalid (but should not crash): setting out of bounds. + vector.set(6, 500); + ERR_PRINT_ON; + + CHECK(vector.get(4) == 4); +} + +TEST_CASE("[Vector] To byte array") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(-1); + vector.push_back(2008); + vector.push_back(999999999); + + Vector<uint8_t> byte_array = vector.to_byte_array(); + CHECK(byte_array.size() == 16); + // vector[0] + CHECK(byte_array[0] == 0); + CHECK(byte_array[1] == 0); + CHECK(byte_array[2] == 0); + CHECK(byte_array[3] == 0); + + // vector[1] + CHECK(byte_array[4] == 255); + CHECK(byte_array[5] == 255); + CHECK(byte_array[6] == 255); + CHECK(byte_array[7] == 255); + + // vector[2] + CHECK(byte_array[8] == 216); + CHECK(byte_array[9] == 7); + CHECK(byte_array[10] == 0); + CHECK(byte_array[11] == 0); + + // vector[3] + CHECK(byte_array[12] == 255); + CHECK(byte_array[13] == 201); + CHECK(byte_array[14] == 154); + CHECK(byte_array[15] == 59); +} + +TEST_CASE("[Vector] Subarray") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + Vector<int> subarray1 = vector.subarray(1, 2); + CHECK(subarray1.size() == 2); + CHECK(subarray1[0] == 1); + CHECK(subarray1[1] == 2); + + Vector<int> subarray2 = vector.subarray(1, -1); + CHECK(subarray2.size() == 4); + CHECK(subarray2[0] == 1); + CHECK(subarray2[1] == 2); + CHECK(subarray2[2] == 3); + CHECK(subarray2[3] == 4); + + Vector<int> subarray3 = vector.subarray(-2, -1); + CHECK(subarray3.size() == 2); + CHECK(subarray3[0] == 3); + CHECK(subarray3[1] == 4); + + Vector<int> subarray4 = vector.subarray(-3, 3); + CHECK(subarray4.size() == 2); + CHECK(subarray4[0] == 2); + CHECK(subarray4[1] == 3); +} + +TEST_CASE("[Vector] Find, has") { + Vector<int> vector; + vector.push_back(3); + vector.push_back(1); + vector.push_back(4); + vector.push_back(0); + vector.push_back(2); + + CHECK(vector[0] == 3); + CHECK(vector[1] == 1); + CHECK(vector[2] == 4); + CHECK(vector[3] == 0); + CHECK(vector[4] == 2); + + CHECK(vector.find(0) == 3); + CHECK(vector.find(1) == 1); + CHECK(vector.find(2) == 4); + CHECK(vector.find(3) == 0); + CHECK(vector.find(4) == 2); + + CHECK(vector.find(-1) == -1); + CHECK(vector.find(5) == -1); + + CHECK(vector.has(0)); + CHECK(vector.has(1)); + CHECK(vector.has(2)); + CHECK(vector.has(3)); + CHECK(vector.has(4)); + + CHECK(!vector.has(-1)); + CHECK(!vector.has(5)); +} + +TEST_CASE("[Vector] Remove") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + vector.remove(0); + + CHECK(vector[0] == 1); + CHECK(vector[1] == 2); + CHECK(vector[2] == 3); + CHECK(vector[3] == 4); + + vector.remove(2); + + CHECK(vector[0] == 1); + CHECK(vector[1] == 2); + CHECK(vector[2] == 4); + + vector.remove(1); + + CHECK(vector[0] == 1); + CHECK(vector[1] == 4); + + vector.remove(0); + + CHECK(vector[0] == 4); +} + +TEST_CASE("[Vector] Remove and find") { + Vector<int> vector; + vector.push_back(0); + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + + CHECK(vector.size() == 5); + + vector.remove(0); + + CHECK(vector.size() == 4); + + CHECK(vector.find(0) == -1); + CHECK(vector.find(1) != -1); + CHECK(vector.find(2) != -1); + CHECK(vector.find(3) != -1); + CHECK(vector.find(4) != -1); + + vector.remove(vector.find(3)); + + CHECK(vector.size() == 3); + + CHECK(vector.find(3) == -1); + CHECK(vector.find(1) != -1); + CHECK(vector.find(2) != -1); + CHECK(vector.find(4) != -1); + + vector.remove(vector.find(2)); + + CHECK(vector.size() == 2); + + CHECK(vector.find(2) == -1); + CHECK(vector.find(1) != -1); + CHECK(vector.find(4) != -1); + + vector.remove(vector.find(4)); + + CHECK(vector.size() == 1); + + CHECK(vector.find(4) == -1); + CHECK(vector.find(1) != -1); + + vector.remove(0); + + CHECK(vector.is_empty()); + CHECK(vector.size() == 0); +} + +TEST_CASE("[Vector] Erase") { + Vector<int> vector; + vector.push_back(1); + vector.push_back(3); + vector.push_back(0); + vector.push_back(2); + vector.push_back(4); + + CHECK(vector.find(2) == 3); + + vector.erase(2); + + CHECK(vector.find(2) == -1); + CHECK(vector.size() == 4); +} + +TEST_CASE("[Vector] Size, resize, reserve") { + Vector<int> vector; + CHECK(vector.is_empty()); + CHECK(vector.size() == 0); + + vector.resize(10); + + CHECK(vector.size() == 10); + + vector.resize(5); + + CHECK(vector.size() == 5); + + vector.remove(0); + vector.remove(0); + vector.remove(0); + + CHECK(vector.size() == 2); + + vector.clear(); + + CHECK(vector.size() == 0); + CHECK(vector.is_empty()); + + vector.push_back(0); + vector.push_back(0); + vector.push_back(0); + + CHECK(vector.size() == 3); + + vector.push_back(0); + + CHECK(vector.size() == 4); +} + +TEST_CASE("[Vector] Sort") { + Vector<int> vector; + vector.push_back(2); + vector.push_back(8); + vector.push_back(-4); + vector.push_back(5); + vector.sort(); + + CHECK(vector.size() == 4); + CHECK(vector[0] == -4); + CHECK(vector[1] == 2); + CHECK(vector[2] == 5); + CHECK(vector[3] == 8); +} + +TEST_CASE("[Vector] Sort custom") { + Vector<String> vector; + vector.push_back("world"); + vector.push_back("World"); + vector.push_back("Hello"); + vector.push_back("10Hello"); + vector.push_back("12Hello"); + vector.push_back("01Hello"); + vector.push_back("1Hello"); + vector.push_back(".Hello"); + vector.sort_custom<NaturalNoCaseComparator>(); + + CHECK(vector.size() == 8); + CHECK(vector[0] == ".Hello"); + CHECK(vector[1] == "01Hello"); + CHECK(vector[2] == "1Hello"); + CHECK(vector[3] == "10Hello"); + CHECK(vector[4] == "12Hello"); + CHECK(vector[5] == "Hello"); + CHECK(vector[6] == "world"); + CHECK(vector[7] == "World"); +} + +TEST_CASE("[Vector] Operators") { + Vector<int> vector; + vector.push_back(2); + vector.push_back(8); + vector.push_back(-4); + vector.push_back(5); + + Vector<int> vector_other; + vector_other.push_back(2); + vector_other.push_back(8); + vector_other.push_back(-4); + vector_other.push_back(5); + + CHECK(vector == vector_other); + + vector_other.push_back(10); + CHECK(vector != vector_other); +} + +} // namespace TestVector + +#endif // TEST_VECTOR_H diff --git a/thirdparty/README.md b/thirdparty/README.md index 605b298ac1..03a2ddf5e4 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -8,13 +8,12 @@ readability. ## basis_universal - Upstream: https://github.com/BinomialLLC/basis_universal -- Version: git (895ee8ee7e04f22267f8d16d46de04d5a01d63ac, 2020) +- Version: git (ba1c3e40f1d434ebaf9a167b44e9b11d2bf0f765, 2021) - License: Apache 2.0 Files extracted from upstream source: -- `.cpp` and `.h` files in root folder except for `basisu_tool.cpp` (contains `main` and can cause link error) -- `.cpp`, `.h` and `.inc` files in `transcoder/`, keeping folder structure +- `encoder/` and `transcoder/` folders - `LICENSE` @@ -62,10 +61,10 @@ Files extracted from upstream source: Extracted from .zip provided. Extracted license and header only. -## embree-aarch64 +## embree -- Upstream: https://github.com/lighttransport/embree-aarch64 -- Version: 3.12.1 (6ef362f99af80c9dfe8dd2bfc582d9067897edc6, 2020) +- Upstream: https://github.com/embree/embree +- Version: 3.13.0 (7c53133eb21424f7f0ae1e25bf357e358feaf6ab, 2021) - License: Apache 2.0 Files extracted from upstream: @@ -73,8 +72,8 @@ Files extracted from upstream: - All cpp files listed in `modules/raycast/godot_update_embree.py` - All header files in the directories listed in `modules/raycast/godot_update_embree.py` -The `modules/raycast/godot_update_embree.py`script can be used to pull the -relevant files from the latest Embree-aarch64 release and apply some automatic changes. +The `modules/raycast/godot_update_embree.py` script can be used to pull the +relevant files from the latest Embree release and apply some automatic changes. Some changes have been made in order to remove exceptions and fix minor build errors. They are marked with `// -- GODOT start --` and `// -- GODOT end --` @@ -138,6 +137,10 @@ Files extracted from upstream source: * Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/ * Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted) * License: Apache 2.0 +- `OpenSans_SemiBold.ttf`: + * Upstream: https://fonts.google.com/specimen/Open+Sans + * Version: 1.10 (downloaded from Google Fonts in February 2021) + * License: Apache 2.0 - `Tamsyn*.png`: * Upstream: http://www.fial.com/~scott/tamsyn-font/ * Version: 1.11 (2015) @@ -364,7 +367,7 @@ File extracted from upstream release tarball: ## meshoptimizer - Upstream: https://github.com/zeux/meshoptimizer -- Version: 0.16 (95893c0566646434dd675b708d293fcb2d526d08, 2021) +- Version: git (f5d83e879c48f8664783a69b4f50711d27549b66, 2021) - License: MIT Files extracted from upstream repository: @@ -372,6 +375,9 @@ Files extracted from upstream repository: - All files in `src/`. - `LICENSE.md`. +An [experimental upstream feature](https://github.com/zeux/meshoptimizer/tree/simplify-attr), +has been backported, see patch in `patches` directory. + ## miniupnpc @@ -463,6 +469,10 @@ Collection of single-file libraries used in Godot components. * Version: git (2f625846a775501fb69456567409a8b12f10ea25, 2012) * License: BSD-3-Clause * Modifications: use `const char*` instead of `char*` for input string +- `smolv.h` + * Upstream: https://github.com/aras-p/smol-v + * Version: git (4b52c165c13763051a18e80ffbc2ee436314ceb2, 2020) + * License: Public Domain or MIT - `stb_rect_pack.h` * Upstream: https://github.com/nothings/stb * Version: 1.00 (2bb4a0accd4003c1db4c24533981e01b1adfd656, 2019) @@ -725,3 +735,4 @@ Files extracted from upstream source: - lib/{common/,compress/,decompress/,zstd.h} - LICENSE + diff --git a/thirdparty/basis_universal/basisu_comp.cpp b/thirdparty/basis_universal/basisu_comp.cpp deleted file mode 100644 index 1e4679311c..0000000000 --- a/thirdparty/basis_universal/basisu_comp.cpp +++ /dev/null @@ -1,1206 +0,0 @@ -// basisu_comp.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "basisu_comp.h" -#include "basisu_enc.h" -#include <unordered_set> - -#define BASISU_USE_STB_IMAGE_RESIZE_FOR_MIPMAP_GEN 0 -#define DEBUG_CROP_TEXTURE_TO_64x64 (0) -#define DEBUG_RESIZE_TEXTURE (0) -#define DEBUG_EXTRACT_SINGLE_BLOCK (0) - -namespace basisu -{ - basis_compressor::basis_compressor() : - m_total_blocks(0), - m_auto_global_sel_pal(false), - m_basis_file_size(0), - m_basis_bits_per_texel(0), - m_any_source_image_has_alpha(false) - { - debug_printf("basis_compressor::basis_compressor\n"); - } - - bool basis_compressor::init(const basis_compressor_params ¶ms) - { - debug_printf("basis_compressor::init\n"); - - m_params = params; - - if (m_params.m_debug) - { - debug_printf("basis_compressor::init:\n"); - -#define PRINT_BOOL_VALUE(v) debug_printf("%s: %u %u\n", BASISU_STRINGIZE2(v), static_cast<int>(m_params.v), m_params.v.was_changed()); -#define PRINT_INT_VALUE(v) debug_printf("%s: %i %u\n", BASISU_STRINGIZE2(v), static_cast<int>(m_params.v), m_params.v.was_changed()); -#define PRINT_UINT_VALUE(v) debug_printf("%s: %u %u\n", BASISU_STRINGIZE2(v), static_cast<uint32_t>(m_params.v), m_params.v.was_changed()); -#define PRINT_FLOAT_VALUE(v) debug_printf("%s: %f %u\n", BASISU_STRINGIZE2(v), static_cast<float>(m_params.v), m_params.v.was_changed()); - - debug_printf("Has global selector codebook: %i\n", m_params.m_pSel_codebook != nullptr); - - debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i\n", - (uint32_t)m_params.m_source_images.size(), (uint32_t)m_params.m_source_filenames.size(), (uint32_t)m_params.m_source_alpha_filenames.size()); - - PRINT_BOOL_VALUE(m_y_flip); - PRINT_BOOL_VALUE(m_debug); - PRINT_BOOL_VALUE(m_debug_images); - PRINT_BOOL_VALUE(m_global_sel_pal); - PRINT_BOOL_VALUE(m_auto_global_sel_pal); - PRINT_BOOL_VALUE(m_compression_level); - PRINT_BOOL_VALUE(m_no_hybrid_sel_cb); - PRINT_BOOL_VALUE(m_perceptual); - PRINT_BOOL_VALUE(m_no_endpoint_rdo); - PRINT_BOOL_VALUE(m_no_selector_rdo); - PRINT_BOOL_VALUE(m_read_source_images); - PRINT_BOOL_VALUE(m_write_output_basis_files); - PRINT_BOOL_VALUE(m_compute_stats); - PRINT_BOOL_VALUE(m_check_for_alpha) - PRINT_BOOL_VALUE(m_force_alpha) - PRINT_BOOL_VALUE(m_seperate_rg_to_color_alpha); - PRINT_BOOL_VALUE(m_multithreading); - PRINT_BOOL_VALUE(m_disable_hierarchical_endpoint_codebooks); - - PRINT_FLOAT_VALUE(m_hybrid_sel_cb_quality_thresh); - - PRINT_INT_VALUE(m_global_pal_bits); - PRINT_INT_VALUE(m_global_mod_bits); - - PRINT_FLOAT_VALUE(m_endpoint_rdo_thresh); - PRINT_FLOAT_VALUE(m_selector_rdo_thresh); - - PRINT_BOOL_VALUE(m_mip_gen); - PRINT_BOOL_VALUE(m_mip_renormalize); - PRINT_BOOL_VALUE(m_mip_wrapping); - PRINT_BOOL_VALUE(m_mip_srgb); - PRINT_FLOAT_VALUE(m_mip_premultiplied); - PRINT_FLOAT_VALUE(m_mip_scale); - PRINT_INT_VALUE(m_mip_smallest_dimension); - debug_printf("m_mip_filter: %s\n", m_params.m_mip_filter.c_str()); - - debug_printf("m_max_endpoint_clusters: %u\n", m_params.m_max_endpoint_clusters); - debug_printf("m_max_selector_clusters: %u\n", m_params.m_max_selector_clusters); - debug_printf("m_quality_level: %i\n", m_params.m_quality_level); - - debug_printf("m_tex_type: %u\n", m_params.m_tex_type); - debug_printf("m_userdata0: 0x%X, m_userdata1: 0x%X\n", m_params.m_userdata0, m_params.m_userdata1); - debug_printf("m_us_per_frame: %i (%f fps)\n", m_params.m_us_per_frame, m_params.m_us_per_frame ? 1.0f / (m_params.m_us_per_frame / 1000000.0f) : 0); - -#undef PRINT_BOOL_VALUE -#undef PRINT_INT_VALUE -#undef PRINT_UINT_VALUE -#undef PRINT_FLOAT_VALUE - } - - if ((m_params.m_read_source_images) && (!m_params.m_source_filenames.size())) - { - assert(0); - return false; - } - - return true; - } - - basis_compressor::error_code basis_compressor::process() - { - debug_printf("basis_compressor::process\n"); - - if (!read_source_images()) - return cECFailedReadingSourceImages; - - if (!validate_texture_type_constraints()) - return cECFailedValidating; - - if (!process_frontend()) - return cECFailedFrontEnd; - - if (!extract_frontend_texture_data()) - return cECFailedFontendExtract; - - if (!process_backend()) - return cECFailedBackend; - - if (!create_basis_file_and_transcode()) - return cECFailedCreateBasisFile; - - if (!write_output_files_and_compute_stats()) - return cECFailedWritingOutput; - - return cECSuccess; - } - - bool basis_compressor::generate_mipmaps(const image &img, std::vector<image> &mips, bool has_alpha) - { - debug_printf("basis_compressor::generate_mipmaps\n"); - - uint32_t total_levels = 1; - uint32_t w = img.get_width(), h = img.get_height(); - while (maximum<uint32_t>(w, h) > (uint32_t)m_params.m_mip_smallest_dimension) - { - w = maximum(w >> 1U, 1U); - h = maximum(h >> 1U, 1U); - total_levels++; - } - -#if BASISU_USE_STB_IMAGE_RESIZE_FOR_MIPMAP_GEN - // Requires stb_image_resize - stbir_filter filter = STBIR_FILTER_DEFAULT; - if (m_params.m_mip_filter == "box") - filter = STBIR_FILTER_BOX; - else if (m_params.m_mip_filter == "triangle") - filter = STBIR_FILTER_TRIANGLE; - else if (m_params.m_mip_filter == "cubic") - filter = STBIR_FILTER_CUBICBSPLINE; - else if (m_params.m_mip_filter == "catmull") - filter = STBIR_FILTER_CATMULLROM; - else if (m_params.m_mip_filter == "mitchell") - filter = STBIR_FILTER_MITCHELL; - - for (uint32_t level = 1; level < total_levels; level++) - { - const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level); - const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level); - - image &level_img = *enlarge_vector(mips, 1); - level_img.resize(level_width, level_height); - - int result = stbir_resize_uint8_generic( - (const uint8_t *)img.get_ptr(), img.get_width(), img.get_height(), img.get_pitch() * sizeof(color_rgba), - (uint8_t *)level_img.get_ptr(), level_img.get_width(), level_img.get_height(), level_img.get_pitch() * sizeof(color_rgba), - has_alpha ? 4 : 3, has_alpha ? 3 : STBIR_ALPHA_CHANNEL_NONE, m_params.m_mip_premultiplied ? STBIR_FLAG_ALPHA_PREMULTIPLIED : 0, - m_params.m_mip_wrapping ? STBIR_EDGE_WRAP : STBIR_EDGE_CLAMP, filter, m_params.m_mip_srgb ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, - nullptr); - - if (result == 0) - { - error_printf("basis_compressor::generate_mipmaps: stbir_resize_uint8_generic() failed!\n"); - return false; - } - - if (m_params.m_mip_renormalize) - level_img.renormalize_normal_map(); - } -#else - for (uint32_t level = 1; level < total_levels; level++) - { - const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level); - const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level); - - image &level_img = *enlarge_vector(mips, 1); - level_img.resize(level_width, level_height); - - bool status = image_resample(img, level_img, m_params.m_mip_srgb, m_params.m_mip_filter.c_str(), m_params.m_mip_scale, m_params.m_mip_wrapping, 0, has_alpha ? 4 : 3); - if (!status) - { - error_printf("basis_compressor::generate_mipmaps: image_resample() failed!\n"); - return false; - } - - if (m_params.m_mip_renormalize) - level_img.renormalize_normal_map(); - } -#endif - - return true; - } - - bool basis_compressor::read_source_images() - { - debug_printf("basis_compressor::read_source_images\n"); - - const uint32_t total_source_files = m_params.m_read_source_images ? (uint32_t)m_params.m_source_filenames.size() : (uint32_t)m_params.m_source_images.size(); - if (!total_source_files) - return false; - - m_stats.resize(0); - m_slice_descs.resize(0); - m_slice_images.resize(0); - - m_total_blocks = 0; - uint32_t total_macroblocks = 0; - - m_any_source_image_has_alpha = false; - - std::vector<image> source_images; - std::vector<std::string> source_filenames; - - // First load all source images, and determine if any have an alpha channel. - for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) - { - const char *pSource_filename = ""; - - image file_image; - - if (m_params.m_read_source_images) - { - pSource_filename = m_params.m_source_filenames[source_file_index].c_str(); - - // Load the source image - if (!load_png(pSource_filename, file_image)) - { - error_printf("Failed reading source image: %s\n", pSource_filename); - return false; - } - - printf("Read source image \"%s\", %ux%u\n", pSource_filename, file_image.get_width(), file_image.get_height()); - - // Optionally load another image and put a grayscale version of it into the alpha channel. - if ((source_file_index < m_params.m_source_alpha_filenames.size()) && (m_params.m_source_alpha_filenames[source_file_index].size())) - { - const char *pSource_alpha_image = m_params.m_source_alpha_filenames[source_file_index].c_str(); - - image alpha_data; - - if (!load_png(pSource_alpha_image, alpha_data)) - { - error_printf("Failed reading source image: %s\n", pSource_alpha_image); - return false; - } - - printf("Read source alpha image \"%s\", %ux%u\n", pSource_alpha_image, alpha_data.get_width(), alpha_data.get_height()); - - alpha_data.crop(file_image.get_width(), file_image.get_height()); - - for (uint32_t y = 0; y < file_image.get_height(); y++) - for (uint32_t x = 0; x < file_image.get_width(); x++) - file_image(x, y).a = (uint8_t)alpha_data(x, y).get_709_luma(); - } - } - else - { - file_image = m_params.m_source_images[source_file_index]; - } - - if (m_params.m_seperate_rg_to_color_alpha) - { - // Used for XY normal maps in RG - puts X in color, Y in alpha - for (uint32_t y = 0; y < file_image.get_height(); y++) - for (uint32_t x = 0; x < file_image.get_width(); x++) - { - const color_rgba &c = file_image(x, y); - file_image(x, y).set_noclamp_rgba(c.r, c.r, c.r, c.g); - } - } - - bool has_alpha = false; - if ((m_params.m_force_alpha) || (m_params.m_seperate_rg_to_color_alpha)) - has_alpha = true; - else if (!m_params.m_check_for_alpha) - file_image.set_alpha(255); - else if (file_image.has_alpha()) - has_alpha = true; - - if (has_alpha) - m_any_source_image_has_alpha = true; - - debug_printf("Source image index %u filename %s %ux%u has alpha: %u\n", source_file_index, pSource_filename, file_image.get_width(), file_image.get_height(), has_alpha); - - if (m_params.m_y_flip) - file_image.flip_y(); - -#if DEBUG_EXTRACT_SINGLE_BLOCK - image block_image(4, 4); - const uint32_t block_x = 0; - const uint32_t block_y = 0; - block_image.blit(block_x * 4, block_y * 4, 4, 4, 0, 0, file_image, 0); - file_image = block_image; -#endif - -#if DEBUG_CROP_TEXTURE_TO_64x64 - file_image.resize(64, 64); -#endif -#if DEBUG_RESIZE_TEXTURE - image temp_img((file_image.get_width() + 1) / 2, (file_image.get_height() + 1) / 2); - image_resample(file_image, temp_img, m_params.m_perceptual, "kaiser"); - temp_img.swap(file_image); -#endif - - if ((!file_image.get_width()) || (!file_image.get_height())) - { - error_printf("basis_compressor::read_source_images: Source image has a zero width and/or height!\n"); - return false; - } - - if ((file_image.get_width() > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION) || (file_image.get_height() > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION)) - { - error_printf("basis_compressor::read_source_images: Source image is too large!\n"); - return false; - } - - source_images.push_back(file_image); - source_filenames.push_back(pSource_filename); - } - - debug_printf("Any source image has alpha: %u\n", m_any_source_image_has_alpha); - - for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) - { - image &file_image = source_images[source_file_index]; - const std::string &source_filename = source_filenames[source_file_index]; - - std::vector<image> slices; - - slices.reserve(32); - slices.push_back(file_image); - - if (m_params.m_mip_gen) - { - if (!generate_mipmaps(file_image, slices, m_any_source_image_has_alpha)) - return false; - } - - uint_vec mip_indices(slices.size()); - for (uint32_t i = 0; i < slices.size(); i++) - mip_indices[i] = i; - - if (m_any_source_image_has_alpha) - { - // If source has alpha, then even mips will have RGB, and odd mips will have alpha in RGB. - std::vector<image> alpha_slices; - uint_vec new_mip_indices; - - alpha_slices.reserve(slices.size() * 2); - - for (uint32_t i = 0; i < slices.size(); i++) - { - image lvl_rgb(slices[i]); - image lvl_a(lvl_rgb); - - for (uint32_t y = 0; y < lvl_a.get_height(); y++) - { - for (uint32_t x = 0; x < lvl_a.get_width(); x++) - { - uint8_t a = lvl_a(x, y).a; - lvl_a(x, y).set_noclamp_rgba(a, a, a, 255); - } - } - - lvl_rgb.set_alpha(255); - - alpha_slices.push_back(lvl_rgb); - new_mip_indices.push_back(i); - - alpha_slices.push_back(lvl_a); - new_mip_indices.push_back(i); - } - - slices.swap(alpha_slices); - mip_indices.swap(new_mip_indices); - } - - assert(slices.size() == mip_indices.size()); - - for (uint32_t slice_index = 0; slice_index < slices.size(); slice_index++) - { - const bool is_alpha_slice = m_any_source_image_has_alpha && ((slice_index & 1) != 0); - - image &slice_image = slices[slice_index]; - const uint32_t orig_width = slice_image.get_width(); - const uint32_t orig_height = slice_image.get_height(); - - // Enlarge the source image to 4x4 block boundaries, duplicating edge pixels if necessary to avoid introducing extra colors into blocks. - slice_image.crop_dup_borders(slice_image.get_block_width(4) * 4, slice_image.get_block_height(4) * 4); - - if (m_params.m_debug_images) - { - save_png(string_format("basis_debug_source_image_%u_%u.png", source_file_index, slice_index).c_str(), slice_image); - } - - enlarge_vector(m_stats, 1); - enlarge_vector(m_slice_images, 1); - enlarge_vector(m_slice_descs, 1); - - const uint32_t dest_image_index = (uint32_t)m_stats.size() - 1; - - m_stats[dest_image_index].m_filename = source_filename.c_str(); - m_stats[dest_image_index].m_width = orig_width; - m_stats[dest_image_index].m_height = orig_height; - - m_slice_images[dest_image_index] = slice_image; - - debug_printf("****** Slice %u: mip %u, alpha_slice: %u, filename: \"%s\", original: %ux%u actual: %ux%u\n", m_slice_descs.size() - 1, mip_indices[slice_index], is_alpha_slice, source_filename.c_str(), orig_width, orig_height, slice_image.get_width(), slice_image.get_height()); - - basisu_backend_slice_desc &slice_desc = m_slice_descs[dest_image_index]; - - slice_desc.m_first_block_index = m_total_blocks; - - slice_desc.m_orig_width = orig_width; - slice_desc.m_orig_height = orig_height; - - slice_desc.m_width = slice_image.get_width(); - slice_desc.m_height = slice_image.get_height(); - - slice_desc.m_num_blocks_x = slice_image.get_block_width(4); - slice_desc.m_num_blocks_y = slice_image.get_block_height(4); - - slice_desc.m_num_macroblocks_x = (slice_desc.m_num_blocks_x + 1) >> 1; - slice_desc.m_num_macroblocks_y = (slice_desc.m_num_blocks_y + 1) >> 1; - - slice_desc.m_source_file_index = source_file_index; - - slice_desc.m_mip_index = mip_indices[slice_index]; - - slice_desc.m_alpha = is_alpha_slice; - slice_desc.m_iframe = false; - if (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames) - { - slice_desc.m_iframe = (source_file_index == 0); - } - - m_total_blocks += slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y; - total_macroblocks += slice_desc.m_num_macroblocks_x * slice_desc.m_num_macroblocks_y; - - } // slice_index - - } // source_file_index - - debug_printf("Total blocks: %u, Total macroblocks: %u\n", m_total_blocks, total_macroblocks); - - // Make sure we don't have too many slices - if (m_slice_descs.size() > BASISU_MAX_SLICES) - { - error_printf("Too many slices!\n"); - return false; - } - - // Basic sanity check on the slices - for (uint32_t i = 1; i < m_slice_descs.size(); i++) - { - const basisu_backend_slice_desc &prev_slice_desc = m_slice_descs[i - 1]; - const basisu_backend_slice_desc &slice_desc = m_slice_descs[i]; - - // Make sure images are in order - int image_delta = (int)slice_desc.m_source_file_index - (int)prev_slice_desc.m_source_file_index; - if (image_delta > 1) - return false; - - // Make sure mipmap levels are in order - if (!image_delta) - { - int level_delta = (int)slice_desc.m_mip_index - (int)prev_slice_desc.m_mip_index; - if (level_delta > 1) - return false; - } - } - - printf("Total basis file slices: %u\n", (uint32_t)m_slice_descs.size()); - - for (uint32_t i = 0; i < m_slice_descs.size(); i++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[i]; - - printf("Slice: %u, alpha: %u, orig width/height: %ux%u, width/height: %ux%u, first_block: %u, image_index: %u, mip_level: %u, iframe: %u\n", - i, slice_desc.m_alpha, slice_desc.m_orig_width, slice_desc.m_orig_height, slice_desc.m_width, slice_desc.m_height, slice_desc.m_first_block_index, slice_desc.m_source_file_index, slice_desc.m_mip_index, slice_desc.m_iframe); - - if (m_any_source_image_has_alpha) - { - // Alpha slices must be at odd slice indices - if (slice_desc.m_alpha) - { - if ((i & 1) == 0) - return false; - - const basisu_backend_slice_desc &prev_slice_desc = m_slice_descs[i - 1]; - - // Make sure previous slice has this image's color data - if (prev_slice_desc.m_source_file_index != slice_desc.m_source_file_index) - return false; - if (prev_slice_desc.m_alpha) - return false; - if (prev_slice_desc.m_mip_index != slice_desc.m_mip_index) - return false; - if (prev_slice_desc.m_num_blocks_x != slice_desc.m_num_blocks_x) - return false; - if (prev_slice_desc.m_num_blocks_y != slice_desc.m_num_blocks_y) - return false; - } - else if (i & 1) - return false; - } - else if (slice_desc.m_alpha) - { - return false; - } - - if ((slice_desc.m_orig_width > slice_desc.m_width) || (slice_desc.m_orig_height > slice_desc.m_height)) - return false; - if ((slice_desc.m_source_file_index == 0) && (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames)) - { - if (!slice_desc.m_iframe) - return false; - } - } - - return true; - } - - // Do some basic validation for 2D arrays, cubemaps, video, and volumes. - bool basis_compressor::validate_texture_type_constraints() - { - debug_printf("basis_compressor::validate_texture_type_constraints\n"); - - // In 2D mode anything goes (each image may have a different resolution and # of mipmap levels). - if (m_params.m_tex_type == basist::cBASISTexType2D) - return true; - - uint32_t total_basis_images = 0; - - for (uint32_t slice_index = 0; slice_index < m_slice_images.size(); slice_index++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; - - total_basis_images = maximum<uint32_t>(total_basis_images, slice_desc.m_source_file_index + 1); - } - - if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray) - { - // For cubemaps, validate that the total # of Basis images is a multiple of 6. - if ((total_basis_images % 6) != 0) - { - error_printf("basis_compressor::validate_texture_type_constraints: For cubemaps the total number of input images is not a multiple of 6!\n"); - return false; - } - } - - // Now validate that all the mip0's have the same dimensions, and that each image has the same # of mipmap levels. - uint_vec image_mipmap_levels(total_basis_images); - - int width = -1, height = -1; - for (uint32_t slice_index = 0; slice_index < m_slice_images.size(); slice_index++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; - - image_mipmap_levels[slice_desc.m_source_file_index] = maximum(image_mipmap_levels[slice_desc.m_source_file_index], slice_desc.m_mip_index + 1); - - if (slice_desc.m_mip_index != 0) - continue; - - if (width < 0) - { - width = slice_desc.m_orig_width; - height = slice_desc.m_orig_height; - } - else if ((width != (int)slice_desc.m_orig_width) || (height != (int)slice_desc.m_orig_height)) - { - error_printf("basis_compressor::validate_texture_type_constraints: The source image resolutions are not all equal!\n"); - return false; - } - } - - for (size_t i = 1; i < image_mipmap_levels.size(); i++) - { - if (image_mipmap_levels[0] != image_mipmap_levels[i]) - { - error_printf("basis_compressor::validate_texture_type_constraints: Each image must have the same number of mipmap levels!\n"); - return false; - } - } - - return true; - } - - bool basis_compressor::process_frontend() - { - debug_printf("basis_compressor::process_frontend\n"); - - m_source_blocks.resize(m_total_blocks); - - for (uint32_t slice_index = 0; slice_index < m_slice_images.size(); slice_index++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; - - const uint32_t num_blocks_x = slice_desc.m_num_blocks_x; - const uint32_t num_blocks_y = slice_desc.m_num_blocks_y; - - const image &source_image = m_slice_images[slice_index]; - - for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) - for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) - source_image.extract_block_clamped(m_source_blocks[slice_desc.m_first_block_index + block_x + block_y * num_blocks_x].get_ptr(), block_x * 4, block_y * 4, 4, 4); - } - -#if 0 - // TODO - basis_etc1_pack_params pack_params; - pack_params.m_quality = cETCQualityMedium; - pack_params.m_perceptual = m_params.m_perceptual; - pack_params.m_use_color4 = false; - - pack_etc1_block_context pack_context; - - std::unordered_set<uint64_t> endpoint_hash; - std::unordered_set<uint32_t> selector_hash; - - for (uint32_t i = 0; i < m_source_blocks.size(); i++) - { - etc_block blk; - pack_etc1_block(blk, m_source_blocks[i].get_ptr(), pack_params, pack_context); - - const color_rgba c0(blk.get_block_color(0, false)); - endpoint_hash.insert((c0.r | (c0.g << 5) | (c0.b << 10)) | (blk.get_inten_table(0) << 16)); - - const color_rgba c1(blk.get_block_color(1, false)); - endpoint_hash.insert((c1.r | (c1.g << 5) | (c1.b << 10)) | (blk.get_inten_table(1) << 16)); - - selector_hash.insert(blk.get_raw_selector_bits()); - } - - const uint32_t total_unique_endpoints = (uint32_t)endpoint_hash.size(); - const uint32_t total_unique_selectors = (uint32_t)selector_hash.size(); - - if (m_params.m_debug) - { - debug_printf("Unique endpoints: %u, unique selectors: %u\n", total_unique_endpoints, total_unique_selectors); - } -#endif - - const double total_texels = m_total_blocks * 16.0f; - - int endpoint_clusters = m_params.m_max_endpoint_clusters; - int selector_clusters = m_params.m_max_selector_clusters; - - if (endpoint_clusters > basisu_frontend::cMaxEndpointClusters) - { - error_printf("Too many endpoint clusters! (%u but max is %u)\n", endpoint_clusters, basisu_frontend::cMaxEndpointClusters); - return false; - } - if (selector_clusters > basisu_frontend::cMaxSelectorClusters) - { - error_printf("Too many selector clusters! (%u but max is %u)\n", selector_clusters, basisu_frontend::cMaxSelectorClusters); - return false; - } - - if (m_params.m_quality_level != -1) - { - const float quality = saturate(m_params.m_quality_level / 255.0f); - - const float bits_per_endpoint_cluster = 14.0f; - const float max_desired_endpoint_cluster_bits_per_texel = 1.0f; // .15f - int max_endpoints = static_cast<int>((max_desired_endpoint_cluster_bits_per_texel * total_texels) / bits_per_endpoint_cluster); - - const float mid = 128.0f / 255.0f; - - float color_endpoint_quality = quality; - - const float endpoint_split_point = 0.5f; - if (color_endpoint_quality <= mid) - { - color_endpoint_quality = lerp(0.0f, endpoint_split_point, powf(color_endpoint_quality / mid, .65f)); - - max_endpoints = clamp<int>(max_endpoints, 256, 3072); - max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks); - - if (max_endpoints < 64) - max_endpoints = 64; - endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(32, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters); - } - else - { - color_endpoint_quality = powf((color_endpoint_quality - mid) / (1.0f - mid), 1.6f); - - max_endpoints = clamp<int>(max_endpoints, 256, 8192); - max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks); - - if (max_endpoints < 3072) - max_endpoints = 3072; - endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(3072, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters); - } - - float bits_per_selector_cluster = m_params.m_global_sel_pal ? 21.0f : 14.0f; - - const float max_desired_selector_cluster_bits_per_texel = 1.0f; // .15f - int max_selectors = static_cast<int>((max_desired_selector_cluster_bits_per_texel * total_texels) / bits_per_selector_cluster); - max_selectors = clamp<int>(max_selectors, 256, basisu_frontend::cMaxSelectorClusters); - max_selectors = minimum<uint32_t>(max_selectors, m_total_blocks); - - float color_selector_quality = quality; - //color_selector_quality = powf(color_selector_quality, 1.65f); - color_selector_quality = powf(color_selector_quality, 2.62f); - - if (max_selectors < 96) - max_selectors = 96; - selector_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(96, static_cast<float>(max_selectors), color_selector_quality)), 8, basisu_frontend::cMaxSelectorClusters); - - debug_printf("Max endpoints: %u, max selectors: %u\n", endpoint_clusters, selector_clusters); - - if (m_params.m_quality_level >= 223) - { - if (!m_params.m_selector_rdo_thresh.was_changed()) - { - if (!m_params.m_endpoint_rdo_thresh.was_changed()) - m_params.m_endpoint_rdo_thresh *= .25f; - - if (!m_params.m_selector_rdo_thresh.was_changed()) - m_params.m_selector_rdo_thresh *= .25f; - } - } - else if (m_params.m_quality_level >= 192) - { - if (!m_params.m_endpoint_rdo_thresh.was_changed()) - m_params.m_endpoint_rdo_thresh *= .5f; - - if (!m_params.m_selector_rdo_thresh.was_changed()) - m_params.m_selector_rdo_thresh *= .5f; - } - else if (m_params.m_quality_level >= 160) - { - if (!m_params.m_endpoint_rdo_thresh.was_changed()) - m_params.m_endpoint_rdo_thresh *= .75f; - - if (!m_params.m_selector_rdo_thresh.was_changed()) - m_params.m_selector_rdo_thresh *= .75f; - } - else if (m_params.m_quality_level >= 129) - { - float l = (quality - 129 / 255.0f) / ((160 - 129) / 255.0f); - - if (!m_params.m_endpoint_rdo_thresh.was_changed()) - m_params.m_endpoint_rdo_thresh *= lerp<float>(1.0f, .75f, l); - - if (!m_params.m_selector_rdo_thresh.was_changed()) - m_params.m_selector_rdo_thresh *= lerp<float>(1.0f, .75f, l); - } - } - - m_auto_global_sel_pal = false; - if (!m_params.m_global_sel_pal && m_params.m_auto_global_sel_pal) - { - const float bits_per_selector_cluster = 31.0f; - double selector_codebook_bpp_est = (bits_per_selector_cluster * selector_clusters) / total_texels; - debug_printf("selector_codebook_bpp_est: %f\n", selector_codebook_bpp_est); - const float force_global_sel_pal_bpp_threshold = .15f; - if ((total_texels <= 128.0f*128.0f) && (selector_codebook_bpp_est > force_global_sel_pal_bpp_threshold)) - { - m_auto_global_sel_pal = true; - debug_printf("Auto global selector palette enabled\n"); - } - } - - basisu_frontend::params p; - p.m_num_source_blocks = m_total_blocks; - p.m_pSource_blocks = &m_source_blocks[0]; - p.m_max_endpoint_clusters = endpoint_clusters; - p.m_max_selector_clusters = selector_clusters; - p.m_perceptual = m_params.m_perceptual; - p.m_debug_stats = m_params.m_debug; - p.m_debug_images = m_params.m_debug_images; - p.m_compression_level = m_params.m_compression_level; - p.m_tex_type = m_params.m_tex_type; - p.m_multithreaded = m_params.m_multithreading; - p.m_disable_hierarchical_endpoint_codebooks = m_params.m_disable_hierarchical_endpoint_codebooks; - p.m_pJob_pool = m_params.m_pJob_pool; - - if ((m_params.m_global_sel_pal) || (m_auto_global_sel_pal)) - { - p.m_pGlobal_sel_codebook = m_params.m_pSel_codebook; - p.m_num_global_sel_codebook_pal_bits = m_params.m_global_pal_bits; - p.m_num_global_sel_codebook_mod_bits = m_params.m_global_mod_bits; - p.m_use_hybrid_selector_codebooks = !m_params.m_no_hybrid_sel_cb; - p.m_hybrid_codebook_quality_thresh = m_params.m_hybrid_sel_cb_quality_thresh; - } - - if (!m_frontend.init(p)) - { - error_printf("basisu_frontend::init() failed!\n"); - return false; - } - - m_frontend.compress(); - - if (m_params.m_debug_images) - { - for (uint32_t i = 0; i < m_slice_descs.size(); i++) - { - char filename[1024]; -#ifdef _WIN32 - sprintf_s(filename, sizeof(filename), "rdo_frontend_output_output_blocks_%u.png", i); -#else - snprintf(filename, sizeof(filename), "rdo_frontend_output_output_blocks_%u.png", i); -#endif - m_frontend.dump_debug_image(filename, m_slice_descs[i].m_first_block_index, m_slice_descs[i].m_num_blocks_x, m_slice_descs[i].m_num_blocks_y, true); - -#ifdef _WIN32 - sprintf_s(filename, sizeof(filename), "rdo_frontend_output_api_%u.png", i); -#else - snprintf(filename, sizeof(filename), "rdo_frontend_output_api_%u.png", i); -#endif - m_frontend.dump_debug_image(filename, m_slice_descs[i].m_first_block_index, m_slice_descs[i].m_num_blocks_x, m_slice_descs[i].m_num_blocks_y, false); - } - } - - return true; - } - - bool basis_compressor::extract_frontend_texture_data() - { - debug_printf("basis_compressor::extract_frontend_texture_data\n"); - - m_frontend_output_textures.resize(m_slice_descs.size()); - m_best_etc1s_images.resize(m_slice_descs.size()); - m_best_etc1s_images_unpacked.resize(m_slice_descs.size()); - - for (uint32_t i = 0; i < m_slice_descs.size(); i++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[i]; - - const uint32_t num_blocks_x = slice_desc.m_num_blocks_x; - const uint32_t num_blocks_y = slice_desc.m_num_blocks_y; - - const uint32_t width = num_blocks_x * 4; - const uint32_t height = num_blocks_y * 4; - - m_frontend_output_textures[i].init(texture_format::cETC1, width, height); - - for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) - for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) - memcpy(m_frontend_output_textures[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_output_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block)); - -#if 0 - if (m_params.m_debug_images) - { - char filename[1024]; - sprintf_s(filename, sizeof(filename), "rdo_etc_frontend_%u_", i); - write_etc1_vis_images(m_frontend_output_textures[i], filename); - } -#endif - - m_best_etc1s_images[i].init(texture_format::cETC1, width, height); - for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) - for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) - memcpy(m_best_etc1s_images[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_etc1s_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block)); - - m_best_etc1s_images[i].unpack(m_best_etc1s_images_unpacked[i]); - } - - return true; - } - - bool basis_compressor::process_backend() - { - debug_printf("basis_compressor::process_backend\n"); - - basisu_backend_params backend_params; - backend_params.m_debug = m_params.m_debug; - backend_params.m_debug_images = m_params.m_debug_images; - backend_params.m_etc1s = true; - backend_params.m_compression_level = m_params.m_compression_level; - - if (!m_params.m_no_endpoint_rdo) - backend_params.m_endpoint_rdo_quality_thresh = m_params.m_endpoint_rdo_thresh; - - if (!m_params.m_no_selector_rdo) - backend_params.m_selector_rdo_quality_thresh = m_params.m_selector_rdo_thresh; - - backend_params.m_use_global_sel_codebook = (m_frontend.get_params().m_pGlobal_sel_codebook != NULL); - backend_params.m_global_sel_codebook_pal_bits = m_frontend.get_params().m_num_global_sel_codebook_pal_bits; - backend_params.m_global_sel_codebook_mod_bits = m_frontend.get_params().m_num_global_sel_codebook_mod_bits; - backend_params.m_use_hybrid_sel_codebooks = m_frontend.get_params().m_use_hybrid_selector_codebooks; - - m_backend.init(&m_frontend, backend_params, m_slice_descs, m_params.m_pSel_codebook); - uint32_t total_packed_bytes = m_backend.encode(); - - if (!total_packed_bytes) - { - error_printf("basis_compressor::encode() failed!\n"); - return false; - } - - debug_printf("Total packed bytes (estimated): %u\n", total_packed_bytes); - - return true; - } - - bool basis_compressor::create_basis_file_and_transcode() - { - debug_printf("basis_compressor::create_basis_file_and_transcode\n"); - - const basisu_backend_output &encoded_output = m_backend.get_output(); - - if (!m_basis_file.init(encoded_output, m_params.m_tex_type, m_params.m_userdata0, m_params.m_userdata1, m_params.m_y_flip, m_params.m_us_per_frame)) - { - error_printf("basis_compressor::write_output_files_and_compute_stats: basisu_backend:init() failed!\n"); - return false; - } - - const uint8_vec &comp_data = m_basis_file.get_compressed_data(); - - m_output_basis_file = comp_data; - - // Verify the compressed data by transcoding it to ETC1/BC1 and validating the CRC's. - basist::basisu_transcoder decoder(m_params.m_pSel_codebook); - if (!decoder.validate_file_checksums(&comp_data[0], (uint32_t)comp_data.size(), true)) - { - error_printf("decoder.validate_file_checksums() failed!\n"); - return false; - } - - m_decoded_output_textures.resize(m_slice_descs.size()); - m_decoded_output_textures_unpacked.resize(m_slice_descs.size()); - - m_decoded_output_textures_bc1.resize(m_slice_descs.size()); - m_decoded_output_textures_unpacked_bc1.resize(m_slice_descs.size()); - - interval_timer tm; - tm.start(); - - if (!decoder.start_transcoding(&comp_data[0], (uint32_t)comp_data.size())) - { - error_printf("decoder.start_transcoding() failed!\n"); - return false; - } - - debug_printf("basisu_comppressor::start_transcoding() took %3.3fms\n", tm.get_elapsed_ms()); - - uint32_t total_orig_pixels = 0; - uint32_t total_texels = 0; - - double total_time_etc1 = 0; - - for (uint32_t i = 0; i < m_slice_descs.size(); i++) - { - gpu_image decoded_texture; - decoded_texture.init(texture_format::cETC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); - - tm.start(); - - if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i, - reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cETC1, 8)) - { - error_printf("Transcoding failed to ETC1 on slice %u!\n", i); - return false; - } - - total_time_etc1 += tm.get_elapsed_secs(); - - uint32_t image_crc16 = basist::crc16(decoded_texture.get_ptr(), decoded_texture.get_size_in_bytes(), 0); - if (image_crc16 != m_backend.get_output().m_slice_image_crcs[i]) - { - error_printf("Decoded image data CRC check failed on slice %u!\n", i); - return false; - } - debug_printf("Decoded image data CRC check succeeded on slice %i\n", i); - - m_decoded_output_textures[i] = decoded_texture; - - total_orig_pixels += m_slice_descs[i].m_orig_width * m_slice_descs[i].m_orig_height; - total_texels += m_slice_descs[i].m_width * m_slice_descs[i].m_height; - } - - tm.start(); - - basist::basisu_transcoder_init(); - - debug_printf("basist::basisu_transcoder_init: Took %f ms\n", tm.get_elapsed_ms()); - - double total_time_bc1 = 0; - - for (uint32_t i = 0; i < m_slice_descs.size(); i++) - { - gpu_image decoded_texture; - decoded_texture.init(texture_format::cBC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); - - tm.start(); - - if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i, - reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cBC1, 8)) - { - error_printf("Transcoding failed to BC1 on slice %u!\n", i); - return false; - } - - total_time_bc1 += tm.get_elapsed_secs(); - - m_decoded_output_textures_bc1[i] = decoded_texture; - } - - for (uint32_t i = 0; i < m_slice_descs.size(); i++) - { - m_decoded_output_textures[i].unpack(m_decoded_output_textures_unpacked[i]); - m_decoded_output_textures_bc1[i].unpack(m_decoded_output_textures_unpacked_bc1[i]); - } - - debug_printf("Transcoded to ETC1 in %3.3fms, %f texels/sec\n", total_time_etc1 * 1000.0f, total_orig_pixels / total_time_etc1); - - debug_printf("Transcoded to BC1 in %3.3fms, %f texels/sec\n", total_time_bc1 * 1000.0f, total_orig_pixels / total_time_bc1); - - debug_printf("Total .basis output file size: %u, %3.3f bits/texel\n", comp_data.size(), comp_data.size() * 8.0f / total_orig_pixels); - - m_output_blocks.resize(0); - - uint32_t total_orig_texels = 0; - for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; - - total_orig_texels += slice_desc.m_orig_width * slice_desc.m_orig_height; - - const uint32_t total_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y; - - assert(m_decoded_output_textures[slice_index].get_total_blocks() == total_blocks); - - memcpy(enlarge_vector(m_output_blocks, total_blocks), m_decoded_output_textures[slice_index].get_ptr(), sizeof(etc_block) * total_blocks); - } - - m_basis_file_size = (uint32_t)comp_data.size(); - m_basis_bits_per_texel = (comp_data.size() * 8.0f) / total_orig_texels; - - return true; - } - - bool basis_compressor::write_output_files_and_compute_stats() - { - debug_printf("basis_compressor::write_output_files_and_compute_stats\n"); - - if (m_params.m_write_output_basis_files) - { - const uint8_vec &comp_data = m_basis_file.get_compressed_data(); - - const std::string& basis_filename = m_params.m_out_filename; - - if (!write_vec_to_file(basis_filename.c_str(), comp_data)) - { - error_printf("Failed writing output data to file \"%s\"\n", basis_filename.c_str()); - return false; - } - - printf("Wrote output .basis file \"%s\"\n", basis_filename.c_str()); - } - - m_stats.resize(m_slice_descs.size()); - - uint32_t total_orig_texels = 0; - - for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) - { - const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; - - total_orig_texels += slice_desc.m_orig_width * slice_desc.m_orig_height; - - if (m_params.m_compute_stats) - { - printf("Slice: %u\n", slice_index); - - image_stats &s = m_stats[slice_index]; - - // TODO: We used to output SSIM (during heavy encoder development), but this slowed down compression too much. We'll be adding it back. - - image_metrics em; - - // ---- .basis ETC1S stats - em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0); - em.print(".basis ETC1S 709 Luma: "); - - s.m_basis_etc1s_luma_709_psnr = static_cast<float>(em.m_psnr); - s.m_basis_etc1s_luma_709_ssim = static_cast<float>(em.m_ssim); - - em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0, true, true); - em.print(".basis ETC1S 601 Luma: "); - - s.m_basis_etc1s_luma_601_psnr = static_cast<float>(em.m_psnr); - - em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 3); - em.print(".basis ETC1S RGB Avg: "); - - s.m_basis_etc1s_rgb_avg_psnr = em.m_psnr; - - if (m_slice_descs.size() == 1) - { - debug_printf(".basis Luma 709 PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_etc1s_luma_709_psnr / ((m_backend.get_output().get_output_size_estimate() * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); - } - - // ---- .basis BC1 stats - em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc1[slice_index], 0, 0); - em.print(".basis BC1 709 Luma: "); - - s.m_basis_bc1_luma_709_psnr = static_cast<float>(em.m_psnr); - s.m_basis_bc1_luma_709_ssim = static_cast<float>(em.m_ssim); - - em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc1[slice_index], 0, 0, true, true); - em.print(".basis BC1 601 Luma: "); - - s.m_basis_bc1_luma_601_psnr = static_cast<float>(em.m_psnr); - - em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc1[slice_index], 0, 3); - em.print(".basis BC1 RGB Avg: "); - - s.m_basis_bc1_rgb_avg_psnr = static_cast<float>(em.m_psnr); - - // ---- Nearly best possible ETC1S stats - em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0); - em.print("Unquantized ETC1S 709 Luma: "); - - s.m_best_luma_709_psnr = static_cast<float>(em.m_psnr); - s.m_best_luma_709_ssim = static_cast<float>(em.m_ssim); - - em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0, true, true); - em.print("Unquantized ETC1S 601 Luma: "); - - s.m_best_luma_601_psnr = static_cast<float>(em.m_psnr); - - em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 3); - em.print("Unquantized ETC1S RGB Avg: "); - - s.m_best_rgb_avg_psnr = static_cast<float>(em.m_psnr); - } - - if (m_frontend.get_params().m_debug_images) - { - std::string out_basename; - if (m_params.m_out_filename.size()) - string_get_filename(m_params.m_out_filename.c_str(), out_basename); - else if (m_params.m_source_filenames.size()) - string_get_filename(m_params.m_source_filenames[slice_desc.m_source_file_index].c_str(), out_basename); - - string_remove_extension(out_basename); - out_basename = "basis_debug_" + out_basename + string_format("_slice_%u", slice_index); - - // Write "best" ETC1S debug images - { - gpu_image best_etc1s_gpu_image(m_best_etc1s_images[slice_index]); - best_etc1s_gpu_image.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height); - write_compressed_texture_file((out_basename + "_best_etc1s.ktx").c_str(), best_etc1s_gpu_image); - - image best_etc1s_unpacked; - best_etc1s_gpu_image.unpack(best_etc1s_unpacked); - save_png(out_basename + "_best_etc1s.png", best_etc1s_unpacked); - } - - // Write decoded ETC1S debug images - { - gpu_image decoded_etc1s(m_decoded_output_textures[slice_index]); - decoded_etc1s.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height); - write_compressed_texture_file((out_basename + "_decoded_etc1s.ktx").c_str(), decoded_etc1s); - - image temp(m_decoded_output_textures_unpacked[slice_index]); - temp.crop(slice_desc.m_orig_width, slice_desc.m_orig_height); - save_png(out_basename + "_decoded_etc1s.png", temp); - } - - // Write decoded BC1 debug images - { - gpu_image decoded_bc1(m_decoded_output_textures_bc1[slice_index]); - decoded_bc1.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height); - write_compressed_texture_file((out_basename + "_decoded_bc1.ktx").c_str(), decoded_bc1); - - image temp(m_decoded_output_textures_unpacked_bc1[slice_index]); - temp.crop(slice_desc.m_orig_width, slice_desc.m_orig_height); - save_png(out_basename + "_decoded_bc1.png", temp); - } - } - } - - return true; - } - -} // namespace basisu diff --git a/thirdparty/basis_universal/basisu_etc.cpp b/thirdparty/basis_universal/basisu_etc.cpp deleted file mode 100644 index 244f1d2e6b..0000000000 --- a/thirdparty/basis_universal/basisu_etc.cpp +++ /dev/null @@ -1,1074 +0,0 @@ -// basis_etc.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "basisu_etc.h" - -#define BASISU_DEBUG_ETC_ENCODER 0 -#define BASISU_DEBUG_ETC_ENCODER_DEEPER 0 - -namespace basisu -{ - const uint32_t BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE = 165; - - static const struct { uint8_t m_v[4]; } g_cluster_fit_order_tab[BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE] = - { - { { 0, 0, 0, 8 } },{ { 0, 5, 2, 1 } },{ { 0, 6, 1, 1 } },{ { 0, 7, 0, 1 } },{ { 0, 7, 1, 0 } }, - { { 0, 0, 8, 0 } },{ { 0, 0, 3, 5 } },{ { 0, 1, 7, 0 } },{ { 0, 0, 4, 4 } },{ { 0, 0, 2, 6 } }, - { { 0, 0, 7, 1 } },{ { 0, 0, 1, 7 } },{ { 0, 0, 5, 3 } },{ { 1, 6, 0, 1 } },{ { 0, 0, 6, 2 } }, - { { 0, 2, 6, 0 } },{ { 2, 4, 2, 0 } },{ { 0, 3, 5, 0 } },{ { 3, 3, 1, 1 } },{ { 4, 2, 0, 2 } }, - { { 1, 5, 2, 0 } },{ { 0, 5, 3, 0 } },{ { 0, 6, 2, 0 } },{ { 2, 4, 1, 1 } },{ { 5, 1, 0, 2 } }, - { { 6, 1, 1, 0 } },{ { 3, 3, 0, 2 } },{ { 6, 0, 0, 2 } },{ { 0, 8, 0, 0 } },{ { 6, 1, 0, 1 } }, - { { 0, 1, 6, 1 } },{ { 1, 6, 1, 0 } },{ { 4, 1, 3, 0 } },{ { 0, 2, 5, 1 } },{ { 5, 0, 3, 0 } }, - { { 5, 3, 0, 0 } },{ { 0, 1, 5, 2 } },{ { 0, 3, 4, 1 } },{ { 2, 5, 1, 0 } },{ { 1, 7, 0, 0 } }, - { { 0, 1, 4, 3 } },{ { 6, 0, 2, 0 } },{ { 0, 4, 4, 0 } },{ { 2, 6, 0, 0 } },{ { 0, 2, 4, 2 } }, - { { 0, 5, 1, 2 } },{ { 0, 6, 0, 2 } },{ { 3, 5, 0, 0 } },{ { 0, 4, 3, 1 } },{ { 3, 4, 1, 0 } }, - { { 4, 3, 1, 0 } },{ { 1, 5, 0, 2 } },{ { 0, 3, 3, 2 } },{ { 1, 4, 1, 2 } },{ { 0, 4, 2, 2 } }, - { { 2, 3, 3, 0 } },{ { 4, 4, 0, 0 } },{ { 1, 2, 4, 1 } },{ { 0, 5, 0, 3 } },{ { 0, 1, 3, 4 } }, - { { 1, 5, 1, 1 } },{ { 1, 4, 2, 1 } },{ { 1, 3, 2, 2 } },{ { 5, 2, 1, 0 } },{ { 1, 3, 3, 1 } }, - { { 0, 1, 2, 5 } },{ { 1, 1, 5, 1 } },{ { 0, 3, 2, 3 } },{ { 2, 5, 0, 1 } },{ { 3, 2, 2, 1 } }, - { { 2, 3, 0, 3 } },{ { 1, 4, 3, 0 } },{ { 2, 2, 1, 3 } },{ { 6, 2, 0, 0 } },{ { 1, 0, 6, 1 } }, - { { 3, 3, 2, 0 } },{ { 7, 1, 0, 0 } },{ { 3, 1, 4, 0 } },{ { 0, 2, 3, 3 } },{ { 0, 4, 1, 3 } }, - { { 0, 4, 0, 4 } },{ { 0, 1, 0, 7 } },{ { 2, 0, 5, 1 } },{ { 2, 0, 4, 2 } },{ { 3, 0, 2, 3 } }, - { { 2, 2, 4, 0 } },{ { 2, 2, 3, 1 } },{ { 4, 0, 3, 1 } },{ { 3, 2, 3, 0 } },{ { 2, 3, 2, 1 } }, - { { 1, 3, 4, 0 } },{ { 7, 0, 1, 0 } },{ { 3, 0, 4, 1 } },{ { 1, 0, 5, 2 } },{ { 8, 0, 0, 0 } }, - { { 3, 0, 1, 4 } },{ { 4, 1, 1, 2 } },{ { 4, 0, 2, 2 } },{ { 1, 2, 5, 0 } },{ { 4, 2, 1, 1 } }, - { { 3, 4, 0, 1 } },{ { 2, 0, 3, 3 } },{ { 5, 0, 1, 2 } },{ { 5, 0, 0, 3 } },{ { 2, 4, 0, 2 } }, - { { 2, 1, 4, 1 } },{ { 4, 0, 1, 3 } },{ { 2, 1, 5, 0 } },{ { 4, 2, 2, 0 } },{ { 4, 0, 4, 0 } }, - { { 1, 0, 4, 3 } },{ { 1, 4, 0, 3 } },{ { 3, 0, 3, 2 } },{ { 4, 3, 0, 1 } },{ { 0, 1, 1, 6 } }, - { { 1, 3, 1, 3 } },{ { 0, 2, 2, 4 } },{ { 2, 0, 2, 4 } },{ { 5, 1, 1, 1 } },{ { 3, 0, 5, 0 } }, - { { 2, 3, 1, 2 } },{ { 3, 0, 0, 5 } },{ { 0, 3, 1, 4 } },{ { 5, 0, 2, 1 } },{ { 2, 1, 3, 2 } }, - { { 2, 0, 6, 0 } },{ { 3, 1, 3, 1 } },{ { 5, 1, 2, 0 } },{ { 1, 0, 3, 4 } },{ { 1, 1, 6, 0 } }, - { { 4, 0, 0, 4 } },{ { 2, 0, 1, 5 } },{ { 0, 3, 0, 5 } },{ { 1, 3, 0, 4 } },{ { 4, 1, 2, 1 } }, - { { 1, 2, 3, 2 } },{ { 3, 1, 0, 4 } },{ { 5, 2, 0, 1 } },{ { 1, 2, 2, 3 } },{ { 3, 2, 1, 2 } }, - { { 2, 2, 2, 2 } },{ { 6, 0, 1, 1 } },{ { 1, 2, 1, 4 } },{ { 1, 1, 4, 2 } },{ { 3, 2, 0, 3 } }, - { { 1, 2, 0, 5 } },{ { 1, 0, 7, 0 } },{ { 3, 1, 2, 2 } },{ { 1, 0, 2, 5 } },{ { 2, 0, 0, 6 } }, - { { 2, 1, 1, 4 } },{ { 2, 2, 0, 4 } },{ { 1, 1, 3, 3 } },{ { 7, 0, 0, 1 } },{ { 1, 0, 0, 7 } }, - { { 2, 1, 2, 3 } },{ { 4, 1, 0, 3 } },{ { 3, 1, 1, 3 } },{ { 1, 1, 2, 4 } },{ { 2, 1, 0, 5 } }, - { { 1, 0, 1, 6 } },{ { 0, 2, 1, 5 } },{ { 0, 2, 0, 6 } },{ { 1, 1, 1, 5 } },{ { 1, 1, 0, 6 } } - }; - - const int g_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = - { - { -8, -2, 2, 8 }, { -17, -5, 5, 17 }, { -29, -9, 9, 29 }, { -42, -13, 13, 42 }, - { -60, -18, 18, 60 }, { -80, -24, 24, 80 }, { -106, -33, 33, 106 }, { -183, -47, 47, 183 } - }; - - const uint8_t g_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 }; - const uint8_t g_selector_index_to_etc1[cETC1SelectorValues] = { 3, 2, 0, 1 }; - - // [flip][subblock][pixel_index] - const etc_coord2 g_etc1_pixel_coords[2][2][8] = - { - { - { - { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 } - }, - { - { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, - { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 } - } - }, - { - { - { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, - { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 } - }, - { - { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 }, - { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 } - }, - } - }; - - // [flip][subblock][pixel_index] - const uint32_t g_etc1_pixel_indices[2][2][8] = - { - { - { - 0 + 4 * 0, 0 + 4 * 1, 0 + 4 * 2, 0 + 4 * 3, - 1 + 4 * 0, 1 + 4 * 1, 1 + 4 * 2, 1 + 4 * 3 - }, - { - 2 + 4 * 0, 2 + 4 * 1, 2 + 4 * 2, 2 + 4 * 3, - 3 + 4 * 0, 3 + 4 * 1, 3 + 4 * 2, 3 + 4 * 3 - } - }, - { - { - 0 + 4 * 0, 1 + 4 * 0, 2 + 4 * 0, 3 + 4 * 0, - 0 + 4 * 1, 1 + 4 * 1, 2 + 4 * 1, 3 + 4 * 1 - }, - { - 0 + 4 * 2, 1 + 4 * 2, 2 + 4 * 2, 3 + 4 * 2, - 0 + 4 * 3, 1 + 4 * 3, 2 + 4 * 3, 3 + 4 * 3 - }, - } - }; - - uint16_t etc_block::pack_color5(const color_rgba& color, bool scaled, uint32_t bias) - { - return pack_color5(color.r, color.g, color.b, scaled, bias); - } - - uint16_t etc_block::pack_color5(uint32_t r, uint32_t g, uint32_t b, bool scaled, uint32_t bias) - { - if (scaled) - { - r = (r * 31U + bias) / 255U; - g = (g * 31U + bias) / 255U; - b = (b * 31U + bias) / 255U; - } - - r = minimum(r, 31U); - g = minimum(g, 31U); - b = minimum(b, 31U); - - return static_cast<uint16_t>(b | (g << 5U) | (r << 10U)); - } - - color_rgba etc_block::unpack_color5(uint16_t packed_color5, bool scaled, uint32_t alpha) - { - uint32_t b = packed_color5 & 31U; - uint32_t g = (packed_color5 >> 5U) & 31U; - uint32_t r = (packed_color5 >> 10U) & 31U; - - if (scaled) - { - b = (b << 3U) | (b >> 2U); - g = (g << 3U) | (g >> 2U); - r = (r << 3U) | (r >> 2U); - } - - return color_rgba(cNoClamp, r, g, b, minimum(alpha, 255U)); - } - - void etc_block::unpack_color5(color_rgba& result, uint16_t packed_color5, bool scaled) - { - result = unpack_color5(packed_color5, scaled, 255); - } - - void etc_block::unpack_color5(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color5, bool scaled) - { - color_rgba c(unpack_color5(packed_color5, scaled, 0)); - r = c.r; - g = c.g; - b = c.b; - } - - bool etc_block::unpack_color5(color_rgba& result, uint16_t packed_color5, uint16_t packed_delta3, bool scaled, uint32_t alpha) - { - color_rgba_i16 dc(unpack_delta3(packed_delta3)); - - int b = (packed_color5 & 31U) + dc.b; - int g = ((packed_color5 >> 5U) & 31U) + dc.g; - int r = ((packed_color5 >> 10U) & 31U) + dc.r; - - bool success = true; - if (static_cast<uint32_t>(r | g | b) > 31U) - { - success = false; - r = clamp<int>(r, 0, 31); - g = clamp<int>(g, 0, 31); - b = clamp<int>(b, 0, 31); - } - - if (scaled) - { - b = (b << 3U) | (b >> 2U); - g = (g << 3U) | (g >> 2U); - r = (r << 3U) | (r >> 2U); - } - - result.set_noclamp_rgba(r, g, b, minimum(alpha, 255U)); - return success; - } - - bool etc_block::unpack_color5(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color5, uint16_t packed_delta3, bool scaled, uint32_t alpha) - { - color_rgba result; - const bool success = unpack_color5(result, packed_color5, packed_delta3, scaled, alpha); - r = result.r; - g = result.g; - b = result.b; - return success; - } - - uint16_t etc_block::pack_delta3(const color_rgba_i16& color) - { - return pack_delta3(color.r, color.g, color.b); - } - - uint16_t etc_block::pack_delta3(int r, int g, int b) - { - assert((r >= cETC1ColorDeltaMin) && (r <= cETC1ColorDeltaMax)); - assert((g >= cETC1ColorDeltaMin) && (g <= cETC1ColorDeltaMax)); - assert((b >= cETC1ColorDeltaMin) && (b <= cETC1ColorDeltaMax)); - if (r < 0) r += 8; - if (g < 0) g += 8; - if (b < 0) b += 8; - return static_cast<uint16_t>(b | (g << 3) | (r << 6)); - } - - color_rgba_i16 etc_block::unpack_delta3(uint16_t packed_delta3) - { - int r = (packed_delta3 >> 6) & 7; - int g = (packed_delta3 >> 3) & 7; - int b = packed_delta3 & 7; - if (r >= 4) r -= 8; - if (g >= 4) g -= 8; - if (b >= 4) b -= 8; - return color_rgba_i16(r, g, b, 255); - } - - void etc_block::unpack_delta3(int& r, int& g, int& b, uint16_t packed_delta3) - { - r = (packed_delta3 >> 6) & 7; - g = (packed_delta3 >> 3) & 7; - b = packed_delta3 & 7; - if (r >= 4) r -= 8; - if (g >= 4) g -= 8; - if (b >= 4) b -= 8; - } - - uint16_t etc_block::pack_color4(const color_rgba& color, bool scaled, uint32_t bias) - { - return pack_color4(color.r, color.g, color.b, scaled, bias); - } - - uint16_t etc_block::pack_color4(uint32_t r, uint32_t g, uint32_t b, bool scaled, uint32_t bias) - { - if (scaled) - { - r = (r * 15U + bias) / 255U; - g = (g * 15U + bias) / 255U; - b = (b * 15U + bias) / 255U; - } - - r = minimum(r, 15U); - g = minimum(g, 15U); - b = minimum(b, 15U); - - return static_cast<uint16_t>(b | (g << 4U) | (r << 8U)); - } - - color_rgba etc_block::unpack_color4(uint16_t packed_color4, bool scaled, uint32_t alpha) - { - uint32_t b = packed_color4 & 15U; - uint32_t g = (packed_color4 >> 4U) & 15U; - uint32_t r = (packed_color4 >> 8U) & 15U; - - if (scaled) - { - b = (b << 4U) | b; - g = (g << 4U) | g; - r = (r << 4U) | r; - } - - return color_rgba(cNoClamp, r, g, b, minimum(alpha, 255U)); - } - - void etc_block::unpack_color4(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color4, bool scaled) - { - color_rgba c(unpack_color4(packed_color4, scaled, 0)); - r = c.r; - g = c.g; - b = c.b; - } - - void etc_block::get_diff_subblock_colors(color_rgba* pDst, uint16_t packed_color5, uint32_t table_idx) - { - assert(table_idx < cETC1IntenModifierValues); - const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; - - uint32_t r, g, b; - unpack_color5(r, g, b, packed_color5, true); - - const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b); - - const int y0 = pInten_modifer_table[0]; - pDst[0].set(ir + y0, ig + y0, ib + y0, 255); - - const int y1 = pInten_modifer_table[1]; - pDst[1].set(ir + y1, ig + y1, ib + y1, 255); - - const int y2 = pInten_modifer_table[2]; - pDst[2].set(ir + y2, ig + y2, ib + y2, 255); - - const int y3 = pInten_modifer_table[3]; - pDst[3].set(ir + y3, ig + y3, ib + y3, 255); - } - - bool etc_block::get_diff_subblock_colors(color_rgba* pDst, uint16_t packed_color5, uint16_t packed_delta3, uint32_t table_idx) - { - assert(table_idx < cETC1IntenModifierValues); - const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; - - uint32_t r, g, b; - bool success = unpack_color5(r, g, b, packed_color5, packed_delta3, true); - - const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b); - - const int y0 = pInten_modifer_table[0]; - pDst[0].set(ir + y0, ig + y0, ib + y0, 255); - - const int y1 = pInten_modifer_table[1]; - pDst[1].set(ir + y1, ig + y1, ib + y1, 255); - - const int y2 = pInten_modifer_table[2]; - pDst[2].set(ir + y2, ig + y2, ib + y2, 255); - - const int y3 = pInten_modifer_table[3]; - pDst[3].set(ir + y3, ig + y3, ib + y3, 255); - - return success; - } - - void etc_block::get_abs_subblock_colors(color_rgba* pDst, uint16_t packed_color4, uint32_t table_idx) - { - assert(table_idx < cETC1IntenModifierValues); - const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; - - uint32_t r, g, b; - unpack_color4(r, g, b, packed_color4, true); - - const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b); - - const int y0 = pInten_modifer_table[0]; - pDst[0].set(ir + y0, ig + y0, ib + y0, 255); - - const int y1 = pInten_modifer_table[1]; - pDst[1].set(ir + y1, ig + y1, ib + y1, 255); - - const int y2 = pInten_modifer_table[2]; - pDst[2].set(ir + y2, ig + y2, ib + y2, 255); - - const int y3 = pInten_modifer_table[3]; - pDst[3].set(ir + y3, ig + y3, ib + y3, 255); - } - - bool unpack_etc1(const etc_block& block, color_rgba *pDst, bool preserve_alpha) - { - const bool diff_flag = block.get_diff_bit(); - const bool flip_flag = block.get_flip_bit(); - const uint32_t table_index0 = block.get_inten_table(0); - const uint32_t table_index1 = block.get_inten_table(1); - - color_rgba subblock_colors0[4]; - color_rgba subblock_colors1[4]; - - if (diff_flag) - { - const uint16_t base_color5 = block.get_base5_color(); - const uint16_t delta_color3 = block.get_delta3_color(); - etc_block::get_diff_subblock_colors(subblock_colors0, base_color5, table_index0); - - if (!etc_block::get_diff_subblock_colors(subblock_colors1, base_color5, delta_color3, table_index1)) - return false; - } - else - { - const uint16_t base_color4_0 = block.get_base4_color(0); - etc_block::get_abs_subblock_colors(subblock_colors0, base_color4_0, table_index0); - - const uint16_t base_color4_1 = block.get_base4_color(1); - etc_block::get_abs_subblock_colors(subblock_colors1, base_color4_1, table_index1); - } - - if (preserve_alpha) - { - if (flip_flag) - { - for (uint32_t y = 0; y < 2; y++) - { - pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]); - pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]); - pDst[2].set_rgb(subblock_colors0[block.get_selector(2, y)]); - pDst[3].set_rgb(subblock_colors0[block.get_selector(3, y)]); - pDst += 4; - } - - for (uint32_t y = 2; y < 4; y++) - { - pDst[0].set_rgb(subblock_colors1[block.get_selector(0, y)]); - pDst[1].set_rgb(subblock_colors1[block.get_selector(1, y)]); - pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]); - pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]); - pDst += 4; - } - } - else - { - for (uint32_t y = 0; y < 4; y++) - { - pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]); - pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]); - pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]); - pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]); - pDst += 4; - } - } - } - else - { - if (flip_flag) - { - // 0000 - // 0000 - // 1111 - // 1111 - for (uint32_t y = 0; y < 2; y++) - { - pDst[0] = subblock_colors0[block.get_selector(0, y)]; - pDst[1] = subblock_colors0[block.get_selector(1, y)]; - pDst[2] = subblock_colors0[block.get_selector(2, y)]; - pDst[3] = subblock_colors0[block.get_selector(3, y)]; - pDst += 4; - } - - for (uint32_t y = 2; y < 4; y++) - { - pDst[0] = subblock_colors1[block.get_selector(0, y)]; - pDst[1] = subblock_colors1[block.get_selector(1, y)]; - pDst[2] = subblock_colors1[block.get_selector(2, y)]; - pDst[3] = subblock_colors1[block.get_selector(3, y)]; - pDst += 4; - } - } - else - { - // 0011 - // 0011 - // 0011 - // 0011 - for (uint32_t y = 0; y < 4; y++) - { - pDst[0] = subblock_colors0[block.get_selector(0, y)]; - pDst[1] = subblock_colors0[block.get_selector(1, y)]; - pDst[2] = subblock_colors1[block.get_selector(2, y)]; - pDst[3] = subblock_colors1[block.get_selector(3, y)]; - pDst += 4; - } - } - } - - return true; - } - - inline int extend_6_to_8(uint32_t n) - { - return (n << 2) | (n >> 4); - } - - inline int extend_7_to_8(uint32_t n) - { - return (n << 1) | (n >> 6); - } - - inline int extend_4_to_8(uint32_t n) - { - return (n << 4) | n; - } - - uint64_t etc_block::evaluate_etc1_error(const color_rgba* pBlock_pixels, bool perceptual, int subblock_index) const - { - color_rgba unpacked_block[16]; - - unpack_etc1(*this, unpacked_block); - - uint64_t total_error = 0; - - if (subblock_index < 0) - { - for (uint32_t i = 0; i < 16; i++) - total_error += color_distance(perceptual, pBlock_pixels[i], unpacked_block[i], false); - } - else - { - const bool flip_bit = get_flip_bit(); - - for (uint32_t i = 0; i < 8; i++) - { - const uint32_t idx = g_etc1_pixel_indices[flip_bit][subblock_index][i]; - - total_error += color_distance(perceptual, pBlock_pixels[idx], unpacked_block[idx], false); - } - } - - return total_error; - } - - void etc_block::get_subblock_pixels(color_rgba* pPixels, int subblock_index) const - { - if (subblock_index < 0) - unpack_etc1(*this, pPixels); - else - { - color_rgba unpacked_block[16]; - - unpack_etc1(*this, unpacked_block); - - const bool flip_bit = get_flip_bit(); - - for (uint32_t i = 0; i < 8; i++) - { - const uint32_t idx = g_etc1_pixel_indices[flip_bit][subblock_index][i]; - - pPixels[i] = unpacked_block[idx]; - } - } - } - - bool etc1_optimizer::compute() - { - assert(m_pResult->m_pSelectors); - - if ((m_pParams->m_pForce_selectors) || (m_pParams->m_pEval_solution_override)) - { - assert(m_pParams->m_quality >= cETCQualitySlow); - } - - const uint32_t n = m_pParams->m_num_src_pixels; - - if (m_pParams->m_cluster_fit) - { - if (m_pParams->m_quality == cETCQualityFast) - compute_internal_cluster_fit(4); - else if (m_pParams->m_quality == cETCQualityMedium) - compute_internal_cluster_fit(32); - else if (m_pParams->m_quality == cETCQualitySlow) - compute_internal_cluster_fit(64); - else - compute_internal_cluster_fit(BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE); - } - else - compute_internal_neighborhood(m_br, m_bg, m_bb); - - if (!m_best_solution.m_valid) - { - m_pResult->m_error = UINT32_MAX; - return false; - } - - const uint8_t* pSelectors = &m_best_solution.m_selectors[0]; - -#ifdef BASISU_BUILD_DEBUG - if (m_pParams->m_pEval_solution_override == nullptr) - { - color_rgba block_colors[4]; - m_best_solution.m_coords.get_block_colors(block_colors); - - const color_rgba* pSrc_pixels = m_pParams->m_pSrc_pixels; - uint64_t actual_error = 0; - for (uint32_t i = 0; i < n; i++) - { - if ((m_pParams->m_perceptual) && (m_pParams->m_quality >= cETCQualitySlow)) - actual_error += color_distance(true, pSrc_pixels[i], block_colors[pSelectors[i]], false); - else - actual_error += color_distance(pSrc_pixels[i], block_colors[pSelectors[i]], false); - } - assert(actual_error == m_best_solution.m_error); - } -#endif - - m_pResult->m_error = m_best_solution.m_error; - - m_pResult->m_block_color_unscaled = m_best_solution.m_coords.m_unscaled_color; - m_pResult->m_block_color4 = m_best_solution.m_coords.m_color4; - - m_pResult->m_block_inten_table = m_best_solution.m_coords.m_inten_table; - memcpy(m_pResult->m_pSelectors, pSelectors, n); - m_pResult->m_n = n; - - return true; - } - - void etc1_optimizer::refine_solution(uint32_t max_refinement_trials) - { - // Now we have the input block, the avg. color of the input pixels, a set of trial selector indices, and the block color+intensity index. - // Now, for each component, attempt to refine the current solution by solving a simple linear equation. For example, for 4 colors: - // The goal is: - // pixel0 - (block_color+inten_table[selector0]) + pixel1 - (block_color+inten_table[selector1]) + pixel2 - (block_color+inten_table[selector2]) + pixel3 - (block_color+inten_table[selector3]) = 0 - // Rearranging this: - // (pixel0 + pixel1 + pixel2 + pixel3) - (block_color+inten_table[selector0]) - (block_color+inten_table[selector1]) - (block_color+inten_table[selector2]) - (block_color+inten_table[selector3]) = 0 - // (pixel0 + pixel1 + pixel2 + pixel3) - block_color - inten_table[selector0] - block_color-inten_table[selector1] - block_color-inten_table[selector2] - block_color-inten_table[selector3] = 0 - // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - inten_table[selector0] - inten_table[selector1] - inten_table[selector2] - inten_table[selector3] = 0 - // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3]) = 0 - // (pixel0 + pixel1 + pixel2 + pixel3)/4 - block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 = 0 - // block_color = (pixel0 + pixel1 + pixel2 + pixel3)/4 - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 - // So what this means: - // optimal_block_color = avg_input - avg_inten_delta - // So the optimal block color can be computed by taking the average block color and subtracting the current average of the intensity delta. - // Unfortunately, optimal_block_color must then be quantized to 555 or 444 so it's not always possible to improve matters using this formula. - // Also, the above formula is for unclamped intensity deltas. The actual implementation takes into account clamping. - - const uint32_t n = m_pParams->m_num_src_pixels; - - for (uint32_t refinement_trial = 0; refinement_trial < max_refinement_trials; refinement_trial++) - { - const uint8_t* pSelectors = &m_best_solution.m_selectors[0]; - const int* pInten_table = g_etc1_inten_tables[m_best_solution.m_coords.m_inten_table]; - - int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0; - const color_rgba base_color(m_best_solution.m_coords.get_scaled_color()); - for (uint32_t r = 0; r < n; r++) - { - const uint32_t s = *pSelectors++; - const int yd_temp = pInten_table[s]; - // Compute actual delta being applied to each pixel, taking into account clamping. - delta_sum_r += clamp<int>(base_color.r + yd_temp, 0, 255) - base_color.r; - delta_sum_g += clamp<int>(base_color.g + yd_temp, 0, 255) - base_color.g; - delta_sum_b += clamp<int>(base_color.b + yd_temp, 0, 255) - base_color.b; - } - - if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b)) - break; - - const float avg_delta_r_f = static_cast<float>(delta_sum_r) / n; - const float avg_delta_g_f = static_cast<float>(delta_sum_g) / n; - const float avg_delta_b_f = static_cast<float>(delta_sum_b) / n; - const int br1 = clamp<int>(static_cast<uint32_t>((m_avg_color[0] - avg_delta_r_f) * m_limit / 255.0f + .5f), 0, m_limit); - const int bg1 = clamp<int>(static_cast<uint32_t>((m_avg_color[1] - avg_delta_g_f) * m_limit / 255.0f + .5f), 0, m_limit); - const int bb1 = clamp<int>(static_cast<uint32_t>((m_avg_color[2] - avg_delta_b_f) * m_limit / 255.0f + .5f), 0, m_limit); - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Refinement trial %u, avg_delta %f %f %f\n", refinement_trial, avg_delta_r_f, avg_delta_g_f, avg_delta_b_f); -#endif - - if (!evaluate_solution(etc1_solution_coordinates(br1, bg1, bb1, 0, m_pParams->m_use_color4), m_trial_solution, &m_best_solution)) - break; - - } // refinement_trial - } - - void etc1_optimizer::compute_internal_neighborhood(int scan_r, int scan_g, int scan_b) - { - if (m_best_solution.m_error == 0) - return; - - const uint32_t n = m_pParams->m_num_src_pixels; - const int scan_delta_size = m_pParams->m_scan_delta_size; - - // Scan through a subset of the 3D lattice centered around the avg block color trying each 3D (555 or 444) lattice point as a potential block color. - // Each time a better solution is found try to refine the current solution's block color based of the current selectors and intensity table index. - for (int zdi = 0; zdi < scan_delta_size; zdi++) - { - const int zd = m_pParams->m_pScan_deltas[zdi]; - const int mbb = scan_b + zd; - if (mbb < 0) continue; else if (mbb > m_limit) break; - - for (int ydi = 0; ydi < scan_delta_size; ydi++) - { - const int yd = m_pParams->m_pScan_deltas[ydi]; - const int mbg = scan_g + yd; - if (mbg < 0) continue; else if (mbg > m_limit) break; - - for (int xdi = 0; xdi < scan_delta_size; xdi++) - { - const int xd = m_pParams->m_pScan_deltas[xdi]; - const int mbr = scan_r + xd; - if (mbr < 0) continue; else if (mbr > m_limit) break; - - etc1_solution_coordinates coords(mbr, mbg, mbb, 0, m_pParams->m_use_color4); - - if (!evaluate_solution(coords, m_trial_solution, &m_best_solution)) - continue; - - if (m_pParams->m_refinement) - { - refine_solution((m_pParams->m_quality == cETCQualityFast) ? 2 : (((xd | yd | zd) == 0) ? 4 : 2)); - } - - } // xdi - } // ydi - } // zdi - } - - void etc1_optimizer::compute_internal_cluster_fit(uint32_t total_perms_to_try) - { - if ((!m_best_solution.m_valid) || ((m_br != m_best_solution.m_coords.m_unscaled_color.r) || (m_bg != m_best_solution.m_coords.m_unscaled_color.g) || (m_bb != m_best_solution.m_coords.m_unscaled_color.b))) - { - evaluate_solution(etc1_solution_coordinates(m_br, m_bg, m_bb, 0, m_pParams->m_use_color4), m_trial_solution, &m_best_solution); - } - - if ((m_best_solution.m_error == 0) || (!m_best_solution.m_valid)) - return; - - for (uint32_t i = 0; i < total_perms_to_try; i++) - { - int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0; - - const int *pInten_table = g_etc1_inten_tables[m_best_solution.m_coords.m_inten_table]; - const color_rgba base_color(m_best_solution.m_coords.get_scaled_color()); - - const uint8_t *pNum_selectors = g_cluster_fit_order_tab[i].m_v; - - for (uint32_t q = 0; q < 4; q++) - { - const int yd_temp = pInten_table[q]; - - delta_sum_r += pNum_selectors[q] * (clamp<int>(base_color.r + yd_temp, 0, 255) - base_color.r); - delta_sum_g += pNum_selectors[q] * (clamp<int>(base_color.g + yd_temp, 0, 255) - base_color.g); - delta_sum_b += pNum_selectors[q] * (clamp<int>(base_color.b + yd_temp, 0, 255) - base_color.b); - } - - if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b)) - continue; - - const float avg_delta_r_f = static_cast<float>(delta_sum_r) / 8; - const float avg_delta_g_f = static_cast<float>(delta_sum_g) / 8; - const float avg_delta_b_f = static_cast<float>(delta_sum_b) / 8; - - const int br1 = clamp<int>(static_cast<uint32_t>((m_avg_color[0] - avg_delta_r_f) * m_limit / 255.0f + .5f), 0, m_limit); - const int bg1 = clamp<int>(static_cast<uint32_t>((m_avg_color[1] - avg_delta_g_f) * m_limit / 255.0f + .5f), 0, m_limit); - const int bb1 = clamp<int>(static_cast<uint32_t>((m_avg_color[2] - avg_delta_b_f) * m_limit / 255.0f + .5f), 0, m_limit); - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Second refinement trial %u, avg_delta %f %f %f\n", i, avg_delta_r_f, avg_delta_g_f, avg_delta_b_f); -#endif - - evaluate_solution(etc1_solution_coordinates(br1, bg1, bb1, 0, m_pParams->m_use_color4), m_trial_solution, &m_best_solution); - - if (m_best_solution.m_error == 0) - break; - } - } - - void etc1_optimizer::init(const params& params, results& result) - { - m_pParams = ¶ms; - m_pResult = &result; - - const uint32_t n = m_pParams->m_num_src_pixels; - - m_selectors.resize(n); - m_best_selectors.resize(n); - m_temp_selectors.resize(n); - m_trial_solution.m_selectors.resize(n); - m_best_solution.m_selectors.resize(n); - - m_limit = m_pParams->m_use_color4 ? 15 : 31; - - vec3F avg_color(0.0f); - - m_luma.resize(n); - m_sorted_luma_indices.resize(n); - m_sorted_luma.resize(n); - - for (uint32_t i = 0; i < n; i++) - { - const color_rgba& c = m_pParams->m_pSrc_pixels[i]; - const vec3F fc(c.r, c.g, c.b); - - avg_color += fc; - - m_luma[i] = static_cast<uint16_t>(c.r + c.g + c.b); - m_sorted_luma_indices[i] = i; - } - avg_color /= static_cast<float>(n); - m_avg_color = avg_color; - - m_br = clamp<int>(static_cast<uint32_t>(m_avg_color[0] * m_limit / 255.0f + .5f), 0, m_limit); - m_bg = clamp<int>(static_cast<uint32_t>(m_avg_color[1] * m_limit / 255.0f + .5f), 0, m_limit); - m_bb = clamp<int>(static_cast<uint32_t>(m_avg_color[2] * m_limit / 255.0f + .5f), 0, m_limit); - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Avg block color: %u %u %u\n", m_br, m_bg, m_bb); -#endif - - if (m_pParams->m_quality <= cETCQualityMedium) - { - indirect_sort(n, &m_sorted_luma_indices[0], &m_luma[0]); - - m_pSorted_luma = &m_sorted_luma[0]; - m_pSorted_luma_indices = &m_sorted_luma_indices[0]; - - for (uint32_t i = 0; i < n; i++) - m_pSorted_luma[i] = m_luma[m_pSorted_luma_indices[i]]; - } - - m_best_solution.m_coords.clear(); - m_best_solution.m_valid = false; - m_best_solution.m_error = UINT64_MAX; - - m_solutions_tried.clear(); - } - - bool etc1_optimizer::evaluate_solution_slow(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) - { - uint32_t k = coords.m_unscaled_color.r | (coords.m_unscaled_color.g << 8) | (coords.m_unscaled_color.b << 16); - if (!m_solutions_tried.insert(k).second) - return false; - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Eval solution: %u %u %u\n", coords.m_unscaled_color.r, coords.m_unscaled_color.g, coords.m_unscaled_color.b); -#endif - - trial_solution.m_valid = false; - - if (m_pParams->m_constrain_against_base_color5) - { - const int dr = (int)coords.m_unscaled_color.r - (int)m_pParams->m_base_color5.r; - const int dg = (int)coords.m_unscaled_color.g - (int)m_pParams->m_base_color5.g; - const int db = (int)coords.m_unscaled_color.b - (int)m_pParams->m_base_color5.b; - - if ((minimum(dr, dg, db) < cETC1ColorDeltaMin) || (maximum(dr, dg, db) > cETC1ColorDeltaMax)) - { -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Eval failed due to constraint from %u %u %u\n", m_pParams->m_base_color5.r, m_pParams->m_base_color5.g, m_pParams->m_base_color5.b); -#endif - return false; - } - } - - const color_rgba base_color(coords.get_scaled_color()); - - const uint32_t n = m_pParams->m_num_src_pixels; - assert(trial_solution.m_selectors.size() == n); - - trial_solution.m_error = UINT64_MAX; - - const uint8_t *pSelectors_to_use = m_pParams->m_pForce_selectors; - - for (uint32_t inten_table = 0; inten_table < cETC1IntenModifierValues; inten_table++) - { - const int* pInten_table = g_etc1_inten_tables[inten_table]; - - color_rgba block_colors[4]; - for (uint32_t s = 0; s < 4; s++) - { - const int yd = pInten_table[s]; - block_colors[s].set(base_color.r + yd, base_color.g + yd, base_color.b + yd, 255); - } - - uint64_t total_error = 0; - - const color_rgba* pSrc_pixels = m_pParams->m_pSrc_pixels; - for (uint32_t c = 0; c < n; c++) - { - const color_rgba& src_pixel = *pSrc_pixels++; - - uint32_t best_selector_index = 0; - uint32_t best_error = 0; - - if (pSelectors_to_use) - { - best_selector_index = pSelectors_to_use[c]; - best_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[best_selector_index], false); - } - else - { - best_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[0], false); - - uint32_t trial_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[1], false); - if (trial_error < best_error) - { - best_error = trial_error; - best_selector_index = 1; - } - - trial_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[2], false); - if (trial_error < best_error) - { - best_error = trial_error; - best_selector_index = 2; - } - - trial_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[3], false); - if (trial_error < best_error) - { - best_error = trial_error; - best_selector_index = 3; - } - } - - m_temp_selectors[c] = static_cast<uint8_t>(best_selector_index); - - total_error += best_error; - if ((m_pParams->m_pEval_solution_override == nullptr) && (total_error >= trial_solution.m_error)) - break; - } - - if (m_pParams->m_pEval_solution_override) - { - if (!(*m_pParams->m_pEval_solution_override)(total_error, *m_pParams, block_colors, &m_temp_selectors[0], coords)) - return false; - } - - if (total_error < trial_solution.m_error) - { - trial_solution.m_error = total_error; - trial_solution.m_coords.m_inten_table = inten_table; - trial_solution.m_selectors.swap(m_temp_selectors); - trial_solution.m_valid = true; - } - } - trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color; - trial_solution.m_coords.m_color4 = m_pParams->m_use_color4; - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Eval done: %u error: %I64u best error so far: %I64u\n", (trial_solution.m_error < pBest_solution->m_error), trial_solution.m_error, pBest_solution->m_error); -#endif - - bool success = false; - if (pBest_solution) - { - if (trial_solution.m_error < pBest_solution->m_error) - { - *pBest_solution = trial_solution; - success = true; - } - } - - return success; - } - - bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) - { - uint32_t k = coords.m_unscaled_color.r | (coords.m_unscaled_color.g << 8) | (coords.m_unscaled_color.b << 16); - if (!m_solutions_tried.insert(k).second) - return false; - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Eval solution fast: %u %u %u\n", coords.m_unscaled_color.r, coords.m_unscaled_color.g, coords.m_unscaled_color.b); -#endif - - if (m_pParams->m_constrain_against_base_color5) - { - const int dr = (int)coords.m_unscaled_color.r - (int)m_pParams->m_base_color5.r; - const int dg = (int)coords.m_unscaled_color.g - (int)m_pParams->m_base_color5.g; - const int db = (int)coords.m_unscaled_color.b - (int)m_pParams->m_base_color5.b; - - if ((minimum(dr, dg, db) < cETC1ColorDeltaMin) || (maximum(dr, dg, db) > cETC1ColorDeltaMax)) - { - trial_solution.m_valid = false; - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Eval failed due to constraint from %u %u %u\n", m_pParams->m_base_color5.r, m_pParams->m_base_color5.g, m_pParams->m_base_color5.b); -#endif - return false; - } - } - - const color_rgba base_color(coords.get_scaled_color()); - - const uint32_t n = m_pParams->m_num_src_pixels; - assert(trial_solution.m_selectors.size() == n); - - trial_solution.m_error = UINT64_MAX; - - for (int inten_table = cETC1IntenModifierValues - 1; inten_table >= 0; --inten_table) - { - const int* pInten_table = g_etc1_inten_tables[inten_table]; - - uint32_t block_inten[4]; - color_rgba block_colors[4]; - for (uint32_t s = 0; s < 4; s++) - { - const int yd = pInten_table[s]; - color_rgba block_color(base_color.r + yd, base_color.g + yd, base_color.b + yd, 255); - block_colors[s] = block_color; - block_inten[s] = block_color.r + block_color.g + block_color.b; - } - - // evaluate_solution_fast() enforces/assumesd a total ordering of the input colors along the intensity (1,1,1) axis to more quickly classify the inputs to selectors. - // The inputs colors have been presorted along the projection onto this axis, and ETC1 block colors are always ordered along the intensity axis, so this classification is fast. - // 0 1 2 3 - // 01 12 23 - const uint32_t block_inten_midpoints[3] = { block_inten[0] + block_inten[1], block_inten[1] + block_inten[2], block_inten[2] + block_inten[3] }; - - uint64_t total_error = 0; - const color_rgba* pSrc_pixels = m_pParams->m_pSrc_pixels; - if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0]) - { - if (block_inten[0] > m_pSorted_luma[n - 1]) - { - const uint32_t min_error = iabs((int)block_inten[0] - (int)m_pSorted_luma[n - 1]); - if (min_error >= trial_solution.m_error) - continue; - } - - memset(&m_temp_selectors[0], 0, n); - - for (uint32_t c = 0; c < n; c++) - total_error += color_distance(block_colors[0], pSrc_pixels[c], false); - } - else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2]) - { - if (m_pSorted_luma[0] > block_inten[3]) - { - const uint32_t min_error = iabs((int)m_pSorted_luma[0] - (int)block_inten[3]); - if (min_error >= trial_solution.m_error) - continue; - } - - memset(&m_temp_selectors[0], 3, n); - - for (uint32_t c = 0; c < n; c++) - total_error += color_distance(block_colors[3], pSrc_pixels[c], false); - } - else - { - uint32_t cur_selector = 0, c; - for (c = 0; c < n; c++) - { - const uint32_t y = m_pSorted_luma[c]; - while ((y * 2) >= block_inten_midpoints[cur_selector]) - if (++cur_selector > 2) - goto done; - const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; - m_temp_selectors[sorted_pixel_index] = static_cast<uint8_t>(cur_selector); - total_error += color_distance(block_colors[cur_selector], pSrc_pixels[sorted_pixel_index], false); - } - done: - while (c < n) - { - const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; - m_temp_selectors[sorted_pixel_index] = 3; - total_error += color_distance(block_colors[3], pSrc_pixels[sorted_pixel_index], false); - ++c; - } - } - - if (total_error < trial_solution.m_error) - { - trial_solution.m_error = total_error; - trial_solution.m_coords.m_inten_table = inten_table; - trial_solution.m_selectors.swap(m_temp_selectors); - trial_solution.m_valid = true; - if (!total_error) - break; - } - } - trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color; - trial_solution.m_coords.m_color4 = m_pParams->m_use_color4; - -#if BASISU_DEBUG_ETC_ENCODER_DEEPER - printf("Eval done: %u error: %I64u best error so far: %I64u\n", (trial_solution.m_error < pBest_solution->m_error), trial_solution.m_error, pBest_solution->m_error); -#endif - - bool success = false; - if (pBest_solution) - { - if (trial_solution.m_error < pBest_solution->m_error) - { - *pBest_solution = trial_solution; - success = true; - } - } - - return success; - } - -} // namespace basisu diff --git a/thirdparty/basis_universal/basisu_pvrtc1_4.cpp b/thirdparty/basis_universal/basisu_pvrtc1_4.cpp deleted file mode 100644 index f0122fcb6c..0000000000 --- a/thirdparty/basis_universal/basisu_pvrtc1_4.cpp +++ /dev/null @@ -1,269 +0,0 @@ -// basisu_pvrtc1_4.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "basisu_pvrtc1_4.h" - -namespace basisu -{ - uint32_t pvrtc4_swizzle_uv(uint32_t width, uint32_t height, uint32_t x, uint32_t y) - { - assert((x < width) && (y < height) && basisu::is_pow2(height) && basisu::is_pow2(width)); - - uint32_t min_d = width, max_v = y; - if (height < width) - { - min_d = height; - max_v = x; - } - - // Interleave the XY LSB's - uint32_t shift_ofs = 0, swizzled = 0; - for (uint32_t s_bit = 1, d_bit = 1; s_bit < min_d; s_bit <<= 1, d_bit <<= 2, ++shift_ofs) - { - if (y & s_bit) swizzled |= d_bit; - if (x & s_bit) swizzled |= (2 * d_bit); - } - - max_v >>= shift_ofs; - - // OR in the rest of the bits from the largest dimension - swizzled |= (max_v << (2 * shift_ofs)); - - return swizzled; - } - - color_rgba pvrtc4_block::get_endpoint(uint32_t endpoint_index, bool unpack) const - { - assert(endpoint_index < 2); - const uint32_t packed = m_endpoints >> (endpoint_index * 16); - - uint32_t r, g, b, a; - if (packed & 0x8000) - { - // opaque 554 or 555 - if (!endpoint_index) - { - r = (packed >> 10) & 31; - g = (packed >> 5) & 31; - b = (packed >> 1) & 15; - - if (unpack) - { - b = (b << 1) | (b >> 3); - } - } - else - { - r = (packed >> 10) & 31; - g = (packed >> 5) & 31; - b = packed & 31; - } - - a = unpack ? 255 : 7; - } - else - { - // translucent 4433 or 4443 - if (!endpoint_index) - { - a = (packed >> 12) & 7; - r = (packed >> 8) & 15; - g = (packed >> 4) & 15; - b = (packed >> 1) & 7; - - if (unpack) - { - a = (a << 1); - a = (a << 4) | a; - - r = (r << 1) | (r >> 3); - g = (g << 1) | (g >> 3); - b = (b << 2) | (b >> 1); - } - } - else - { - a = (packed >> 12) & 7; - r = (packed >> 8) & 15; - g = (packed >> 4) & 15; - b = packed & 15; - - if (unpack) - { - a = (a << 1); - a = (a << 4) | a; - - r = (r << 1) | (r >> 3); - g = (g << 1) | (g >> 3); - b = (b << 1) | (b >> 3); - } - } - } - - if (unpack) - { - r = (r << 3) | (r >> 2); - g = (g << 3) | (g >> 2); - b = (b << 3) | (b >> 2); - } - - assert((r < 256) && (g < 256) && (b < 256) && (a < 256)); - - return color_rgba(r, g, b, a); - } - - color_rgba pvrtc4_block::get_endpoint_5554(uint32_t endpoint_index) const - { - assert(endpoint_index < 2); - const uint32_t packed = m_endpoints >> (endpoint_index * 16); - - uint32_t r, g, b, a; - if (packed & 0x8000) - { - // opaque 554 or 555 - if (!endpoint_index) - { - r = (packed >> 10) & 31; - g = (packed >> 5) & 31; - b = (packed >> 1) & 15; - - b = (b << 1) | (b >> 3); - } - else - { - r = (packed >> 10) & 31; - g = (packed >> 5) & 31; - b = packed & 31; - } - - a = 15; - } - else - { - // translucent 4433 or 4443 - if (!endpoint_index) - { - a = (packed >> 12) & 7; - r = (packed >> 8) & 15; - g = (packed >> 4) & 15; - b = (packed >> 1) & 7; - - a = a << 1; - - r = (r << 1) | (r >> 3); - g = (g << 1) | (g >> 3); - b = (b << 2) | (b >> 1); - } - else - { - a = (packed >> 12) & 7; - r = (packed >> 8) & 15; - g = (packed >> 4) & 15; - b = packed & 15; - - a = a << 1; - - r = (r << 1) | (r >> 3); - g = (g << 1) | (g >> 3); - b = (b << 1) | (b >> 3); - } - } - - assert((r < 32) && (g < 32) && (b < 32) && (a < 16)); - - return color_rgba(r, g, b, a); - } - - bool pvrtc4_image::get_interpolated_colors(uint32_t x, uint32_t y, color_rgba* pColors) const - { - assert((x < m_width) && (y < m_height)); - - int block_x0 = (static_cast<int>(x) - 2) >> 2; - int block_x1 = block_x0 + 1; - int block_y0 = (static_cast<int>(y) - 2) >> 2; - int block_y1 = block_y0 + 1; - - block_x0 = posmod(block_x0, m_block_width); - block_x1 = posmod(block_x1, m_block_width); - block_y0 = posmod(block_y0, m_block_height); - block_y1 = posmod(block_y1, m_block_height); - - pColors[0] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); - pColors[3] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); - - if (get_block_uses_transparent_modulation(x >> 2, y >> 2)) - { - for (uint32_t c = 0; c < 4; c++) - { - uint32_t m = (pColors[0][c] + pColors[3][c]) / 2; - pColors[1][c] = static_cast<uint8_t>(m); - pColors[2][c] = static_cast<uint8_t>(m); - } - pColors[2][3] = 0; - return true; - } - - for (uint32_t c = 0; c < 4; c++) - { - pColors[1][c] = static_cast<uint8_t>((pColors[0][c] * 5 + pColors[3][c] * 3) / 8); - pColors[2][c] = static_cast<uint8_t>((pColors[0][c] * 3 + pColors[3][c] * 5) / 8); - } - - return false; - } - - color_rgba pvrtc4_image::get_pixel(uint32_t x, uint32_t y, uint32_t m) const - { - assert((x < m_width) && (y < m_height)); - - int block_x0 = (static_cast<int>(x) - 2) >> 2; - int block_x1 = block_x0 + 1; - int block_y0 = (static_cast<int>(y) - 2) >> 2; - int block_y1 = block_y0 + 1; - - block_x0 = posmod(block_x0, m_block_width); - block_x1 = posmod(block_x1, m_block_width); - block_y0 = posmod(block_y0, m_block_height); - block_y1 = posmod(block_y1, m_block_height); - - if (get_block_uses_transparent_modulation(x >> 2, y >> 2)) - { - if (m == 0) - return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); - else if (m == 3) - return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); - - color_rgba l(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0))); - color_rgba h(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1))); - - return color_rgba((l[0] + h[0]) / 2, (l[1] + h[1]) / 2, (l[2] + h[2]) / 2, (m == 2) ? 0 : (l[3] + h[3]) / 2); - } - else - { - if (m == 0) - return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); - else if (m == 3) - return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); - - color_rgba l(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0))); - color_rgba h(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1))); - - if (m == 2) - return color_rgba((l[0] * 3 + h[0] * 5) / 8, (l[1] * 3 + h[1] * 5) / 8, (l[2] * 3 + h[2] * 5) / 8, (l[3] * 3 + h[3] * 5) / 8); - else - return color_rgba((l[0] * 5 + h[0] * 3) / 8, (l[1] * 5 + h[1] * 3) / 8, (l[2] * 5 + h[2] * 3) / 8, (l[3] * 5 + h[3] * 3) / 8); - } - } - -} // basisu diff --git a/thirdparty/basis_universal/encoder/apg_bmp.c b/thirdparty/basis_universal/encoder/apg_bmp.c new file mode 100644 index 0000000000..ef3d015e40 --- /dev/null +++ b/thirdparty/basis_universal/encoder/apg_bmp.c @@ -0,0 +1,541 @@ +/* +BMP File Reader/Writer Implementation +Anton Gerdelan +Version: 3 +Licence: see apg_bmp.h +C99 +*/ + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS 1 +#endif + +#include "apg_bmp.h" +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* Maximum pixel dimensions of width or height of an image. Should accommodate max used in graphics APIs. + NOTE: 65536*65536 is the biggest number storable in 32 bits. + This needs to be multiplied by n_channels so actual memory indices are not uint32 but size_t to avoid overflow. + Note this will crash stb_image_write et al at maximum size which use 32bits, so reduce max size to accom. */ +#define _BMP_MAX_DIMS 65536 +#define _BMP_FILE_HDR_SZ 14 +#define _BMP_MIN_DIB_HDR_SZ 40 +#define _BMP_MIN_HDR_SZ ( _BMP_FILE_HDR_SZ + _BMP_MIN_DIB_HDR_SZ ) +#define _BMP_MAX_IMAGE_FILE_SIZE (1024ULL*1024ULL*1024ULL) + +#pragma pack( push, 1 ) // supported on GCC in addition to individual packing attribs +/* All BMP files, regardless of type, start with this file header */ +typedef struct _bmp_file_header_t { + char file_type[2]; + uint32_t file_sz; + uint16_t reserved1; + uint16_t reserved2; + uint32_t image_data_offset; +} _bmp_file_header_t; + +/* Following the file header is the BMP type header. this is the most commonly used format */ +typedef struct _bmp_dib_BITMAPINFOHEADER_t { + uint32_t this_header_sz; + int32_t w; // in older headers w & h these are shorts and may be unsigned + int32_t h; // + uint16_t n_planes; // must be 1 + uint16_t bpp; // bits per pixel. 1,4,8,16,24,32. + uint32_t compression_method; // 16 and 32-bit images must have a value of 3 here + uint32_t image_uncompressed_sz; // not consistently used in the wild, so ignored here. + int32_t horiz_pixels_per_meter; // not used. + int32_t vert_pixels_per_meter; // not used. + uint32_t n_colours_in_palette; // + uint32_t n_important_colours; // not used. + /* NOTE(Anton) a DIB header may end here at 40-bytes. be careful using sizeof() */ + /* if 'compression' value, above, is set to 3 ie the image is 16 or 32-bit, then these colour channel masks follow the headers. + these are big-endian order bit masks to assign bits of each pixel to different colours. bits used must be contiguous and not overlap. */ + uint32_t bitmask_r; + uint32_t bitmask_g; + uint32_t bitmask_b; +} _bmp_dib_BITMAPINFOHEADER_t; +#pragma pack( pop ) + +typedef enum _bmp_compression_t { + BI_RGB = 0, + BI_RLE8 = 1, + BI_RLE4 = 2, + BI_BITFIELDS = 3, + BI_JPEG = 4, + BI_PNG = 5, + BI_ALPHABITFIELDS = 6, + BI_CMYK = 11, + BI_CMYKRLE8 = 12, + BI_CMYRLE4 = 13 +} _bmp_compression_t; + +/* convenience struct and file->memory function */ +typedef struct _entire_file_t { + void* data; + size_t sz; +} _entire_file_t; + +/* +RETURNS +- true on success. record->data is allocated memory and must be freed by the caller. +- false on any error. Any allocated memory is freed if false is returned */ +static bool _read_entire_file( const char* filename, _entire_file_t* record ) { + FILE* fp = fopen( filename, "rb" ); + if ( !fp ) { return false; } + fseek( fp, 0L, SEEK_END ); + record->sz = (size_t)ftell( fp ); + + // Immediately bail on anything larger than _BMP_MAX_IMAGE_FILE_SIZE. + if (record->sz > _BMP_MAX_IMAGE_FILE_SIZE) { + fclose( fp ); + return false; + } + + record->data = malloc( record->sz ); + if ( !record->data ) { + fclose( fp ); + return false; + } + rewind( fp ); + size_t nr = fread( record->data, record->sz, 1, fp ); + fclose( fp ); + if ( 1 != nr ) { return false; } + return true; +} + +static bool _validate_file_hdr( _bmp_file_header_t* file_hdr_ptr, size_t file_sz ) { + if ( !file_hdr_ptr ) { return false; } + if ( file_hdr_ptr->file_type[0] != 'B' || file_hdr_ptr->file_type[1] != 'M' ) { return false; } + if ( file_hdr_ptr->image_data_offset > file_sz ) { return false; } + return true; +} + +static bool _validate_dib_hdr( _bmp_dib_BITMAPINFOHEADER_t* dib_hdr_ptr, size_t file_sz ) { + if ( !dib_hdr_ptr ) { return false; } + if ( _BMP_FILE_HDR_SZ + dib_hdr_ptr->this_header_sz > file_sz ) { return false; } + if ( ( 32 == dib_hdr_ptr->bpp || 16 == dib_hdr_ptr->bpp ) && ( BI_BITFIELDS != dib_hdr_ptr->compression_method && BI_ALPHABITFIELDS != dib_hdr_ptr->compression_method ) ) { + return false; + } + if ( BI_RGB != dib_hdr_ptr->compression_method && BI_BITFIELDS != dib_hdr_ptr->compression_method && BI_ALPHABITFIELDS != dib_hdr_ptr->compression_method ) { + return false; + } + // NOTE(Anton) using abs() in the if-statement was blowing up on large negative numbers. switched to labs() + if ( 0 == dib_hdr_ptr->w || 0 == dib_hdr_ptr->h || labs( dib_hdr_ptr->w ) > _BMP_MAX_DIMS || labs( dib_hdr_ptr->h ) > _BMP_MAX_DIMS ) { return false; } + + /* NOTE(Anton) if images reliably used n_colours_in_palette we could have done a palette/file size integrity check here. + because some always set 0 then we have to check every palette indexing as we read them */ + return true; +} + +/* NOTE(Anton) this could have ifdef branches on different compilers for the intrinsics versions for perf */ +static uint32_t _bitscan( uint32_t dword ) { + for ( uint32_t i = 0; i < 32; i++ ) { + if ( 1 & dword ) { return i; } + dword = dword >> 1; + } + return (uint32_t)-1; +} + +unsigned char* apg_bmp_read( const char* filename, int* w, int* h, unsigned int* n_chans ) { + if ( !filename || !w || !h || !n_chans ) { return NULL; } + + // read in the whole file into memory first - much faster than parsing on-the-fly + _entire_file_t record; + if ( !_read_entire_file( filename, &record ) ) { return NULL; } + if ( record.sz < _BMP_MIN_HDR_SZ ) { + free( record.data ); + return NULL; + } + + // grab and validate the first, file, header + _bmp_file_header_t* file_hdr_ptr = (_bmp_file_header_t*)record.data; + if ( !_validate_file_hdr( file_hdr_ptr, record.sz ) ) { + free( record.data ); + return NULL; + } + + // grad and validate the second, DIB, header + _bmp_dib_BITMAPINFOHEADER_t* dib_hdr_ptr = (_bmp_dib_BITMAPINFOHEADER_t*)( (uint8_t*)record.data + _BMP_FILE_HDR_SZ ); + if ( !_validate_dib_hdr( dib_hdr_ptr, record.sz ) ) { + free( record.data ); + return NULL; + } + + // bitmaps can have negative dims to indicate the image should be flipped + uint32_t width = *w = abs( dib_hdr_ptr->w ); + uint32_t height = *h = abs( dib_hdr_ptr->h ); + + // TODO(Anton) flip image memory at the end if this is true. because doing it per row was making me write bugs. + // bool vertically_flip = dib_hdr_ptr->h > 0 ? false : true; + + // channel count and palette are not well defined in the header so we make a good guess here + uint32_t n_dst_chans = 3, n_src_chans = 3; + bool has_palette = false; + switch ( dib_hdr_ptr->bpp ) { + case 32: n_dst_chans = n_src_chans = 4; break; // technically can be RGB but not supported + case 24: n_dst_chans = n_src_chans = 3; break; // technically can be RGBA but not supported + case 8: // seems to always use a BGR0 palette, even for greyscale + n_dst_chans = 3; + has_palette = true; + n_src_chans = 1; + break; + case 4: // always has a palette - needed for a MS-saved BMP + n_dst_chans = 3; + has_palette = true; + n_src_chans = 1; + break; + case 1: // 1-bpp means the palette has 3 colour channels with 2 colours i.e. monochrome but not always black & white + n_dst_chans = 3; + has_palette = true; + n_src_chans = 1; + break; + default: // this includes 2bpp and 16bpp + free( record.data ); + return NULL; + } // endswitch + *n_chans = n_dst_chans; + // NOTE(Anton) some image formats are not allowed a palette - could check for a bad header spec here also + if ( dib_hdr_ptr->n_colours_in_palette > 0 ) { has_palette = true; } + +#ifdef APG_BMP_DEBUG_OUTPUT + printf( "apg_bmp_debug: reading image\n|-filename `%s`\n|-dims %ux%u pixels\n|-bpp %u\n|-n_src_chans %u\n|-n_dst_chans %u\n", filename, *w, *h, + dib_hdr_ptr->bpp, n_src_chans, n_dst_chans ); +#endif + + uint32_t palette_offset = _BMP_FILE_HDR_SZ + dib_hdr_ptr->this_header_sz; + bool has_bitmasks = false; + if ( BI_BITFIELDS == dib_hdr_ptr->compression_method || BI_ALPHABITFIELDS == dib_hdr_ptr->compression_method ) { + has_bitmasks = true; + palette_offset += 12; + } + if ( palette_offset > record.sz ) { + free( record.data ); + return NULL; + } + + // work out if any padding how much to skip at end of each row + uint32_t unpadded_row_sz = width * n_src_chans; + // bit-encoded palette indices have different padding properties + if ( 4 == dib_hdr_ptr->bpp ) { + unpadded_row_sz = width % 2 > 0 ? width / 2 + 1 : width / 2; // find how many whole bytes required for this bit width + } + if ( 1 == dib_hdr_ptr->bpp ) { + unpadded_row_sz = width % 8 > 0 ? width / 8 + 1 : width / 8; // find how many whole bytes required for this bit width + } + uint32_t row_padding_sz = 0 == unpadded_row_sz % 4 ? 0 : 4 - ( unpadded_row_sz % 4 ); // NOTE(Anton) didn't expect operator precedence of - over % + + // another file size integrity check: partially validate source image data size + // 'image_data_offset' is by row padded to 4 bytes and is either colour data or palette indices. + if ( file_hdr_ptr->image_data_offset + ( unpadded_row_sz + row_padding_sz ) * height > record.sz ) { + free( record.data ); + return NULL; + } + + // find which bit number each colour channel starts at, so we can separate colours out + uint32_t bitshift_rgba[4] = {0, 0, 0, 0}; // NOTE(Anton) noticed this was int and not uint32_t so changed it. 17 Mar 2020 + uint32_t bitmask_a = 0; + if ( has_bitmasks ) { + bitmask_a = ~( dib_hdr_ptr->bitmask_r | dib_hdr_ptr->bitmask_g | dib_hdr_ptr->bitmask_b ); + bitshift_rgba[0] = _bitscan( dib_hdr_ptr->bitmask_r ); + bitshift_rgba[1] = _bitscan( dib_hdr_ptr->bitmask_g ); + bitshift_rgba[2] = _bitscan( dib_hdr_ptr->bitmask_b ); + bitshift_rgba[3] = _bitscan( bitmask_a ); + } + + // allocate memory for the output pixels block. cast to size_t in case width and height are both the max of 65536 and n_dst_chans > 1 + unsigned char* dst_img_ptr = malloc( (size_t)width * (size_t)height * (size_t)n_dst_chans ); + if ( !dst_img_ptr ) { + free( record.data ); + return NULL; + } + + uint8_t* palette_data_ptr = (uint8_t*)record.data + palette_offset; + uint8_t* src_img_ptr = (uint8_t*)record.data + file_hdr_ptr->image_data_offset; + size_t dst_stride_sz = width * n_dst_chans; + + // == 32-bpp -> 32-bit RGBA. == 32-bit and 16-bit require bitmasks + if ( 32 == dib_hdr_ptr->bpp ) { + // check source image has enough data in it to read from + if ( (size_t)file_hdr_ptr->image_data_offset + (size_t)height * (size_t)width * (size_t)n_src_chans > record.sz ) { + free( record.data ); + free( dst_img_ptr ); + return NULL; + } + size_t src_byte_idx = 0; + for ( uint32_t r = 0; r < height; r++ ) { + size_t dst_pixels_idx = r * dst_stride_sz; + for ( uint32_t c = 0; c < width; c++ ) { + uint32_t pixel; + memcpy( &pixel, &src_img_ptr[src_byte_idx], 4 ); + // NOTE(Anton) the below assumes 32-bits is always RGBA 1 byte per channel. 10,10,10 RGB exists though and isn't handled. + dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & dib_hdr_ptr->bitmask_r ) >> bitshift_rgba[0] ); + dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & dib_hdr_ptr->bitmask_g ) >> bitshift_rgba[1] ); + dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & dib_hdr_ptr->bitmask_b ) >> bitshift_rgba[2] ); + dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & bitmask_a ) >> bitshift_rgba[3] ); + src_byte_idx += 4; + } + src_byte_idx += row_padding_sz; + } + + // == 8-bpp -> 24-bit RGB == + } else if ( 8 == dib_hdr_ptr->bpp && has_palette ) { + // validate indices (body of image data) fits in file + if ( file_hdr_ptr->image_data_offset + height * width > record.sz ) { + free( record.data ); + free( dst_img_ptr ); + return NULL; + } + size_t src_byte_idx = 0; + for ( uint32_t r = 0; r < height; r++ ) { + size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz; + for ( uint32_t c = 0; c < width; c++ ) { + // "most palettes are 4 bytes in RGB0 order but 3 for..." - it was actually BRG0 in old images -- Anton + uint8_t index = src_img_ptr[src_byte_idx]; // 8-bit index value per pixel + + if ( palette_offset + index * 4 + 2 >= record.sz ) { + free( record.data ); + return dst_img_ptr; + } + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[index * 4 + 2]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[index * 4 + 1]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[index * 4 + 0]; + src_byte_idx++; + } + src_byte_idx += row_padding_sz; + } + + // == 4-bpp (16-colour) -> 24-bit RGB == + } else if ( 4 == dib_hdr_ptr->bpp && has_palette ) { + size_t src_byte_idx = 0; + for ( uint32_t r = 0; r < height; r++ ) { + size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz; + for ( uint32_t c = 0; c < width; c++ ) { + if ( file_hdr_ptr->image_data_offset + src_byte_idx > record.sz ) { + free( record.data ); + free( dst_img_ptr ); + return NULL; + } + // handle 2 pixels at a time + uint8_t pixel_duo = src_img_ptr[src_byte_idx]; + uint8_t a_index = ( 0xFF & pixel_duo ) >> 4; + uint8_t b_index = 0xF & pixel_duo; + + if ( palette_offset + a_index * 4 + 2 >= record.sz ) { // invalid src image + free( record.data ); + return dst_img_ptr; + } + if ( dst_pixels_idx + 3 > width * height * n_dst_chans ) { // done + free( record.data ); + return dst_img_ptr; + } + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[a_index * 4 + 2]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[a_index * 4 + 1]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[a_index * 4 + 0]; + if ( ++c >= width ) { // advance a column + c = 0; + r++; + if ( r >= height ) { // done. no need to get second pixel. eg a 1x1 pixel image. + free( record.data ); + return dst_img_ptr; + } + dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz; + } + + if ( palette_offset + b_index * 4 + 2 >= record.sz ) { // invalid src image + free( record.data ); + return dst_img_ptr; + } + if ( dst_pixels_idx + 3 > width * height * n_dst_chans ) { // done. probably redundant check since checking r >= height. + free( record.data ); + return dst_img_ptr; + } + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[b_index * 4 + 2]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[b_index * 4 + 1]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[b_index * 4 + 0]; + src_byte_idx++; + } + src_byte_idx += row_padding_sz; + } + + // == 1-bpp -> 24-bit RGB == + } else if ( 1 == dib_hdr_ptr->bpp && has_palette ) { + /* encoding method for monochrome is not well documented. + a 2x2 pixel image is stored as 4 1-bit palette indexes + the palette is stored as any 2 RGB0 colours (not necessarily B&W) + so for an image with indexes like so: + 1 1 + 0 1 + it is bit-encoded as follows, starting at MSB: + 01000000 00000000 00000000 00000000 (first byte val 64) + 11000000 00000000 00000000 00000000 (first byte val 192) + data is still split by row and each row padded to 4 byte multiples + */ + size_t src_byte_idx = 0; + for ( uint32_t r = 0; r < height; r++ ) { + uint8_t bit_idx = 0; // used in monochrome + size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz; + for ( uint32_t c = 0; c < width; c++ ) { + if ( 8 == bit_idx ) { // start reading from the next byte + src_byte_idx++; + bit_idx = 0; + } + if ( file_hdr_ptr->image_data_offset + src_byte_idx > record.sz ) { + free( record.data ); + return dst_img_ptr; + } + uint8_t pixel_oct = src_img_ptr[src_byte_idx]; + uint8_t bit = 128 >> bit_idx; + uint8_t masked = pixel_oct & bit; + uint8_t palette_idx = masked > 0 ? 1 : 0; + + if ( palette_offset + palette_idx * 4 + 2 >= record.sz ) { + free( record.data ); + return dst_img_ptr; + } + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[palette_idx * 4 + 2]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[palette_idx * 4 + 1]; + dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[palette_idx * 4 + 0]; + bit_idx++; + } + src_byte_idx += ( row_padding_sz + 1 ); // 1bpp is special here + } + + // == 24-bpp -> 24-bit RGB == (but also should handle some other n_chans cases) + } else { + // NOTE(Anton) this only supports 1 byte per channel + if ( file_hdr_ptr->image_data_offset + height * width * n_dst_chans > record.sz ) { + free( record.data ); + free( dst_img_ptr ); + return NULL; + } + size_t src_byte_idx = 0; + for ( uint32_t r = 0; r < height; r++ ) { + size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz; + for ( uint32_t c = 0; c < width; c++ ) { + // re-orders from BGR to RGB + if ( n_dst_chans > 3 ) { dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx + 3]; } + if ( n_dst_chans > 2 ) { dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx + 2]; } + if ( n_dst_chans > 1 ) { dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx + 1]; } + dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx]; + src_byte_idx += n_src_chans; + } + src_byte_idx += row_padding_sz; + } + } // endif bpp + + free( record.data ); + return dst_img_ptr; +} + +void apg_bmp_free( unsigned char* pixels_ptr ) { + if ( !pixels_ptr ) { return; } + free( pixels_ptr ); +} + +unsigned int apg_bmp_write( const char* filename, unsigned char* pixels_ptr, int w, int h, unsigned int n_chans ) { + if ( !filename || !pixels_ptr ) { return 0; } + if ( 0 == w || 0 == h ) { return 0; } + if ( labs( w ) > _BMP_MAX_DIMS || labs( h ) > _BMP_MAX_DIMS ) { return 0; } + if ( n_chans != 3 && n_chans != 4 ) { return 0; } + + uint32_t height = (uint32_t)labs( h ); + uint32_t width = (uint32_t)labs( w ); + // work out if any padding how much to skip at end of each row + const size_t unpadded_row_sz = width * n_chans; + const size_t row_padding_sz = 0 == unpadded_row_sz % 4 ? 0 : 4 - unpadded_row_sz % 4; + const size_t row_sz = unpadded_row_sz + row_padding_sz; + const size_t dst_pixels_padded_sz = row_sz * height; + + const size_t dib_hdr_sz = sizeof( _bmp_dib_BITMAPINFOHEADER_t ); + _bmp_file_header_t file_hdr; + { + file_hdr.file_type[0] = 'B'; + file_hdr.file_type[1] = 'M'; + file_hdr.file_sz = _BMP_FILE_HDR_SZ + (uint32_t)dib_hdr_sz + (uint32_t)dst_pixels_padded_sz; + file_hdr.reserved1 = 0; + file_hdr.reserved2 = 0; + file_hdr.image_data_offset = _BMP_FILE_HDR_SZ + (uint32_t)dib_hdr_sz; + } + _bmp_dib_BITMAPINFOHEADER_t dib_hdr; + { + dib_hdr.this_header_sz = _BMP_MIN_DIB_HDR_SZ; // NOTE: must be 40 and not include the bitmask memory in size here + dib_hdr.w = w; + dib_hdr.h = h; + dib_hdr.n_planes = 1; + dib_hdr.bpp = 3 == n_chans ? 24 : 32; + dib_hdr.compression_method = 3 == n_chans ? BI_RGB : BI_BITFIELDS; + dib_hdr.image_uncompressed_sz = 0; + dib_hdr.horiz_pixels_per_meter = 0; + dib_hdr.vert_pixels_per_meter = 0; + dib_hdr.n_colours_in_palette = 0; + dib_hdr.n_important_colours = 0; + // big-endian masks. only used in BI_BITFIELDS and BI_ALPHABITFIELDS ( 16 and 32-bit images ) + // important note: GIMP stores BMP data in this array order for 32-bit: [A][B][G][R] + dib_hdr.bitmask_r = 0xFF000000; + dib_hdr.bitmask_g = 0x00FF0000; + dib_hdr.bitmask_b = 0x0000FF00; + } + + uint8_t* dst_pixels_ptr = malloc( dst_pixels_padded_sz ); + if ( !dst_pixels_ptr ) { return 0; } + { + size_t dst_byte_idx = 0; + uint8_t padding[4] = {0, 0, 0, 0}; + uint8_t rgba[4] = {0, 0, 0, 0}; + uint8_t bgra[4] = {0, 0, 0, 0}; + + for ( uint32_t row = 0; row < height; row++ ) { + size_t src_byte_idx = ( height - 1 - row ) * n_chans * width; + for ( uint32_t col = 0; col < width; col++ ) { + for ( uint32_t chan = 0; chan < n_chans; chan++ ) { rgba[chan] = pixels_ptr[src_byte_idx++]; } + if ( 3 == n_chans ) { + bgra[0] = rgba[2]; + bgra[1] = rgba[1]; + bgra[2] = rgba[0]; + } else { + /* NOTE(Anton) RGBA with alpha channel would be better supported with an extended DIB header */ + bgra[0] = rgba[3]; + bgra[1] = rgba[2]; + bgra[2] = rgba[1]; + bgra[3] = rgba[0]; // alpha + } + memcpy( &dst_pixels_ptr[dst_byte_idx], bgra, n_chans ); + dst_byte_idx += (size_t)n_chans; + } // endfor col + if ( row_padding_sz > 0 ) { + memcpy( &dst_pixels_ptr[dst_byte_idx], padding, row_padding_sz ); + dst_byte_idx += row_padding_sz; + } + } // endfor row + } + { + FILE* fp = fopen( filename, "wb" ); + if ( !fp ) { + free( dst_pixels_ptr ); + return 0; + } + if ( 1 != fwrite( &file_hdr, _BMP_FILE_HDR_SZ, 1, fp ) ) { + free( dst_pixels_ptr ); + fclose( fp ); + return 0; + } + if ( 1 != fwrite( &dib_hdr, dib_hdr_sz, 1, fp ) ) { + free( dst_pixels_ptr ); + fclose( fp ); + return 0; + } + if ( 1 != fwrite( dst_pixels_ptr, dst_pixels_padded_sz, 1, fp ) ) { + free( dst_pixels_ptr ); + fclose( fp ); + return 0; + } + fclose( fp ); + } + free( dst_pixels_ptr ); + + return 1; +} diff --git a/thirdparty/basis_universal/encoder/apg_bmp.h b/thirdparty/basis_universal/encoder/apg_bmp.h new file mode 100644 index 0000000000..8cd73b62e0 --- /dev/null +++ b/thirdparty/basis_universal/encoder/apg_bmp.h @@ -0,0 +1,123 @@ +/* +BMP File Reader/Writer Implementation +Anton Gerdelan +Version: 3.1 18 March 2020. +Licence: see bottom of file. +C89 ( Implementation is C99 ) + +Contributors: +- Anton Gerdelan - Initial code. +- Saija Sorsa - Fuzz testing. + +Instructions: +- Just drop this header, and the matching .c file into your project. +- To get debug printouts during parsing define APG_BMP_DEBUG_OUTPUT. + +Advantages: +- The implementation is fast, simple, and supports more formats than most BMP reader libraries. +- The reader function is fuzzed with AFL https://lcamtuf.coredump.cx/afl/. +- The reader is robust to large files and malformed files, and will return any valid partial data in an image. +- Reader supports 32bpp (with alpha channel), 24bpp, 8bpp, 4bpp, and 1bpp monochrome BMP images. +- Reader handles indexed BMP images using a colour palette. +- Writer supports 32bpp RGBA and 24bpp uncompressed RGB images. + +Current Limitations: +- 16-bit images not supported (don't have any samples to test on). +- No support for interleaved channel bit layouts eg RGB101010 RGB555 RGB565. +- No support for compressed BMP images, although in practice these are not used. +- Output images with alpha channel are written in BITMAPINFOHEADER format. + For better alpha support in other apps the 124-bit v5 header could be used instead, + at the cost of some backward compatibility and bloat. + +To Do: +- FUZZING + - create a unique fuzz test set for (8,4,1 BPP). +- (maybe) FEATURE Flipping the image based on negative width and height in header, and/or function arguments. +- (maybe) PERF ifdef intrinsics/asm for bitscan. Platform-specific code so won't include unless necessary. +- (maybe) FEATURE Add parameter for padding output memory to eg 4-byte alignment or n channels. +- (maybe) FEATURE Improved apps support in alpha channel writing (using v5 header). +*/ + +#ifndef APG_BMP_H_ +#define APG_BMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* CPP */ + +/* Reads a bitmap from a file, allocates memory for the raw image data, and returns it. +PARAMS + * w,h, - Retrieves the width and height of the BMP in pixels. + * n_chans - Retrieves the number of channels in the BMP. +RETURNS + * Tightly-packed pixel memory in RGBA order. The caller must call free() on the memory. + * NULL on any error. Any allocated memory is freed before returning NULL. */ +unsigned char* apg_bmp_read( const char* filename, int* w, int* h, unsigned int* n_chans ); + +/* Calls free() on memory created by apg_bmp_read */ +void apg_bmp_free( unsigned char* pixels_ptr ); + +/* Writes a bitmap to a file. +PARAMS + * filename - e.g."my_bitmap.bmp". Must not be NULL. + * pixels_ptr - Pointer to tightly-packed pixel memory in RGBA order. Must not be NULL. There must be abs(w)*abs(h)*n_chans bytes in the memory pointed to. + * w,h, - Width and height of the image in pixels. + * n_chans - The number of channels in the BMP. 3 or 4 supported for writing, which means RGB or RGBA memory, respectively. +RETURNS + * Zero on any error, non zero on success. */ +unsigned int apg_bmp_write( const char* filename, unsigned char* pixels_ptr, int w, int h, unsigned int n_chans ); + +#ifdef __cplusplus +} +#endif /* CPP */ + +#endif /*_APG_BMP_H_ */ + +/* +------------------------------------------------------------------------------------- +This software is available under two licences - you may use it under either licence. +------------------------------------------------------------------------------------- +FIRST LICENCE OPTION + +> Apache License +> Version 2.0, January 2004 +> http://www.apache.org/licenses/ +> Copyright 2019 Anton Gerdelan. +> Licensed under the Apache License, Version 2.0 (the "License"); +> you may not use this file except in compliance with the License. +> You may obtain a copy of the License at +> http://www.apache.org/licenses/LICENSE-2.0 +> Unless required by applicable law or agreed to in writing, software +> distributed under the License is distributed on an "AS IS" BASIS, +> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +> See the License for the specific language governing permissions and +> limitations under the License. +------------------------------------------------------------------------------------- +SECOND LICENCE OPTION + +> This is free and unencumbered software released into the public domain. +> +> Anyone is free to copy, modify, publish, use, compile, sell, or +> distribute this software, either in source code form or as a compiled +> binary, for any purpose, commercial or non-commercial, and by any +> means. +> +> In jurisdictions that recognize copyright laws, the author or authors +> of this software dedicate any and all copyright interest in the +> software to the public domain. We make this dedication for the benefit +> of the public at large and to the detriment of our heirs and +> successors. We intend this dedication to be an overt act of +> relinquishment in perpetuity of all present and future rights to this +> software under copyright law. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +> IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +> OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +> ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +> OTHER DEALINGS IN THE SOFTWARE. +> +> For more information, please refer to <http://unlicense.org> +------------------------------------------------------------------------------------- +*/ diff --git a/thirdparty/basis_universal/basisu_astc_decomp.cpp b/thirdparty/basis_universal/encoder/basisu_astc_decomp.cpp index cc0a6ced7a..53bccfc515 100644 --- a/thirdparty/basis_universal/basisu_astc_decomp.cpp +++ b/thirdparty/basis_universal/encoder/basisu_astc_decomp.cpp @@ -50,6 +50,13 @@ typedef uint64_t deUint64; #define DE_ASSERT assert +#ifdef _MSC_VER +#pragma warning (disable:4505) // unreferenced local function has been removed +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + namespace basisu_astc { static bool inBounds(int v, int l, int h) @@ -150,7 +157,7 @@ namespace basisu_astc UVec4 asUint() const { - return UVec4(std::max(0, m_c[0]), std::max(0, m_c[1]), std::max(0, m_c[2]), std::max(0, m_c[3])); + return UVec4(basisu::maximum(0, m_c[0]), basisu::maximum(0, m_c[1]), basisu::maximum(0, m_c[2]), basisu::maximum(0, m_c[3])); } int32_t operator[] (uint32_t idx) const { assert(idx < 4); return m_c[idx]; } @@ -1256,7 +1263,7 @@ void interpolateWeights (TexelWeightPair* dst, const deUint32 (&unquantizedWeigh const int numWeightsPerTexel = blockMode.isDualPlane ? 2 : 1; const deUint32 scaleX = (1024 + blockWidth/2) / (blockWidth-1); const deUint32 scaleY = (1024 + blockHeight/2) / (blockHeight-1); - DE_ASSERT(blockMode.weightGridWidth*blockMode.weightGridHeight*numWeightsPerTexel <= DE_LENGTH_OF_ARRAY(unquantizedWeights)); + DE_ASSERT(blockMode.weightGridWidth*blockMode.weightGridHeight*numWeightsPerTexel <= (int)DE_LENGTH_OF_ARRAY(unquantizedWeights)); for (int texelY = 0; texelY < blockHeight; texelY++) { for (int texelX = 0; texelX < blockWidth; texelX++) @@ -1548,3 +1555,7 @@ bool decompress(uint8_t *pDst, const uint8_t * data, bool isSRGB, int blockWidth } // astc } // basisu_astc + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/thirdparty/basis_universal/basisu_astc_decomp.h b/thirdparty/basis_universal/encoder/basisu_astc_decomp.h index 6cd053b7b6..9ec2e46076 100644 --- a/thirdparty/basis_universal/basisu_astc_decomp.h +++ b/thirdparty/basis_universal/encoder/basisu_astc_decomp.h @@ -23,7 +23,7 @@ * \brief ASTC Utilities. *//*--------------------------------------------------------------------*/ -#include "transcoder/basisu.h" // to pick up the iterator debug level madness +#include "../transcoder/basisu.h" // to pick up the iterator debug level madness #include <vector> #include <stdint.h> diff --git a/thirdparty/basis_universal/basisu_backend.cpp b/thirdparty/basis_universal/encoder/basisu_backend.cpp index 3a689e58d7..19911fcbb4 100644 --- a/thirdparty/basis_universal/basisu_backend.cpp +++ b/thirdparty/basis_universal/encoder/basisu_backend.cpp @@ -1,5 +1,5 @@ // basisu_backend.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,11 @@ // #include "basisu_backend.h" +#if BASISU_SUPPORT_SSE +#define CPPSPMD_NAME(a) a##_sse41 +#include "basisu_kernels_declares.h" +#endif + #define BASISU_FASTER_SELECTOR_REORDERING 0 #define BASISU_BACKEND_VERIFY(c) verify(c, __LINE__); @@ -176,64 +181,117 @@ namespace basisu void basisu_backend::reoptimize_and_sort_endpoints_codebook(uint32_t total_block_endpoints_remapped, uint_vec& all_endpoint_indices) { basisu_frontend& r = *m_pFront_end; - const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames; + //const bool is_video = r.get_params().m_tex_type == basist::cBASISTexTypeVideoFrames; - if ((total_block_endpoints_remapped) && (m_params.m_compression_level > 0)) + if (m_params.m_used_global_codebooks) { - // We're changed the block endpoint indices, so we need to go and adjust the endpoint codebook (remove unused entries, optimize existing entries that have changed) - uint_vec new_block_endpoints(get_total_blocks()); - - for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) + m_endpoint_remap_table_old_to_new.clear(); + m_endpoint_remap_table_old_to_new.resize(r.get_total_endpoint_clusters()); + for (uint32_t i = 0; i < r.get_total_endpoint_clusters(); i++) + m_endpoint_remap_table_old_to_new[i] = i; + } + else + { + //if ((total_block_endpoints_remapped) && (m_params.m_compression_level > 0)) + if ((total_block_endpoints_remapped) && (m_params.m_compression_level > 1)) { - const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; - const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; - const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; + // We've changed the block endpoint indices, so we need to go and adjust the endpoint codebook (remove unused entries, optimize existing entries that have changed) + uint_vec new_block_endpoints(get_total_blocks()); - for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) - for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) - new_block_endpoints[first_block_index + block_x + block_y * num_blocks_x] = m_slice_encoder_blocks[slice_index](block_x, block_y).m_endpoint_index; - } + for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) + { + const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; + const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; + const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; - int_vec old_to_new_endpoint_indices; - r.reoptimize_remapped_endpoints(new_block_endpoints, old_to_new_endpoint_indices, true); + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + new_block_endpoints[first_block_index + block_x + block_y * num_blocks_x] = m_slice_encoder_blocks[slice_index](block_x, block_y).m_endpoint_index; + } - create_endpoint_palette(); + int_vec old_to_new_endpoint_indices; + r.reoptimize_remapped_endpoints(new_block_endpoints, old_to_new_endpoint_indices, true); - for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) - { - const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; + create_endpoint_palette(); - const uint32_t width = m_slices[slice_index].m_width; - const uint32_t height = m_slices[slice_index].m_height; - const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; - const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; - - for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) { - for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + //const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; + + //const uint32_t width = m_slices[slice_index].m_width; + //const uint32_t height = m_slices[slice_index].m_height; + const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; + const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; + + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) { - const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x; + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + { + //const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x; - encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y); + encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y); - m.m_endpoint_index = old_to_new_endpoint_indices[m.m_endpoint_index]; - } // block_x - } // block_y - } // slice_index + m.m_endpoint_index = old_to_new_endpoint_indices[m.m_endpoint_index]; + } // block_x + } // block_y + } // slice_index + + for (uint32_t i = 0; i < all_endpoint_indices.size(); i++) + all_endpoint_indices[i] = old_to_new_endpoint_indices[all_endpoint_indices[i]]; + + } //if (total_block_endpoints_remapped) + + // Sort endpoint codebook + palette_index_reorderer reorderer; + reorderer.init((uint32_t)all_endpoint_indices.size(), &all_endpoint_indices[0], r.get_total_endpoint_clusters(), nullptr, nullptr, 0); + m_endpoint_remap_table_old_to_new = reorderer.get_remap_table(); + } - for (uint32_t i = 0; i < all_endpoint_indices.size(); i++) - all_endpoint_indices[i] = old_to_new_endpoint_indices[all_endpoint_indices[i]]; + // For endpoints, old_to_new[] may not be bijective! + // Some "old" entries may be unused and don't get remapped into the "new" array. - } //if (total_block_endpoints_remapped) + m_old_endpoint_was_used.clear(); + m_old_endpoint_was_used.resize(r.get_total_endpoint_clusters()); + uint32_t first_old_entry_index = UINT32_MAX; - // Sort endpoint codebook - palette_index_reorderer reorderer; - reorderer.init((uint32_t)all_endpoint_indices.size(), &all_endpoint_indices[0], r.get_total_endpoint_clusters(), nullptr, nullptr, 0); - m_endpoint_remap_table_old_to_new = reorderer.get_remap_table(); + for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) + { + const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x, num_blocks_y = m_slices[slice_index].m_num_blocks_y; + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + { + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + { + encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y); + const uint32_t old_endpoint_index = m.m_endpoint_index; + m_old_endpoint_was_used[old_endpoint_index] = true; + first_old_entry_index = basisu::minimum(first_old_entry_index, old_endpoint_index); + } // block_x + } // block_y + } // slice_index + + debug_printf("basisu_backend::reoptimize_and_sort_endpoints_codebook: First old entry index: %u\n", first_old_entry_index); + + m_new_endpoint_was_used.clear(); + m_new_endpoint_was_used.resize(r.get_total_endpoint_clusters()); + + m_endpoint_remap_table_new_to_old.clear(); m_endpoint_remap_table_new_to_old.resize(r.get_total_endpoint_clusters()); - for (uint32_t i = 0; i < m_endpoint_remap_table_old_to_new.size(); i++) - m_endpoint_remap_table_new_to_old[m_endpoint_remap_table_old_to_new[i]] = i; + + // Set unused entries in the new array to point to the first used entry in the old array. + m_endpoint_remap_table_new_to_old.set_all(first_old_entry_index); + + for (uint32_t old_index = 0; old_index < m_endpoint_remap_table_old_to_new.size(); old_index++) + { + if (m_old_endpoint_was_used[old_index]) + { + const uint32_t new_index = m_endpoint_remap_table_old_to_new[old_index]; + + m_new_endpoint_was_used[new_index] = true; + + m_endpoint_remap_table_new_to_old[new_index] = old_index; + } + } } void basisu_backend::sort_selector_codebook() @@ -242,7 +300,7 @@ namespace basisu m_selector_remap_table_new_to_old.resize(r.get_total_selector_clusters()); - if (m_params.m_compression_level == 0) + if ((m_params.m_compression_level == 0) || (m_params.m_used_global_codebooks)) { for (uint32_t i = 0; i < r.get_total_selector_clusters(); i++) m_selector_remap_table_new_to_old[i] = i; @@ -336,10 +394,10 @@ namespace basisu for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) { const bool is_iframe = m_slices[slice_index].m_iframe; - const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; + //const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; - const uint32_t width = m_slices[slice_index].m_width; - const uint32_t height = m_slices[slice_index].m_height; + //const uint32_t width = m_slices[slice_index].m_width; + //const uint32_t height = m_slices[slice_index].m_height; const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; const int prev_frame_slice_index = find_video_frame(slice_index, -1); @@ -393,6 +451,7 @@ namespace basisu BASISU_BACKEND_VERIFY(total_invalid_crs == 0); } + void basisu_backend::create_encoder_blocks() { basisu_frontend& r = *m_pFront_end; @@ -411,8 +470,8 @@ namespace basisu const bool is_iframe = m_slices[slice_index].m_iframe; const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; - const uint32_t width = m_slices[slice_index].m_width; - const uint32_t height = m_slices[slice_index].m_height; + //const uint32_t width = m_slices[slice_index].m_width; + //const uint32_t height = m_slices[slice_index].m_height; const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; @@ -590,7 +649,7 @@ namespace basisu { for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) { - const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; + //const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; const uint32_t width = m_slices[slice_index].m_width; const uint32_t height = m_slices[slice_index].m_height; const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; @@ -603,7 +662,7 @@ namespace basisu { for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) { - const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x; + //const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x; encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y); @@ -662,7 +721,7 @@ namespace basisu histogram selector_histogram(r.get_total_selector_clusters() + basist::MAX_SELECTOR_HISTORY_BUF_SIZE + 1); histogram selector_history_buf_rle_histogram(1 << basist::SELECTOR_HISTORY_BUF_RLE_COUNT_BITS); - std::vector<uint_vec> selector_syms(m_slices.size()); + basisu::vector<uint_vec> selector_syms(m_slices.size()); const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = r.get_total_selector_clusters(); const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX + basist::MAX_SELECTOR_HISTORY_BUF_SIZE; @@ -672,7 +731,7 @@ namespace basisu histogram delta_endpoint_histogram(r.get_total_endpoint_clusters()); histogram endpoint_pred_histogram(basist::ENDPOINT_PRED_TOTAL_SYMBOLS); - std::vector<uint_vec> endpoint_pred_syms(m_slices.size()); + basisu::vector<uint_vec> endpoint_pred_syms(m_slices.size()); uint32_t total_endpoint_indices_remapped = 0; @@ -680,11 +739,11 @@ namespace basisu for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) { - const int prev_frame_slice_index = is_video ? find_video_frame(slice_index, -1) : -1; - const int next_frame_slice_index = is_video ? find_video_frame(slice_index, 1) : -1; + //const int prev_frame_slice_index = is_video ? find_video_frame(slice_index, -1) : -1; + //const int next_frame_slice_index = is_video ? find_video_frame(slice_index, 1) : -1; const uint32_t first_block_index = m_slices[slice_index].m_first_block_index; - const uint32_t width = m_slices[slice_index].m_width; - const uint32_t height = m_slices[slice_index].m_height; + //const uint32_t width = m_slices[slice_index].m_width; + //const uint32_t height = m_slices[slice_index].m_height; const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; @@ -702,7 +761,7 @@ namespace basisu { for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) { - const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x; + //const uint32_t block_index = first_block_index + block_x + block_y * num_blocks_x; encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y); @@ -723,6 +782,7 @@ namespace basisu } // block_x } // block_y + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) { for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) @@ -821,6 +881,10 @@ namespace basisu if (trial_idx == new_endpoint_index) continue; + // Skip it if this new endpoint palette entry is actually never used. + if (!m_new_endpoint_was_used[trial_idx]) + continue; + const etc1_endpoint_palette_entry& p = m_endpoint_palette[m_endpoint_remap_table_new_to_old[trial_idx]]; trial_etc_blk.set_block_color5_etc1s(p.m_color5); trial_etc_blk.set_inten_tables_etc1s(p.m_inten5); @@ -884,23 +948,32 @@ namespace basisu { const pixel_block& src_pixels = r.get_source_pixel_block(block_index); - etc_block etc_blk(r.get_output_block(block_index)); + const etc_block& etc_blk = r.get_output_block(block_index); color_rgba etc_blk_unpacked[16]; unpack_etc1(etc_blk, etc_blk_unpacked); uint64_t cur_err = 0; - for (uint32_t p = 0; p < 16; p++) - cur_err += color_distance(r.get_params().m_perceptual, src_pixels.get_ptr()[p], etc_blk_unpacked[p], false); - + if (r.get_params().m_perceptual) + { + for (uint32_t p = 0; p < 16; p++) + cur_err += color_distance(true, src_pixels.get_ptr()[p], etc_blk_unpacked[p], false); + } + else + { + for (uint32_t p = 0; p < 16; p++) + cur_err += color_distance(false, src_pixels.get_ptr()[p], etc_blk_unpacked[p], false); + } + uint64_t best_trial_err = UINT64_MAX; int best_trial_idx = 0; uint32_t best_trial_history_buf_idx = 0; - const float selector_remap_thresh = maximum(1.0f, m_params.m_selector_rdo_quality_thresh); //2.5f; const bool use_strict_search = (m_params.m_compression_level == 0) && (selector_remap_thresh == 1.0f); + const uint64_t limit_err = (uint64_t)ceilf(cur_err * selector_remap_thresh); + for (uint32_t j = 0; j < selector_history_buf.size(); j++) { const int trial_idx = selector_history_buf[j]; @@ -917,31 +990,43 @@ namespace basisu } else { - for (uint32_t sy = 0; sy < 4; sy++) - for (uint32_t sx = 0; sx < 4; sx++) - etc_blk.set_selector(sx, sy, m_selector_palette[m_selector_remap_table_new_to_old[trial_idx]](sx, sy)); + uint64_t trial_err = 0; + const uint64_t thresh_err = minimum(limit_err, best_trial_err); - // TODO: Optimize this - unpack_etc1(etc_blk, etc_blk_unpacked); + color_rgba block_colors[4]; + etc_blk.get_block_colors(block_colors, 0); - uint64_t trial_err = 0; - const uint64_t thresh_err = minimum((uint64_t)ceilf(cur_err * selector_remap_thresh), best_trial_err); - for (uint32_t p = 0; p < 16; p++) + const uint8_t* pSelectors = &m_selector_palette[m_selector_remap_table_new_to_old[trial_idx]](0, 0); + + if (r.get_params().m_perceptual) { - trial_err += color_distance(r.get_params().m_perceptual, src_pixels.get_ptr()[p], etc_blk_unpacked[p], false); - if (trial_err > thresh_err) - break; + for (uint32_t p = 0; p < 16; p++) + { + uint32_t sel = pSelectors[p]; + trial_err += color_distance(true, src_pixels.get_ptr()[p], block_colors[sel], false); + if (trial_err > thresh_err) + break; + } } - - if (trial_err <= cur_err * selector_remap_thresh) + else { - if (trial_err < best_trial_err) + for (uint32_t p = 0; p < 16; p++) { - best_trial_err = trial_err; - best_trial_idx = trial_idx; - best_trial_history_buf_idx = j; + uint32_t sel = pSelectors[p]; + trial_err += color_distance(false, src_pixels.get_ptr()[p], block_colors[sel], false); + if (trial_err > thresh_err) + break; } } + + if ((trial_err < best_trial_err) && (trial_err <= thresh_err)) + { + assert(trial_err <= limit_err); + + best_trial_err = trial_err; + best_trial_idx = trial_idx; + best_trial_history_buf_idx = j; + } } } @@ -1086,7 +1171,8 @@ namespace basisu total_selector_indices_remapped, total_selector_indices_remapped * 100.0f / get_total_blocks(), total_used_selector_history_buf, total_used_selector_history_buf * 100.0f / get_total_blocks()); - if ((total_endpoint_indices_remapped) && (m_params.m_compression_level > 0)) + //if ((total_endpoint_indices_remapped) && (m_params.m_compression_level > 0)) + if ((total_endpoint_indices_remapped) && (m_params.m_compression_level > 1) && (!m_params.m_used_global_codebooks)) { int_vec unused; r.reoptimize_remapped_endpoints(block_endpoint_indices, unused, false, &block_selector_indices); @@ -1168,8 +1254,8 @@ namespace basisu for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) { - const uint32_t width = m_slices[slice_index].m_width; - const uint32_t height = m_slices[slice_index].m_height; + //const uint32_t width = m_slices[slice_index].m_width; + //const uint32_t height = m_slices[slice_index].m_height; const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x; const uint32_t num_blocks_y = m_slices[slice_index].m_num_blocks_y; @@ -1296,10 +1382,53 @@ namespace basisu { const basisu_frontend& r = *m_pFront_end; + // The endpoint indices may have been changed by the backend's RDO step, so go and figure out which ones are actually used again. + bool_vec old_endpoint_was_used(r.get_total_endpoint_clusters()); + uint32_t first_old_entry_index = UINT32_MAX; + + for (uint32_t slice_index = 0; slice_index < m_slices.size(); slice_index++) + { + const uint32_t num_blocks_x = m_slices[slice_index].m_num_blocks_x, num_blocks_y = m_slices[slice_index].m_num_blocks_y; + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + { + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + { + encoder_block& m = m_slice_encoder_blocks[slice_index](block_x, block_y); + const uint32_t old_endpoint_index = m.m_endpoint_index; + + old_endpoint_was_used[old_endpoint_index] = true; + first_old_entry_index = basisu::minimum(first_old_entry_index, old_endpoint_index); + } // block_x + } // block_y + } // slice_index + + debug_printf("basisu_backend::encode_endpoint_palette: first_old_entry_index: %u\n", first_old_entry_index); + // Maps NEW to OLD endpoints - uint_vec endpoint_remap_table_inv(r.get_total_endpoint_clusters()); + uint_vec endpoint_remap_table_new_to_old(r.get_total_endpoint_clusters()); + endpoint_remap_table_new_to_old.set_all(first_old_entry_index); + + bool_vec new_endpoint_was_used(r.get_total_endpoint_clusters()); + for (uint32_t old_endpoint_index = 0; old_endpoint_index < m_endpoint_remap_table_old_to_new.size(); old_endpoint_index++) - endpoint_remap_table_inv[m_endpoint_remap_table_old_to_new[old_endpoint_index]] = old_endpoint_index; + { + if (old_endpoint_was_used[old_endpoint_index]) + { + const uint32_t new_endpoint_index = m_endpoint_remap_table_old_to_new[old_endpoint_index]; + + new_endpoint_was_used[new_endpoint_index] = true; + + endpoint_remap_table_new_to_old[new_endpoint_index] = old_endpoint_index; + } + } + + // TODO: Some new endpoint palette entries may actually be unused and aren't worth coding. Fix that. + + uint32_t total_unused_new_entries = 0; + for (uint32_t i = 0; i < new_endpoint_was_used.size(); i++) + if (!new_endpoint_was_used[i]) + total_unused_new_entries++; + debug_printf("basisu_backend::encode_endpoint_palette: total_unused_new_entries: %u out of %u\n", total_unused_new_entries, new_endpoint_was_used.size()); bool is_grayscale = true; for (uint32_t old_endpoint_index = 0; old_endpoint_index < (uint32_t)m_endpoint_palette.size(); old_endpoint_index++) @@ -1324,7 +1453,7 @@ namespace basisu for (uint32_t new_endpoint_index = 0; new_endpoint_index < r.get_total_endpoint_clusters(); new_endpoint_index++) { - const uint32_t old_endpoint_index = endpoint_remap_table_inv[new_endpoint_index]; + const uint32_t old_endpoint_index = endpoint_remap_table_new_to_old[new_endpoint_index]; int delta_inten = m_endpoint_palette[old_endpoint_index].m_inten5 - prev_inten; inten_delta_hist.inc(delta_inten & 7); @@ -1390,7 +1519,7 @@ namespace basisu for (uint32_t new_endpoint_index = 0; new_endpoint_index < r.get_total_endpoint_clusters(); new_endpoint_index++) { - const uint32_t old_endpoint_index = endpoint_remap_table_inv[new_endpoint_index]; + const uint32_t old_endpoint_index = endpoint_remap_table_new_to_old[new_endpoint_index]; int delta_inten = (m_endpoint_palette[old_endpoint_index].m_inten5 - prev_inten) & 7; coder.put_code(delta_inten, inten_delta_model); @@ -1644,9 +1773,11 @@ namespace basisu uint32_t basisu_backend::encode() { - const bool is_video = m_pFront_end->get_params().m_tex_type == basist::cBASISTexTypeVideoFrames; + //const bool is_video = m_pFront_end->get_params().m_tex_type == basist::cBASISTexTypeVideoFrames; m_output.m_slice_desc = m_slices; m_output.m_etc1s = m_params.m_etc1s; + m_output.m_uses_global_codebooks = m_params.m_used_global_codebooks; + m_output.m_srgb = m_pFront_end->get_params().m_perceptual; create_endpoint_palette(); create_selector_palette(); diff --git a/thirdparty/basis_universal/basisu_backend.h b/thirdparty/basis_universal/encoder/basisu_backend.h index 1c72fa8cc8..393dccd22f 100644 --- a/thirdparty/basis_universal/basisu_backend.h +++ b/thirdparty/basis_universal/encoder/basisu_backend.h @@ -1,5 +1,5 @@ // basisu_backend.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,10 +14,10 @@ // limitations under the License. #pragma once -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" #include "basisu_enc.h" -#include "transcoder/basisu_transcoder_internal.h" -#include "transcoder/basisu_global_selector_palette.h" +#include "../transcoder/basisu_transcoder_internal.h" +#include "../transcoder/basisu_global_selector_palette.h" #include "basisu_frontend.h" namespace basisu @@ -49,7 +49,7 @@ namespace basisu } }; - typedef std::vector<encoder_block> encoder_block_vec; + typedef basisu::vector<encoder_block> encoder_block_vec; typedef vector2D<encoder_block> encoder_block_vec2D; struct etc1_endpoint_palette_entry @@ -69,7 +69,7 @@ namespace basisu } }; - typedef std::vector<etc1_endpoint_palette_entry> etc1_endpoint_palette_entry_vec; + typedef basisu::vector<etc1_endpoint_palette_entry> etc1_endpoint_palette_entry_vec; struct basisu_backend_params { @@ -84,6 +84,8 @@ namespace basisu uint32_t m_global_sel_codebook_mod_bits; bool m_use_hybrid_sel_codebooks; + bool m_used_global_codebooks; + basisu_backend_params() { clear(); @@ -102,6 +104,7 @@ namespace basisu m_global_sel_codebook_pal_bits = ETC1_GLOBAL_SELECTOR_CODEBOOK_MAX_PAL_BITS; m_global_sel_codebook_mod_bits = basist::etc1_global_palette_entry_modifier::cTotalBits; m_use_hybrid_sel_codebooks = false; + m_used_global_codebooks = false; } }; @@ -111,10 +114,12 @@ namespace basisu { clear(); } + void clear() { clear_obj(*this); } + uint32_t m_first_block_index; uint32_t m_orig_width; @@ -135,11 +140,15 @@ namespace basisu bool m_iframe; }; - typedef std::vector<basisu_backend_slice_desc> basisu_backend_slice_desc_vec; + typedef basisu::vector<basisu_backend_slice_desc> basisu_backend_slice_desc_vec; struct basisu_backend_output { + basist::basis_tex_format m_tex_format; + bool m_etc1s; + bool m_uses_global_codebooks; + bool m_srgb; uint32_t m_num_endpoints; uint32_t m_num_selectors; @@ -150,7 +159,7 @@ namespace basisu basisu_backend_slice_desc_vec m_slice_desc; uint8_vec m_slice_image_tables; - std::vector<uint8_vec> m_slice_image_data; + basisu::vector<uint8_vec> m_slice_image_data; uint16_vec m_slice_image_crcs; basisu_backend_output() @@ -160,7 +169,10 @@ namespace basisu void clear() { + m_tex_format = basist::basis_tex_format::cETC1S; m_etc1s = false; + m_uses_global_codebooks = false; + m_srgb = true; m_num_endpoints = 0; m_num_selectors = 0; @@ -198,6 +210,7 @@ namespace basisu uint32_t encode(); const basisu_backend_output &get_output() const { return m_output; } + const basisu_backend_params& get_params() const { return m_params; } private: basisu_frontend *m_pFront_end; @@ -216,15 +229,17 @@ namespace basisu bool m_was_used; }; - typedef std::vector<etc1_global_selector_cb_entry_desc> etc1_global_selector_cb_entry_desc_vec; + typedef basisu::vector<etc1_global_selector_cb_entry_desc> etc1_global_selector_cb_entry_desc_vec; etc1_global_selector_cb_entry_desc_vec m_global_selector_palette_desc; - std::vector<encoder_block_vec2D> m_slice_encoder_blocks; + basisu::vector<encoder_block_vec2D> m_slice_encoder_blocks; // Maps OLD to NEW endpoint/selector indices uint_vec m_endpoint_remap_table_old_to_new; uint_vec m_endpoint_remap_table_new_to_old; + bool_vec m_old_endpoint_was_used; + bool_vec m_new_endpoint_was_used; uint_vec m_selector_remap_table_old_to_new; diff --git a/thirdparty/basis_universal/basisu_basis_file.cpp b/thirdparty/basis_universal/encoder/basisu_basis_file.cpp index 3e6b1906b9..f4c77bef23 100644 --- a/thirdparty/basis_universal/basisu_basis_file.cpp +++ b/thirdparty/basis_universal/encoder/basisu_basis_file.cpp @@ -1,5 +1,5 @@ // basisu_basis_file.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "basisu_basis_file.h" -#include "transcoder/basisu_transcoder.h" +#include "../transcoder/basisu_transcoder.h" // The output file version. Keep in sync with BASISD_SUPPORTED_BASIS_VERSION. #define BASIS_FILE_VERSION (0x13) @@ -31,15 +31,26 @@ namespace basisu m_header.m_total_images = 0; for (uint32_t i = 0; i < encoder_output.m_slice_desc.size(); i++) m_header.m_total_images = maximum<uint32_t>(m_header.m_total_images, encoder_output.m_slice_desc[i].m_source_file_index + 1); - - m_header.m_format = 0;// basist::block_format::cETC1; + + m_header.m_tex_format = (int)encoder_output.m_tex_format; m_header.m_flags = 0; if (encoder_output.m_etc1s) + { + assert(encoder_output.m_tex_format == basist::basis_tex_format::cETC1S); m_header.m_flags = m_header.m_flags | basist::cBASISHeaderFlagETC1S; + } + else + { + assert(encoder_output.m_tex_format != basist::basis_tex_format::cETC1S); + } if (y_flipped) m_header.m_flags = m_header.m_flags | basist::cBASISHeaderFlagYFlipped; + if (encoder_output.m_uses_global_codebooks) + m_header.m_flags = m_header.m_flags | basist::cBASISHeaderFlagUsesGlobalCodebook; + if (encoder_output.m_srgb) + m_header.m_flags = m_header.m_flags | basist::cBASISHeaderFlagSRGB; for (uint32_t i = 0; i < encoder_output.m_slice_desc.size(); i++) { @@ -57,12 +68,26 @@ namespace basisu m_header.m_userdata1 = userdata1; m_header.m_total_endpoints = encoder_output.m_num_endpoints; - m_header.m_endpoint_cb_file_ofs = m_endpoint_cb_file_ofs; - m_header.m_endpoint_cb_file_size = (uint32_t)encoder_output.m_endpoint_palette.size(); + if (!encoder_output.m_uses_global_codebooks) + { + m_header.m_endpoint_cb_file_ofs = m_endpoint_cb_file_ofs; + m_header.m_endpoint_cb_file_size = (uint32_t)encoder_output.m_endpoint_palette.size(); + } + else + { + assert(!m_endpoint_cb_file_ofs); + } m_header.m_total_selectors = encoder_output.m_num_selectors; - m_header.m_selector_cb_file_ofs = m_selector_cb_file_ofs; - m_header.m_selector_cb_file_size = (uint32_t)encoder_output.m_selector_palette.size(); + if (!encoder_output.m_uses_global_codebooks) + { + m_header.m_selector_cb_file_ofs = m_selector_cb_file_ofs; + m_header.m_selector_cb_file_size = (uint32_t)encoder_output.m_selector_palette.size(); + } + else + { + assert(!m_selector_cb_file_ofs); + } m_header.m_tables_file_ofs = m_tables_file_ofs; m_header.m_tables_file_size = (uint32_t)encoder_output.m_slice_image_tables.size(); @@ -85,7 +110,7 @@ namespace basisu m_images_descs[i].m_level_index = slice_descs[i].m_mip_index; if (slice_descs[i].m_alpha) - m_images_descs[i].m_flags = m_images_descs[i].m_flags | basist::cSliceDescFlagsIsAlphaData; + m_images_descs[i].m_flags = m_images_descs[i].m_flags | basist::cSliceDescFlagsHasAlpha; if (slice_descs[i].m_iframe) m_images_descs[i].m_flags = m_images_descs[i].m_flags | basist::cSliceDescFlagsFrameIsIFrame; @@ -127,14 +152,26 @@ namespace basisu assert(m_comp_data.size() == m_slice_descs_file_ofs); append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&m_images_descs[0]), m_images_descs.size() * sizeof(m_images_descs[0])); - assert(m_comp_data.size() == m_endpoint_cb_file_ofs); - append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&encoder_output.m_endpoint_palette[0]), encoder_output.m_endpoint_palette.size()); + if (!encoder_output.m_uses_global_codebooks) + { + if (encoder_output.m_endpoint_palette.size()) + { + assert(m_comp_data.size() == m_endpoint_cb_file_ofs); + append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&encoder_output.m_endpoint_palette[0]), encoder_output.m_endpoint_palette.size()); + } - assert(m_comp_data.size() == m_selector_cb_file_ofs); - append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&encoder_output.m_selector_palette[0]), encoder_output.m_selector_palette.size()); + if (encoder_output.m_selector_palette.size()) + { + assert(m_comp_data.size() == m_selector_cb_file_ofs); + append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&encoder_output.m_selector_palette[0]), encoder_output.m_selector_palette.size()); + } + } - assert(m_comp_data.size() == m_tables_file_ofs); - append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&encoder_output.m_slice_image_tables[0]), encoder_output.m_slice_image_tables.size()); + if (encoder_output.m_slice_image_tables.size()) + { + assert(m_comp_data.size() == m_tables_file_ofs); + append_vector(m_comp_data, reinterpret_cast<const uint8_t*>(&encoder_output.m_slice_image_tables[0]), encoder_output.m_slice_image_tables.size()); + } assert(m_comp_data.size() == m_first_image_file_ofs); for (uint32_t i = 0; i < slice_descs.size(); i++) @@ -163,8 +200,17 @@ namespace basisu const basisu_backend_slice_desc_vec &slice_descs = encoder_output.m_slice_desc; // The Basis file uses 32-bit fields for lots of stuff, so make sure it's not too large. - uint64_t check_size = (uint64_t)sizeof(basist::basis_file_header) + (uint64_t)sizeof(basist::basis_slice_desc) * slice_descs.size() + + uint64_t check_size = 0; + if (!encoder_output.m_uses_global_codebooks) + { + check_size = (uint64_t)sizeof(basist::basis_file_header) + (uint64_t)sizeof(basist::basis_slice_desc) * slice_descs.size() + (uint64_t)encoder_output.m_endpoint_palette.size() + (uint64_t)encoder_output.m_selector_palette.size() + (uint64_t)encoder_output.m_slice_image_tables.size(); + } + else + { + check_size = (uint64_t)sizeof(basist::basis_file_header) + (uint64_t)sizeof(basist::basis_slice_desc) * slice_descs.size() + + (uint64_t)encoder_output.m_slice_image_tables.size(); + } if (check_size >= 0xFFFF0000ULL) { error_printf("basisu_file::init: File is too large!\n"); @@ -173,10 +219,29 @@ namespace basisu m_header_file_ofs = 0; m_slice_descs_file_ofs = sizeof(basist::basis_file_header); - m_endpoint_cb_file_ofs = m_slice_descs_file_ofs + sizeof(basist::basis_slice_desc) * (uint32_t)slice_descs.size(); - m_selector_cb_file_ofs = m_endpoint_cb_file_ofs + (uint32_t)encoder_output.m_endpoint_palette.size(); - m_tables_file_ofs = m_selector_cb_file_ofs + (uint32_t)encoder_output.m_selector_palette.size(); - m_first_image_file_ofs = m_tables_file_ofs + (uint32_t)encoder_output.m_slice_image_tables.size(); + if (encoder_output.m_tex_format == basist::basis_tex_format::cETC1S) + { + if (encoder_output.m_uses_global_codebooks) + { + m_endpoint_cb_file_ofs = 0; + m_selector_cb_file_ofs = 0; + m_tables_file_ofs = m_slice_descs_file_ofs + sizeof(basist::basis_slice_desc) * (uint32_t)slice_descs.size(); + } + else + { + m_endpoint_cb_file_ofs = m_slice_descs_file_ofs + sizeof(basist::basis_slice_desc) * (uint32_t)slice_descs.size(); + m_selector_cb_file_ofs = m_endpoint_cb_file_ofs + (uint32_t)encoder_output.m_endpoint_palette.size(); + m_tables_file_ofs = m_selector_cb_file_ofs + (uint32_t)encoder_output.m_selector_palette.size(); + } + m_first_image_file_ofs = m_tables_file_ofs + (uint32_t)encoder_output.m_slice_image_tables.size(); + } + else + { + m_endpoint_cb_file_ofs = 0; + m_selector_cb_file_ofs = 0; + m_tables_file_ofs = 0; + m_first_image_file_ofs = m_slice_descs_file_ofs + sizeof(basist::basis_slice_desc) * (uint32_t)slice_descs.size(); + } uint64_t total_file_size = m_first_image_file_ofs; for (uint32_t i = 0; i < encoder_output.m_slice_image_data.size(); i++) diff --git a/thirdparty/basis_universal/basisu_basis_file.h b/thirdparty/basis_universal/encoder/basisu_basis_file.h index df3abbdcfd..98498a0121 100644 --- a/thirdparty/basis_universal/basisu_basis_file.h +++ b/thirdparty/basis_universal/encoder/basisu_basis_file.h @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #pragma once -#include "transcoder/basisu_file_headers.h" +#include "../transcoder/basisu_file_headers.h" #include "basisu_backend.h" namespace basisu @@ -49,7 +49,7 @@ namespace basisu private: basist::basis_file_header m_header; - std::vector<basist::basis_slice_desc> m_images_descs; + basisu::vector<basist::basis_slice_desc> m_images_descs; uint8_vec m_comp_data; diff --git a/thirdparty/basis_universal/encoder/basisu_bc7enc.cpp b/thirdparty/basis_universal/encoder/basisu_bc7enc.cpp new file mode 100644 index 0000000000..06aa7eb8b1 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_bc7enc.cpp @@ -0,0 +1,1984 @@ +// File: basisu_bc7enc.cpp +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_bc7enc.h" + +#ifdef _DEBUG +#define BC7ENC_CHECK_OVERALL_ERROR 1 +#else +#define BC7ENC_CHECK_OVERALL_ERROR 0 +#endif + +using namespace basist; + +namespace basisu +{ + +// Helpers +static inline color_quad_u8 *color_quad_u8_set_clamped(color_quad_u8 *pRes, int32_t r, int32_t g, int32_t b, int32_t a) { pRes->m_c[0] = (uint8_t)clampi(r, 0, 255); pRes->m_c[1] = (uint8_t)clampi(g, 0, 255); pRes->m_c[2] = (uint8_t)clampi(b, 0, 255); pRes->m_c[3] = (uint8_t)clampi(a, 0, 255); return pRes; } +static inline color_quad_u8 *color_quad_u8_set(color_quad_u8 *pRes, int32_t r, int32_t g, int32_t b, int32_t a) { assert((uint32_t)(r | g | b | a) <= 255); pRes->m_c[0] = (uint8_t)r; pRes->m_c[1] = (uint8_t)g; pRes->m_c[2] = (uint8_t)b; pRes->m_c[3] = (uint8_t)a; return pRes; } +static inline bc7enc_bool color_quad_u8_notequals(const color_quad_u8 *pLHS, const color_quad_u8 *pRHS) { return (pLHS->m_c[0] != pRHS->m_c[0]) || (pLHS->m_c[1] != pRHS->m_c[1]) || (pLHS->m_c[2] != pRHS->m_c[2]) || (pLHS->m_c[3] != pRHS->m_c[3]); } +static inline bc7enc_vec4F*vec4F_set_scalar(bc7enc_vec4F*pV, float x) { pV->m_c[0] = x; pV->m_c[1] = x; pV->m_c[2] = x; pV->m_c[3] = x; return pV; } +static inline bc7enc_vec4F*vec4F_set(bc7enc_vec4F*pV, float x, float y, float z, float w) { pV->m_c[0] = x; pV->m_c[1] = y; pV->m_c[2] = z; pV->m_c[3] = w; return pV; } +static inline bc7enc_vec4F*vec4F_saturate_in_place(bc7enc_vec4F*pV) { pV->m_c[0] = saturate(pV->m_c[0]); pV->m_c[1] = saturate(pV->m_c[1]); pV->m_c[2] = saturate(pV->m_c[2]); pV->m_c[3] = saturate(pV->m_c[3]); return pV; } +static inline bc7enc_vec4F vec4F_saturate(const bc7enc_vec4F*pV) { bc7enc_vec4F res; res.m_c[0] = saturate(pV->m_c[0]); res.m_c[1] = saturate(pV->m_c[1]); res.m_c[2] = saturate(pV->m_c[2]); res.m_c[3] = saturate(pV->m_c[3]); return res; } +static inline bc7enc_vec4F vec4F_from_color(const color_quad_u8 *pC) { bc7enc_vec4F res; vec4F_set(&res, pC->m_c[0], pC->m_c[1], pC->m_c[2], pC->m_c[3]); return res; } +static inline bc7enc_vec4F vec4F_add(const bc7enc_vec4F*pLHS, const bc7enc_vec4F*pRHS) { bc7enc_vec4F res; vec4F_set(&res, pLHS->m_c[0] + pRHS->m_c[0], pLHS->m_c[1] + pRHS->m_c[1], pLHS->m_c[2] + pRHS->m_c[2], pLHS->m_c[3] + pRHS->m_c[3]); return res; } +static inline bc7enc_vec4F vec4F_sub(const bc7enc_vec4F*pLHS, const bc7enc_vec4F*pRHS) { bc7enc_vec4F res; vec4F_set(&res, pLHS->m_c[0] - pRHS->m_c[0], pLHS->m_c[1] - pRHS->m_c[1], pLHS->m_c[2] - pRHS->m_c[2], pLHS->m_c[3] - pRHS->m_c[3]); return res; } +static inline float vec4F_dot(const bc7enc_vec4F*pLHS, const bc7enc_vec4F*pRHS) { return pLHS->m_c[0] * pRHS->m_c[0] + pLHS->m_c[1] * pRHS->m_c[1] + pLHS->m_c[2] * pRHS->m_c[2] + pLHS->m_c[3] * pRHS->m_c[3]; } +static inline bc7enc_vec4F vec4F_mul(const bc7enc_vec4F*pLHS, float s) { bc7enc_vec4F res; vec4F_set(&res, pLHS->m_c[0] * s, pLHS->m_c[1] * s, pLHS->m_c[2] * s, pLHS->m_c[3] * s); return res; } +static inline bc7enc_vec4F* vec4F_normalize_in_place(bc7enc_vec4F*pV) { float s = pV->m_c[0] * pV->m_c[0] + pV->m_c[1] * pV->m_c[1] + pV->m_c[2] * pV->m_c[2] + pV->m_c[3] * pV->m_c[3]; if (s != 0.0f) { s = 1.0f / sqrtf(s); pV->m_c[0] *= s; pV->m_c[1] *= s; pV->m_c[2] *= s; pV->m_c[3] *= s; } return pV; } + +// Precomputed weight constants used during least fit determination. For each entry in g_bc7_weights[]: w * w, (1.0f - w) * w, (1.0f - w) * (1.0f - w), w +const float g_bc7_weights1x[2 * 4] = { 0.000000f, 0.000000f, 1.000000f, 0.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +const float g_bc7_weights2x[4 * 4] = { 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.107666f, 0.220459f, 0.451416f, 0.328125f, 0.451416f, 0.220459f, 0.107666f, 0.671875f, 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +const float g_bc7_weights3x[8 * 4] = { 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.019775f, 0.120850f, 0.738525f, 0.140625f, 0.079102f, 0.202148f, 0.516602f, 0.281250f, 0.177979f, 0.243896f, 0.334229f, 0.421875f, 0.334229f, 0.243896f, 0.177979f, 0.578125f, 0.516602f, 0.202148f, + 0.079102f, 0.718750f, 0.738525f, 0.120850f, 0.019775f, 0.859375f, 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +const float g_bc7_weights4x[16 * 4] = { 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.003906f, 0.058594f, 0.878906f, 0.062500f, 0.019775f, 0.120850f, 0.738525f, 0.140625f, 0.041260f, 0.161865f, 0.635010f, 0.203125f, 0.070557f, 0.195068f, 0.539307f, 0.265625f, 0.107666f, 0.220459f, + 0.451416f, 0.328125f, 0.165039f, 0.241211f, 0.352539f, 0.406250f, 0.219727f, 0.249023f, 0.282227f, 0.468750f, 0.282227f, 0.249023f, 0.219727f, 0.531250f, 0.352539f, 0.241211f, 0.165039f, 0.593750f, 0.451416f, 0.220459f, 0.107666f, 0.671875f, 0.539307f, 0.195068f, 0.070557f, 0.734375f, + 0.635010f, 0.161865f, 0.041260f, 0.796875f, 0.738525f, 0.120850f, 0.019775f, 0.859375f, 0.878906f, 0.058594f, 0.003906f, 0.937500f, 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +const float g_astc_weights4x[16 * 4] = { 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.003906f, 0.058594f, 0.878906f, 0.062500f, 0.015625f, 0.109375f, 0.765625f, 0.125000f, 0.035156f, 0.152344f, 0.660156f, 0.187500f, 0.070557f, 0.195068f, 0.539307f, 0.265625f, 0.107666f, 0.220459f, + 0.451416f, 0.328125f, 0.152588f, 0.238037f, 0.371338f, 0.390625f, 0.205322f, 0.247803f, 0.299072f, 0.453125f, 0.299072f, 0.247803f, 0.205322f, 0.546875f, 0.371338f, 0.238037f, 0.152588f, 0.609375f, 0.451416f, 0.220459f, 0.107666f, 0.671875f, 0.539307f, 0.195068f, 0.070557f, 0.734375f, + 0.660156f, 0.152344f, 0.035156f, 0.812500f, 0.765625f, 0.109375f, 0.015625f, 0.875000f, 0.878906f, 0.058594f, 0.003906f, 0.937500f, 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +const float g_astc_weights5x[32 * 4] = { 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.000977f, 0.030273f, 0.938477f, 0.031250f, 0.003906f, 0.058594f, 0.878906f, 0.062500f, 0.008789f, 0.084961f, 0.821289f, + 0.093750f, 0.015625f, 0.109375f, 0.765625f, 0.125000f, 0.024414f, 0.131836f, 0.711914f, 0.156250f, 0.035156f, 0.152344f, 0.660156f, 0.187500f, 0.047852f, 0.170898f, 0.610352f, 0.218750f, 0.062500f, 0.187500f, + 0.562500f, 0.250000f, 0.079102f, 0.202148f, 0.516602f, 0.281250f, 0.097656f, 0.214844f, 0.472656f, 0.312500f, 0.118164f, 0.225586f, 0.430664f, 0.343750f, 0.140625f, 0.234375f, 0.390625f, 0.375000f, 0.165039f, + 0.241211f, 0.352539f, 0.406250f, 0.191406f, 0.246094f, 0.316406f, 0.437500f, 0.219727f, 0.249023f, 0.282227f, 0.468750f, 0.282227f, 0.249023f, 0.219727f, 0.531250f, 0.316406f, 0.246094f, 0.191406f, 0.562500f, + 0.352539f, 0.241211f, 0.165039f, 0.593750f, 0.390625f, 0.234375f, 0.140625f, 0.625000f, 0.430664f, 0.225586f, 0.118164f, 0.656250f, 0.472656f, 0.214844f, 0.097656f, 0.687500f, 0.516602f, 0.202148f, 0.079102f, + 0.718750f, 0.562500f, 0.187500f, 0.062500f, 0.750000f, 0.610352f, 0.170898f, 0.047852f, 0.781250f, 0.660156f, 0.152344f, 0.035156f, 0.812500f, 0.711914f, 0.131836f, 0.024414f, 0.843750f, 0.765625f, 0.109375f, + 0.015625f, 0.875000f, 0.821289f, 0.084961f, 0.008789f, 0.906250f, 0.878906f, 0.058594f, 0.003906f, 0.937500f, 0.938477f, 0.030273f, 0.000977f, 0.968750f, 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +const float g_astc_weights_3levelsx[3 * 4] = { + 0.000000f, 0.000000f, 1.000000f, 0.000000f, + .5f * .5f, (1.0f - .5f) * .5f, (1.0f - .5f) * (1.0f - .5f), .5f, + 1.000000f, 0.000000f, 0.000000f, 1.000000f }; + +static endpoint_err g_bc7_mode_1_optimal_endpoints[256][2]; // [c][pbit] +static const uint32_t BC7ENC_MODE_1_OPTIMAL_INDEX = 2; + +static endpoint_err g_astc_4bit_3bit_optimal_endpoints[256]; // [c] +static const uint32_t BC7ENC_ASTC_4BIT_3BIT_OPTIMAL_INDEX = 2; + +static endpoint_err g_astc_4bit_2bit_optimal_endpoints[256]; // [c] +static const uint32_t BC7ENC_ASTC_4BIT_2BIT_OPTIMAL_INDEX = 1; + +static endpoint_err g_astc_range7_2bit_optimal_endpoints[256]; // [c] +static const uint32_t BC7ENC_ASTC_RANGE7_2BIT_OPTIMAL_INDEX = 1; + +static endpoint_err g_astc_range13_4bit_optimal_endpoints[256]; // [c] +static const uint32_t BC7ENC_ASTC_RANGE13_4BIT_OPTIMAL_INDEX = 2; + +static endpoint_err g_astc_range13_2bit_optimal_endpoints[256]; // [c] +static const uint32_t BC7ENC_ASTC_RANGE13_2BIT_OPTIMAL_INDEX = 1; + +static endpoint_err g_astc_range11_5bit_optimal_endpoints[256]; // [c] +static const uint32_t BC7ENC_ASTC_RANGE11_5BIT_OPTIMAL_INDEX = 13; // not 1, which is optimal, because 26 losslessly maps to BC7 4-bit weights + +astc_quant_bin g_astc_sorted_order_unquant[BC7ENC_TOTAL_ASTC_RANGES][256]; // [sorted unquantized order] + +static uint8_t g_astc_nearest_sorted_index[BC7ENC_TOTAL_ASTC_RANGES][256]; + +static void astc_init() +{ + for (uint32_t range = 0; range < BC7ENC_TOTAL_ASTC_RANGES; range++) + { + if (!astc_is_valid_endpoint_range(range)) + continue; + + const uint32_t levels = astc_get_levels(range); + + uint32_t vals[256]; + // TODO + for (uint32_t i = 0; i < levels; i++) + vals[i] = (unquant_astc_endpoint_val(i, range) << 8) | i; + + std::sort(vals, vals + levels); + + for (uint32_t i = 0; i < levels; i++) + { + uint32_t order = vals[i] & 0xFF; + uint32_t unq = vals[i] >> 8; + + g_astc_sorted_order_unquant[range][i].m_unquant = (uint8_t)unq; + g_astc_sorted_order_unquant[range][i].m_index = (uint8_t)order; + + } // i + +#if 0 + if (g_astc_bise_range_table[range][1] || g_astc_bise_range_table[range][2]) + { + printf("// Range: %u, Levels: %u, Bits: %u, Trits: %u, Quints: %u\n", range, levels, g_astc_bise_range_table[range][0], g_astc_bise_range_table[range][1], g_astc_bise_range_table[range][2]); + + printf("{"); + for (uint32_t i = 0; i < levels; i++) + { + printf("{%u,%u}", g_astc_sorted_order_unquant[range][i].m_index, g_astc_sorted_order_unquant[range][i].m_unquant); + if (i != (levels - 1)) + printf(","); + } + printf("}\n"); + } +#endif + +#if 0 + if (g_astc_bise_range_table[range][1] || g_astc_bise_range_table[range][2]) + { + printf("// Range: %u, Levels: %u, Bits: %u, Trits: %u, Quints: %u\n", range, levels, g_astc_bise_range_table[range][0], g_astc_bise_range_table[range][1], g_astc_bise_range_table[range][2]); + + printf("{"); + for (uint32_t i = 0; i < levels; i++) + { + printf("{%u,%u}", g_astc_unquant[range][i].m_index, g_astc_unquant[range][i].m_unquant); + if (i != (levels - 1)) + printf(","); + } + printf("}\n"); + } +#endif + + for (uint32_t i = 0; i < 256; i++) + { + uint32_t best_index = 0; + int best_err = INT32_MAX; + + for (uint32_t j = 0; j < levels; j++) + { + int err = g_astc_sorted_order_unquant[range][j].m_unquant - i; + if (err < 0) + err = -err; + if (err < best_err) + { + best_err = err; + best_index = j; + } + } + + g_astc_nearest_sorted_index[range][i] = (uint8_t)best_index; + } // i + } // range +} + +static inline uint32_t astc_interpolate(uint32_t l, uint32_t h, uint32_t w) +{ + // This is for linear values, not sRGB. + l = (l << 8) | l; + h = (h << 8) | h; + uint32_t k = (l * (64 - w) + h * w + 32) >> 6; + return k >> 8; +} + +// Initialize the lookup table used for optimal single color compression in mode 1. Must be called before encoding. +void bc7enc_compress_block_init() +{ + astc_init(); + + // BC7 666.1 + for (int c = 0; c < 256; c++) + { + for (uint32_t lp = 0; lp < 2; lp++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 64; l++) + { + uint32_t low = ((l << 1) | lp) << 1; + low |= (low >> 7); + for (uint32_t h = 0; h < 64; h++) + { + uint32_t high = ((h << 1) | lp) << 1; + high |= (high >> 7); + const int k = (low * (64 - g_bc7_weights3[BC7ENC_MODE_1_OPTIMAL_INDEX]) + high * g_bc7_weights3[BC7ENC_MODE_1_OPTIMAL_INDEX] + 32) >> 6; + const int err = (k - c) * (k - c); + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + g_bc7_mode_1_optimal_endpoints[c][lp] = best; + } // lp + } // c + + // ASTC [0,15] 3-bit + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 16; l++) + { + uint32_t low = (l << 4) | l; + + for (uint32_t h = 0; h < 16; h++) + { + uint32_t high = (h << 4) | h; + + const int k = astc_interpolate(low, high, g_bc7_weights3[BC7ENC_ASTC_4BIT_3BIT_OPTIMAL_INDEX]); + const int err = (k - c) * (k - c); + + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_astc_4bit_3bit_optimal_endpoints[c] = best; + + } // c + + // ASTC [0,15] 2-bit + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 16; l++) + { + uint32_t low = (l << 4) | l; + + for (uint32_t h = 0; h < 16; h++) + { + uint32_t high = (h << 4) | h; + + const int k = astc_interpolate(low, high, g_bc7_weights2[BC7ENC_ASTC_4BIT_2BIT_OPTIMAL_INDEX]); + const int err = (k - c) * (k - c); + + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_astc_4bit_2bit_optimal_endpoints[c] = best; + + } // c + + // ASTC range 7 [0,11] 2-bit + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 12; l++) + { + uint32_t low = g_astc_sorted_order_unquant[7][l].m_unquant; + + for (uint32_t h = 0; h < 12; h++) + { + uint32_t high = g_astc_sorted_order_unquant[7][h].m_unquant; + + const int k = astc_interpolate(low, high, g_bc7_weights2[BC7ENC_ASTC_RANGE7_2BIT_OPTIMAL_INDEX]); + const int err = (k - c) * (k - c); + + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_astc_range7_2bit_optimal_endpoints[c] = best; + + } // c + + // ASTC range 13 [0,47] 4-bit + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 48; l++) + { + uint32_t low = g_astc_sorted_order_unquant[13][l].m_unquant; + + for (uint32_t h = 0; h < 48; h++) + { + uint32_t high = g_astc_sorted_order_unquant[13][h].m_unquant; + + const int k = astc_interpolate(low, high, g_astc_weights4[BC7ENC_ASTC_RANGE13_4BIT_OPTIMAL_INDEX]); + const int err = (k - c) * (k - c); + + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_astc_range13_4bit_optimal_endpoints[c] = best; + + } // c + + // ASTC range 13 [0,47] 2-bit + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 48; l++) + { + uint32_t low = g_astc_sorted_order_unquant[13][l].m_unquant; + + for (uint32_t h = 0; h < 48; h++) + { + uint32_t high = g_astc_sorted_order_unquant[13][h].m_unquant; + + const int k = astc_interpolate(low, high, g_bc7_weights2[BC7ENC_ASTC_RANGE13_2BIT_OPTIMAL_INDEX]); + const int err = (k - c) * (k - c); + + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_astc_range13_2bit_optimal_endpoints[c] = best; + + } // c + + // ASTC range 11 [0,31] 5-bit + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + for (uint32_t l = 0; l < 32; l++) + { + uint32_t low = g_astc_sorted_order_unquant[11][l].m_unquant; + + for (uint32_t h = 0; h < 32; h++) + { + uint32_t high = g_astc_sorted_order_unquant[11][h].m_unquant; + + const int k = astc_interpolate(low, high, g_astc_weights5[BC7ENC_ASTC_RANGE11_5BIT_OPTIMAL_INDEX]); + const int err = (k - c) * (k - c); + + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_astc_range11_5bit_optimal_endpoints[c] = best; + + } // c +} + +static void compute_least_squares_endpoints_rgba(uint32_t N, const uint8_t *pSelectors, const bc7enc_vec4F* pSelector_weights, bc7enc_vec4F* pXl, bc7enc_vec4F* pXh, const color_quad_u8 *pColors) +{ + // Least squares using normal equations: http://www.cs.cornell.edu/~bindel/class/cs3220-s12/notes/lec10.pdf + // I did this in matrix form first, expanded out all the ops, then optimized it a bit. + double z00 = 0.0f, z01 = 0.0f, z10 = 0.0f, z11 = 0.0f; + double q00_r = 0.0f, q10_r = 0.0f, t_r = 0.0f; + double q00_g = 0.0f, q10_g = 0.0f, t_g = 0.0f; + double q00_b = 0.0f, q10_b = 0.0f, t_b = 0.0f; + double q00_a = 0.0f, q10_a = 0.0f, t_a = 0.0f; + + for (uint32_t i = 0; i < N; i++) + { + const uint32_t sel = pSelectors[i]; + z00 += pSelector_weights[sel].m_c[0]; + z10 += pSelector_weights[sel].m_c[1]; + z11 += pSelector_weights[sel].m_c[2]; + float w = pSelector_weights[sel].m_c[3]; + q00_r += w * pColors[i].m_c[0]; t_r += pColors[i].m_c[0]; + q00_g += w * pColors[i].m_c[1]; t_g += pColors[i].m_c[1]; + q00_b += w * pColors[i].m_c[2]; t_b += pColors[i].m_c[2]; + q00_a += w * pColors[i].m_c[3]; t_a += pColors[i].m_c[3]; + } + + q10_r = t_r - q00_r; + q10_g = t_g - q00_g; + q10_b = t_b - q00_b; + q10_a = t_a - q00_a; + + z01 = z10; + + double det = z00 * z11 - z01 * z10; + if (det != 0.0f) + det = 1.0f / det; + + double iz00, iz01, iz10, iz11; + iz00 = z11 * det; + iz01 = -z01 * det; + iz10 = -z10 * det; + iz11 = z00 * det; + + pXl->m_c[0] = (float)(iz00 * q00_r + iz01 * q10_r); pXh->m_c[0] = (float)(iz10 * q00_r + iz11 * q10_r); + pXl->m_c[1] = (float)(iz00 * q00_g + iz01 * q10_g); pXh->m_c[1] = (float)(iz10 * q00_g + iz11 * q10_g); + pXl->m_c[2] = (float)(iz00 * q00_b + iz01 * q10_b); pXh->m_c[2] = (float)(iz10 * q00_b + iz11 * q10_b); + pXl->m_c[3] = (float)(iz00 * q00_a + iz01 * q10_a); pXh->m_c[3] = (float)(iz10 * q00_a + iz11 * q10_a); + + for (uint32_t c = 0; c < 4; c++) + { + if ((pXl->m_c[c] < 0.0f) || (pXh->m_c[c] > 255.0f)) + { + uint32_t lo_v = UINT32_MAX, hi_v = 0; + for (uint32_t i = 0; i < N; i++) + { + lo_v = minimumu(lo_v, pColors[i].m_c[c]); + hi_v = maximumu(hi_v, pColors[i].m_c[c]); + } + + if (lo_v == hi_v) + { + pXl->m_c[c] = (float)lo_v; + pXh->m_c[c] = (float)hi_v; + } + } + } +} + +static void compute_least_squares_endpoints_rgb(uint32_t N, const uint8_t *pSelectors, const bc7enc_vec4F*pSelector_weights, bc7enc_vec4F*pXl, bc7enc_vec4F*pXh, const color_quad_u8 *pColors) +{ + double z00 = 0.0f, z01 = 0.0f, z10 = 0.0f, z11 = 0.0f; + double q00_r = 0.0f, q10_r = 0.0f, t_r = 0.0f; + double q00_g = 0.0f, q10_g = 0.0f, t_g = 0.0f; + double q00_b = 0.0f, q10_b = 0.0f, t_b = 0.0f; + + for (uint32_t i = 0; i < N; i++) + { + const uint32_t sel = pSelectors[i]; + z00 += pSelector_weights[sel].m_c[0]; + z10 += pSelector_weights[sel].m_c[1]; + z11 += pSelector_weights[sel].m_c[2]; + float w = pSelector_weights[sel].m_c[3]; + q00_r += w * pColors[i].m_c[0]; t_r += pColors[i].m_c[0]; + q00_g += w * pColors[i].m_c[1]; t_g += pColors[i].m_c[1]; + q00_b += w * pColors[i].m_c[2]; t_b += pColors[i].m_c[2]; + } + + q10_r = t_r - q00_r; + q10_g = t_g - q00_g; + q10_b = t_b - q00_b; + + z01 = z10; + + double det = z00 * z11 - z01 * z10; + if (det != 0.0f) + det = 1.0f / det; + + double iz00, iz01, iz10, iz11; + iz00 = z11 * det; + iz01 = -z01 * det; + iz10 = -z10 * det; + iz11 = z00 * det; + + pXl->m_c[0] = (float)(iz00 * q00_r + iz01 * q10_r); pXh->m_c[0] = (float)(iz10 * q00_r + iz11 * q10_r); + pXl->m_c[1] = (float)(iz00 * q00_g + iz01 * q10_g); pXh->m_c[1] = (float)(iz10 * q00_g + iz11 * q10_g); + pXl->m_c[2] = (float)(iz00 * q00_b + iz01 * q10_b); pXh->m_c[2] = (float)(iz10 * q00_b + iz11 * q10_b); + pXl->m_c[3] = 255.0f; pXh->m_c[3] = 255.0f; + + for (uint32_t c = 0; c < 3; c++) + { + if ((pXl->m_c[c] < 0.0f) || (pXh->m_c[c] > 255.0f)) + { + uint32_t lo_v = UINT32_MAX, hi_v = 0; + for (uint32_t i = 0; i < N; i++) + { + lo_v = minimumu(lo_v, pColors[i].m_c[c]); + hi_v = maximumu(hi_v, pColors[i].m_c[c]); + } + + if (lo_v == hi_v) + { + pXl->m_c[c] = (float)lo_v; + pXh->m_c[c] = (float)hi_v; + } + } + } +} + +static inline color_quad_u8 scale_color(const color_quad_u8* pC, const color_cell_compressor_params* pParams) +{ + color_quad_u8 results; + + if (pParams->m_astc_endpoint_range) + { + for (uint32_t i = 0; i < 4; i++) + { + results.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pC->m_c[i]].m_unquant; + } + } + else + { + const uint32_t n = pParams->m_comp_bits + (pParams->m_has_pbits ? 1 : 0); + assert((n >= 4) && (n <= 8)); + + for (uint32_t i = 0; i < 4; i++) + { + uint32_t v = pC->m_c[i] << (8 - n); + v |= (v >> n); + assert(v <= 255); + results.m_c[i] = (uint8_t)(v); + } + } + + return results; +} + +static inline uint64_t compute_color_distance_rgb(const color_quad_u8 *pE1, const color_quad_u8 *pE2, bc7enc_bool perceptual, const uint32_t weights[4]) +{ + int dr, dg, db; + + if (perceptual) + { + const int l1 = pE1->m_c[0] * 109 + pE1->m_c[1] * 366 + pE1->m_c[2] * 37; + const int cr1 = ((int)pE1->m_c[0] << 9) - l1; + const int cb1 = ((int)pE1->m_c[2] << 9) - l1; + const int l2 = pE2->m_c[0] * 109 + pE2->m_c[1] * 366 + pE2->m_c[2] * 37; + const int cr2 = ((int)pE2->m_c[0] << 9) - l2; + const int cb2 = ((int)pE2->m_c[2] << 9) - l2; + dr = (l1 - l2) >> 8; + dg = (cr1 - cr2) >> 8; + db = (cb1 - cb2) >> 8; + } + else + { + dr = (int)pE1->m_c[0] - (int)pE2->m_c[0]; + dg = (int)pE1->m_c[1] - (int)pE2->m_c[1]; + db = (int)pE1->m_c[2] - (int)pE2->m_c[2]; + } + + return weights[0] * (uint32_t)(dr * dr) + weights[1] * (uint32_t)(dg * dg) + weights[2] * (uint32_t)(db * db); +} + +static inline uint64_t compute_color_distance_rgba(const color_quad_u8 *pE1, const color_quad_u8 *pE2, bc7enc_bool perceptual, const uint32_t weights[4]) +{ + int da = (int)pE1->m_c[3] - (int)pE2->m_c[3]; + return compute_color_distance_rgb(pE1, pE2, perceptual, weights) + (weights[3] * (uint32_t)(da * da)); +} + +static uint64_t pack_mode1_to_one_color(const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults, uint32_t r, uint32_t g, uint32_t b, uint8_t *pSelectors) +{ + uint32_t best_err = UINT_MAX; + uint32_t best_p = 0; + + for (uint32_t p = 0; p < 2; p++) + { + uint32_t err = g_bc7_mode_1_optimal_endpoints[r][p].m_error + g_bc7_mode_1_optimal_endpoints[g][p].m_error + g_bc7_mode_1_optimal_endpoints[b][p].m_error; + if (err < best_err) + { + best_err = err; + best_p = p; + } + } + + const endpoint_err *pEr = &g_bc7_mode_1_optimal_endpoints[r][best_p]; + const endpoint_err *pEg = &g_bc7_mode_1_optimal_endpoints[g][best_p]; + const endpoint_err *pEb = &g_bc7_mode_1_optimal_endpoints[b][best_p]; + + color_quad_u8_set(&pResults->m_low_endpoint, pEr->m_lo, pEg->m_lo, pEb->m_lo, 0); + color_quad_u8_set(&pResults->m_high_endpoint, pEr->m_hi, pEg->m_hi, pEb->m_hi, 0); + pResults->m_pbits[0] = best_p; + pResults->m_pbits[1] = 0; + + memset(pSelectors, BC7ENC_MODE_1_OPTIMAL_INDEX, pParams->m_num_pixels); + + color_quad_u8 p; + for (uint32_t i = 0; i < 3; i++) + { + uint32_t low = ((pResults->m_low_endpoint.m_c[i] << 1) | pResults->m_pbits[0]) << 1; + low |= (low >> 7); + + uint32_t high = ((pResults->m_high_endpoint.m_c[i] << 1) | pResults->m_pbits[0]) << 1; + high |= (high >> 7); + + p.m_c[i] = (uint8_t)((low * (64 - g_bc7_weights3[BC7ENC_MODE_1_OPTIMAL_INDEX]) + high * g_bc7_weights3[BC7ENC_MODE_1_OPTIMAL_INDEX] + 32) >> 6); + } + p.m_c[3] = 255; + + uint64_t total_err = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + total_err += compute_color_distance_rgb(&p, &pParams->m_pPixels[i], pParams->m_perceptual, pParams->m_weights); + + pResults->m_best_overall_err = total_err; + + return total_err; +} + +static uint64_t pack_astc_4bit_3bit_to_one_color(const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults, uint32_t r, uint32_t g, uint32_t b, uint8_t *pSelectors) +{ + const endpoint_err *pEr = &g_astc_4bit_3bit_optimal_endpoints[r]; + const endpoint_err *pEg = &g_astc_4bit_3bit_optimal_endpoints[g]; + const endpoint_err *pEb = &g_astc_4bit_3bit_optimal_endpoints[b]; + + color_quad_u8_set(&pResults->m_low_endpoint, pEr->m_lo, pEg->m_lo, pEb->m_lo, 0); + color_quad_u8_set(&pResults->m_high_endpoint, pEr->m_hi, pEg->m_hi, pEb->m_hi, 0); + pResults->m_pbits[0] = 0; + pResults->m_pbits[1] = 0; + + for (uint32_t i = 0; i < 4; i++) + { + pResults->m_astc_low_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[i]].m_index; + pResults->m_astc_high_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[i]].m_index; + } + + memset(pSelectors, BC7ENC_ASTC_4BIT_3BIT_OPTIMAL_INDEX, pParams->m_num_pixels); + + color_quad_u8 p; + for (uint32_t i = 0; i < 3; i++) + { + uint32_t low = (pResults->m_low_endpoint.m_c[i] << 4) | pResults->m_low_endpoint.m_c[i]; + uint32_t high = (pResults->m_high_endpoint.m_c[i] << 4) | pResults->m_high_endpoint.m_c[i]; + + p.m_c[i] = (uint8_t)astc_interpolate(low, high, g_bc7_weights3[BC7ENC_ASTC_4BIT_3BIT_OPTIMAL_INDEX]); + } + p.m_c[3] = 255; + + uint64_t total_err = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + total_err += compute_color_distance_rgb(&p, &pParams->m_pPixels[i], pParams->m_perceptual, pParams->m_weights); + + pResults->m_best_overall_err = total_err; + + return total_err; +} + +static uint64_t pack_astc_4bit_2bit_to_one_color_rgba(const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults, uint32_t r, uint32_t g, uint32_t b, uint32_t a, uint8_t *pSelectors) +{ + const endpoint_err *pEr = &g_astc_4bit_2bit_optimal_endpoints[r]; + const endpoint_err *pEg = &g_astc_4bit_2bit_optimal_endpoints[g]; + const endpoint_err *pEb = &g_astc_4bit_2bit_optimal_endpoints[b]; + const endpoint_err *pEa = &g_astc_4bit_2bit_optimal_endpoints[a]; + + color_quad_u8_set(&pResults->m_low_endpoint, pEr->m_lo, pEg->m_lo, pEb->m_lo, pEa->m_lo); + color_quad_u8_set(&pResults->m_high_endpoint, pEr->m_hi, pEg->m_hi, pEb->m_hi, pEa->m_hi); + pResults->m_pbits[0] = 0; + pResults->m_pbits[1] = 0; + + for (uint32_t i = 0; i < 4; i++) + { + pResults->m_astc_low_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[i]].m_index; + pResults->m_astc_high_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[i]].m_index; + } + + memset(pSelectors, BC7ENC_ASTC_4BIT_2BIT_OPTIMAL_INDEX, pParams->m_num_pixels); + + color_quad_u8 p; + for (uint32_t i = 0; i < 4; i++) + { + uint32_t low = (pResults->m_low_endpoint.m_c[i] << 4) | pResults->m_low_endpoint.m_c[i]; + uint32_t high = (pResults->m_high_endpoint.m_c[i] << 4) | pResults->m_high_endpoint.m_c[i]; + + p.m_c[i] = (uint8_t)astc_interpolate(low, high, g_bc7_weights2[BC7ENC_ASTC_4BIT_2BIT_OPTIMAL_INDEX]); + } + + uint64_t total_err = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + total_err += compute_color_distance_rgba(&p, &pParams->m_pPixels[i], pParams->m_perceptual, pParams->m_weights); + + pResults->m_best_overall_err = total_err; + + return total_err; +} + +static uint64_t pack_astc_range7_2bit_to_one_color(const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults, uint32_t r, uint32_t g, uint32_t b, uint8_t *pSelectors) +{ + assert(pParams->m_astc_endpoint_range == 7 && pParams->m_num_selector_weights == 4); + + const endpoint_err *pEr = &g_astc_range7_2bit_optimal_endpoints[r]; + const endpoint_err *pEg = &g_astc_range7_2bit_optimal_endpoints[g]; + const endpoint_err *pEb = &g_astc_range7_2bit_optimal_endpoints[b]; + + color_quad_u8_set(&pResults->m_low_endpoint, pEr->m_lo, pEg->m_lo, pEb->m_lo, 0); + color_quad_u8_set(&pResults->m_high_endpoint, pEr->m_hi, pEg->m_hi, pEb->m_hi, 0); + pResults->m_pbits[0] = 0; + pResults->m_pbits[1] = 0; + + for (uint32_t i = 0; i < 4; i++) + { + pResults->m_astc_low_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[i]].m_index; + pResults->m_astc_high_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[i]].m_index; + } + + memset(pSelectors, BC7ENC_ASTC_RANGE7_2BIT_OPTIMAL_INDEX, pParams->m_num_pixels); + + color_quad_u8 p; + for (uint32_t i = 0; i < 3; i++) + { + uint32_t low = g_astc_sorted_order_unquant[7][pResults->m_low_endpoint.m_c[i]].m_unquant; + uint32_t high = g_astc_sorted_order_unquant[7][pResults->m_high_endpoint.m_c[i]].m_unquant; + + p.m_c[i] = (uint8_t)astc_interpolate(low, high, g_bc7_weights2[BC7ENC_ASTC_RANGE7_2BIT_OPTIMAL_INDEX]); + } + p.m_c[3] = 255; + + uint64_t total_err = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + total_err += compute_color_distance_rgb(&p, &pParams->m_pPixels[i], pParams->m_perceptual, pParams->m_weights); + + pResults->m_best_overall_err = total_err; + + return total_err; +} + +static uint64_t pack_astc_range13_2bit_to_one_color(const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults, uint32_t r, uint32_t g, uint32_t b, uint8_t *pSelectors) +{ + assert(pParams->m_astc_endpoint_range == 13 && pParams->m_num_selector_weights == 4 && !pParams->m_has_alpha); + + const endpoint_err *pEr = &g_astc_range13_2bit_optimal_endpoints[r]; + const endpoint_err *pEg = &g_astc_range13_2bit_optimal_endpoints[g]; + const endpoint_err *pEb = &g_astc_range13_2bit_optimal_endpoints[b]; + + color_quad_u8_set(&pResults->m_low_endpoint, pEr->m_lo, pEg->m_lo, pEb->m_lo, 47); + color_quad_u8_set(&pResults->m_high_endpoint, pEr->m_hi, pEg->m_hi, pEb->m_hi, 47); + pResults->m_pbits[0] = 0; + pResults->m_pbits[1] = 0; + + for (uint32_t i = 0; i < 4; i++) + { + pResults->m_astc_low_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[i]].m_index; + pResults->m_astc_high_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[i]].m_index; + } + + memset(pSelectors, BC7ENC_ASTC_RANGE13_2BIT_OPTIMAL_INDEX, pParams->m_num_pixels); + + color_quad_u8 p; + for (uint32_t i = 0; i < 4; i++) + { + uint32_t low = g_astc_sorted_order_unquant[13][pResults->m_low_endpoint.m_c[i]].m_unquant; + uint32_t high = g_astc_sorted_order_unquant[13][pResults->m_high_endpoint.m_c[i]].m_unquant; + + p.m_c[i] = (uint8_t)astc_interpolate(low, high, g_bc7_weights2[BC7ENC_ASTC_RANGE13_2BIT_OPTIMAL_INDEX]); + } + + uint64_t total_err = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + total_err += compute_color_distance_rgb(&p, &pParams->m_pPixels[i], pParams->m_perceptual, pParams->m_weights); + + pResults->m_best_overall_err = total_err; + + return total_err; +} + +static uint64_t pack_astc_range11_5bit_to_one_color(const color_cell_compressor_params* pParams, color_cell_compressor_results* pResults, uint32_t r, uint32_t g, uint32_t b, uint8_t* pSelectors) +{ + assert(pParams->m_astc_endpoint_range == 11 && pParams->m_num_selector_weights == 32 && !pParams->m_has_alpha); + + const endpoint_err* pEr = &g_astc_range11_5bit_optimal_endpoints[r]; + const endpoint_err* pEg = &g_astc_range11_5bit_optimal_endpoints[g]; + const endpoint_err* pEb = &g_astc_range11_5bit_optimal_endpoints[b]; + + color_quad_u8_set(&pResults->m_low_endpoint, pEr->m_lo, pEg->m_lo, pEb->m_lo, 31); + color_quad_u8_set(&pResults->m_high_endpoint, pEr->m_hi, pEg->m_hi, pEb->m_hi, 31); + pResults->m_pbits[0] = 0; + pResults->m_pbits[1] = 0; + + for (uint32_t i = 0; i < 4; i++) + { + pResults->m_astc_low_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[i]].m_index; + pResults->m_astc_high_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[i]].m_index; + } + + memset(pSelectors, BC7ENC_ASTC_RANGE11_5BIT_OPTIMAL_INDEX, pParams->m_num_pixels); + + color_quad_u8 p; + for (uint32_t i = 0; i < 4; i++) + { + uint32_t low = g_astc_sorted_order_unquant[11][pResults->m_low_endpoint.m_c[i]].m_unquant; + uint32_t high = g_astc_sorted_order_unquant[11][pResults->m_high_endpoint.m_c[i]].m_unquant; + + p.m_c[i] = (uint8_t)astc_interpolate(low, high, g_astc_weights5[BC7ENC_ASTC_RANGE11_5BIT_OPTIMAL_INDEX]); + } + + uint64_t total_err = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + total_err += compute_color_distance_rgb(&p, &pParams->m_pPixels[i], pParams->m_perceptual, pParams->m_weights); + + pResults->m_best_overall_err = total_err; + + return total_err; +} + +static uint64_t evaluate_solution(const color_quad_u8 *pLow, const color_quad_u8 *pHigh, const uint32_t pbits[2], const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults) +{ + color_quad_u8 quantMinColor = *pLow; + color_quad_u8 quantMaxColor = *pHigh; + + if (pParams->m_has_pbits) + { + uint32_t minPBit, maxPBit; + + if (pParams->m_endpoints_share_pbit) + maxPBit = minPBit = pbits[0]; + else + { + minPBit = pbits[0]; + maxPBit = pbits[1]; + } + + quantMinColor.m_c[0] = (uint8_t)((pLow->m_c[0] << 1) | minPBit); + quantMinColor.m_c[1] = (uint8_t)((pLow->m_c[1] << 1) | minPBit); + quantMinColor.m_c[2] = (uint8_t)((pLow->m_c[2] << 1) | minPBit); + quantMinColor.m_c[3] = (uint8_t)((pLow->m_c[3] << 1) | minPBit); + + quantMaxColor.m_c[0] = (uint8_t)((pHigh->m_c[0] << 1) | maxPBit); + quantMaxColor.m_c[1] = (uint8_t)((pHigh->m_c[1] << 1) | maxPBit); + quantMaxColor.m_c[2] = (uint8_t)((pHigh->m_c[2] << 1) | maxPBit); + quantMaxColor.m_c[3] = (uint8_t)((pHigh->m_c[3] << 1) | maxPBit); + } + + color_quad_u8 actualMinColor = scale_color(&quantMinColor, pParams); + color_quad_u8 actualMaxColor = scale_color(&quantMaxColor, pParams); + + const uint32_t N = pParams->m_num_selector_weights; + assert(N >= 1 && N <= 32); + + color_quad_u8 weightedColors[32]; + weightedColors[0] = actualMinColor; + weightedColors[N - 1] = actualMaxColor; + + const uint32_t nc = pParams->m_has_alpha ? 4 : 3; + if (pParams->m_astc_endpoint_range) + { + for (uint32_t i = 1; i < (N - 1); i++) + { + for (uint32_t j = 0; j < nc; j++) + weightedColors[i].m_c[j] = (uint8_t)(astc_interpolate(actualMinColor.m_c[j], actualMaxColor.m_c[j], pParams->m_pSelector_weights[i])); + } + } + else + { + for (uint32_t i = 1; i < (N - 1); i++) + for (uint32_t j = 0; j < nc; j++) + weightedColors[i].m_c[j] = (uint8_t)((actualMinColor.m_c[j] * (64 - pParams->m_pSelector_weights[i]) + actualMaxColor.m_c[j] * pParams->m_pSelector_weights[i] + 32) >> 6); + } + + const int lr = actualMinColor.m_c[0]; + const int lg = actualMinColor.m_c[1]; + const int lb = actualMinColor.m_c[2]; + const int dr = actualMaxColor.m_c[0] - lr; + const int dg = actualMaxColor.m_c[1] - lg; + const int db = actualMaxColor.m_c[2] - lb; + + uint64_t total_err = 0; + + if (pParams->m_pForce_selectors) + { + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + const color_quad_u8* pC = &pParams->m_pPixels[i]; + + const uint8_t sel = pParams->m_pForce_selectors[i]; + assert(sel < N); + + total_err += (pParams->m_has_alpha ? compute_color_distance_rgba : compute_color_distance_rgb)(&weightedColors[sel], pC, pParams->m_perceptual, pParams->m_weights); + + pResults->m_pSelectors_temp[i] = sel; + } + } + else if (!pParams->m_perceptual) + { + if (pParams->m_has_alpha) + { + const int la = actualMinColor.m_c[3]; + const int da = actualMaxColor.m_c[3] - la; + + const float f = N / (float)(squarei(dr) + squarei(dg) + squarei(db) + squarei(da) + .00000125f); + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + const color_quad_u8 *pC = &pParams->m_pPixels[i]; + int r = pC->m_c[0]; + int g = pC->m_c[1]; + int b = pC->m_c[2]; + int a = pC->m_c[3]; + + int best_sel = (int)((float)((r - lr) * dr + (g - lg) * dg + (b - lb) * db + (a - la) * da) * f + .5f); + best_sel = clampi(best_sel, 1, N - 1); + + uint64_t err0 = compute_color_distance_rgba(&weightedColors[best_sel - 1], pC, BC7ENC_FALSE, pParams->m_weights); + uint64_t err1 = compute_color_distance_rgba(&weightedColors[best_sel], pC, BC7ENC_FALSE, pParams->m_weights); + + if (err0 == err1) + { + // Prefer non-interpolation + if ((best_sel - 1) == 0) + best_sel = 0; + } + else if (err1 > err0) + { + err1 = err0; + --best_sel; + } + total_err += err1; + + pResults->m_pSelectors_temp[i] = (uint8_t)best_sel; + } + } + else + { + const float f = N / (float)(squarei(dr) + squarei(dg) + squarei(db) + .00000125f); + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + const color_quad_u8 *pC = &pParams->m_pPixels[i]; + int r = pC->m_c[0]; + int g = pC->m_c[1]; + int b = pC->m_c[2]; + + int sel = (int)((float)((r - lr) * dr + (g - lg) * dg + (b - lb) * db) * f + .5f); + sel = clampi(sel, 1, N - 1); + + uint64_t err0 = compute_color_distance_rgb(&weightedColors[sel - 1], pC, BC7ENC_FALSE, pParams->m_weights); + uint64_t err1 = compute_color_distance_rgb(&weightedColors[sel], pC, BC7ENC_FALSE, pParams->m_weights); + + int best_sel = sel; + uint64_t best_err = err1; + if (err0 == err1) + { + // Prefer non-interpolation + if ((best_sel - 1) == 0) + best_sel = 0; + } + else if (err0 < best_err) + { + best_err = err0; + best_sel = sel - 1; + } + + total_err += best_err; + + pResults->m_pSelectors_temp[i] = (uint8_t)best_sel; + } + } + } + else + { + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + uint64_t best_err = UINT64_MAX; + uint32_t best_sel = 0; + + if (pParams->m_has_alpha) + { + for (uint32_t j = 0; j < N; j++) + { + uint64_t err = compute_color_distance_rgba(&weightedColors[j], &pParams->m_pPixels[i], BC7ENC_TRUE, pParams->m_weights); + if (err < best_err) + { + best_err = err; + best_sel = j; + } + // Prefer non-interpolation + else if ((err == best_err) && (j == (N - 1))) + best_sel = j; + } + } + else + { + for (uint32_t j = 0; j < N; j++) + { + uint64_t err = compute_color_distance_rgb(&weightedColors[j], &pParams->m_pPixels[i], BC7ENC_TRUE, pParams->m_weights); + if (err < best_err) + { + best_err = err; + best_sel = j; + } + // Prefer non-interpolation + else if ((err == best_err) && (j == (N - 1))) + best_sel = j; + } + } + + total_err += best_err; + + pResults->m_pSelectors_temp[i] = (uint8_t)best_sel; + } + } + + if (total_err < pResults->m_best_overall_err) + { + pResults->m_best_overall_err = total_err; + + pResults->m_low_endpoint = *pLow; + pResults->m_high_endpoint = *pHigh; + + pResults->m_pbits[0] = pbits[0]; + pResults->m_pbits[1] = pbits[1]; + + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + } + + return total_err; +} + +static bool areDegenerateEndpoints(color_quad_u8* pTrialMinColor, color_quad_u8* pTrialMaxColor, const bc7enc_vec4F* pXl, const bc7enc_vec4F* pXh) +{ + for (uint32_t i = 0; i < 3; i++) + { + if (pTrialMinColor->m_c[i] == pTrialMaxColor->m_c[i]) + { + if (fabs(pXl->m_c[i] - pXh->m_c[i]) > 0.0f) + return true; + } + } + + return false; +} + +static void fixDegenerateEndpoints(uint32_t mode, color_quad_u8 *pTrialMinColor, color_quad_u8 *pTrialMaxColor, const bc7enc_vec4F*pXl, const bc7enc_vec4F*pXh, uint32_t iscale, int flags) +{ + if (mode == 255) + { + for (uint32_t i = 0; i < 3; i++) + { + if (pTrialMinColor->m_c[i] == pTrialMaxColor->m_c[i]) + { + if (fabs(pXl->m_c[i] - pXh->m_c[i]) > 0.000125f) + { + if (flags & 1) + { + if (pTrialMinColor->m_c[i] > 0) + pTrialMinColor->m_c[i]--; + } + if (flags & 2) + { + if (pTrialMaxColor->m_c[i] < iscale) + pTrialMaxColor->m_c[i]++; + } + } + } + } + } + else if (mode == 1) + { + // fix degenerate case where the input collapses to a single colorspace voxel, and we loose all freedom (test with grayscale ramps) + for (uint32_t i = 0; i < 3; i++) + { + if (pTrialMinColor->m_c[i] == pTrialMaxColor->m_c[i]) + { + if (fabs(pXl->m_c[i] - pXh->m_c[i]) > 0.000125f) + { + if (pTrialMinColor->m_c[i] > (iscale >> 1)) + { + if (pTrialMinColor->m_c[i] > 0) + pTrialMinColor->m_c[i]--; + else + if (pTrialMaxColor->m_c[i] < iscale) + pTrialMaxColor->m_c[i]++; + } + else + { + if (pTrialMaxColor->m_c[i] < iscale) + pTrialMaxColor->m_c[i]++; + else if (pTrialMinColor->m_c[i] > 0) + pTrialMinColor->m_c[i]--; + } + } + } + } + } +} + +static uint64_t find_optimal_solution(uint32_t mode, bc7enc_vec4F xl, bc7enc_vec4F xh, const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults) +{ + vec4F_saturate_in_place(&xl); vec4F_saturate_in_place(&xh); + + if (pParams->m_astc_endpoint_range) + { + const uint32_t levels = astc_get_levels(pParams->m_astc_endpoint_range); + + const float scale = 255.0f; + + color_quad_u8 trialMinColor8Bit, trialMaxColor8Bit; + color_quad_u8_set_clamped(&trialMinColor8Bit, (int)(xl.m_c[0] * scale + .5f), (int)(xl.m_c[1] * scale + .5f), (int)(xl.m_c[2] * scale + .5f), (int)(xl.m_c[3] * scale + .5f)); + color_quad_u8_set_clamped(&trialMaxColor8Bit, (int)(xh.m_c[0] * scale + .5f), (int)(xh.m_c[1] * scale + .5f), (int)(xh.m_c[2] * scale + .5f), (int)(xh.m_c[3] * scale + .5f)); + + color_quad_u8 trialMinColor, trialMaxColor; + for (uint32_t i = 0; i < 4; i++) + { + trialMinColor.m_c[i] = g_astc_nearest_sorted_index[pParams->m_astc_endpoint_range][trialMinColor8Bit.m_c[i]]; + trialMaxColor.m_c[i] = g_astc_nearest_sorted_index[pParams->m_astc_endpoint_range][trialMaxColor8Bit.m_c[i]]; + } + + if (areDegenerateEndpoints(&trialMinColor, &trialMaxColor, &xl, &xh)) + { + color_quad_u8 trialMinColorOrig(trialMinColor), trialMaxColorOrig(trialMaxColor); + + fixDegenerateEndpoints(mode, &trialMinColor, &trialMaxColor, &xl, &xh, levels - 1, 1); + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&trialMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&trialMaxColor, &pResults->m_high_endpoint)) + evaluate_solution(&trialMinColor, &trialMaxColor, pResults->m_pbits, pParams, pResults); + + trialMinColor = trialMinColorOrig; + trialMaxColor = trialMaxColorOrig; + fixDegenerateEndpoints(mode, &trialMinColor, &trialMaxColor, &xl, &xh, levels - 1, 0); + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&trialMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&trialMaxColor, &pResults->m_high_endpoint)) + evaluate_solution(&trialMinColor, &trialMaxColor, pResults->m_pbits, pParams, pResults); + + trialMinColor = trialMinColorOrig; + trialMaxColor = trialMaxColorOrig; + fixDegenerateEndpoints(mode, &trialMinColor, &trialMaxColor, &xl, &xh, levels - 1, 2); + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&trialMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&trialMaxColor, &pResults->m_high_endpoint)) + evaluate_solution(&trialMinColor, &trialMaxColor, pResults->m_pbits, pParams, pResults); + + trialMinColor = trialMinColorOrig; + trialMaxColor = trialMaxColorOrig; + fixDegenerateEndpoints(mode, &trialMinColor, &trialMaxColor, &xl, &xh, levels - 1, 3); + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&trialMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&trialMaxColor, &pResults->m_high_endpoint)) + evaluate_solution(&trialMinColor, &trialMaxColor, pResults->m_pbits, pParams, pResults); + } + else + { + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&trialMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&trialMaxColor, &pResults->m_high_endpoint)) + { + evaluate_solution(&trialMinColor, &trialMaxColor, pResults->m_pbits, pParams, pResults); + } + } + + for (uint32_t i = 0; i < 4; i++) + { + pResults->m_astc_low_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[i]].m_index; + pResults->m_astc_high_endpoint.m_c[i] = g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[i]].m_index; + } + } + else if (pParams->m_has_pbits) + { + const int iscalep = (1 << (pParams->m_comp_bits + 1)) - 1; + const float scalep = (float)iscalep; + + const int32_t totalComps = pParams->m_has_alpha ? 4 : 3; + + uint32_t best_pbits[2]; + color_quad_u8 bestMinColor, bestMaxColor; + + if (!pParams->m_endpoints_share_pbit) + { + float best_err0 = 1e+9; + float best_err1 = 1e+9; + + for (int p = 0; p < 2; p++) + { + color_quad_u8 xMinColor, xMaxColor; + + // Notes: The pbit controls which quantization intervals are selected. + // total_levels=2^(comp_bits+1), where comp_bits=4 for mode 0, etc. + // pbit 0: v=(b*2)/(total_levels-1), pbit 1: v=(b*2+1)/(total_levels-1) where b is the component bin from [0,total_levels/2-1] and v is the [0,1] component value + // rearranging you get for pbit 0: b=floor(v*(total_levels-1)/2+.5) + // rearranging you get for pbit 1: b=floor((v*(total_levels-1)-1)/2+.5) + for (uint32_t c = 0; c < 4; c++) + { + xMinColor.m_c[c] = (uint8_t)(clampi(((int)((xl.m_c[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + xMaxColor.m_c[c] = (uint8_t)(clampi(((int)((xh.m_c[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + } + + color_quad_u8 scaledLow = scale_color(&xMinColor, pParams); + color_quad_u8 scaledHigh = scale_color(&xMaxColor, pParams); + + float err0 = 0, err1 = 0; + for (int i = 0; i < totalComps; i++) + { + err0 += squaref(scaledLow.m_c[i] - xl.m_c[i] * 255.0f); + err1 += squaref(scaledHigh.m_c[i] - xh.m_c[i] * 255.0f); + } + + if (err0 < best_err0) + { + best_err0 = err0; + best_pbits[0] = p; + + bestMinColor.m_c[0] = xMinColor.m_c[0] >> 1; + bestMinColor.m_c[1] = xMinColor.m_c[1] >> 1; + bestMinColor.m_c[2] = xMinColor.m_c[2] >> 1; + bestMinColor.m_c[3] = xMinColor.m_c[3] >> 1; + } + + if (err1 < best_err1) + { + best_err1 = err1; + best_pbits[1] = p; + + bestMaxColor.m_c[0] = xMaxColor.m_c[0] >> 1; + bestMaxColor.m_c[1] = xMaxColor.m_c[1] >> 1; + bestMaxColor.m_c[2] = xMaxColor.m_c[2] >> 1; + bestMaxColor.m_c[3] = xMaxColor.m_c[3] >> 1; + } + } + } + else + { + // Endpoints share pbits + float best_err = 1e+9; + + for (int p = 0; p < 2; p++) + { + color_quad_u8 xMinColor, xMaxColor; + for (uint32_t c = 0; c < 4; c++) + { + xMinColor.m_c[c] = (uint8_t)(clampi(((int)((xl.m_c[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + xMaxColor.m_c[c] = (uint8_t)(clampi(((int)((xh.m_c[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + } + + color_quad_u8 scaledLow = scale_color(&xMinColor, pParams); + color_quad_u8 scaledHigh = scale_color(&xMaxColor, pParams); + + float err = 0; + for (int i = 0; i < totalComps; i++) + err += squaref((scaledLow.m_c[i] / 255.0f) - xl.m_c[i]) + squaref((scaledHigh.m_c[i] / 255.0f) - xh.m_c[i]); + + if (err < best_err) + { + best_err = err; + best_pbits[0] = p; + best_pbits[1] = p; + for (uint32_t j = 0; j < 4; j++) + { + bestMinColor.m_c[j] = xMinColor.m_c[j] >> 1; + bestMaxColor.m_c[j] = xMaxColor.m_c[j] >> 1; + } + } + } + } + + fixDegenerateEndpoints(mode, &bestMinColor, &bestMaxColor, &xl, &xh, iscalep >> 1, 0); + + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&bestMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&bestMaxColor, &pResults->m_high_endpoint) || (best_pbits[0] != pResults->m_pbits[0]) || (best_pbits[1] != pResults->m_pbits[1])) + evaluate_solution(&bestMinColor, &bestMaxColor, best_pbits, pParams, pResults); + } + else + { + const int iscale = (1 << pParams->m_comp_bits) - 1; + const float scale = (float)iscale; + + color_quad_u8 trialMinColor, trialMaxColor; + color_quad_u8_set_clamped(&trialMinColor, (int)(xl.m_c[0] * scale + .5f), (int)(xl.m_c[1] * scale + .5f), (int)(xl.m_c[2] * scale + .5f), (int)(xl.m_c[3] * scale + .5f)); + color_quad_u8_set_clamped(&trialMaxColor, (int)(xh.m_c[0] * scale + .5f), (int)(xh.m_c[1] * scale + .5f), (int)(xh.m_c[2] * scale + .5f), (int)(xh.m_c[3] * scale + .5f)); + + fixDegenerateEndpoints(mode, &trialMinColor, &trialMaxColor, &xl, &xh, iscale, 0); + + if ((pResults->m_best_overall_err == UINT64_MAX) || color_quad_u8_notequals(&trialMinColor, &pResults->m_low_endpoint) || color_quad_u8_notequals(&trialMaxColor, &pResults->m_high_endpoint)) + evaluate_solution(&trialMinColor, &trialMaxColor, pResults->m_pbits, pParams, pResults); + } + + return pResults->m_best_overall_err; +} + +void check_best_overall_error(const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults) +{ + const uint32_t n = pParams->m_num_selector_weights; + + assert(n <= 32); + + color_quad_u8 colors[32]; + for (uint32_t c = 0; c < 4; c++) + { + colors[0].m_c[c] = g_astc_unquant[pParams->m_astc_endpoint_range][pResults->m_astc_low_endpoint.m_c[c]].m_unquant; + assert(colors[0].m_c[c] == g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_low_endpoint.m_c[c]].m_unquant); + + colors[n-1].m_c[c] = g_astc_unquant[pParams->m_astc_endpoint_range][pResults->m_astc_high_endpoint.m_c[c]].m_unquant; + assert(colors[n-1].m_c[c] == g_astc_sorted_order_unquant[pParams->m_astc_endpoint_range][pResults->m_high_endpoint.m_c[c]].m_unquant); + } + + for (uint32_t i = 1; i < pParams->m_num_selector_weights - 1; i++) + for (uint32_t c = 0; c < 4; c++) + colors[i].m_c[c] = (uint8_t)astc_interpolate(colors[0].m_c[c], colors[n - 1].m_c[c], pParams->m_pSelector_weights[i]); + + uint64_t total_err = 0; + for (uint32_t p = 0; p < pParams->m_num_pixels; p++) + { + const color_quad_u8 &orig = pParams->m_pPixels[p]; + const color_quad_u8 &packed = colors[pResults->m_pSelectors[p]]; + + if (pParams->m_has_alpha) + total_err += compute_color_distance_rgba(&orig, &packed, pParams->m_perceptual, pParams->m_weights); + else + total_err += compute_color_distance_rgb(&orig, &packed, pParams->m_perceptual, pParams->m_weights); + } + assert(total_err == pResults->m_best_overall_err); + + // HACK HACK + //if (total_err != pResults->m_best_overall_err) + // printf("X"); +} + +static bool is_solid_rgb(const color_cell_compressor_params *pParams, uint32_t &r, uint32_t &g, uint32_t &b) +{ + r = pParams->m_pPixels[0].m_c[0]; + g = pParams->m_pPixels[0].m_c[1]; + b = pParams->m_pPixels[0].m_c[2]; + + bool allSame = true; + for (uint32_t i = 1; i < pParams->m_num_pixels; i++) + { + if ((r != pParams->m_pPixels[i].m_c[0]) || (g != pParams->m_pPixels[i].m_c[1]) || (b != pParams->m_pPixels[i].m_c[2])) + { + allSame = false; + break; + } + } + + return allSame; +} + +static bool is_solid_rgba(const color_cell_compressor_params *pParams, uint32_t &r, uint32_t &g, uint32_t &b, uint32_t &a) +{ + r = pParams->m_pPixels[0].m_c[0]; + g = pParams->m_pPixels[0].m_c[1]; + b = pParams->m_pPixels[0].m_c[2]; + a = pParams->m_pPixels[0].m_c[3]; + + bool allSame = true; + for (uint32_t i = 1; i < pParams->m_num_pixels; i++) + { + if ((r != pParams->m_pPixels[i].m_c[0]) || (g != pParams->m_pPixels[i].m_c[1]) || (b != pParams->m_pPixels[i].m_c[2]) || (a != pParams->m_pPixels[i].m_c[3])) + { + allSame = false; + break; + } + } + + return allSame; +} + +uint64_t color_cell_compression(uint32_t mode, const color_cell_compressor_params *pParams, color_cell_compressor_results *pResults, const bc7enc_compress_block_params *pComp_params) +{ + if (!pParams->m_astc_endpoint_range) + { + assert((mode == 6) || (!pParams->m_has_alpha)); + } + assert(pParams->m_num_selector_weights >= 1 && pParams->m_num_selector_weights <= 32); + assert(pParams->m_pSelector_weights[0] == 0); + assert(pParams->m_pSelector_weights[pParams->m_num_selector_weights - 1] == 64); + + pResults->m_best_overall_err = UINT64_MAX; + + uint32_t cr, cg, cb, ca; + + // If the partition's colors are all the same, then just pack them as a single color. + if (!pParams->m_pForce_selectors) + { + if (mode == 1) + { + if (is_solid_rgb(pParams, cr, cg, cb)) + return pack_mode1_to_one_color(pParams, pResults, cr, cg, cb, pResults->m_pSelectors); + } + else if ((pParams->m_astc_endpoint_range == 8) && (pParams->m_num_selector_weights == 8) && (!pParams->m_has_alpha)) + { + if (is_solid_rgb(pParams, cr, cg, cb)) + return pack_astc_4bit_3bit_to_one_color(pParams, pResults, cr, cg, cb, pResults->m_pSelectors); + } + else if ((pParams->m_astc_endpoint_range == 7) && (pParams->m_num_selector_weights == 4) && (!pParams->m_has_alpha)) + { + if (is_solid_rgb(pParams, cr, cg, cb)) + return pack_astc_range7_2bit_to_one_color(pParams, pResults, cr, cg, cb, pResults->m_pSelectors); + } + else if ((pParams->m_astc_endpoint_range == 8) && (pParams->m_num_selector_weights == 4) && (pParams->m_has_alpha)) + { + if (is_solid_rgba(pParams, cr, cg, cb, ca)) + return pack_astc_4bit_2bit_to_one_color_rgba(pParams, pResults, cr, cg, cb, ca, pResults->m_pSelectors); + } + else if ((pParams->m_astc_endpoint_range == 13) && (pParams->m_num_selector_weights == 4) && (!pParams->m_has_alpha)) + { + if (is_solid_rgb(pParams, cr, cg, cb)) + return pack_astc_range13_2bit_to_one_color(pParams, pResults, cr, cg, cb, pResults->m_pSelectors); + } + else if ((pParams->m_astc_endpoint_range == 11) && (pParams->m_num_selector_weights == 32) && (!pParams->m_has_alpha)) + { + if (is_solid_rgb(pParams, cr, cg, cb)) + return pack_astc_range11_5bit_to_one_color(pParams, pResults, cr, cg, cb, pResults->m_pSelectors); + } + } + + // Compute partition's mean color and principle axis. + bc7enc_vec4F meanColor, axis; + vec4F_set_scalar(&meanColor, 0.0f); + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + bc7enc_vec4F color = vec4F_from_color(&pParams->m_pPixels[i]); + meanColor = vec4F_add(&meanColor, &color); + } + + bc7enc_vec4F meanColorScaled = vec4F_mul(&meanColor, 1.0f / (float)(pParams->m_num_pixels)); + + meanColor = vec4F_mul(&meanColor, 1.0f / (float)(pParams->m_num_pixels * 255.0f)); + vec4F_saturate_in_place(&meanColor); + + if (pParams->m_has_alpha) + { + // Use incremental PCA for RGBA PCA, because it's simple. + vec4F_set_scalar(&axis, 0.0f); + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + bc7enc_vec4F color = vec4F_from_color(&pParams->m_pPixels[i]); + color = vec4F_sub(&color, &meanColorScaled); + bc7enc_vec4F a = vec4F_mul(&color, color.m_c[0]); + bc7enc_vec4F b = vec4F_mul(&color, color.m_c[1]); + bc7enc_vec4F c = vec4F_mul(&color, color.m_c[2]); + bc7enc_vec4F d = vec4F_mul(&color, color.m_c[3]); + bc7enc_vec4F n = i ? axis : color; + vec4F_normalize_in_place(&n); + axis.m_c[0] += vec4F_dot(&a, &n); + axis.m_c[1] += vec4F_dot(&b, &n); + axis.m_c[2] += vec4F_dot(&c, &n); + axis.m_c[3] += vec4F_dot(&d, &n); + } + vec4F_normalize_in_place(&axis); + } + else + { + // Use covar technique for RGB PCA, because it doesn't require per-pixel normalization. + float cov[6] = { 0, 0, 0, 0, 0, 0 }; + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + const color_quad_u8 *pV = &pParams->m_pPixels[i]; + float r = pV->m_c[0] - meanColorScaled.m_c[0]; + float g = pV->m_c[1] - meanColorScaled.m_c[1]; + float b = pV->m_c[2] - meanColorScaled.m_c[2]; + cov[0] += r*r; cov[1] += r*g; cov[2] += r*b; cov[3] += g*g; cov[4] += g*b; cov[5] += b*b; + } + + float xr = .9f, xg = 1.0f, xb = .7f; + for (uint32_t iter = 0; iter < 3; iter++) + { + float r = xr * cov[0] + xg * cov[1] + xb * cov[2]; + float g = xr * cov[1] + xg * cov[3] + xb * cov[4]; + float b = xr * cov[2] + xg * cov[4] + xb * cov[5]; + + float m = maximumf(maximumf(fabsf(r), fabsf(g)), fabsf(b)); + if (m > 1e-10f) + { + m = 1.0f / m; + r *= m; g *= m; b *= m; + } + + xr = r; xg = g; xb = b; + } + + float len = xr * xr + xg * xg + xb * xb; + if (len < 1e-10f) + vec4F_set_scalar(&axis, 0.0f); + else + { + len = 1.0f / sqrtf(len); + xr *= len; xg *= len; xb *= len; + vec4F_set(&axis, xr, xg, xb, 0); + } + } + + if (vec4F_dot(&axis, &axis) < .5f) + { + if (pParams->m_perceptual) + vec4F_set(&axis, .213f, .715f, .072f, pParams->m_has_alpha ? .715f : 0); + else + vec4F_set(&axis, 1.0f, 1.0f, 1.0f, pParams->m_has_alpha ? 1.0f : 0); + vec4F_normalize_in_place(&axis); + } + + bc7enc_vec4F minColor, maxColor; + + float l = 1e+9f, h = -1e+9f; + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + bc7enc_vec4F color = vec4F_from_color(&pParams->m_pPixels[i]); + + bc7enc_vec4F q = vec4F_sub(&color, &meanColorScaled); + float d = vec4F_dot(&q, &axis); + + l = minimumf(l, d); + h = maximumf(h, d); + } + + l *= (1.0f / 255.0f); + h *= (1.0f / 255.0f); + + bc7enc_vec4F b0 = vec4F_mul(&axis, l); + bc7enc_vec4F b1 = vec4F_mul(&axis, h); + bc7enc_vec4F c0 = vec4F_add(&meanColor, &b0); + bc7enc_vec4F c1 = vec4F_add(&meanColor, &b1); + minColor = vec4F_saturate(&c0); + maxColor = vec4F_saturate(&c1); + + bc7enc_vec4F whiteVec; + vec4F_set_scalar(&whiteVec, 1.0f); + if (vec4F_dot(&minColor, &whiteVec) > vec4F_dot(&maxColor, &whiteVec)) + { +#if 1 + std::swap(minColor.m_c[0], maxColor.m_c[0]); + std::swap(minColor.m_c[1], maxColor.m_c[1]); + std::swap(minColor.m_c[2], maxColor.m_c[2]); + std::swap(minColor.m_c[3], maxColor.m_c[3]); +#elif 0 + // Fails to compile correctly with MSVC 2019 (code generation bug) + std::swap(minColor, maxColor); +#else + // Fails with MSVC 2019 + bc7enc_vec4F temp = minColor; + minColor = maxColor; + maxColor = temp; +#endif + } + + // First find a solution using the block's PCA. + if (!find_optimal_solution(mode, minColor, maxColor, pParams, pResults)) + return 0; + + for (uint32_t i = 0; i < pComp_params->m_least_squares_passes; i++) + { + // Now try to refine the solution using least squares by computing the optimal endpoints from the current selectors. + bc7enc_vec4F xl, xh; + vec4F_set_scalar(&xl, 0.0f); + vec4F_set_scalar(&xh, 0.0f); + if (pParams->m_has_alpha) + compute_least_squares_endpoints_rgba(pParams->m_num_pixels, pResults->m_pSelectors, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + else + compute_least_squares_endpoints_rgb(pParams->m_num_pixels, pResults->m_pSelectors, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + + xl = vec4F_mul(&xl, (1.0f / 255.0f)); + xh = vec4F_mul(&xh, (1.0f / 255.0f)); + + if (!find_optimal_solution(mode, xl, xh, pParams, pResults)) + return 0; + } + + if ((!pParams->m_pForce_selectors) && (pComp_params->m_uber_level > 0)) + { + // In uber level 1, try varying the selectors a little, somewhat like cluster fit would. First try incrementing the minimum selectors, + // then try decrementing the selectrors, then try both. + uint8_t selectors_temp[16], selectors_temp1[16]; + memcpy(selectors_temp, pResults->m_pSelectors, pParams->m_num_pixels); + + const int max_selector = pParams->m_num_selector_weights - 1; + + uint32_t min_sel = 256; + uint32_t max_sel = 0; + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + uint32_t sel = selectors_temp[i]; + min_sel = minimumu(min_sel, sel); + max_sel = maximumu(max_sel, sel); + } + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + uint32_t sel = selectors_temp[i]; + if ((sel == min_sel) && (sel < (pParams->m_num_selector_weights - 1))) + sel++; + selectors_temp1[i] = (uint8_t)sel; + } + + bc7enc_vec4F xl, xh; + vec4F_set_scalar(&xl, 0.0f); + vec4F_set_scalar(&xh, 0.0f); + if (pParams->m_has_alpha) + compute_least_squares_endpoints_rgba(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + else + compute_least_squares_endpoints_rgb(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + + xl = vec4F_mul(&xl, (1.0f / 255.0f)); + xh = vec4F_mul(&xh, (1.0f / 255.0f)); + + if (!find_optimal_solution(mode, xl, xh, pParams, pResults)) + return 0; + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + uint32_t sel = selectors_temp[i]; + if ((sel == max_sel) && (sel > 0)) + sel--; + selectors_temp1[i] = (uint8_t)sel; + } + + if (pParams->m_has_alpha) + compute_least_squares_endpoints_rgba(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + else + compute_least_squares_endpoints_rgb(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + + xl = vec4F_mul(&xl, (1.0f / 255.0f)); + xh = vec4F_mul(&xh, (1.0f / 255.0f)); + + if (!find_optimal_solution(mode, xl, xh, pParams, pResults)) + return 0; + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + { + uint32_t sel = selectors_temp[i]; + if ((sel == min_sel) && (sel < (pParams->m_num_selector_weights - 1))) + sel++; + else if ((sel == max_sel) && (sel > 0)) + sel--; + selectors_temp1[i] = (uint8_t)sel; + } + + if (pParams->m_has_alpha) + compute_least_squares_endpoints_rgba(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + else + compute_least_squares_endpoints_rgb(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + + xl = vec4F_mul(&xl, (1.0f / 255.0f)); + xh = vec4F_mul(&xh, (1.0f / 255.0f)); + + if (!find_optimal_solution(mode, xl, xh, pParams, pResults)) + return 0; + + // In uber levels 2+, try taking more advantage of endpoint extrapolation by scaling the selectors in one direction or another. + const uint32_t uber_err_thresh = (pParams->m_num_pixels * 56) >> 4; + if ((pComp_params->m_uber_level >= 2) && (pResults->m_best_overall_err > uber_err_thresh)) + { + const int Q = (pComp_params->m_uber_level >= 4) ? (pComp_params->m_uber_level - 2) : 1; + for (int ly = -Q; ly <= 1; ly++) + { + for (int hy = max_selector - 1; hy <= (max_selector + Q); hy++) + { + if ((ly == 0) && (hy == max_selector)) + continue; + + for (uint32_t i = 0; i < pParams->m_num_pixels; i++) + selectors_temp1[i] = (uint8_t)clampf(floorf((float)max_selector * ((float)selectors_temp[i] - (float)ly) / ((float)hy - (float)ly) + .5f), 0, (float)max_selector); + + //bc7enc_vec4F xl, xh; + vec4F_set_scalar(&xl, 0.0f); + vec4F_set_scalar(&xh, 0.0f); + if (pParams->m_has_alpha) + compute_least_squares_endpoints_rgba(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + else + compute_least_squares_endpoints_rgb(pParams->m_num_pixels, selectors_temp1, pParams->m_pSelector_weightsx, &xl, &xh, pParams->m_pPixels); + + xl = vec4F_mul(&xl, (1.0f / 255.0f)); + xh = vec4F_mul(&xh, (1.0f / 255.0f)); + + if (!find_optimal_solution(mode, xl, xh, pParams, pResults)) + return 0; + } + } + } + } + + if (!pParams->m_pForce_selectors) + { + // Try encoding the partition as a single color by using the optimal single colors tables to encode the block to its mean. + if (mode == 1) + { + color_cell_compressor_results avg_results = *pResults; + const uint32_t r = (int)(.5f + meanColor.m_c[0] * 255.0f), g = (int)(.5f + meanColor.m_c[1] * 255.0f), b = (int)(.5f + meanColor.m_c[2] * 255.0f); + uint64_t avg_err = pack_mode1_to_one_color(pParams, &avg_results, r, g, b, pResults->m_pSelectors_temp); + if (avg_err < pResults->m_best_overall_err) + { + *pResults = avg_results; + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + pResults->m_best_overall_err = avg_err; + } + } + else if ((pParams->m_astc_endpoint_range == 8) && (pParams->m_num_selector_weights == 8) && (!pParams->m_has_alpha)) + { + color_cell_compressor_results avg_results = *pResults; + const uint32_t r = (int)(.5f + meanColor.m_c[0] * 255.0f), g = (int)(.5f + meanColor.m_c[1] * 255.0f), b = (int)(.5f + meanColor.m_c[2] * 255.0f); + uint64_t avg_err = pack_astc_4bit_3bit_to_one_color(pParams, &avg_results, r, g, b, pResults->m_pSelectors_temp); + if (avg_err < pResults->m_best_overall_err) + { + *pResults = avg_results; + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + pResults->m_best_overall_err = avg_err; + } + } + else if ((pParams->m_astc_endpoint_range == 7) && (pParams->m_num_selector_weights == 4) && (!pParams->m_has_alpha)) + { + color_cell_compressor_results avg_results = *pResults; + const uint32_t r = (int)(.5f + meanColor.m_c[0] * 255.0f), g = (int)(.5f + meanColor.m_c[1] * 255.0f), b = (int)(.5f + meanColor.m_c[2] * 255.0f); + uint64_t avg_err = pack_astc_range7_2bit_to_one_color(pParams, &avg_results, r, g, b, pResults->m_pSelectors_temp); + if (avg_err < pResults->m_best_overall_err) + { + *pResults = avg_results; + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + pResults->m_best_overall_err = avg_err; + } + } + else if ((pParams->m_astc_endpoint_range == 8) && (pParams->m_num_selector_weights == 4) && (pParams->m_has_alpha)) + { + color_cell_compressor_results avg_results = *pResults; + const uint32_t r = (int)(.5f + meanColor.m_c[0] * 255.0f), g = (int)(.5f + meanColor.m_c[1] * 255.0f), b = (int)(.5f + meanColor.m_c[2] * 255.0f), a = (int)(.5f + meanColor.m_c[3] * 255.0f); + uint64_t avg_err = pack_astc_4bit_2bit_to_one_color_rgba(pParams, &avg_results, r, g, b, a, pResults->m_pSelectors_temp); + if (avg_err < pResults->m_best_overall_err) + { + *pResults = avg_results; + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + pResults->m_best_overall_err = avg_err; + } + } + else if ((pParams->m_astc_endpoint_range == 13) && (pParams->m_num_selector_weights == 4) && (!pParams->m_has_alpha)) + { + color_cell_compressor_results avg_results = *pResults; + const uint32_t r = (int)(.5f + meanColor.m_c[0] * 255.0f), g = (int)(.5f + meanColor.m_c[1] * 255.0f), b = (int)(.5f + meanColor.m_c[2] * 255.0f); + uint64_t avg_err = pack_astc_range13_2bit_to_one_color(pParams, &avg_results, r, g, b, pResults->m_pSelectors_temp); + if (avg_err < pResults->m_best_overall_err) + { + *pResults = avg_results; + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + pResults->m_best_overall_err = avg_err; + } + } + else if ((pParams->m_astc_endpoint_range == 11) && (pParams->m_num_selector_weights == 32) && (!pParams->m_has_alpha)) + { + color_cell_compressor_results avg_results = *pResults; + const uint32_t r = (int)(.5f + meanColor.m_c[0] * 255.0f), g = (int)(.5f + meanColor.m_c[1] * 255.0f), b = (int)(.5f + meanColor.m_c[2] * 255.0f); + uint64_t avg_err = pack_astc_range11_5bit_to_one_color(pParams, &avg_results, r, g, b, pResults->m_pSelectors_temp); + if (avg_err < pResults->m_best_overall_err) + { + *pResults = avg_results; + memcpy(pResults->m_pSelectors, pResults->m_pSelectors_temp, sizeof(pResults->m_pSelectors[0]) * pParams->m_num_pixels); + pResults->m_best_overall_err = avg_err; + } + } + } + +#if BC7ENC_CHECK_OVERALL_ERROR + check_best_overall_error(pParams, pResults); +#endif + + return pResults->m_best_overall_err; +} + +uint64_t color_cell_compression_est_astc( + uint32_t num_weights, uint32_t num_comps, const uint32_t *pWeight_table, + uint32_t num_pixels, const color_quad_u8* pPixels, + uint64_t best_err_so_far, const uint32_t weights[4]) +{ + assert(num_comps == 3 || num_comps == 4); + assert(num_weights >= 1 && num_weights <= 32); + assert(pWeight_table[0] == 0 && pWeight_table[num_weights - 1] == 64); + + // Find RGB bounds as an approximation of the block's principle axis + uint32_t lr = 255, lg = 255, lb = 255, la = 255; + uint32_t hr = 0, hg = 0, hb = 0, ha = 0; + if (num_comps == 4) + { + for (uint32_t i = 0; i < num_pixels; i++) + { + const color_quad_u8* pC = &pPixels[i]; + if (pC->m_c[0] < lr) lr = pC->m_c[0]; + if (pC->m_c[1] < lg) lg = pC->m_c[1]; + if (pC->m_c[2] < lb) lb = pC->m_c[2]; + if (pC->m_c[3] < la) la = pC->m_c[3]; + + if (pC->m_c[0] > hr) hr = pC->m_c[0]; + if (pC->m_c[1] > hg) hg = pC->m_c[1]; + if (pC->m_c[2] > hb) hb = pC->m_c[2]; + if (pC->m_c[3] > ha) ha = pC->m_c[3]; + } + } + else + { + for (uint32_t i = 0; i < num_pixels; i++) + { + const color_quad_u8* pC = &pPixels[i]; + if (pC->m_c[0] < lr) lr = pC->m_c[0]; + if (pC->m_c[1] < lg) lg = pC->m_c[1]; + if (pC->m_c[2] < lb) lb = pC->m_c[2]; + + if (pC->m_c[0] > hr) hr = pC->m_c[0]; + if (pC->m_c[1] > hg) hg = pC->m_c[1]; + if (pC->m_c[2] > hb) hb = pC->m_c[2]; + } + la = 255; + ha = 255; + } + + color_quad_u8 lowColor, highColor; + color_quad_u8_set(&lowColor, lr, lg, lb, la); + color_quad_u8_set(&highColor, hr, hg, hb, ha); + + // Place endpoints at bbox diagonals and compute interpolated colors + color_quad_u8 weightedColors[32]; + + weightedColors[0] = lowColor; + weightedColors[num_weights - 1] = highColor; + for (uint32_t i = 1; i < (num_weights - 1); i++) + { + weightedColors[i].m_c[0] = (uint8_t)astc_interpolate(lowColor.m_c[0], highColor.m_c[0], pWeight_table[i]); + weightedColors[i].m_c[1] = (uint8_t)astc_interpolate(lowColor.m_c[1], highColor.m_c[1], pWeight_table[i]); + weightedColors[i].m_c[2] = (uint8_t)astc_interpolate(lowColor.m_c[2], highColor.m_c[2], pWeight_table[i]); + weightedColors[i].m_c[3] = (num_comps == 4) ? (uint8_t)astc_interpolate(lowColor.m_c[3], highColor.m_c[3], pWeight_table[i]) : 255; + } + + // Compute dots and thresholds + const int ar = highColor.m_c[0] - lowColor.m_c[0]; + const int ag = highColor.m_c[1] - lowColor.m_c[1]; + const int ab = highColor.m_c[2] - lowColor.m_c[2]; + const int aa = highColor.m_c[3] - lowColor.m_c[3]; + + int dots[32]; + if (num_comps == 4) + { + for (uint32_t i = 0; i < num_weights; i++) + dots[i] = weightedColors[i].m_c[0] * ar + weightedColors[i].m_c[1] * ag + weightedColors[i].m_c[2] * ab + weightedColors[i].m_c[3] * aa; + } + else + { + assert(aa == 0); + for (uint32_t i = 0; i < num_weights; i++) + dots[i] = weightedColors[i].m_c[0] * ar + weightedColors[i].m_c[1] * ag + weightedColors[i].m_c[2] * ab; + } + + int thresh[32 - 1]; + for (uint32_t i = 0; i < (num_weights - 1); i++) + thresh[i] = (dots[i] + dots[i + 1] + 1) >> 1; + + uint64_t total_err = 0; + if ((weights[0] | weights[1] | weights[2] | weights[3]) == 1) + { + if (num_comps == 4) + { + for (uint32_t i = 0; i < num_pixels; i++) + { + const color_quad_u8* pC = &pPixels[i]; + + int d = ar * pC->m_c[0] + ag * pC->m_c[1] + ab * pC->m_c[2] + aa * pC->m_c[3]; + + // Find approximate selector + uint32_t s = 0; + for (int j = num_weights - 2; j >= 0; j--) + { + if (d >= thresh[j]) + { + s = j + 1; + break; + } + } + + // Compute error + const color_quad_u8* pE1 = &weightedColors[s]; + + int dr = (int)pE1->m_c[0] - (int)pC->m_c[0]; + int dg = (int)pE1->m_c[1] - (int)pC->m_c[1]; + int db = (int)pE1->m_c[2] - (int)pC->m_c[2]; + int da = (int)pE1->m_c[3] - (int)pC->m_c[3]; + + total_err += (dr * dr) + (dg * dg) + (db * db) + (da * da); + if (total_err > best_err_so_far) + break; + } + } + else + { + for (uint32_t i = 0; i < num_pixels; i++) + { + const color_quad_u8* pC = &pPixels[i]; + + int d = ar * pC->m_c[0] + ag * pC->m_c[1] + ab * pC->m_c[2]; + + // Find approximate selector + uint32_t s = 0; + for (int j = num_weights - 2; j >= 0; j--) + { + if (d >= thresh[j]) + { + s = j + 1; + break; + } + } + + // Compute error + const color_quad_u8* pE1 = &weightedColors[s]; + + int dr = (int)pE1->m_c[0] - (int)pC->m_c[0]; + int dg = (int)pE1->m_c[1] - (int)pC->m_c[1]; + int db = (int)pE1->m_c[2] - (int)pC->m_c[2]; + + total_err += (dr * dr) + (dg * dg) + (db * db); + if (total_err > best_err_so_far) + break; + } + } + } + else + { + if (num_comps == 4) + { + for (uint32_t i = 0; i < num_pixels; i++) + { + const color_quad_u8* pC = &pPixels[i]; + + int d = ar * pC->m_c[0] + ag * pC->m_c[1] + ab * pC->m_c[2] + aa * pC->m_c[3]; + + // Find approximate selector + uint32_t s = 0; + for (int j = num_weights - 2; j >= 0; j--) + { + if (d >= thresh[j]) + { + s = j + 1; + break; + } + } + + // Compute error + const color_quad_u8* pE1 = &weightedColors[s]; + + int dr = (int)pE1->m_c[0] - (int)pC->m_c[0]; + int dg = (int)pE1->m_c[1] - (int)pC->m_c[1]; + int db = (int)pE1->m_c[2] - (int)pC->m_c[2]; + int da = (int)pE1->m_c[3] - (int)pC->m_c[3]; + + total_err += weights[0] * (dr * dr) + weights[1] * (dg * dg) + weights[2] * (db * db) + weights[3] * (da * da); + if (total_err > best_err_so_far) + break; + } + } + else + { + for (uint32_t i = 0; i < num_pixels; i++) + { + const color_quad_u8* pC = &pPixels[i]; + + int d = ar * pC->m_c[0] + ag * pC->m_c[1] + ab * pC->m_c[2]; + + // Find approximate selector + uint32_t s = 0; + for (int j = num_weights - 2; j >= 0; j--) + { + if (d >= thresh[j]) + { + s = j + 1; + break; + } + } + + // Compute error + const color_quad_u8* pE1 = &weightedColors[s]; + + int dr = (int)pE1->m_c[0] - (int)pC->m_c[0]; + int dg = (int)pE1->m_c[1] - (int)pC->m_c[1]; + int db = (int)pE1->m_c[2] - (int)pC->m_c[2]; + + total_err += weights[0] * (dr * dr) + weights[1] * (dg * dg) + weights[2] * (db * db); + if (total_err > best_err_so_far) + break; + } + } + } + + return total_err; +} + +} // namespace basisu diff --git a/thirdparty/basis_universal/encoder/basisu_bc7enc.h b/thirdparty/basis_universal/encoder/basisu_bc7enc.h new file mode 100644 index 0000000000..23469912e2 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_bc7enc.h @@ -0,0 +1,131 @@ +// File: basisu_bc7enc.h +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_enc.h" +#include "../transcoder/basisu_transcoder_uastc.h" + +namespace basisu +{ + +#define BC7ENC_MAX_PARTITIONS1 (64) +#define BC7ENC_MAX_UBER_LEVEL (4) + + typedef uint8_t bc7enc_bool; + +#define BC7ENC_TRUE (1) +#define BC7ENC_FALSE (0) + + typedef struct { float m_c[4]; } bc7enc_vec4F; + + extern const float g_bc7_weights1x[2 * 4]; + extern const float g_bc7_weights2x[4 * 4]; + extern const float g_bc7_weights3x[8 * 4]; + extern const float g_bc7_weights4x[16 * 4]; + extern const float g_astc_weights4x[16 * 4]; + extern const float g_astc_weights5x[32 * 4]; + extern const float g_astc_weights_3levelsx[3 * 4]; + + extern basist::astc_quant_bin g_astc_sorted_order_unquant[basist::BC7ENC_TOTAL_ASTC_RANGES][256]; // [sorted unquantized order] + + struct color_cell_compressor_params + { + uint32_t m_num_pixels; + const basist::color_quad_u8* m_pPixels; + + uint32_t m_num_selector_weights; + const uint32_t* m_pSelector_weights; + + const bc7enc_vec4F* m_pSelector_weightsx; + uint32_t m_comp_bits; + + const uint8_t *m_pForce_selectors; + + // Non-zero m_astc_endpoint_range enables ASTC mode. m_comp_bits and m_has_pbits are always false. We only support 2, 3, or 4 bit weight encodings. + uint32_t m_astc_endpoint_range; + + uint32_t m_weights[4]; + bc7enc_bool m_has_alpha; + bc7enc_bool m_has_pbits; + bc7enc_bool m_endpoints_share_pbit; + bc7enc_bool m_perceptual; + }; + + struct color_cell_compressor_results + { + uint64_t m_best_overall_err; + basist::color_quad_u8 m_low_endpoint; + basist::color_quad_u8 m_high_endpoint; + uint32_t m_pbits[2]; + uint8_t* m_pSelectors; + uint8_t* m_pSelectors_temp; + + // Encoded ASTC indices, if ASTC mode is enabled + basist::color_quad_u8 m_astc_low_endpoint; + basist::color_quad_u8 m_astc_high_endpoint; + }; + + struct bc7enc_compress_block_params + { + // m_max_partitions_mode1 may range from 0 (disables mode 1) to BC7ENC_MAX_PARTITIONS1. The higher this value, the slower the compressor, but the higher the quality. + uint32_t m_max_partitions_mode1; + + // Relative RGBA or YCbCrA weights. + uint32_t m_weights[4]; + + // m_uber_level may range from 0 to BC7ENC_MAX_UBER_LEVEL. The higher this value, the slower the compressor, but the higher the quality. + uint32_t m_uber_level; + + // If m_perceptual is true, colorspace error is computed in YCbCr space, otherwise RGB. + bc7enc_bool m_perceptual; + + uint32_t m_least_squares_passes; + }; + + uint64_t color_cell_compression(uint32_t mode, const color_cell_compressor_params* pParams, color_cell_compressor_results* pResults, const bc7enc_compress_block_params* pComp_params); + + uint64_t color_cell_compression_est_astc( + uint32_t num_weights, uint32_t num_comps, const uint32_t* pWeight_table, + uint32_t num_pixels, const basist::color_quad_u8* pPixels, + uint64_t best_err_so_far, const uint32_t weights[4]); + + inline void bc7enc_compress_block_params_init_linear_weights(bc7enc_compress_block_params* p) + { + p->m_perceptual = BC7ENC_FALSE; + p->m_weights[0] = 1; + p->m_weights[1] = 1; + p->m_weights[2] = 1; + p->m_weights[3] = 1; + } + + inline void bc7enc_compress_block_params_init_perceptual_weights(bc7enc_compress_block_params* p) + { + p->m_perceptual = BC7ENC_TRUE; + p->m_weights[0] = 128; + p->m_weights[1] = 64; + p->m_weights[2] = 16; + p->m_weights[3] = 32; + } + + inline void bc7enc_compress_block_params_init(bc7enc_compress_block_params* p) + { + p->m_max_partitions_mode1 = BC7ENC_MAX_PARTITIONS1; + p->m_least_squares_passes = 1; + p->m_uber_level = 0; + bc7enc_compress_block_params_init_perceptual_weights(p); + } + + // bc7enc_compress_block_init() MUST be called before calling bc7enc_compress_block() (or you'll get artifacts). + void bc7enc_compress_block_init(); + +} // namespace basisu diff --git a/thirdparty/basis_universal/encoder/basisu_comp.cpp b/thirdparty/basis_universal/encoder/basisu_comp.cpp new file mode 100644 index 0000000000..dc4ae11539 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_comp.cpp @@ -0,0 +1,2113 @@ +// basisu_comp.cpp +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_comp.h" +#include "basisu_enc.h" +#include <unordered_set> +#include <atomic> + +// basisu_transcoder.cpp is where basisu_miniz lives now, we just need the declarations here. +#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES +#include "basisu_miniz.h" + +#if !BASISD_SUPPORT_KTX2 +#error BASISD_SUPPORT_KTX2 must be enabled (set to 1). +#endif + +#if BASISD_SUPPORT_KTX2_ZSTD +#include "../zstd/zstd.h" +#endif + +// Set to 1 to disable the mipPadding alignment workaround (which only seems to be needed when no key-values are written at all) +#define BASISU_DISABLE_KTX2_ALIGNMENT_WORKAROUND (0) + +// Set to 1 to disable writing all KTX2 key values, triggering the validator bug. +#define BASISU_DISABLE_KTX2_KEY_VALUES (0) + +using namespace buminiz; + +#define BASISU_USE_STB_IMAGE_RESIZE_FOR_MIPMAP_GEN 0 +#define DEBUG_CROP_TEXTURE_TO_64x64 (0) +#define DEBUG_RESIZE_TEXTURE (0) +#define DEBUG_EXTRACT_SINGLE_BLOCK (0) + +namespace basisu +{ + basis_compressor::basis_compressor() : + m_basis_file_size(0), + m_basis_bits_per_texel(0.0f), + m_total_blocks(0), + m_auto_global_sel_pal(false), + m_any_source_image_has_alpha(false) + { + debug_printf("basis_compressor::basis_compressor\n"); + } + + bool basis_compressor::init(const basis_compressor_params ¶ms) + { + debug_printf("basis_compressor::init\n"); + + m_params = params; + + if (m_params.m_debug) + { + debug_printf("basis_compressor::init:\n"); + +#define PRINT_BOOL_VALUE(v) debug_printf("%s: %u %u\n", BASISU_STRINGIZE2(v), static_cast<int>(m_params.v), m_params.v.was_changed()); +#define PRINT_INT_VALUE(v) debug_printf("%s: %i %u\n", BASISU_STRINGIZE2(v), static_cast<int>(m_params.v), m_params.v.was_changed()); +#define PRINT_UINT_VALUE(v) debug_printf("%s: %u %u\n", BASISU_STRINGIZE2(v), static_cast<uint32_t>(m_params.v), m_params.v.was_changed()); +#define PRINT_FLOAT_VALUE(v) debug_printf("%s: %f %u\n", BASISU_STRINGIZE2(v), static_cast<float>(m_params.v), m_params.v.was_changed()); + + debug_printf("Has global selector codebook: %i\n", m_params.m_pSel_codebook != nullptr); + + debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i, Source mipmap images: %u\n", + m_params.m_source_images.size(), m_params.m_source_filenames.size(), m_params.m_source_alpha_filenames.size(), m_params.m_source_mipmap_images.size()); + + if (m_params.m_source_mipmap_images.size()) + { + debug_printf("m_source_mipmap_images array sizes:\n"); + for (uint32_t i = 0; i < m_params.m_source_mipmap_images.size(); i++) + debug_printf("%u ", m_params.m_source_mipmap_images[i].size()); + debug_printf("\n"); + } + + PRINT_BOOL_VALUE(m_uastc); + PRINT_BOOL_VALUE(m_y_flip); + PRINT_BOOL_VALUE(m_debug); + PRINT_BOOL_VALUE(m_validate); + PRINT_BOOL_VALUE(m_debug_images); + PRINT_BOOL_VALUE(m_global_sel_pal); + PRINT_BOOL_VALUE(m_auto_global_sel_pal); + PRINT_INT_VALUE(m_compression_level); + PRINT_BOOL_VALUE(m_no_hybrid_sel_cb); + PRINT_BOOL_VALUE(m_perceptual); + PRINT_BOOL_VALUE(m_no_endpoint_rdo); + PRINT_BOOL_VALUE(m_no_selector_rdo); + PRINT_BOOL_VALUE(m_read_source_images); + PRINT_BOOL_VALUE(m_write_output_basis_files); + PRINT_BOOL_VALUE(m_compute_stats); + PRINT_BOOL_VALUE(m_check_for_alpha); + PRINT_BOOL_VALUE(m_force_alpha); + debug_printf("swizzle: %d,%d,%d,%d\n", + m_params.m_swizzle[0], + m_params.m_swizzle[1], + m_params.m_swizzle[2], + m_params.m_swizzle[3]); + PRINT_BOOL_VALUE(m_renormalize); + PRINT_BOOL_VALUE(m_multithreading); + PRINT_BOOL_VALUE(m_disable_hierarchical_endpoint_codebooks); + + PRINT_FLOAT_VALUE(m_hybrid_sel_cb_quality_thresh); + + PRINT_INT_VALUE(m_global_pal_bits); + PRINT_INT_VALUE(m_global_mod_bits); + + PRINT_FLOAT_VALUE(m_endpoint_rdo_thresh); + PRINT_FLOAT_VALUE(m_selector_rdo_thresh); + + PRINT_BOOL_VALUE(m_mip_gen); + PRINT_BOOL_VALUE(m_mip_renormalize); + PRINT_BOOL_VALUE(m_mip_wrapping); + PRINT_BOOL_VALUE(m_mip_fast); + PRINT_BOOL_VALUE(m_mip_srgb); + PRINT_FLOAT_VALUE(m_mip_premultiplied); + PRINT_FLOAT_VALUE(m_mip_scale); + PRINT_INT_VALUE(m_mip_smallest_dimension); + debug_printf("m_mip_filter: %s\n", m_params.m_mip_filter.c_str()); + + debug_printf("m_max_endpoint_clusters: %u\n", m_params.m_max_endpoint_clusters); + debug_printf("m_max_selector_clusters: %u\n", m_params.m_max_selector_clusters); + debug_printf("m_quality_level: %i\n", m_params.m_quality_level); + + debug_printf("m_tex_type: %u\n", m_params.m_tex_type); + debug_printf("m_userdata0: 0x%X, m_userdata1: 0x%X\n", m_params.m_userdata0, m_params.m_userdata1); + debug_printf("m_us_per_frame: %i (%f fps)\n", m_params.m_us_per_frame, m_params.m_us_per_frame ? 1.0f / (m_params.m_us_per_frame / 1000000.0f) : 0); + debug_printf("m_pack_uastc_flags: 0x%X\n", m_params.m_pack_uastc_flags); + + PRINT_BOOL_VALUE(m_rdo_uastc); + PRINT_FLOAT_VALUE(m_rdo_uastc_quality_scalar); + PRINT_INT_VALUE(m_rdo_uastc_dict_size); + PRINT_FLOAT_VALUE(m_rdo_uastc_max_allowed_rms_increase_ratio); + PRINT_FLOAT_VALUE(m_rdo_uastc_skip_block_rms_thresh); + PRINT_FLOAT_VALUE(m_rdo_uastc_max_smooth_block_error_scale); + PRINT_FLOAT_VALUE(m_rdo_uastc_smooth_block_max_std_dev); + PRINT_BOOL_VALUE(m_rdo_uastc_favor_simpler_modes_in_rdo_mode) + PRINT_BOOL_VALUE(m_rdo_uastc_multithreading); + + PRINT_INT_VALUE(m_resample_width); + PRINT_INT_VALUE(m_resample_height); + PRINT_FLOAT_VALUE(m_resample_factor); + debug_printf("Has global codebooks: %u\n", m_params.m_pGlobal_codebooks ? 1 : 0); + if (m_params.m_pGlobal_codebooks) + { + debug_printf("Global codebook endpoints: %u selectors: %u\n", m_params.m_pGlobal_codebooks->get_endpoints().size(), m_params.m_pGlobal_codebooks->get_selectors().size()); + } + + PRINT_BOOL_VALUE(m_create_ktx2_file); + + debug_printf("KTX2 UASTC supercompression: %u\n", m_params.m_ktx2_uastc_supercompression); + debug_printf("KTX2 Zstd supercompression level: %i\n", (int)m_params.m_ktx2_zstd_supercompression_level); + debug_printf("KTX2 sRGB transfer func: %u\n", (int)m_params.m_ktx2_srgb_transfer_func); + debug_printf("Total KTX2 key values: %u\n", m_params.m_ktx2_key_values.size()); + for (uint32_t i = 0; i < m_params.m_ktx2_key_values.size(); i++) + { + debug_printf("Key: \"%s\"\n", m_params.m_ktx2_key_values[i].m_key.data()); + debug_printf("Value size: %u\n", m_params.m_ktx2_key_values[i].m_value.size()); + } + +#undef PRINT_BOOL_VALUE +#undef PRINT_INT_VALUE +#undef PRINT_UINT_VALUE +#undef PRINT_FLOAT_VALUE + } + + if ((m_params.m_read_source_images) && (!m_params.m_source_filenames.size())) + { + assert(0); + return false; + } + + return true; + } + + basis_compressor::error_code basis_compressor::process() + { + debug_printf("basis_compressor::process\n"); + + if (!read_source_images()) + return cECFailedReadingSourceImages; + + if (!validate_texture_type_constraints()) + return cECFailedValidating; + + if (m_params.m_create_ktx2_file) + { + if (!validate_ktx2_constraints()) + return cECFailedValidating; + } + + if (!extract_source_blocks()) + return cECFailedFrontEnd; + + if (m_params.m_uastc) + { + error_code ec = encode_slices_to_uastc(); + if (ec != cECSuccess) + return ec; + } + else + { + if (!process_frontend()) + return cECFailedFrontEnd; + + if (!extract_frontend_texture_data()) + return cECFailedFontendExtract; + + if (!process_backend()) + return cECFailedBackend; + } + + if (!create_basis_file_and_transcode()) + return cECFailedCreateBasisFile; + + if (m_params.m_create_ktx2_file) + { + if (!create_ktx2_file()) + return cECFailedCreateKTX2File; + } + + if (!write_output_files_and_compute_stats()) + return cECFailedWritingOutput; + + return cECSuccess; + } + + basis_compressor::error_code basis_compressor::encode_slices_to_uastc() + { + debug_printf("basis_compressor::encode_slices_to_uastc\n"); + + m_uastc_slice_textures.resize(m_slice_descs.size()); + for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) + m_uastc_slice_textures[slice_index].init(texture_format::cUASTC4x4, m_slice_descs[slice_index].m_orig_width, m_slice_descs[slice_index].m_orig_height); + + m_uastc_backend_output.m_tex_format = basist::basis_tex_format::cUASTC4x4; + m_uastc_backend_output.m_etc1s = false; + m_uastc_backend_output.m_slice_desc = m_slice_descs; + m_uastc_backend_output.m_slice_image_data.resize(m_slice_descs.size()); + m_uastc_backend_output.m_slice_image_crcs.resize(m_slice_descs.size()); + + for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) + { + gpu_image& tex = m_uastc_slice_textures[slice_index]; + basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index]; + (void)slice_desc; + + const uint32_t num_blocks_x = tex.get_blocks_x(); + const uint32_t num_blocks_y = tex.get_blocks_y(); + const uint32_t total_blocks = tex.get_total_blocks(); + const image& source_image = m_slice_images[slice_index]; + + std::atomic<uint32_t> total_blocks_processed; + total_blocks_processed = 0; + + const uint32_t N = 256; + for (uint32_t block_index_iter = 0; block_index_iter < total_blocks; block_index_iter += N) + { + const uint32_t first_index = block_index_iter; + const uint32_t last_index = minimum<uint32_t>(total_blocks, block_index_iter + N); + + // FIXME: This sucks, but we're having a stack size related problem with std::function with emscripten. +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->add_job([this, first_index, last_index, num_blocks_x, num_blocks_y, total_blocks, &source_image, &tex, &total_blocks_processed] + { +#endif + BASISU_NOTE_UNUSED(num_blocks_y); + + uint32_t uastc_flags = m_params.m_pack_uastc_flags; + if ((m_params.m_rdo_uastc) && (m_params.m_rdo_uastc_favor_simpler_modes_in_rdo_mode)) + uastc_flags |= cPackUASTCFavorSimplerModes; + + for (uint32_t block_index = first_index; block_index < last_index; block_index++) + { + const uint32_t block_x = block_index % num_blocks_x; + const uint32_t block_y = block_index / num_blocks_x; + + color_rgba block_pixels[4][4]; + + source_image.extract_block_clamped((color_rgba*)block_pixels, block_x * 4, block_y * 4, 4, 4); + + basist::uastc_block& dest_block = *(basist::uastc_block*)tex.get_block_ptr(block_x, block_y); + + encode_uastc(&block_pixels[0][0].r, dest_block, uastc_flags); + + total_blocks_processed++; + + uint32_t val = total_blocks_processed; + if ((val & 16383) == 16383) + { + debug_printf("basis_compressor::encode_slices_to_uastc: %3.1f%% done\n", static_cast<float>(val) * 100.0f / total_blocks); + } + + } + +#ifndef __EMSCRIPTEN__ + }); +#endif + + } // block_index_iter + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->wait_for_all(); +#endif + + if (m_params.m_rdo_uastc) + { + uastc_rdo_params rdo_params; + rdo_params.m_lambda = m_params.m_rdo_uastc_quality_scalar; + rdo_params.m_max_allowed_rms_increase_ratio = m_params.m_rdo_uastc_max_allowed_rms_increase_ratio; + rdo_params.m_skip_block_rms_thresh = m_params.m_rdo_uastc_skip_block_rms_thresh; + rdo_params.m_lz_dict_size = m_params.m_rdo_uastc_dict_size; + rdo_params.m_smooth_block_max_error_scale = m_params.m_rdo_uastc_max_smooth_block_error_scale; + rdo_params.m_max_smooth_block_std_dev = m_params.m_rdo_uastc_smooth_block_max_std_dev; + + bool status = uastc_rdo(tex.get_total_blocks(), (basist::uastc_block*)tex.get_ptr(), + (const color_rgba *)m_source_blocks[slice_desc.m_first_block_index].m_pixels, rdo_params, m_params.m_pack_uastc_flags, m_params.m_rdo_uastc_multithreading ? m_params.m_pJob_pool : nullptr, + (m_params.m_rdo_uastc_multithreading && m_params.m_pJob_pool) ? basisu::minimum<uint32_t>(4, (uint32_t)m_params.m_pJob_pool->get_total_threads()) : 0); + if (!status) + { + return cECFailedUASTCRDOPostProcess; + } + } + + m_uastc_backend_output.m_slice_image_data[slice_index].resize(tex.get_size_in_bytes()); + memcpy(&m_uastc_backend_output.m_slice_image_data[slice_index][0], tex.get_ptr(), tex.get_size_in_bytes()); + + m_uastc_backend_output.m_slice_image_crcs[slice_index] = basist::crc16(tex.get_ptr(), tex.get_size_in_bytes(), 0); + + } // slice_index + + return cECSuccess; + } + + bool basis_compressor::generate_mipmaps(const image &img, basisu::vector<image> &mips, bool has_alpha) + { + debug_printf("basis_compressor::generate_mipmaps\n"); + + interval_timer tm; + tm.start(); + + uint32_t total_levels = 1; + uint32_t w = img.get_width(), h = img.get_height(); + while (maximum<uint32_t>(w, h) > (uint32_t)m_params.m_mip_smallest_dimension) + { + w = maximum(w >> 1U, 1U); + h = maximum(h >> 1U, 1U); + total_levels++; + } + +#if BASISU_USE_STB_IMAGE_RESIZE_FOR_MIPMAP_GEN + // Requires stb_image_resize + stbir_filter filter = STBIR_FILTER_DEFAULT; + if (m_params.m_mip_filter == "box") + filter = STBIR_FILTER_BOX; + else if (m_params.m_mip_filter == "triangle") + filter = STBIR_FILTER_TRIANGLE; + else if (m_params.m_mip_filter == "cubic") + filter = STBIR_FILTER_CUBICBSPLINE; + else if (m_params.m_mip_filter == "catmull") + filter = STBIR_FILTER_CATMULLROM; + else if (m_params.m_mip_filter == "mitchell") + filter = STBIR_FILTER_MITCHELL; + + for (uint32_t level = 1; level < total_levels; level++) + { + const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level); + const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level); + + image &level_img = *enlarge_vector(mips, 1); + level_img.resize(level_width, level_height); + + int result = stbir_resize_uint8_generic( + (const uint8_t *)img.get_ptr(), img.get_width(), img.get_height(), img.get_pitch() * sizeof(color_rgba), + (uint8_t *)level_img.get_ptr(), level_img.get_width(), level_img.get_height(), level_img.get_pitch() * sizeof(color_rgba), + has_alpha ? 4 : 3, has_alpha ? 3 : STBIR_ALPHA_CHANNEL_NONE, m_params.m_mip_premultiplied ? STBIR_FLAG_ALPHA_PREMULTIPLIED : 0, + m_params.m_mip_wrapping ? STBIR_EDGE_WRAP : STBIR_EDGE_CLAMP, filter, m_params.m_mip_srgb ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, + nullptr); + + if (result == 0) + { + error_printf("basis_compressor::generate_mipmaps: stbir_resize_uint8_generic() failed!\n"); + return false; + } + + if (m_params.m_mip_renormalize) + level_img.renormalize_normal_map(); + } +#else + for (uint32_t level = 1; level < total_levels; level++) + { + const uint32_t level_width = maximum<uint32_t>(1, img.get_width() >> level); + const uint32_t level_height = maximum<uint32_t>(1, img.get_height() >> level); + + image& level_img = *enlarge_vector(mips, 1); + level_img.resize(level_width, level_height); + + const image* pSource_image = &img; + + if (m_params.m_mip_fast) + { + if (level > 1) + pSource_image = &mips[level - 1]; + } + + bool status = image_resample(*pSource_image, level_img, m_params.m_mip_srgb, m_params.m_mip_filter.c_str(), m_params.m_mip_scale, m_params.m_mip_wrapping, 0, has_alpha ? 4 : 3); + if (!status) + { + error_printf("basis_compressor::generate_mipmaps: image_resample() failed!\n"); + return false; + } + + if (m_params.m_mip_renormalize) + level_img.renormalize_normal_map(); + } +#endif + + if (m_params.m_debug) + debug_printf("Total mipmap generation time: %f secs\n", tm.get_elapsed_secs()); + + return true; + } + + bool basis_compressor::read_source_images() + { + debug_printf("basis_compressor::read_source_images\n"); + + const uint32_t total_source_files = m_params.m_read_source_images ? (uint32_t)m_params.m_source_filenames.size() : (uint32_t)m_params.m_source_images.size(); + if (!total_source_files) + return false; + + m_stats.resize(0); + m_slice_descs.resize(0); + m_slice_images.resize(0); + + m_total_blocks = 0; + uint32_t total_macroblocks = 0; + + m_any_source_image_has_alpha = false; + + basisu::vector<image> source_images; + basisu::vector<std::string> source_filenames; + + // First load all source images, and determine if any have an alpha channel. + for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) + { + const char *pSource_filename = ""; + + image file_image; + + if (m_params.m_read_source_images) + { + pSource_filename = m_params.m_source_filenames[source_file_index].c_str(); + + // Load the source image + if (!load_image(pSource_filename, file_image)) + { + error_printf("Failed reading source image: %s\n", pSource_filename); + return false; + } + + printf("Read source image \"%s\", %ux%u\n", pSource_filename, file_image.get_width(), file_image.get_height()); + + // Optionally load another image and put a grayscale version of it into the alpha channel. + if ((source_file_index < m_params.m_source_alpha_filenames.size()) && (m_params.m_source_alpha_filenames[source_file_index].size())) + { + const char *pSource_alpha_image = m_params.m_source_alpha_filenames[source_file_index].c_str(); + + image alpha_data; + + if (!load_image(pSource_alpha_image, alpha_data)) + { + error_printf("Failed reading source image: %s\n", pSource_alpha_image); + return false; + } + + printf("Read source alpha image \"%s\", %ux%u\n", pSource_alpha_image, alpha_data.get_width(), alpha_data.get_height()); + + alpha_data.crop(file_image.get_width(), file_image.get_height()); + + for (uint32_t y = 0; y < file_image.get_height(); y++) + for (uint32_t x = 0; x < file_image.get_width(); x++) + file_image(x, y).a = (uint8_t)alpha_data(x, y).get_709_luma(); + } + } + else + { + file_image = m_params.m_source_images[source_file_index]; + } + + if (m_params.m_renormalize) + file_image.renormalize_normal_map(); + + bool alpha_swizzled = false; + if (m_params.m_swizzle[0] != 0 || + m_params.m_swizzle[1] != 1 || + m_params.m_swizzle[2] != 2 || + m_params.m_swizzle[3] != 3) + { + // Used for XY normal maps in RG - puts X in color, Y in alpha + for (uint32_t y = 0; y < file_image.get_height(); y++) + for (uint32_t x = 0; x < file_image.get_width(); x++) + { + const color_rgba &c = file_image(x, y); + file_image(x, y).set_noclamp_rgba(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], c[m_params.m_swizzle[3]]); + } + alpha_swizzled = m_params.m_swizzle[3] != 3; + } + + bool has_alpha = false; + if (m_params.m_force_alpha || alpha_swizzled) + has_alpha = true; + else if (!m_params.m_check_for_alpha) + file_image.set_alpha(255); + else if (file_image.has_alpha()) + has_alpha = true; + + if (has_alpha) + m_any_source_image_has_alpha = true; + + debug_printf("Source image index %u filename %s %ux%u has alpha: %u\n", source_file_index, pSource_filename, file_image.get_width(), file_image.get_height(), has_alpha); + + if (m_params.m_y_flip) + file_image.flip_y(); + +#if DEBUG_EXTRACT_SINGLE_BLOCK + image block_image(4, 4); + const uint32_t block_x = 0; + const uint32_t block_y = 0; + block_image.blit(block_x * 4, block_y * 4, 4, 4, 0, 0, file_image, 0); + file_image = block_image; +#endif + +#if DEBUG_CROP_TEXTURE_TO_64x64 + file_image.resize(64, 64); +#endif + + if (m_params.m_resample_width > 0 && m_params.m_resample_height > 0) + { + int new_width = basisu::minimum<int>(m_params.m_resample_width, BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION); + int new_height = basisu::minimum<int>(m_params.m_resample_height, BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION); + + debug_printf("Resampling to %ix%i\n", new_width, new_height); + + // TODO: A box filter - kaiser looks too sharp on video. Let the caller control this. + image temp_img(new_width, new_height); + image_resample(file_image, temp_img, m_params.m_perceptual, "box"); // "kaiser"); + temp_img.swap(file_image); + } + else if (m_params.m_resample_factor > 0.0f) + { + int new_width = basisu::minimum<int>(basisu::maximum(1, (int)ceilf(file_image.get_width() * m_params.m_resample_factor)), BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION); + int new_height = basisu::minimum<int>(basisu::maximum(1, (int)ceilf(file_image.get_height() * m_params.m_resample_factor)), BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION); + + debug_printf("Resampling to %ix%i\n", new_width, new_height); + + // TODO: A box filter - kaiser looks too sharp on video. Let the caller control this. + image temp_img(new_width, new_height); + image_resample(file_image, temp_img, m_params.m_perceptual, "box"); // "kaiser"); + temp_img.swap(file_image); + } + + if ((!file_image.get_width()) || (!file_image.get_height())) + { + error_printf("basis_compressor::read_source_images: Source image has a zero width and/or height!\n"); + return false; + } + + if ((file_image.get_width() > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION) || (file_image.get_height() > BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION)) + { + error_printf("basis_compressor::read_source_images: Source image is too large!\n"); + return false; + } + + source_images.push_back(file_image); + source_filenames.push_back(pSource_filename); + } + + // Check if the caller has generated their own mipmaps. + if (m_params.m_source_mipmap_images.size()) + { + // Make sure they've passed us enough mipmap chains. + if ((m_params.m_source_images.size() != m_params.m_source_mipmap_images.size()) || (total_source_files != m_params.m_source_images.size())) + { + error_printf("basis_compressor::read_source_images(): m_params.m_source_mipmap_images.size() must equal m_params.m_source_images.size()!\n"); + return false; + } + + // Check if any of the user-supplied mipmap levels has alpha. + // We're assuming the user has already preswizzled their mipmap source images. + if (!m_any_source_image_has_alpha) + { + for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) + { + for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++) + { + const image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index]; + + if (mip_img.has_alpha()) + { + m_any_source_image_has_alpha = true; + break; + } + } + + if (m_any_source_image_has_alpha) + break; + } + } + } + + debug_printf("Any source image has alpha: %u\n", m_any_source_image_has_alpha); + + for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) + { + image &file_image = source_images[source_file_index]; + const std::string &source_filename = source_filenames[source_file_index]; + + // Now, for each source image, create the slices corresponding to that image. + basisu::vector<image> slices; + + slices.reserve(32); + + // The first (largest) mipmap level. + slices.push_back(file_image); + + if (m_params.m_source_mipmap_images.size()) + { + // User-provided mipmaps for each layer or image in the texture array. + for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++) + { + image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index]; + + if (m_params.m_swizzle[0] != 0 || + m_params.m_swizzle[1] != 1 || + m_params.m_swizzle[2] != 2 || + m_params.m_swizzle[3] != 3) + { + // Used for XY normal maps in RG - puts X in color, Y in alpha + for (uint32_t y = 0; y < mip_img.get_height(); y++) + for (uint32_t x = 0; x < mip_img.get_width(); x++) + { + const color_rgba &c = mip_img(x, y); + mip_img(x, y).set_noclamp_rgba(c[m_params.m_swizzle[0]], c[m_params.m_swizzle[1]], c[m_params.m_swizzle[2]], c[m_params.m_swizzle[3]]); + } + } + + slices.push_back(mip_img); + } + } + else if (m_params.m_mip_gen) + { + // Automatically generate mipmaps. + if (!generate_mipmaps(file_image, slices, m_any_source_image_has_alpha)) + return false; + } + + uint_vec mip_indices(slices.size()); + for (uint32_t i = 0; i < slices.size(); i++) + mip_indices[i] = i; + + if ((m_any_source_image_has_alpha) && (!m_params.m_uastc)) + { + // For ETC1S, if source has alpha, then even mips will have RGB, and odd mips will have alpha in RGB. + basisu::vector<image> alpha_slices; + uint_vec new_mip_indices; + + alpha_slices.reserve(slices.size() * 2); + + for (uint32_t i = 0; i < slices.size(); i++) + { + image lvl_rgb(slices[i]); + image lvl_a(lvl_rgb); + + for (uint32_t y = 0; y < lvl_a.get_height(); y++) + { + for (uint32_t x = 0; x < lvl_a.get_width(); x++) + { + uint8_t a = lvl_a(x, y).a; + lvl_a(x, y).set_noclamp_rgba(a, a, a, 255); + } + } + + lvl_rgb.set_alpha(255); + + alpha_slices.push_back(lvl_rgb); + new_mip_indices.push_back(i); + + alpha_slices.push_back(lvl_a); + new_mip_indices.push_back(i); + } + + slices.swap(alpha_slices); + mip_indices.swap(new_mip_indices); + } + + assert(slices.size() == mip_indices.size()); + + for (uint32_t slice_index = 0; slice_index < slices.size(); slice_index++) + { + image& slice_image = slices[slice_index]; + const uint32_t orig_width = slice_image.get_width(); + const uint32_t orig_height = slice_image.get_height(); + + bool is_alpha_slice = false; + if (m_any_source_image_has_alpha) + { + if (m_params.m_uastc) + { + is_alpha_slice = slice_image.has_alpha(); + } + else + { + is_alpha_slice = (slice_index & 1) != 0; + } + } + + // Enlarge the source image to 4x4 block boundaries, duplicating edge pixels if necessary to avoid introducing extra colors into blocks. + slice_image.crop_dup_borders(slice_image.get_block_width(4) * 4, slice_image.get_block_height(4) * 4); + + if (m_params.m_debug_images) + { + save_png(string_format("basis_debug_source_image_%u_slice_%u.png", source_file_index, slice_index).c_str(), slice_image); + } + + enlarge_vector(m_stats, 1); + enlarge_vector(m_slice_images, 1); + enlarge_vector(m_slice_descs, 1); + + const uint32_t dest_image_index = (uint32_t)m_stats.size() - 1; + + m_stats[dest_image_index].m_filename = source_filename.c_str(); + m_stats[dest_image_index].m_width = orig_width; + m_stats[dest_image_index].m_height = orig_height; + + m_slice_images[dest_image_index] = slice_image; + + debug_printf("****** Slice %u: mip %u, alpha_slice: %u, filename: \"%s\", original: %ux%u actual: %ux%u\n", m_slice_descs.size() - 1, mip_indices[slice_index], is_alpha_slice, source_filename.c_str(), orig_width, orig_height, slice_image.get_width(), slice_image.get_height()); + + basisu_backend_slice_desc &slice_desc = m_slice_descs[dest_image_index]; + + slice_desc.m_first_block_index = m_total_blocks; + + slice_desc.m_orig_width = orig_width; + slice_desc.m_orig_height = orig_height; + + slice_desc.m_width = slice_image.get_width(); + slice_desc.m_height = slice_image.get_height(); + + slice_desc.m_num_blocks_x = slice_image.get_block_width(4); + slice_desc.m_num_blocks_y = slice_image.get_block_height(4); + + slice_desc.m_num_macroblocks_x = (slice_desc.m_num_blocks_x + 1) >> 1; + slice_desc.m_num_macroblocks_y = (slice_desc.m_num_blocks_y + 1) >> 1; + + slice_desc.m_source_file_index = source_file_index; + + slice_desc.m_mip_index = mip_indices[slice_index]; + + slice_desc.m_alpha = is_alpha_slice; + slice_desc.m_iframe = false; + if (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames) + { + slice_desc.m_iframe = (source_file_index == 0); + } + + m_total_blocks += slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y; + total_macroblocks += slice_desc.m_num_macroblocks_x * slice_desc.m_num_macroblocks_y; + + } // slice_index + + } // source_file_index + + debug_printf("Total blocks: %u, Total macroblocks: %u\n", m_total_blocks, total_macroblocks); + + // Make sure we don't have too many slices + if (m_slice_descs.size() > BASISU_MAX_SLICES) + { + error_printf("Too many slices!\n"); + return false; + } + + // Basic sanity check on the slices + for (uint32_t i = 1; i < m_slice_descs.size(); i++) + { + const basisu_backend_slice_desc &prev_slice_desc = m_slice_descs[i - 1]; + const basisu_backend_slice_desc &slice_desc = m_slice_descs[i]; + + // Make sure images are in order + int image_delta = (int)slice_desc.m_source_file_index - (int)prev_slice_desc.m_source_file_index; + if (image_delta > 1) + return false; + + // Make sure mipmap levels are in order + if (!image_delta) + { + int level_delta = (int)slice_desc.m_mip_index - (int)prev_slice_desc.m_mip_index; + if (level_delta > 1) + return false; + } + } + + if (m_params.m_status_output) + { + printf("Total basis file slices: %u\n", (uint32_t)m_slice_descs.size()); + } + + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + const basisu_backend_slice_desc &slice_desc = m_slice_descs[i]; + + if (m_params.m_status_output) + { + printf("Slice: %u, alpha: %u, orig width/height: %ux%u, width/height: %ux%u, first_block: %u, image_index: %u, mip_level: %u, iframe: %u\n", + i, slice_desc.m_alpha, slice_desc.m_orig_width, slice_desc.m_orig_height, slice_desc.m_width, slice_desc.m_height, slice_desc.m_first_block_index, slice_desc.m_source_file_index, slice_desc.m_mip_index, slice_desc.m_iframe); + } + + if (m_any_source_image_has_alpha) + { + if (!m_params.m_uastc) + { + // For ETC1S, alpha slices must be at odd slice indices. + if (slice_desc.m_alpha) + { + if ((i & 1) == 0) + return false; + + const basisu_backend_slice_desc& prev_slice_desc = m_slice_descs[i - 1]; + + // Make sure previous slice has this image's color data + if (prev_slice_desc.m_source_file_index != slice_desc.m_source_file_index) + return false; + if (prev_slice_desc.m_alpha) + return false; + if (prev_slice_desc.m_mip_index != slice_desc.m_mip_index) + return false; + if (prev_slice_desc.m_num_blocks_x != slice_desc.m_num_blocks_x) + return false; + if (prev_slice_desc.m_num_blocks_y != slice_desc.m_num_blocks_y) + return false; + } + else if (i & 1) + return false; + } + } + else if (slice_desc.m_alpha) + { + return false; + } + + if ((slice_desc.m_orig_width > slice_desc.m_width) || (slice_desc.m_orig_height > slice_desc.m_height)) + return false; + if ((slice_desc.m_source_file_index == 0) && (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames)) + { + if (!slice_desc.m_iframe) + return false; + } + } + + return true; + } + + // Do some basic validation for 2D arrays, cubemaps, video, and volumes. + bool basis_compressor::validate_texture_type_constraints() + { + debug_printf("basis_compressor::validate_texture_type_constraints\n"); + + // In 2D mode anything goes (each image may have a different resolution and # of mipmap levels). + if (m_params.m_tex_type == basist::cBASISTexType2D) + return true; + + uint32_t total_basis_images = 0; + + for (uint32_t slice_index = 0; slice_index < m_slice_images.size(); slice_index++) + { + const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; + + total_basis_images = maximum<uint32_t>(total_basis_images, slice_desc.m_source_file_index + 1); + } + + if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray) + { + // For cubemaps, validate that the total # of Basis images is a multiple of 6. + if ((total_basis_images % 6) != 0) + { + error_printf("basis_compressor::validate_texture_type_constraints: For cubemaps the total number of input images is not a multiple of 6!\n"); + return false; + } + } + + // Now validate that all the mip0's have the same dimensions, and that each image has the same # of mipmap levels. + uint_vec image_mipmap_levels(total_basis_images); + + int width = -1, height = -1; + for (uint32_t slice_index = 0; slice_index < m_slice_images.size(); slice_index++) + { + const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; + + image_mipmap_levels[slice_desc.m_source_file_index] = maximum(image_mipmap_levels[slice_desc.m_source_file_index], slice_desc.m_mip_index + 1); + + if (slice_desc.m_mip_index != 0) + continue; + + if (width < 0) + { + width = slice_desc.m_orig_width; + height = slice_desc.m_orig_height; + } + else if ((width != (int)slice_desc.m_orig_width) || (height != (int)slice_desc.m_orig_height)) + { + error_printf("basis_compressor::validate_texture_type_constraints: The source image resolutions are not all equal!\n"); + return false; + } + } + + for (size_t i = 1; i < image_mipmap_levels.size(); i++) + { + if (image_mipmap_levels[0] != image_mipmap_levels[i]) + { + error_printf("basis_compressor::validate_texture_type_constraints: Each image must have the same number of mipmap levels!\n"); + return false; + } + } + + return true; + } + + bool basis_compressor::extract_source_blocks() + { + debug_printf("basis_compressor::extract_source_blocks\n"); + + m_source_blocks.resize(m_total_blocks); + + for (uint32_t slice_index = 0; slice_index < m_slice_images.size(); slice_index++) + { + const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index]; + + const uint32_t num_blocks_x = slice_desc.m_num_blocks_x; + const uint32_t num_blocks_y = slice_desc.m_num_blocks_y; + + const image& source_image = m_slice_images[slice_index]; + + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + source_image.extract_block_clamped(m_source_blocks[slice_desc.m_first_block_index + block_x + block_y * num_blocks_x].get_ptr(), block_x * 4, block_y * 4, 4, 4); + } + + return true; + } + + bool basis_compressor::process_frontend() + { + debug_printf("basis_compressor::process_frontend\n"); + +#if 0 + // TODO + basis_etc1_pack_params pack_params; + pack_params.m_quality = cETCQualityMedium; + pack_params.m_perceptual = m_params.m_perceptual; + pack_params.m_use_color4 = false; + + pack_etc1_block_context pack_context; + + std::unordered_set<uint64_t> endpoint_hash; + std::unordered_set<uint32_t> selector_hash; + + for (uint32_t i = 0; i < m_source_blocks.size(); i++) + { + etc_block blk; + pack_etc1_block(blk, m_source_blocks[i].get_ptr(), pack_params, pack_context); + + const color_rgba c0(blk.get_block_color(0, false)); + endpoint_hash.insert((c0.r | (c0.g << 5) | (c0.b << 10)) | (blk.get_inten_table(0) << 16)); + + const color_rgba c1(blk.get_block_color(1, false)); + endpoint_hash.insert((c1.r | (c1.g << 5) | (c1.b << 10)) | (blk.get_inten_table(1) << 16)); + + selector_hash.insert(blk.get_raw_selector_bits()); + } + + const uint32_t total_unique_endpoints = (uint32_t)endpoint_hash.size(); + const uint32_t total_unique_selectors = (uint32_t)selector_hash.size(); + + if (m_params.m_debug) + { + debug_printf("Unique endpoints: %u, unique selectors: %u\n", total_unique_endpoints, total_unique_selectors); + } +#endif + + const double total_texels = m_total_blocks * 16.0f; + + int endpoint_clusters = m_params.m_max_endpoint_clusters; + int selector_clusters = m_params.m_max_selector_clusters; + + if (endpoint_clusters > basisu_frontend::cMaxEndpointClusters) + { + error_printf("Too many endpoint clusters! (%u but max is %u)\n", endpoint_clusters, basisu_frontend::cMaxEndpointClusters); + return false; + } + if (selector_clusters > basisu_frontend::cMaxSelectorClusters) + { + error_printf("Too many selector clusters! (%u but max is %u)\n", selector_clusters, basisu_frontend::cMaxSelectorClusters); + return false; + } + + if (m_params.m_quality_level != -1) + { + const float quality = saturate(m_params.m_quality_level / 255.0f); + + const float bits_per_endpoint_cluster = 14.0f; + const float max_desired_endpoint_cluster_bits_per_texel = 1.0f; // .15f + int max_endpoints = static_cast<int>((max_desired_endpoint_cluster_bits_per_texel * total_texels) / bits_per_endpoint_cluster); + + const float mid = 128.0f / 255.0f; + + float color_endpoint_quality = quality; + + const float endpoint_split_point = 0.5f; + + // In v1.2 and in previous versions, the endpoint codebook size at quality 128 was 3072. This wasn't quite large enough. + const int ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE = 4800; + const int MAX_ENDPOINT_CODEBOOK_SIZE = 8192; + + if (color_endpoint_quality <= mid) + { + color_endpoint_quality = lerp(0.0f, endpoint_split_point, powf(color_endpoint_quality / mid, .65f)); + + max_endpoints = clamp<int>(max_endpoints, 256, ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE); + max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks); + + if (max_endpoints < 64) + max_endpoints = 64; + endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(32, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters); + } + else + { + color_endpoint_quality = powf((color_endpoint_quality - mid) / (1.0f - mid), 1.6f); + + max_endpoints = clamp<int>(max_endpoints, 256, MAX_ENDPOINT_CODEBOOK_SIZE); + max_endpoints = minimum<uint32_t>(max_endpoints, m_total_blocks); + + if (max_endpoints < ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE) + max_endpoints = ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE; + endpoint_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(ENDPOINT_CODEBOOK_MID_QUALITY_CODEBOOK_SIZE, static_cast<float>(max_endpoints), color_endpoint_quality)), 32, basisu_frontend::cMaxEndpointClusters); + } + + float bits_per_selector_cluster = m_params.m_global_sel_pal ? 21.0f : 14.0f; + + const float max_desired_selector_cluster_bits_per_texel = 1.0f; // .15f + int max_selectors = static_cast<int>((max_desired_selector_cluster_bits_per_texel * total_texels) / bits_per_selector_cluster); + max_selectors = clamp<int>(max_selectors, 256, basisu_frontend::cMaxSelectorClusters); + max_selectors = minimum<uint32_t>(max_selectors, m_total_blocks); + + float color_selector_quality = quality; + //color_selector_quality = powf(color_selector_quality, 1.65f); + color_selector_quality = powf(color_selector_quality, 2.62f); + + if (max_selectors < 96) + max_selectors = 96; + selector_clusters = clamp<uint32_t>((uint32_t)(.5f + lerp<float>(96, static_cast<float>(max_selectors), color_selector_quality)), 8, basisu_frontend::cMaxSelectorClusters); + + debug_printf("Max endpoints: %u, max selectors: %u\n", endpoint_clusters, selector_clusters); + + if (m_params.m_quality_level >= 223) + { + if (!m_params.m_selector_rdo_thresh.was_changed()) + { + if (!m_params.m_endpoint_rdo_thresh.was_changed()) + m_params.m_endpoint_rdo_thresh *= .25f; + + if (!m_params.m_selector_rdo_thresh.was_changed()) + m_params.m_selector_rdo_thresh *= .25f; + } + } + else if (m_params.m_quality_level >= 192) + { + if (!m_params.m_endpoint_rdo_thresh.was_changed()) + m_params.m_endpoint_rdo_thresh *= .5f; + + if (!m_params.m_selector_rdo_thresh.was_changed()) + m_params.m_selector_rdo_thresh *= .5f; + } + else if (m_params.m_quality_level >= 160) + { + if (!m_params.m_endpoint_rdo_thresh.was_changed()) + m_params.m_endpoint_rdo_thresh *= .75f; + + if (!m_params.m_selector_rdo_thresh.was_changed()) + m_params.m_selector_rdo_thresh *= .75f; + } + else if (m_params.m_quality_level >= 129) + { + float l = (quality - 129 / 255.0f) / ((160 - 129) / 255.0f); + + if (!m_params.m_endpoint_rdo_thresh.was_changed()) + m_params.m_endpoint_rdo_thresh *= lerp<float>(1.0f, .75f, l); + + if (!m_params.m_selector_rdo_thresh.was_changed()) + m_params.m_selector_rdo_thresh *= lerp<float>(1.0f, .75f, l); + } + } + + m_auto_global_sel_pal = false; + if (!m_params.m_global_sel_pal && m_params.m_auto_global_sel_pal) + { + const float bits_per_selector_cluster = 31.0f; + double selector_codebook_bpp_est = (bits_per_selector_cluster * selector_clusters) / total_texels; + debug_printf("selector_codebook_bpp_est: %f\n", selector_codebook_bpp_est); + const float force_global_sel_pal_bpp_threshold = .15f; + if ((total_texels <= 128.0f*128.0f) && (selector_codebook_bpp_est > force_global_sel_pal_bpp_threshold)) + { + m_auto_global_sel_pal = true; + debug_printf("Auto global selector palette enabled\n"); + } + } + + basisu_frontend::params p; + p.m_num_source_blocks = m_total_blocks; + p.m_pSource_blocks = &m_source_blocks[0]; + p.m_max_endpoint_clusters = endpoint_clusters; + p.m_max_selector_clusters = selector_clusters; + p.m_perceptual = m_params.m_perceptual; + p.m_debug_stats = m_params.m_debug; + p.m_debug_images = m_params.m_debug_images; + p.m_compression_level = m_params.m_compression_level; + p.m_tex_type = m_params.m_tex_type; + p.m_multithreaded = m_params.m_multithreading; + p.m_disable_hierarchical_endpoint_codebooks = m_params.m_disable_hierarchical_endpoint_codebooks; + p.m_validate = m_params.m_validate; + p.m_pJob_pool = m_params.m_pJob_pool; + p.m_pGlobal_codebooks = m_params.m_pGlobal_codebooks; + + if ((m_params.m_global_sel_pal) || (m_auto_global_sel_pal)) + { + p.m_pGlobal_sel_codebook = m_params.m_pSel_codebook; + p.m_num_global_sel_codebook_pal_bits = m_params.m_global_pal_bits; + p.m_num_global_sel_codebook_mod_bits = m_params.m_global_mod_bits; + p.m_use_hybrid_selector_codebooks = !m_params.m_no_hybrid_sel_cb; + p.m_hybrid_codebook_quality_thresh = m_params.m_hybrid_sel_cb_quality_thresh; + } + + if (!m_frontend.init(p)) + { + error_printf("basisu_frontend::init() failed!\n"); + return false; + } + + m_frontend.compress(); + + if (m_params.m_debug_images) + { + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + char filename[1024]; +#ifdef _WIN32 + sprintf_s(filename, sizeof(filename), "rdo_frontend_output_output_blocks_%u.png", i); +#else + snprintf(filename, sizeof(filename), "rdo_frontend_output_output_blocks_%u.png", i); +#endif + m_frontend.dump_debug_image(filename, m_slice_descs[i].m_first_block_index, m_slice_descs[i].m_num_blocks_x, m_slice_descs[i].m_num_blocks_y, true); + +#ifdef _WIN32 + sprintf_s(filename, sizeof(filename), "rdo_frontend_output_api_%u.png", i); +#else + snprintf(filename, sizeof(filename), "rdo_frontend_output_api_%u.png", i); +#endif + m_frontend.dump_debug_image(filename, m_slice_descs[i].m_first_block_index, m_slice_descs[i].m_num_blocks_x, m_slice_descs[i].m_num_blocks_y, false); + } + } + + return true; + } + + bool basis_compressor::extract_frontend_texture_data() + { + debug_printf("basis_compressor::extract_frontend_texture_data\n"); + + m_frontend_output_textures.resize(m_slice_descs.size()); + m_best_etc1s_images.resize(m_slice_descs.size()); + m_best_etc1s_images_unpacked.resize(m_slice_descs.size()); + + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + const basisu_backend_slice_desc &slice_desc = m_slice_descs[i]; + + const uint32_t num_blocks_x = slice_desc.m_num_blocks_x; + const uint32_t num_blocks_y = slice_desc.m_num_blocks_y; + + const uint32_t width = num_blocks_x * 4; + const uint32_t height = num_blocks_y * 4; + + m_frontend_output_textures[i].init(texture_format::cETC1, width, height); + + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + memcpy(m_frontend_output_textures[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_output_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block)); + +#if 0 + if (m_params.m_debug_images) + { + char filename[1024]; + sprintf_s(filename, sizeof(filename), "rdo_etc_frontend_%u_", i); + write_etc1_vis_images(m_frontend_output_textures[i], filename); + } +#endif + + m_best_etc1s_images[i].init(texture_format::cETC1, width, height); + for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) + for (uint32_t block_x = 0; block_x < num_blocks_x; block_x++) + memcpy(m_best_etc1s_images[i].get_block_ptr(block_x, block_y, 0), &m_frontend.get_etc1s_block(slice_desc.m_first_block_index + block_x + block_y * num_blocks_x), sizeof(etc_block)); + + m_best_etc1s_images[i].unpack(m_best_etc1s_images_unpacked[i]); + } + + return true; + } + + bool basis_compressor::process_backend() + { + debug_printf("basis_compressor::process_backend\n"); + + basisu_backend_params backend_params; + backend_params.m_debug = m_params.m_debug; + backend_params.m_debug_images = m_params.m_debug_images; + backend_params.m_etc1s = true; + backend_params.m_compression_level = m_params.m_compression_level; + + if (!m_params.m_no_endpoint_rdo) + backend_params.m_endpoint_rdo_quality_thresh = m_params.m_endpoint_rdo_thresh; + + if (!m_params.m_no_selector_rdo) + backend_params.m_selector_rdo_quality_thresh = m_params.m_selector_rdo_thresh; + + backend_params.m_use_global_sel_codebook = (m_frontend.get_params().m_pGlobal_sel_codebook != NULL); + backend_params.m_global_sel_codebook_pal_bits = m_frontend.get_params().m_num_global_sel_codebook_pal_bits; + backend_params.m_global_sel_codebook_mod_bits = m_frontend.get_params().m_num_global_sel_codebook_mod_bits; + backend_params.m_use_hybrid_sel_codebooks = m_frontend.get_params().m_use_hybrid_selector_codebooks; + backend_params.m_used_global_codebooks = m_frontend.get_params().m_pGlobal_codebooks != nullptr; + + m_backend.init(&m_frontend, backend_params, m_slice_descs, m_params.m_pSel_codebook); + uint32_t total_packed_bytes = m_backend.encode(); + + if (!total_packed_bytes) + { + error_printf("basis_compressor::encode() failed!\n"); + return false; + } + + debug_printf("Total packed bytes (estimated): %u\n", total_packed_bytes); + + return true; + } + + bool basis_compressor::create_basis_file_and_transcode() + { + debug_printf("basis_compressor::create_basis_file_and_transcode\n"); + + const basisu_backend_output& encoded_output = m_params.m_uastc ? m_uastc_backend_output : m_backend.get_output(); + + if (!m_basis_file.init(encoded_output, m_params.m_tex_type, m_params.m_userdata0, m_params.m_userdata1, m_params.m_y_flip, m_params.m_us_per_frame)) + { + error_printf("basis_compressor::create_basis_file_and_transcode: basisu_backend:init() failed!\n"); + return false; + } + + const uint8_vec &comp_data = m_basis_file.get_compressed_data(); + + m_output_basis_file = comp_data; + + interval_timer tm; + tm.start(); + + basist::basisu_transcoder_init(); + + debug_printf("basist::basisu_transcoder_init: Took %f ms\n", tm.get_elapsed_ms()); + + // Verify the compressed data by transcoding it to ASTC (or ETC1)/BC7 and validating the CRC's. + basist::basisu_transcoder decoder(m_params.m_pSel_codebook); + if (!decoder.validate_file_checksums(&comp_data[0], (uint32_t)comp_data.size(), true)) + { + error_printf("decoder.validate_file_checksums() failed!\n"); + return false; + } + + m_decoded_output_textures.resize(m_slice_descs.size()); + m_decoded_output_textures_unpacked.resize(m_slice_descs.size()); + + m_decoded_output_textures_bc7.resize(m_slice_descs.size()); + m_decoded_output_textures_unpacked_bc7.resize(m_slice_descs.size()); + + tm.start(); + if (m_params.m_pGlobal_codebooks) + { + decoder.set_global_codebooks(m_params.m_pGlobal_codebooks); + } + + if (!decoder.start_transcoding(&comp_data[0], (uint32_t)comp_data.size())) + { + error_printf("decoder.start_transcoding() failed!\n"); + return false; + } + + double start_transcoding_time = tm.get_elapsed_secs(); + + debug_printf("basisu_compressor::start_transcoding() took %3.3fms\n", start_transcoding_time * 1000.0f); + + uint32_t total_orig_pixels = 0; + uint32_t total_texels = 0; + + double total_time_etc1s_or_astc = 0; + + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + gpu_image decoded_texture; + decoded_texture.init(m_params.m_uastc ? texture_format::cASTC4x4 : texture_format::cETC1, m_slice_descs[i].m_width, m_slice_descs[i].m_height); + + tm.start(); + + basist::block_format format = m_params.m_uastc ? basist::block_format::cASTC_4x4 : basist::block_format::cETC1; + uint32_t bytes_per_block = m_params.m_uastc ? 16 : 8; + + if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i, + reinterpret_cast<etc_block *>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, format, bytes_per_block)) + { + error_printf("Transcoding failed on slice %u!\n", i); + return false; + } + + total_time_etc1s_or_astc += tm.get_elapsed_secs(); + + if (encoded_output.m_tex_format == basist::basis_tex_format::cETC1S) + { + uint32_t image_crc16 = basist::crc16(decoded_texture.get_ptr(), decoded_texture.get_size_in_bytes(), 0); + if (image_crc16 != encoded_output.m_slice_image_crcs[i]) + { + error_printf("Decoded image data CRC check failed on slice %u!\n", i); + return false; + } + debug_printf("Decoded image data CRC check succeeded on slice %i\n", i); + } + + m_decoded_output_textures[i] = decoded_texture; + + total_orig_pixels += m_slice_descs[i].m_orig_width * m_slice_descs[i].m_orig_height; + total_texels += m_slice_descs[i].m_width * m_slice_descs[i].m_height; + } + + double total_time_bc7 = 0; + + if (basist::basis_is_format_supported(basist::transcoder_texture_format::cTFBC7_RGBA, basist::basis_tex_format::cUASTC4x4) && + basist::basis_is_format_supported(basist::transcoder_texture_format::cTFBC7_RGBA, basist::basis_tex_format::cETC1S)) + { + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + gpu_image decoded_texture; + decoded_texture.init(texture_format::cBC7, m_slice_descs[i].m_width, m_slice_descs[i].m_height); + + tm.start(); + + if (!decoder.transcode_slice(&comp_data[0], (uint32_t)comp_data.size(), i, + reinterpret_cast<etc_block*>(decoded_texture.get_ptr()), m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y, basist::block_format::cBC7, 16)) + { + error_printf("Transcoding failed to BC7 on slice %u!\n", i); + return false; + } + + total_time_bc7 += tm.get_elapsed_secs(); + + m_decoded_output_textures_bc7[i] = decoded_texture; + } + } + + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + m_decoded_output_textures[i].unpack(m_decoded_output_textures_unpacked[i]); + + if (m_decoded_output_textures_bc7[i].get_pixel_width()) + m_decoded_output_textures_bc7[i].unpack(m_decoded_output_textures_unpacked_bc7[i]); + } + + debug_printf("Transcoded to %s in %3.3fms, %f texels/sec\n", m_params.m_uastc ? "ASTC" : "ETC1", total_time_etc1s_or_astc * 1000.0f, total_orig_pixels / total_time_etc1s_or_astc); + + if (total_time_bc7 != 0) + debug_printf("Transcoded to BC7 in %3.3fms, %f texels/sec\n", total_time_bc7 * 1000.0f, total_orig_pixels / total_time_bc7); + + debug_printf("Total .basis output file size: %u, %3.3f bits/texel\n", comp_data.size(), comp_data.size() * 8.0f / total_orig_pixels); + + uint32_t total_orig_texels = 0; + for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) + { + const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; + + total_orig_texels += slice_desc.m_orig_width * slice_desc.m_orig_height; + + const uint32_t total_blocks = slice_desc.m_num_blocks_x * slice_desc.m_num_blocks_y; + BASISU_NOTE_UNUSED(total_blocks); + + assert(m_decoded_output_textures[slice_index].get_total_blocks() == total_blocks); + } + + m_basis_file_size = (uint32_t)comp_data.size(); + m_basis_bits_per_texel = (comp_data.size() * 8.0f) / total_orig_texels; + + return true; + } + + bool basis_compressor::write_output_files_and_compute_stats() + { + debug_printf("basis_compressor::write_output_files_and_compute_stats\n"); + + const uint8_vec& comp_data = m_params.m_create_ktx2_file ? m_output_ktx2_file : m_basis_file.get_compressed_data(); + if (m_params.m_write_output_basis_files) + { + const std::string& output_filename = m_params.m_out_filename; + + if (!write_vec_to_file(output_filename.c_str(), comp_data)) + { + error_printf("Failed writing output data to file \"%s\"\n", output_filename.c_str()); + return false; + } + + printf("Wrote output .basis/.ktx2 file \"%s\"\n", output_filename.c_str()); + } + + size_t comp_size = 0; + if ((m_params.m_compute_stats) && (m_params.m_uastc) && (comp_data.size())) + { + void* pComp_data = tdefl_compress_mem_to_heap(&comp_data[0], comp_data.size(), &comp_size, TDEFL_MAX_PROBES_MASK);// TDEFL_DEFAULT_MAX_PROBES); + size_t decomp_size = 0; + void* pDecomp_data = tinfl_decompress_mem_to_heap(pComp_data, comp_size, &decomp_size, 0); + if ((decomp_size != comp_data.size()) || (memcmp(pDecomp_data, &comp_data[0], decomp_size) != 0)) + { + printf("basis_compressor::create_basis_file_and_transcode:: miniz compression or decompression failed!\n"); + return false; + } + + mz_free(pComp_data); + mz_free(pDecomp_data); + + uint32_t total_texels = 0; + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + total_texels += (m_slice_descs[i].m_num_blocks_x * m_slice_descs[i].m_num_blocks_y) * 16; + + m_basis_bits_per_texel = comp_size * 8.0f / total_texels; + + debug_printf(".basis file size: %u, LZ compressed file size: %u, %3.2f bits/texel\n", + (uint32_t)comp_data.size(), + (uint32_t)comp_size, + m_basis_bits_per_texel); + } + + m_stats.resize(m_slice_descs.size()); + + uint32_t total_orig_texels = 0; + + for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) + { + const basisu_backend_slice_desc &slice_desc = m_slice_descs[slice_index]; + + total_orig_texels += slice_desc.m_orig_width * slice_desc.m_orig_height; + + if (m_params.m_compute_stats) + { + printf("Slice: %u\n", slice_index); + + image_stats &s = m_stats[slice_index]; + + // TODO: We used to output SSIM (during heavy encoder development), but this slowed down compression too much. We'll be adding it back. + + image_metrics em; + + // ---- .basis stats + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 3); + em.print(".basis RGB Avg: "); + s.m_basis_rgb_avg_psnr = em.m_psnr; + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 4); + em.print(".basis RGBA Avg: "); + s.m_basis_rgba_avg_psnr = em.m_psnr; + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 1); + em.print(".basis R Avg: "); + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 1, 1); + em.print(".basis G Avg: "); + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 2, 1); + em.print(".basis B Avg: "); + + if (m_params.m_uastc) + { + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 3, 1); + em.print(".basis A Avg: "); + + s.m_basis_a_avg_psnr = em.m_psnr; + } + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0); + em.print(".basis 709 Luma: "); + s.m_basis_luma_709_psnr = static_cast<float>(em.m_psnr); + s.m_basis_luma_709_ssim = static_cast<float>(em.m_ssim); + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked[slice_index], 0, 0, true, true); + em.print(".basis 601 Luma: "); + s.m_basis_luma_601_psnr = static_cast<float>(em.m_psnr); + + if (m_slice_descs.size() == 1) + { + const uint32_t output_size = comp_size ? (uint32_t)comp_size : (uint32_t)comp_data.size(); + debug_printf(".basis RGB PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_rgb_avg_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); + debug_printf(".basis Luma 709 PSNR per bit/texel*10000: %3.3f\n", 10000.0f * s.m_basis_luma_709_psnr / ((output_size * 8.0f) / (slice_desc.m_orig_width * slice_desc.m_orig_height))); + } + + if (m_decoded_output_textures_unpacked_bc7[slice_index].get_width()) + { + // ---- BC7 stats + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 3); + em.print("BC7 RGB Avg: "); + s.m_bc7_rgb_avg_psnr = em.m_psnr; + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 4); + em.print("BC7 RGBA Avg: "); + s.m_bc7_rgba_avg_psnr = em.m_psnr; + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 1); + em.print("BC7 R Avg: "); + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 1, 1); + em.print("BC7 G Avg: "); + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 2, 1); + em.print("BC7 B Avg: "); + + if (m_params.m_uastc) + { + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 3, 1); + em.print("BC7 A Avg: "); + + s.m_bc7_a_avg_psnr = em.m_psnr; + } + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0); + em.print("BC7 709 Luma: "); + s.m_bc7_luma_709_psnr = static_cast<float>(em.m_psnr); + s.m_bc7_luma_709_ssim = static_cast<float>(em.m_ssim); + + em.calc(m_slice_images[slice_index], m_decoded_output_textures_unpacked_bc7[slice_index], 0, 0, true, true); + em.print("BC7 601 Luma: "); + s.m_bc7_luma_601_psnr = static_cast<float>(em.m_psnr); + } + + if (!m_params.m_uastc) + { + // ---- Nearly best possible ETC1S stats + em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0); + em.print("Unquantized ETC1S 709 Luma: "); + + s.m_best_etc1s_luma_709_psnr = static_cast<float>(em.m_psnr); + s.m_best_etc1s_luma_709_ssim = static_cast<float>(em.m_ssim); + + em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 0, true, true); + em.print("Unquantized ETC1S 601 Luma: "); + + s.m_best_etc1s_luma_601_psnr = static_cast<float>(em.m_psnr); + + em.calc(m_slice_images[slice_index], m_best_etc1s_images_unpacked[slice_index], 0, 3); + em.print("Unquantized ETC1S RGB Avg: "); + + s.m_best_etc1s_rgb_avg_psnr = static_cast<float>(em.m_psnr); + } + } + + std::string out_basename; + if (m_params.m_out_filename.size()) + string_get_filename(m_params.m_out_filename.c_str(), out_basename); + else if (m_params.m_source_filenames.size()) + string_get_filename(m_params.m_source_filenames[slice_desc.m_source_file_index].c_str(), out_basename); + + string_remove_extension(out_basename); + out_basename = "basis_debug_" + out_basename + string_format("_slice_%u", slice_index); + + if ((!m_params.m_uastc) && (m_frontend.get_params().m_debug_images)) + { + // Write "best" ETC1S debug images + if (!m_params.m_uastc) + { + gpu_image best_etc1s_gpu_image(m_best_etc1s_images[slice_index]); + best_etc1s_gpu_image.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height); + write_compressed_texture_file((out_basename + "_best_etc1s.ktx").c_str(), best_etc1s_gpu_image); + + image best_etc1s_unpacked; + best_etc1s_gpu_image.unpack(best_etc1s_unpacked); + save_png(out_basename + "_best_etc1s.png", best_etc1s_unpacked); + } + } + + if (m_params.m_debug_images) + { + // Write decoded ETC1S/ASTC debug images + { + gpu_image decoded_etc1s_or_astc(m_decoded_output_textures[slice_index]); + decoded_etc1s_or_astc.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height); + write_compressed_texture_file((out_basename + "_transcoded_etc1s_or_astc.ktx").c_str(), decoded_etc1s_or_astc); + + image temp(m_decoded_output_textures_unpacked[slice_index]); + temp.crop(slice_desc.m_orig_width, slice_desc.m_orig_height); + save_png(out_basename + "_transcoded_etc1s_or_astc.png", temp); + } + + // Write decoded BC7 debug images + if (m_decoded_output_textures_bc7[slice_index].get_pixel_width()) + { + gpu_image decoded_bc7(m_decoded_output_textures_bc7[slice_index]); + decoded_bc7.override_dimensions(slice_desc.m_orig_width, slice_desc.m_orig_height); + write_compressed_texture_file((out_basename + "_transcoded_bc7.ktx").c_str(), decoded_bc7); + + image temp(m_decoded_output_textures_unpacked_bc7[slice_index]); + temp.crop(slice_desc.m_orig_width, slice_desc.m_orig_height); + save_png(out_basename + "_transcoded_bc7.png", temp); + } + } + } + + return true; + } + + // Make sure all the mip 0's have the same dimensions and number of mipmap levels, or we can't encode the KTX2 file. + bool basis_compressor::validate_ktx2_constraints() + { + uint32_t base_width = 0, base_height = 0; + uint32_t total_layers = 0; + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + if (m_slice_descs[i].m_mip_index == 0) + { + if (!base_width) + { + base_width = m_slice_descs[i].m_orig_width; + base_height = m_slice_descs[i].m_orig_height; + } + else + { + if ((m_slice_descs[i].m_orig_width != base_width) || (m_slice_descs[i].m_orig_height != base_height)) + { + return false; + } + } + + total_layers = maximum<uint32_t>(total_layers, m_slice_descs[i].m_source_file_index + 1); + } + } + + basisu::vector<uint32_t> total_mips(total_layers); + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + total_mips[m_slice_descs[i].m_source_file_index] = maximum<uint32_t>(total_mips[m_slice_descs[i].m_source_file_index], m_slice_descs[i].m_mip_index + 1); + + for (uint32_t i = 1; i < total_layers; i++) + { + if (total_mips[0] != total_mips[i]) + { + return false; + } + } + + return true; + } + + static uint8_t g_ktx2_etc1s_nonalpha_dfd[44] = { 0x2C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x28,0x0,0xA3,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF }; + static uint8_t g_ktx2_etc1s_alpha_dfd[60] = { 0x3C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x38,0x0,0xA3,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF,0x40,0x0,0x3F,0xF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF }; + static uint8_t g_ktx2_uastc_nonalpha_dfd[44] = { 0x2C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x28,0x0,0xA6,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7F,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF }; + static uint8_t g_ktx2_uastc_alpha_dfd[44] = { 0x2C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x28,0x0,0xA6,0x1,0x2,0x0,0x3,0x3,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7F,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xFF,0xFF,0xFF }; + + void basis_compressor::get_dfd(uint8_vec &dfd, const basist::ktx2_header &header) + { + const uint8_t* pDFD; + uint32_t dfd_len; + + if (m_params.m_uastc) + { + if (m_any_source_image_has_alpha) + { + pDFD = g_ktx2_uastc_alpha_dfd; + dfd_len = sizeof(g_ktx2_uastc_alpha_dfd); + } + else + { + pDFD = g_ktx2_uastc_nonalpha_dfd; + dfd_len = sizeof(g_ktx2_uastc_nonalpha_dfd); + } + } + else + { + if (m_any_source_image_has_alpha) + { + pDFD = g_ktx2_etc1s_alpha_dfd; + dfd_len = sizeof(g_ktx2_etc1s_alpha_dfd); + } + else + { + pDFD = g_ktx2_etc1s_nonalpha_dfd; + dfd_len = sizeof(g_ktx2_etc1s_nonalpha_dfd); + } + } + + assert(dfd_len >= 44); + + dfd.resize(dfd_len); + memcpy(dfd.data(), pDFD, dfd_len); + + uint32_t dfd_bits = basisu::read_le_dword(dfd.data() + 3 * sizeof(uint32_t)); + + dfd_bits &= ~(0xFF << 16); + + if (m_params.m_ktx2_srgb_transfer_func) + dfd_bits |= (basist::KTX2_KHR_DF_TRANSFER_SRGB << 16); + else + dfd_bits |= (basist::KTX2_KHR_DF_TRANSFER_LINEAR << 16); + + basisu::write_le_dword(dfd.data() + 3 * sizeof(uint32_t), dfd_bits); + + if (header.m_supercompression_scheme != basist::KTX2_SS_NONE) + { + uint32_t plane_bits = basisu::read_le_dword(dfd.data() + 5 * sizeof(uint32_t)); + + plane_bits &= ~0xFF; + + basisu::write_le_dword(dfd.data() + 5 * sizeof(uint32_t), plane_bits); + } + + // Fix up the DFD channel(s) + uint32_t dfd_chan0 = basisu::read_le_dword(dfd.data() + 7 * sizeof(uint32_t)); + + if (m_params.m_uastc) + { + dfd_chan0 &= ~(0xF << 24); + + // TODO: Allow the caller to override this + if (m_any_source_image_has_alpha) + dfd_chan0 |= (basist::KTX2_DF_CHANNEL_UASTC_RGBA << 24); + else + dfd_chan0 |= (basist::KTX2_DF_CHANNEL_UASTC_RGB << 24); + } + + basisu::write_le_dword(dfd.data() + 7 * sizeof(uint32_t), dfd_chan0); + } + + bool basis_compressor::create_ktx2_file() + { + if (m_params.m_uastc) + { + if ((m_params.m_ktx2_uastc_supercompression != basist::KTX2_SS_NONE) && (m_params.m_ktx2_uastc_supercompression != basist::KTX2_SS_ZSTANDARD)) + return false; + } + + const basisu_backend_output& backend_output = m_backend.get_output(); + + // Determine the width/height, number of array layers, mipmap levels, and the number of faces (1 for 2D, 6 for cubemap). + // This does not support 1D or 3D. + uint32_t base_width = 0, base_height = 0, total_layers = 0, total_levels = 0, total_faces = 1; + + for (uint32_t i = 0; i < m_slice_descs.size(); i++) + { + if ((m_slice_descs[i].m_mip_index == 0) && (!base_width)) + { + base_width = m_slice_descs[i].m_orig_width; + base_height = m_slice_descs[i].m_orig_height; + } + + total_layers = maximum<uint32_t>(total_layers, m_slice_descs[i].m_source_file_index + 1); + + if (!m_slice_descs[i].m_source_file_index) + total_levels = maximum<uint32_t>(total_levels, m_slice_descs[i].m_mip_index + 1); + } + + if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray) + { + assert((total_layers % 6) == 0); + + total_layers /= 6; + assert(total_layers >= 1); + + total_faces = 6; + } + + basist::ktx2_header header; + memset(&header, 0, sizeof(header)); + + memcpy(header.m_identifier, basist::g_ktx2_file_identifier, sizeof(basist::g_ktx2_file_identifier)); + header.m_pixel_width = base_width; + header.m_pixel_height = base_height; + header.m_face_count = total_faces; + header.m_vk_format = basist::KTX2_VK_FORMAT_UNDEFINED; + header.m_type_size = 1; + header.m_level_count = total_levels; + header.m_layer_count = (total_layers > 1) ? total_layers : 0; + + if (m_params.m_uastc) + { + switch (m_params.m_ktx2_uastc_supercompression) + { + case basist::KTX2_SS_NONE: + { + header.m_supercompression_scheme = basist::KTX2_SS_NONE; + break; + } + case basist::KTX2_SS_ZSTANDARD: + { +#if BASISD_SUPPORT_KTX2_ZSTD + header.m_supercompression_scheme = basist::KTX2_SS_ZSTANDARD; +#else + header.m_supercompression_scheme = basist::KTX2_SS_NONE; +#endif + break; + } + default: assert(0); return false; + } + } + + basisu::vector<uint8_vec> level_data_bytes(total_levels); + basisu::vector<uint8_vec> compressed_level_data_bytes(total_levels); + uint_vec slice_level_offsets(m_slice_descs.size()); + + // This will append the texture data in the correct order (for each level: layer, then face). + for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) + { + const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index]; + + slice_level_offsets[slice_index] = level_data_bytes[slice_desc.m_mip_index].size(); + + if (m_params.m_uastc) + append_vector(level_data_bytes[slice_desc.m_mip_index], m_uastc_backend_output.m_slice_image_data[slice_index]); + else + append_vector(level_data_bytes[slice_desc.m_mip_index], backend_output.m_slice_image_data[slice_index]); + } + + // UASTC supercompression + if ((m_params.m_uastc) && (header.m_supercompression_scheme == basist::KTX2_SS_ZSTANDARD)) + { +#if BASISD_SUPPORT_KTX2_ZSTD + for (uint32_t level_index = 0; level_index < total_levels; level_index++) + { + compressed_level_data_bytes[level_index].resize(ZSTD_compressBound(level_data_bytes[level_index].size())); + + size_t result = ZSTD_compress(compressed_level_data_bytes[level_index].data(), compressed_level_data_bytes[level_index].size(), + level_data_bytes[level_index].data(), level_data_bytes[level_index].size(), + m_params.m_ktx2_zstd_supercompression_level); + + if (ZSTD_isError(result)) + return false; + + compressed_level_data_bytes[level_index].resize(result); + } +#else + // Can't get here + assert(0); + return false; +#endif + } + else + { + // No supercompression + compressed_level_data_bytes = level_data_bytes; + } + + uint8_vec etc1s_global_data; + + // Create ETC1S global supercompressed data + if (!m_params.m_uastc) + { + basist::ktx2_etc1s_global_data_header etc1s_global_data_header; + clear_obj(etc1s_global_data_header); + + etc1s_global_data_header.m_endpoint_count = backend_output.m_num_endpoints; + etc1s_global_data_header.m_selector_count = backend_output.m_num_selectors; + etc1s_global_data_header.m_endpoints_byte_length = backend_output.m_endpoint_palette.size(); + etc1s_global_data_header.m_selectors_byte_length = backend_output.m_selector_palette.size(); + etc1s_global_data_header.m_tables_byte_length = backend_output.m_slice_image_tables.size(); + + basisu::vector<basist::ktx2_etc1s_image_desc> etc1s_image_descs(total_levels * total_layers * total_faces); + memset(etc1s_image_descs.data(), 0, etc1s_image_descs.size_in_bytes()); + + for (uint32_t slice_index = 0; slice_index < m_slice_descs.size(); slice_index++) + { + const basisu_backend_slice_desc& slice_desc = m_slice_descs[slice_index]; + + const uint32_t level_index = slice_desc.m_mip_index; + uint32_t layer_index = slice_desc.m_source_file_index; + uint32_t face_index = 0; + + if (m_params.m_tex_type == basist::cBASISTexTypeCubemapArray) + { + face_index = layer_index % 6; + layer_index /= 6; + } + + const uint32_t etc1s_image_index = level_index * (total_layers * total_faces) + layer_index * total_faces + face_index; + + if (slice_desc.m_alpha) + { + etc1s_image_descs[etc1s_image_index].m_alpha_slice_byte_length = backend_output.m_slice_image_data[slice_index].size(); + etc1s_image_descs[etc1s_image_index].m_alpha_slice_byte_offset = slice_level_offsets[slice_index]; + } + else + { + if (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames) + etc1s_image_descs[etc1s_image_index].m_image_flags = !slice_desc.m_iframe ? basist::KTX2_IMAGE_IS_P_FRAME : 0; + + etc1s_image_descs[etc1s_image_index].m_rgb_slice_byte_length = backend_output.m_slice_image_data[slice_index].size(); + etc1s_image_descs[etc1s_image_index].m_rgb_slice_byte_offset = slice_level_offsets[slice_index]; + } + } // slice_index + + append_vector(etc1s_global_data, (const uint8_t*)&etc1s_global_data_header, sizeof(etc1s_global_data_header)); + append_vector(etc1s_global_data, (const uint8_t*)etc1s_image_descs.data(), etc1s_image_descs.size_in_bytes()); + append_vector(etc1s_global_data, backend_output.m_endpoint_palette); + append_vector(etc1s_global_data, backend_output.m_selector_palette); + append_vector(etc1s_global_data, backend_output.m_slice_image_tables); + + header.m_supercompression_scheme = basist::KTX2_SS_BASISLZ; + } + + // Key values + basist::ktx2_transcoder::key_value_vec key_values(m_params.m_ktx2_key_values); + key_values.enlarge(1); + + const char* pKTXwriter = "KTXwriter"; + key_values.back().m_key.resize(strlen(pKTXwriter) + 1); + memcpy(key_values.back().m_key.data(), pKTXwriter, strlen(pKTXwriter) + 1); + + char writer_id[128]; +#ifdef _MSC_VER + sprintf_s(writer_id, sizeof(writer_id), "Basis Universal %s", BASISU_LIB_VERSION_STRING); +#else + snprintf(writer_id, sizeof(writer_id), "Basis Universal %s", BASISU_LIB_VERSION_STRING); +#endif + key_values.back().m_value.resize(strlen(writer_id) + 1); + memcpy(key_values.back().m_value.data(), writer_id, strlen(writer_id) + 1); + + key_values.sort(); + +#if BASISU_DISABLE_KTX2_KEY_VALUES + // HACK HACK - Clear the key values array, which causes no key values to be written (triggering the ktx2check validator bug). + key_values.clear(); +#endif + + uint8_vec key_value_data; + + // DFD + uint8_vec dfd; + get_dfd(dfd, header); + + const uint32_t kvd_file_offset = sizeof(header) + sizeof(basist::ktx2_level_index) * total_levels + dfd.size(); + + for (uint32_t pass = 0; pass < 2; pass++) + { + for (uint32_t i = 0; i < key_values.size(); i++) + { + if (key_values[i].m_key.size() < 2) + return false; + + if (key_values[i].m_key.back() != 0) + return false; + + const uint64_t total_len = (uint64_t)key_values[i].m_key.size() + (uint64_t)key_values[i].m_value.size(); + if (total_len >= UINT32_MAX) + return false; + + packed_uint<4> le_len((uint32_t)total_len); + append_vector(key_value_data, (const uint8_t*)&le_len, sizeof(le_len)); + + append_vector(key_value_data, key_values[i].m_key); + append_vector(key_value_data, key_values[i].m_value); + + const uint32_t ofs = key_value_data.size() & 3; + const uint32_t padding = (4 - ofs) & 3; + for (uint32_t p = 0; p < padding; p++) + key_value_data.push_back(0); + } + + if (header.m_supercompression_scheme != basist::KTX2_SS_NONE) + break; + +#if BASISU_DISABLE_KTX2_ALIGNMENT_WORKAROUND + break; +#endif + + // Hack to ensure the KVD block ends on a 16 byte boundary, because we have no other official way of aligning the data. + uint32_t kvd_end_file_offset = kvd_file_offset + key_value_data.size(); + uint32_t bytes_needed_to_pad = (16 - (kvd_end_file_offset & 15)) & 15; + if (!bytes_needed_to_pad) + { + // We're good. No need to add a dummy key. + break; + } + + assert(!pass); + if (pass) + return false; + + if (bytes_needed_to_pad < 6) + bytes_needed_to_pad += 16; + + printf("WARNING: Due to a KTX2 validator bug related to mipPadding, we must insert a dummy key into the KTX2 file of %u bytes\n", bytes_needed_to_pad); + + // We're not good - need to add a dummy key large enough to force file alignment so the mip level array gets aligned. + // We can't just add some bytes before the mip level array because ktx2check will see that as extra data in the file that shouldn't be there in ktxValidator::validateDataSize(). + key_values.enlarge(1); + for (uint32_t i = 0; i < (bytes_needed_to_pad - 4 - 1 - 1); i++) + key_values.back().m_key.push_back(127); + + key_values.back().m_key.push_back(0); + + key_values.back().m_value.push_back(0); + + key_values.sort(); + + key_value_data.resize(0); + + // Try again + } + + basisu::vector<basist::ktx2_level_index> level_index_array(total_levels); + memset(level_index_array.data(), 0, level_index_array.size_in_bytes()); + + m_output_ktx2_file.clear(); + m_output_ktx2_file.reserve(m_output_basis_file.size()); + + // Dummy header + m_output_ktx2_file.resize(sizeof(header)); + + // Level index array + append_vector(m_output_ktx2_file, (const uint8_t*)level_index_array.data(), level_index_array.size_in_bytes()); + + // DFD + const uint8_t* pDFD = dfd.data(); + uint32_t dfd_len = dfd.size(); + + header.m_dfd_byte_offset = m_output_ktx2_file.size(); + header.m_dfd_byte_length = dfd_len; + append_vector(m_output_ktx2_file, pDFD, dfd_len); + + // Key value data + if (key_value_data.size()) + { + assert(kvd_file_offset == m_output_ktx2_file.size()); + + header.m_kvd_byte_offset = m_output_ktx2_file.size(); + header.m_kvd_byte_length = key_value_data.size(); + append_vector(m_output_ktx2_file, key_value_data); + } + + // Global Supercompressed Data + if (etc1s_global_data.size()) + { + uint32_t ofs = m_output_ktx2_file.size() & 7; + uint32_t padding = (8 - ofs) & 7; + for (uint32_t i = 0; i < padding; i++) + m_output_ktx2_file.push_back(0); + + header.m_sgd_byte_length = etc1s_global_data.size(); + header.m_sgd_byte_offset = m_output_ktx2_file.size(); + + append_vector(m_output_ktx2_file, etc1s_global_data); + } + + // mipPadding + if (header.m_supercompression_scheme == basist::KTX2_SS_NONE) + { + // We currently can't do this or the validator will incorrectly give an error. + uint32_t ofs = m_output_ktx2_file.size() & 15; + uint32_t padding = (16 - ofs) & 15; + + // Make sure we're always aligned here (due to a validator bug). + if (padding) + { + printf("Warning: KTX2 mip level data is not 16-byte aligned. This may trigger a ktx2check validation bug. Writing %u bytes of mipPadding.\n", padding); + } + + for (uint32_t i = 0; i < padding; i++) + m_output_ktx2_file.push_back(0); + } + + // Level data - write the smallest mipmap first. + for (int level = total_levels - 1; level >= 0; level--) + { + level_index_array[level].m_byte_length = compressed_level_data_bytes[level].size(); + if (m_params.m_uastc) + level_index_array[level].m_uncompressed_byte_length = level_data_bytes[level].size(); + + level_index_array[level].m_byte_offset = m_output_ktx2_file.size(); + append_vector(m_output_ktx2_file, compressed_level_data_bytes[level]); + } + + // Write final header + memcpy(m_output_ktx2_file.data(), &header, sizeof(header)); + + // Write final level index array + memcpy(m_output_ktx2_file.data() + sizeof(header), level_index_array.data(), level_index_array.size_in_bytes()); + + debug_printf("Total .ktx2 output file size: %u\n", m_output_ktx2_file.size()); + + return true; + } + +} // namespace basisu diff --git a/thirdparty/basis_universal/basisu_comp.h b/thirdparty/basis_universal/encoder/basisu_comp.h index 1c201ddbed..2c3af968f7 100644 --- a/thirdparty/basis_universal/basisu_comp.h +++ b/thirdparty/basis_universal/encoder/basisu_comp.h @@ -1,5 +1,5 @@ // basisu_comp.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,23 @@ #include "basisu_frontend.h" #include "basisu_backend.h" #include "basisu_basis_file.h" -#include "transcoder/basisu_global_selector_palette.h" -#include "transcoder/basisu_transcoder.h" +#include "../transcoder/basisu_global_selector_palette.h" +#include "../transcoder/basisu_transcoder.h" +#include "basisu_uastc_enc.h" + +#define BASISU_LIB_VERSION 115 +#define BASISU_LIB_VERSION_STRING "1.15" + +#ifndef BASISD_SUPPORT_KTX2 + #error BASISD_SUPPORT_KTX2 is undefined +#endif +#ifndef BASISD_SUPPORT_KTX2_ZSTD + #error BASISD_SUPPORT_KTX2_ZSTD is undefined +#endif + +#if !BASISD_SUPPORT_KTX2 + #error BASISD_SUPPORT_KTX2 must be enabled when building the encoder. To reduce code size if KTX2 support is not needed, set BASISD_SUPPORT_KTX2_ZSTD to 0 +#endif namespace basisu { @@ -40,6 +55,10 @@ namespace basisu const uint32_t BASISU_MAX_SLICES = 0xFFFFFF; + const int BASISU_RDO_UASTC_DICT_SIZE_DEFAULT = 4096; // 32768; + const int BASISU_RDO_UASTC_DICT_SIZE_MIN = 64; + const int BASISU_RDO_UASTC_DICT_SIZE_MAX = 65536; + struct image_stats { image_stats() @@ -52,43 +71,52 @@ namespace basisu m_filename.clear(); m_width = 0; m_height = 0; - - m_basis_etc1s_rgb_avg_psnr = 0.0f; - m_basis_etc1s_luma_709_psnr = 0.0f; - m_basis_etc1s_luma_601_psnr = 0.0f; - m_basis_etc1s_luma_709_ssim = 0.0f; - - m_basis_bc1_rgb_avg_psnr = 0.0f; - m_basis_bc1_luma_709_psnr = 0.0f; - m_basis_bc1_luma_601_psnr = 0.0f; - m_basis_bc1_luma_709_ssim = 0.0f; - - m_best_rgb_avg_psnr = 0.0f; - m_best_luma_709_psnr = 0.0f; - m_best_luma_601_psnr = 0.0f; - m_best_luma_709_ssim = 0.0f; + + m_basis_rgb_avg_psnr = 0.0f; + m_basis_rgba_avg_psnr = 0.0f; + m_basis_a_avg_psnr = 0.0f; + m_basis_luma_709_psnr = 0.0f; + m_basis_luma_601_psnr = 0.0f; + m_basis_luma_709_ssim = 0.0f; + + m_bc7_rgb_avg_psnr = 0.0f; + m_bc7_rgba_avg_psnr = 0.0f; + m_bc7_a_avg_psnr = 0.0f; + m_bc7_luma_709_psnr = 0.0f; + m_bc7_luma_601_psnr = 0.0f; + m_bc7_luma_709_ssim = 0.0f; + + m_best_etc1s_rgb_avg_psnr = 0.0f; + m_best_etc1s_luma_709_psnr = 0.0f; + m_best_etc1s_luma_601_psnr = 0.0f; + m_best_etc1s_luma_709_ssim = 0.0f; } std::string m_filename; uint32_t m_width; uint32_t m_height; - // .basis compressed - float m_basis_etc1s_rgb_avg_psnr; - float m_basis_etc1s_luma_709_psnr; - float m_basis_etc1s_luma_601_psnr; - float m_basis_etc1s_luma_709_ssim; + // .basis compressed (ETC1S or UASTC statistics) + float m_basis_rgb_avg_psnr; + float m_basis_rgba_avg_psnr; + float m_basis_a_avg_psnr; + float m_basis_luma_709_psnr; + float m_basis_luma_601_psnr; + float m_basis_luma_709_ssim; + + // BC7 statistics + float m_bc7_rgb_avg_psnr; + float m_bc7_rgba_avg_psnr; + float m_bc7_a_avg_psnr; + float m_bc7_luma_709_psnr; + float m_bc7_luma_601_psnr; + float m_bc7_luma_709_ssim; - float m_basis_bc1_rgb_avg_psnr; - float m_basis_bc1_luma_709_psnr; - float m_basis_bc1_luma_601_psnr; - float m_basis_bc1_luma_709_ssim; - - // Normal (highest quality) compressed ETC1S - float m_best_rgb_avg_psnr; - float m_best_luma_709_psnr; - float m_best_luma_601_psnr; - float m_best_luma_709_ssim; + // Highest achievable quality ETC1S statistics + float m_best_etc1s_rgb_avg_psnr; + float m_best_etc1s_luma_709_psnr; + float m_best_etc1s_luma_601_psnr; + float m_best_etc1s_luma_709_ssim; }; template<bool def> @@ -175,18 +203,30 @@ namespace basisu struct basis_compressor_params { basis_compressor_params() : + m_pSel_codebook(NULL), + m_compression_level((int)BASISU_DEFAULT_COMPRESSION_LEVEL, 0, (int)BASISU_MAX_COMPRESSION_LEVEL), + m_selector_rdo_thresh(BASISU_DEFAULT_SELECTOR_RDO_THRESH, 0.0f, 1e+10f), + m_endpoint_rdo_thresh(BASISU_DEFAULT_ENDPOINT_RDO_THRESH, 0.0f, 1e+10f), m_hybrid_sel_cb_quality_thresh(BASISU_DEFAULT_HYBRID_SEL_CB_QUALITY_THRESH, 0.0f, 1e+10f), m_global_pal_bits(8, 0, ETC1_GLOBAL_SELECTOR_CODEBOOK_MAX_PAL_BITS), m_global_mod_bits(8, 0, basist::etc1_global_palette_entry_modifier::cTotalBits), - m_endpoint_rdo_thresh(BASISU_DEFAULT_ENDPOINT_RDO_THRESH, 0.0f, 1e+10f), - m_selector_rdo_thresh(BASISU_DEFAULT_SELECTOR_RDO_THRESH, 0.0f, 1e+10f), - m_pSel_codebook(NULL), + m_mip_scale(1.0f, .000125f, 4.0f), + m_mip_smallest_dimension(1, 1, 16384), m_max_endpoint_clusters(512), m_max_selector_clusters(512), m_quality_level(-1), - m_mip_scale(1.0f, .000125f, 4.0f), - m_mip_smallest_dimension(1, 1, 16384), - m_compression_level((int)BASISU_DEFAULT_COMPRESSION_LEVEL, 0, (int)BASISU_MAX_COMPRESSION_LEVEL), + m_pack_uastc_flags(cPackUASTCLevelDefault), + m_rdo_uastc_quality_scalar(1.0f, 0.001f, 50.0f), + m_rdo_uastc_dict_size(BASISU_RDO_UASTC_DICT_SIZE_DEFAULT, BASISU_RDO_UASTC_DICT_SIZE_MIN, BASISU_RDO_UASTC_DICT_SIZE_MAX), + m_rdo_uastc_max_smooth_block_error_scale(UASTC_RDO_DEFAULT_SMOOTH_BLOCK_MAX_ERROR_SCALE, 1.0f, 300.0f), + m_rdo_uastc_smooth_block_max_std_dev(UASTC_RDO_DEFAULT_MAX_SMOOTH_BLOCK_STD_DEV, .01f, 65536.0f), + m_rdo_uastc_max_allowed_rms_increase_ratio(UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO, .01f, 100.0f), + m_rdo_uastc_skip_block_rms_thresh(UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH, .01f, 100.0f), + m_resample_width(0, 1, 16384), + m_resample_height(0, 1, 16384), + m_resample_factor(0.0f, .00125f, 100.0f), + m_ktx2_uastc_supercompression(basist::KTX2_SS_NONE), + m_ktx2_zstd_supercompression_level(6, INT_MIN, INT_MAX), m_pJob_pool(nullptr) { clear(); @@ -196,15 +236,20 @@ namespace basisu { m_pSel_codebook = NULL; + m_uastc.clear(); + m_status_output.clear(); + m_source_filenames.clear(); m_source_alpha_filenames.clear(); m_source_images.clear(); + m_source_mipmap_images.clear(); m_out_filename.clear(); m_y_flip.clear(); m_debug.clear(); + m_validate.clear(); m_debug_images.clear(); m_global_sel_pal.clear(); m_auto_global_sel_pal.clear(); @@ -219,7 +264,11 @@ namespace basisu m_check_for_alpha.clear(); m_force_alpha.clear(); m_multithreading.clear(); - m_seperate_rg_to_color_alpha.clear(); + m_swizzle[0] = 0; + m_swizzle[1] = 1; + m_swizzle[2] = 2; + m_swizzle[3] = 3; + m_renormalize.clear(); m_hybrid_sel_cb_quality_thresh.clear(); m_global_pal_bits.clear(); m_global_mod_bits.clear(); @@ -236,6 +285,7 @@ namespace basisu m_mip_premultiplied.clear(); m_mip_renormalize.clear(); m_mip_wrapping.clear(); + m_mip_fast.clear(); m_mip_smallest_dimension.clear(); m_max_endpoint_clusters = 0; @@ -247,30 +297,63 @@ namespace basisu m_userdata1 = 0; m_us_per_frame = 0; + m_pack_uastc_flags = cPackUASTCLevelDefault; + m_rdo_uastc.clear(); + m_rdo_uastc_quality_scalar.clear(); + m_rdo_uastc_max_smooth_block_error_scale.clear(); + m_rdo_uastc_smooth_block_max_std_dev.clear(); + m_rdo_uastc_max_allowed_rms_increase_ratio.clear(); + m_rdo_uastc_skip_block_rms_thresh.clear(); + m_rdo_uastc_favor_simpler_modes_in_rdo_mode.clear(); + m_rdo_uastc_multithreading.clear(); + + m_resample_width.clear(); + m_resample_height.clear(); + m_resample_factor.clear(); + + m_pGlobal_codebooks = nullptr; + + m_create_ktx2_file.clear(); + m_ktx2_uastc_supercompression = basist::KTX2_SS_NONE; + m_ktx2_key_values.clear(); + m_ktx2_zstd_supercompression_level.clear(); + m_ktx2_srgb_transfer_func.clear(); + m_pJob_pool = nullptr; } - + // Pointer to the global selector codebook, or nullptr to not use a global selector codebook const basist::etc1_global_selector_codebook *m_pSel_codebook; + // True to generate UASTC .basis file data, otherwise ETC1S. + bool_param<false> m_uastc; + // If m_read_source_images is true, m_source_filenames (and optionally m_source_alpha_filenames) contains the filenames of PNG images to read. // Otherwise, the compressor processes the images in m_source_images. - std::vector<std::string> m_source_filenames; - std::vector<std::string> m_source_alpha_filenames; + basisu::vector<std::string> m_source_filenames; + basisu::vector<std::string> m_source_alpha_filenames; - std::vector<image> m_source_images; - // TODO: Allow caller to supply their own mipmaps + basisu::vector<image> m_source_images; + + // Stores mipmaps starting from level 1. Level 0 is still stored in m_source_images, as usual. + // If m_source_mipmaps isn't empty, automatic mipmap generation isn't done. m_source_mipmaps.size() MUST equal m_source_images.size() or the compressor returns an error. + // The compressor applies the user-provided swizzling (in m_swizzle) to these images. + basisu::vector< basisu::vector<image> > m_source_mipmap_images; // Filename of the output basis file - std::string m_out_filename; + std::string m_out_filename; // The params are done this way so we can detect when the user has explictly changed them. // Flip images across Y axis bool_param<false> m_y_flip; + + // If true, the compressor will print basis status to stdout during compression. + bool_param<true> m_status_output; // Output debug information during compression bool_param<false> m_debug; + bool_param<false> m_validate; // m_debug_images is pretty slow bool_param<false> m_debug_images; @@ -284,7 +367,7 @@ namespace basisu // Frontend/backend codec parameters bool_param<false> m_no_hybrid_sel_cb; - // Use perceptual sRGB colorspace metrics (for normal maps, etc.) + // Use perceptual sRGB colorspace metrics instead of linear bool_param<true> m_perceptual; // Disable selector RDO, for faster compression but larger files @@ -299,7 +382,7 @@ namespace basisu // Write the output basis file to disk using m_out_filename bool_param<false> m_write_output_basis_files; - + // Compute and display image metrics bool_param<false> m_compute_stats; @@ -311,7 +394,9 @@ namespace basisu bool_param<true> m_multithreading; // Split the R channel to RGB and the G channel to alpha, then write a basis file with alpha channels - bool_param<false> m_seperate_rg_to_color_alpha; + char m_swizzle[4]; + + bool_param<false> m_renormalize; bool_param<false> m_disable_hierarchical_endpoint_codebooks; @@ -328,10 +413,11 @@ namespace basisu bool_param<true> m_mip_premultiplied; // not currently supported bool_param<false> m_mip_renormalize; bool_param<true> m_mip_wrapping; + bool_param<true> m_mip_fast; param<int> m_mip_smallest_dimension; // Codebook size (quality) control. - // If m_quality_level != -1, it controls the quality level. It ranges from [0,255]. + // If m_quality_level != -1, it controls the quality level. It ranges from [0,255] or [BASISU_QUALITY_MIN, BASISU_QUALITY_MAX]. // Otherwise m_max_endpoint_clusters/m_max_selector_clusters controls the codebook sizes directly. uint32_t m_max_endpoint_clusters; uint32_t m_max_selector_clusters; @@ -343,6 +429,31 @@ namespace basisu uint32_t m_userdata1; uint32_t m_us_per_frame; + // cPackUASTCLevelDefault, etc. + uint32_t m_pack_uastc_flags; + bool_param<false> m_rdo_uastc; + param<float> m_rdo_uastc_quality_scalar; + param<int> m_rdo_uastc_dict_size; + param<float> m_rdo_uastc_max_smooth_block_error_scale; + param<float> m_rdo_uastc_smooth_block_max_std_dev; + param<float> m_rdo_uastc_max_allowed_rms_increase_ratio; + param<float> m_rdo_uastc_skip_block_rms_thresh; + bool_param<true> m_rdo_uastc_favor_simpler_modes_in_rdo_mode; + bool_param<true> m_rdo_uastc_multithreading; + + param<int> m_resample_width; + param<int> m_resample_height; + param<float> m_resample_factor; + const basist::basisu_lowlevel_etc1s_transcoder *m_pGlobal_codebooks; + + // KTX2 specific parameters. + // Internally, the compressor always creates a .basis file then it converts that lossless to KTX2. + bool_param<false> m_create_ktx2_file; + basist::ktx2_supercompression m_ktx2_uastc_supercompression; + basist::ktx2_transcoder::key_value_vec m_ktx2_key_values; + param<int> m_ktx2_zstd_supercompression_level; + bool_param<false> m_ktx2_srgb_transfer_func; + job_pool *m_pJob_pool; }; @@ -360,35 +471,41 @@ namespace basisu cECSuccess = 0, cECFailedReadingSourceImages, cECFailedValidating, + cECFailedEncodeUASTC, cECFailedFrontEnd, cECFailedFontendExtract, cECFailedBackend, cECFailedCreateBasisFile, - cECFailedWritingOutput + cECFailedWritingOutput, + cECFailedUASTCRDOPostProcess, + cECFailedCreateKTX2File }; error_code process(); + // The output .basis file will always be valid of process() succeeded. const uint8_vec &get_output_basis_file() const { return m_output_basis_file; } - const etc_block_vec &get_output_blocks() const { return m_output_blocks; } + + // The output .ktx2 file will only be valid if m_create_ktx2_file was true and process() succeeded. + const uint8_vec& get_output_ktx2_file() const { return m_output_ktx2_file; } - const std::vector<image_stats> &get_stats() const { return m_stats; } + const basisu::vector<image_stats> &get_stats() const { return m_stats; } uint32_t get_basis_file_size() const { return m_basis_file_size; } double get_basis_bits_per_texel() const { return m_basis_bits_per_texel; } - + bool get_any_source_image_has_alpha() const { return m_any_source_image_has_alpha; } - + private: basis_compressor_params m_params; - std::vector<image> m_slice_images; + basisu::vector<image> m_slice_images; - std::vector<image_stats> m_stats; + basisu::vector<image_stats> m_stats; uint32_t m_basis_file_size; double m_basis_bits_per_texel; - + basisu_backend_slice_desc_vec m_slice_descs; uint32_t m_total_blocks; @@ -397,33 +514,41 @@ namespace basisu basisu_frontend m_frontend; pixel_block_vec m_source_blocks; - std::vector<gpu_image> m_frontend_output_textures; + basisu::vector<gpu_image> m_frontend_output_textures; - std::vector<gpu_image> m_best_etc1s_images; - std::vector<image> m_best_etc1s_images_unpacked; + basisu::vector<gpu_image> m_best_etc1s_images; + basisu::vector<image> m_best_etc1s_images_unpacked; basisu_backend m_backend; basisu_file m_basis_file; - std::vector<gpu_image> m_decoded_output_textures; - std::vector<image> m_decoded_output_textures_unpacked; - std::vector<gpu_image> m_decoded_output_textures_bc1; - std::vector<image> m_decoded_output_textures_unpacked_bc1; + basisu::vector<gpu_image> m_decoded_output_textures; + basisu::vector<image> m_decoded_output_textures_unpacked; + basisu::vector<gpu_image> m_decoded_output_textures_bc7; + basisu::vector<image> m_decoded_output_textures_unpacked_bc7; uint8_vec m_output_basis_file; - etc_block_vec m_output_blocks; + uint8_vec m_output_ktx2_file; + + basisu::vector<gpu_image> m_uastc_slice_textures; + basisu_backend_output m_uastc_backend_output; bool m_any_source_image_has_alpha; bool read_source_images(); + bool extract_source_blocks(); bool process_frontend(); bool extract_frontend_texture_data(); bool process_backend(); bool create_basis_file_and_transcode(); bool write_output_files_and_compute_stats(); - bool generate_mipmaps(const image &img, std::vector<image> &mips, bool has_alpha); + error_code encode_slices_to_uastc(); + bool generate_mipmaps(const image &img, basisu::vector<image> &mips, bool has_alpha); bool validate_texture_type_constraints(); + bool validate_ktx2_constraints(); + void get_dfd(uint8_vec& dfd, const basist::ktx2_header& hdr); + bool create_ktx2_file(); }; } // namespace basisu diff --git a/thirdparty/basis_universal/basisu_enc.cpp b/thirdparty/basis_universal/encoder/basisu_enc.cpp index 7057c65cf8..f02fb62c11 100644 --- a/thirdparty/basis_universal/basisu_enc.cpp +++ b/thirdparty/basis_universal/encoder/basisu_enc.cpp @@ -1,5 +1,5 @@ // basisu_enc.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,11 @@ #include "basisu_resampler.h" #include "basisu_resampler_filters.h" #include "basisu_etc.h" -#include "transcoder/basisu_transcoder.h" +#include "../transcoder/basisu_transcoder.h" +#include "basisu_bc7enc.h" +#include "apg_bmp.h" +#include "jpgd.h" +#include <vector> #if defined(_WIN32) // For QueryPerformanceCounter/QueryPerformanceFrequency @@ -29,6 +33,9 @@ namespace basisu { uint64_t interval_timer::g_init_ticks, interval_timer::g_freq; double interval_timer::g_timer_freq; +#if BASISU_SUPPORT_SSE + bool g_cpu_supports_sse41; +#endif uint8_t g_hamming_dist[256] = { @@ -50,10 +57,117 @@ namespace basisu 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; + // This is a Public Domain 8x8 font from here: + // https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h + const uint8_t g_debug_font8x8_basic[127 - 32 + 1][8] = + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 ( ) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F + }; + // Encoder library initialization (just call once at startup) void basisu_encoder_init() { + detect_sse41(); + basist::basisu_transcoder_init(); + pack_etc1_solid_color_init(); + //uastc_init(); + bc7enc_compress_block_init(); // must be after uastc_init() } void error_printf(const char *pFmt, ...) @@ -108,7 +222,7 @@ namespace basisu #else #error TODO #endif - + interval_timer::interval_timer() : m_start_time(0), m_stop_time(0), m_started(false), m_stopped(false) { if (!g_timer_freq) @@ -169,38 +283,142 @@ namespace basisu return ticks * g_timer_freq; } - bool load_png(const char* pFilename, image& img) + const uint32_t MAX_32BIT_ALLOC_SIZE = 250000000; + + bool load_bmp(const char* pFilename, image& img) { - std::vector<uint8_t> buffer; - unsigned err = lodepng::load_file(buffer, std::string(pFilename)); - if (err) + int w = 0, h = 0; + unsigned int n_chans = 0; + unsigned char* pImage_data = apg_bmp_read(pFilename, &w, &h, &n_chans); + + if ((!pImage_data) || (!w) || (!h) || ((n_chans != 3) && (n_chans != 4))) + { + error_printf("Failed loading .BMP image \"%s\"!\n", pFilename); + + if (pImage_data) + apg_bmp_free(pImage_data); + return false; + } - unsigned w = 0, h = 0; + if (sizeof(void *) == sizeof(uint32_t)) + { + if ((w * h * n_chans) > MAX_32BIT_ALLOC_SIZE) + { + error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", pFilename, w, h); + + if (pImage_data) + apg_bmp_free(pImage_data); + + return false; + } + } + + img.resize(w, h); + + const uint8_t *pSrc = pImage_data; + for (int y = 0; y < h; y++) + { + color_rgba *pDst = &img(0, y); + + for (int x = 0; x < w; x++) + { + pDst->r = pSrc[0]; + pDst->g = pSrc[1]; + pDst->b = pSrc[2]; + pDst->a = (n_chans == 3) ? 255 : pSrc[3]; + + pSrc += n_chans; + ++pDst; + } + } + + apg_bmp_free(pImage_data); + + return true; + } + + bool load_tga(const char* pFilename, image& img) + { + int w = 0, h = 0, n_chans = 0; + uint8_t* pImage_data = read_tga(pFilename, w, h, n_chans); + if ((!pImage_data) || (!w) || (!h) || ((n_chans != 3) && (n_chans != 4))) + { + error_printf("Failed loading .TGA image \"%s\"!\n", pFilename); + + if (pImage_data) + free(pImage_data); + + return false; + } + if (sizeof(void *) == sizeof(uint32_t)) { + if ((w * h * n_chans) > MAX_32BIT_ALLOC_SIZE) + { + error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", pFilename, w, h); + + if (pImage_data) + free(pImage_data); + + return false; + } + } + + img.resize(w, h); + + const uint8_t *pSrc = pImage_data; + for (int y = 0; y < h; y++) + { + color_rgba *pDst = &img(0, y); + + for (int x = 0; x < w; x++) + { + pDst->r = pSrc[0]; + pDst->g = pSrc[1]; + pDst->b = pSrc[2]; + pDst->a = (n_chans == 3) ? 255 : pSrc[3]; + + pSrc += n_chans; + ++pDst; + } + } + + free(pImage_data); + + return true; + } + + bool load_png(const uint8_t *pBuf, size_t buf_size, image &img, const char *pFilename) + { + if (!buf_size) + return false; + + unsigned err = 0, w = 0, h = 0; + + if (sizeof(void*) == sizeof(uint32_t)) + { // Inspect the image first on 32-bit builds, to see if the image would require too much memory. lodepng::State state; - err = lodepng_inspect(&w, &h, &state, &buffer[0], buffer.size()); + err = lodepng_inspect(&w, &h, &state, pBuf, buf_size); if ((err != 0) || (!w) || (!h)) return false; const uint32_t exepected_alloc_size = w * h * sizeof(uint32_t); - + // If the file is too large on 32-bit builds then just bail now, to prevent causing a memory exception. - const uint32_t MAX_ALLOC_SIZE = 250000000; - if (exepected_alloc_size >= MAX_ALLOC_SIZE) + if (exepected_alloc_size >= MAX_32BIT_ALLOC_SIZE) { - error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", pFilename, w, h); + error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", (pFilename != nullptr) ? pFilename : "<memory>", w, h); return false; } - + w = h = 0; } - + std::vector<uint8_t> out; - err = lodepng::decode(out, w, h, &buffer[0], buffer.size()); + err = lodepng::decode(out, w, h, pBuf, buf_size); if ((err != 0) || (!w) || (!h)) return false; @@ -213,12 +431,62 @@ namespace basisu return true; } + + bool load_png(const char* pFilename, image& img) + { + std::vector<uint8_t> buffer; + unsigned err = lodepng::load_file(buffer, std::string(pFilename)); + if (err) + return false; + + + return load_png(buffer.data(), buffer.size(), img, pFilename); + } + + bool load_jpg(const char *pFilename, image& img) + { + int width = 0, height = 0, actual_comps = 0; + uint8_t *pImage_data = jpgd::decompress_jpeg_image_from_file(pFilename, &width, &height, &actual_comps, 4, jpgd::jpeg_decoder::cFlagLinearChromaFiltering); + if (!pImage_data) + return false; + + img.init(pImage_data, width, height, 4); + + free(pImage_data); + + return true; + } + + bool load_image(const char* pFilename, image& img) + { + std::string ext(string_get_extension(std::string(pFilename))); + + if (ext.length() == 0) + return false; + + const char *pExt = ext.c_str(); + + if (strcasecmp(pExt, "png") == 0) + return load_png(pFilename, img); + if (strcasecmp(pExt, "bmp") == 0) + return load_bmp(pFilename, img); + if (strcasecmp(pExt, "tga") == 0) + return load_tga(pFilename, img); + if ( (strcasecmp(pExt, "jpg") == 0) || (strcasecmp(pExt, "jfif") == 0) || (strcasecmp(pExt, "jpeg") == 0) ) + return load_jpg(pFilename, img); + + return false; + } - bool save_png(const char* pFilename, const image & img, uint32_t image_save_flags, uint32_t grayscale_comp) + bool save_png(const char* pFilename, const image &img, uint32_t image_save_flags, uint32_t grayscale_comp) { if (!img.get_total_pixels()) return false; + const uint32_t MAX_PNG_IMAGE_DIM = 32768; + if ((img.get_width() > MAX_PNG_IMAGE_DIM) || (img.get_height() > MAX_PNG_IMAGE_DIM)) + return false; + std::vector<uint8_t> out; unsigned err = 0; @@ -231,16 +499,19 @@ namespace basisu for (uint32_t x = 0; x < img.get_width(); x++) *pDst++ = img(x, y)[grayscale_comp]; - err = lodepng::encode(out, (const uint8_t*)& g_pixels[0], img.get_width(), img.get_height(), LCT_GREY, 8); + err = lodepng::encode(out, (const uint8_t*)&g_pixels[0], img.get_width(), img.get_height(), LCT_GREY, 8); } else { bool has_alpha = img.has_alpha(); if ((!has_alpha) || ((image_save_flags & cImageSaveIgnoreAlpha) != 0)) { - uint8_vec rgb_pixels(img.get_width() * 3 * img.get_height()); + const uint64_t total_bytes = (uint64_t)img.get_width() * 3U * (uint64_t)img.get_height(); + if (total_bytes > INT_MAX) + return false; + uint8_vec rgb_pixels(static_cast<size_t>(total_bytes)); uint8_t *pDst = &rgb_pixels[0]; - + for (uint32_t y = 0; y < img.get_height(); y++) { for (uint32_t x = 0; x < img.get_width(); x++) @@ -302,7 +573,11 @@ namespace basisu } } - data.resize((size_t)filesize); + if (!data.try_resize((size_t)filesize)) + { + fclose(pFile); + return false; + } if (filesize) { @@ -525,7 +800,7 @@ namespace basisu if ((s >= num_syms) || (A[r].m_key < A[s].m_key)) { A[next].m_key = A[r].m_key; - A[r].m_key = static_cast<uint16_t>(next); + A[r].m_key = next; ++r; } else @@ -536,13 +811,13 @@ namespace basisu if ((s >= num_syms) || ((r < next) && A[r].m_key < A[s].m_key)) { - A[next].m_key = static_cast<uint16_t>(A[next].m_key + A[r].m_key); - A[r].m_key = static_cast<uint16_t>(next); + A[next].m_key = A[next].m_key + A[r].m_key; + A[r].m_key = next; ++r; } else { - A[next].m_key = static_cast<uint16_t>(A[next].m_key + A[s].m_key); + A[next].m_key = A[next].m_key + A[s].m_key; ++s; } } @@ -562,7 +837,7 @@ namespace basisu ; for ( ; num_avail > num_used; --next, --num_avail) - A[next].m_key = static_cast<uint16_t>(depth); + A[next].m_key = depth; num_avail = 2 * num_used; num_used = 0; @@ -610,6 +885,10 @@ namespace basisu for (i = 0; i < num_syms; i++) { uint32_t freq = pSyms0[i].m_key; + + // We scale all input frequencies to 16-bits. + assert(freq <= UINT16_MAX); + hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } @@ -731,8 +1010,13 @@ namespace basisu else { for (uint32_t i = 0; i < num_syms; i++) + { if (pSym_freq[i]) - sym_freq[i] = static_cast<uint16_t>(maximum<uint32_t>((pSym_freq[i] * 65534U + (max_freq >> 1)) / max_freq, 1)); + { + uint32_t f = static_cast<uint32_t>((static_cast<uint64_t>(pSym_freq[i]) * 65534U + (max_freq >> 1)) / max_freq); + sym_freq[i] = static_cast<uint16_t>(clamp<uint32_t>(f, 1, 65534)); + } + } } return init(num_syms, &sym_freq[0], max_code_size); @@ -1125,10 +1409,10 @@ namespace basisu void image_metrics::calc(const image &a, const image &b, uint32_t first_chan, uint32_t total_chans, bool avg_comp_error, bool use_601_luma) { assert((first_chan < 4U) && (first_chan + total_chans <= 4U)); - - const uint32_t width = std::min(a.get_width(), b.get_width()); - const uint32_t height = std::min(a.get_height(), b.get_height()); - + + const uint32_t width = basisu::minimum(a.get_width(), b.get_width()); + const uint32_t height = basisu::minimum(a.get_height(), b.get_height()); + double hist[256]; clear_obj(hist); @@ -1159,7 +1443,7 @@ namespace basisu { if (hist[i]) { - m_max = std::max<float>(m_max, (float)i); + m_max = basisu::maximum<float>(m_max, (float)i); double v = i * hist[i]; sum += v; sum2 += i * v; @@ -1171,9 +1455,9 @@ namespace basisu total_values *= (double)clamp<uint32_t>(total_chans, 1, 4); m_mean = (float)clamp<double>(sum / total_values, 0.0f, 255.0); - m_mean_squared = (float)clamp<double>(sum2 / total_values, 0.0f, 255.0 * 255.0); + m_mean_squared = (float)clamp<double>(sum2 / total_values, 0.0f, 255.0f * 255.0f); m_rms = (float)sqrt(m_mean_squared); - m_psnr = m_rms ? (float)clamp<double>(log10(255.0 / m_rms) * 20.0, 0.0f, 300.0f) : 1e+10f; + m_psnr = m_rms ? (float)clamp<double>(log10(255.0 / m_rms) * 20.0f, 0.0f, 100.0f) : 100.0f; } void fill_buffer_with_random_bytes(void *pBuf, size_t size, uint32_t seed) @@ -1253,8 +1537,8 @@ namespace basisu } job_pool::job_pool(uint32_t num_threads) : - m_kill_flag(false), - m_num_active_jobs(0) + m_num_active_jobs(0), + m_kill_flag(false) { assert(num_threads >= 1U); @@ -1302,13 +1586,15 @@ namespace basisu std::unique_lock<std::mutex> lock(m_mutex); m_queue.emplace_back(std::move(job)); - + const size_t queue_size = m_queue.size(); lock.unlock(); if (queue_size > 1) + { m_has_work.notify_one(); + } } void job_pool::wait_for_all() @@ -1373,4 +1659,481 @@ namespace basisu debug_printf("job_pool::job_thread: exiting\n"); } + // .TGA image loading + #pragma pack(push) + #pragma pack(1) + struct tga_header + { + uint8_t m_id_len; + uint8_t m_cmap; + uint8_t m_type; + packed_uint<2> m_cmap_first; + packed_uint<2> m_cmap_len; + uint8_t m_cmap_bpp; + packed_uint<2> m_x_org; + packed_uint<2> m_y_org; + packed_uint<2> m_width; + packed_uint<2> m_height; + uint8_t m_depth; + uint8_t m_desc; + }; + #pragma pack(pop) + + const uint32_t MAX_TGA_IMAGE_SIZE = 16384; + + enum tga_image_type + { + cITPalettized = 1, + cITRGB = 2, + cITGrayscale = 3 + }; + + uint8_t *read_tga(const uint8_t *pBuf, uint32_t buf_size, int &width, int &height, int &n_chans) + { + width = 0; + height = 0; + n_chans = 0; + + if (buf_size <= sizeof(tga_header)) + return nullptr; + + const tga_header &hdr = *reinterpret_cast<const tga_header *>(pBuf); + + if ((!hdr.m_width) || (!hdr.m_height) || (hdr.m_width > MAX_TGA_IMAGE_SIZE) || (hdr.m_height > MAX_TGA_IMAGE_SIZE)) + return nullptr; + + if (hdr.m_desc >> 6) + return nullptr; + + // Simple validation + if ((hdr.m_cmap != 0) && (hdr.m_cmap != 1)) + return nullptr; + + if (hdr.m_cmap) + { + if ((hdr.m_cmap_bpp == 0) || (hdr.m_cmap_bpp > 32)) + return nullptr; + + // Nobody implements CMapFirst correctly, so we're not supporting it. Never seen it used, either. + if (hdr.m_cmap_first != 0) + return nullptr; + } + + const bool x_flipped = (hdr.m_desc & 0x10) != 0; + const bool y_flipped = (hdr.m_desc & 0x20) == 0; + + bool rle_flag = false; + int file_image_type = hdr.m_type; + if (file_image_type > 8) + { + file_image_type -= 8; + rle_flag = true; + } + + const tga_image_type image_type = static_cast<tga_image_type>(file_image_type); + + switch (file_image_type) + { + case cITRGB: + if (hdr.m_depth == 8) + return nullptr; + break; + case cITPalettized: + if ((hdr.m_depth != 8) || (hdr.m_cmap != 1) || (hdr.m_cmap_len == 0)) + return nullptr; + break; + case cITGrayscale: + if ((hdr.m_cmap != 0) || (hdr.m_cmap_len != 0)) + return nullptr; + if ((hdr.m_depth != 8) && (hdr.m_depth != 16)) + return nullptr; + break; + default: + return nullptr; + } + + uint32_t tga_bytes_per_pixel = 0; + + switch (hdr.m_depth) + { + case 32: + tga_bytes_per_pixel = 4; + n_chans = 4; + break; + case 24: + tga_bytes_per_pixel = 3; + n_chans = 3; + break; + case 16: + case 15: + tga_bytes_per_pixel = 2; + // For compatibility with stb_image_write.h + n_chans = ((file_image_type == cITGrayscale) && (hdr.m_depth == 16)) ? 4 : 3; + break; + case 8: + tga_bytes_per_pixel = 1; + // For palettized RGBA support, which both FreeImage and stb_image support. + n_chans = ((file_image_type == cITPalettized) && (hdr.m_cmap_bpp == 32)) ? 4 : 3; + break; + default: + return nullptr; + } + + const uint32_t bytes_per_line = hdr.m_width * tga_bytes_per_pixel; + + const uint8_t *pSrc = pBuf + sizeof(tga_header); + uint32_t bytes_remaining = buf_size - sizeof(tga_header); + + if (hdr.m_id_len) + { + if (bytes_remaining < hdr.m_id_len) + return nullptr; + pSrc += hdr.m_id_len; + bytes_remaining += hdr.m_id_len; + } + + color_rgba pal[256]; + for (uint32_t i = 0; i < 256; i++) + pal[i].set(0, 0, 0, 255); + + if ((hdr.m_cmap) && (hdr.m_cmap_len)) + { + if (image_type == cITPalettized) + { + // Note I cannot find any files using 32bpp palettes in the wild (never seen any in ~30 years). + if ( ((hdr.m_cmap_bpp != 32) && (hdr.m_cmap_bpp != 24) && (hdr.m_cmap_bpp != 15) && (hdr.m_cmap_bpp != 16)) || (hdr.m_cmap_len > 256) ) + return nullptr; + + if (hdr.m_cmap_bpp == 32) + { + const uint32_t pal_size = hdr.m_cmap_len * 4; + if (bytes_remaining < pal_size) + return nullptr; + + for (uint32_t i = 0; i < hdr.m_cmap_len; i++) + { + pal[i].r = pSrc[i * 4 + 2]; + pal[i].g = pSrc[i * 4 + 1]; + pal[i].b = pSrc[i * 4 + 0]; + pal[i].a = pSrc[i * 4 + 3]; + } + + bytes_remaining -= pal_size; + pSrc += pal_size; + } + else if (hdr.m_cmap_bpp == 24) + { + const uint32_t pal_size = hdr.m_cmap_len * 3; + if (bytes_remaining < pal_size) + return nullptr; + + for (uint32_t i = 0; i < hdr.m_cmap_len; i++) + { + pal[i].r = pSrc[i * 3 + 2]; + pal[i].g = pSrc[i * 3 + 1]; + pal[i].b = pSrc[i * 3 + 0]; + pal[i].a = 255; + } + + bytes_remaining -= pal_size; + pSrc += pal_size; + } + else + { + const uint32_t pal_size = hdr.m_cmap_len * 2; + if (bytes_remaining < pal_size) + return nullptr; + + for (uint32_t i = 0; i < hdr.m_cmap_len; i++) + { + const uint32_t v = pSrc[i * 2 + 0] | (pSrc[i * 2 + 1] << 8); + + pal[i].r = (((v >> 10) & 31) * 255 + 15) / 31; + pal[i].g = (((v >> 5) & 31) * 255 + 15) / 31; + pal[i].b = ((v & 31) * 255 + 15) / 31; + pal[i].a = 255; + } + + bytes_remaining -= pal_size; + pSrc += pal_size; + } + } + else + { + const uint32_t bytes_to_skip = (hdr.m_cmap_bpp >> 3) * hdr.m_cmap_len; + if (bytes_remaining < bytes_to_skip) + return nullptr; + pSrc += bytes_to_skip; + bytes_remaining += bytes_to_skip; + } + } + + width = hdr.m_width; + height = hdr.m_height; + + const uint32_t source_pitch = width * tga_bytes_per_pixel; + const uint32_t dest_pitch = width * n_chans; + + uint8_t *pImage = (uint8_t *)malloc(dest_pitch * height); + if (!pImage) + return nullptr; + + std::vector<uint8_t> input_line_buf; + if (rle_flag) + input_line_buf.resize(source_pitch); + + int run_type = 0, run_remaining = 0; + uint8_t run_pixel[4]; + memset(run_pixel, 0, sizeof(run_pixel)); + + for (int y = 0; y < height; y++) + { + const uint8_t *pLine_data; + + if (rle_flag) + { + int pixels_remaining = width; + uint8_t *pDst = &input_line_buf[0]; + + do + { + if (!run_remaining) + { + if (bytes_remaining < 1) + { + free(pImage); + return nullptr; + } + + int v = *pSrc++; + bytes_remaining--; + + run_type = v & 0x80; + run_remaining = (v & 0x7F) + 1; + + if (run_type) + { + if (bytes_remaining < tga_bytes_per_pixel) + { + free(pImage); + return nullptr; + } + + memcpy(run_pixel, pSrc, tga_bytes_per_pixel); + pSrc += tga_bytes_per_pixel; + bytes_remaining -= tga_bytes_per_pixel; + } + } + + const uint32_t n = basisu::minimum<uint32_t>(pixels_remaining, run_remaining); + pixels_remaining -= n; + run_remaining -= n; + + if (run_type) + { + for (uint32_t i = 0; i < n; i++) + for (uint32_t j = 0; j < tga_bytes_per_pixel; j++) + *pDst++ = run_pixel[j]; + } + else + { + const uint32_t bytes_wanted = n * tga_bytes_per_pixel; + + if (bytes_remaining < bytes_wanted) + { + free(pImage); + return nullptr; + } + + memcpy(pDst, pSrc, bytes_wanted); + pDst += bytes_wanted; + + pSrc += bytes_wanted; + bytes_remaining -= bytes_wanted; + } + + } while (pixels_remaining); + + assert((pDst - &input_line_buf[0]) == width * tga_bytes_per_pixel); + + pLine_data = &input_line_buf[0]; + } + else + { + if (bytes_remaining < source_pitch) + { + free(pImage); + return nullptr; + } + + pLine_data = pSrc; + bytes_remaining -= source_pitch; + pSrc += source_pitch; + } + + // Convert to 24bpp RGB or 32bpp RGBA. + uint8_t *pDst = pImage + (y_flipped ? (height - 1 - y) : y) * dest_pitch + (x_flipped ? (width - 1) * n_chans : 0); + const int dst_stride = x_flipped ? -((int)n_chans) : n_chans; + + switch (hdr.m_depth) + { + case 32: + assert(tga_bytes_per_pixel == 4 && n_chans == 4); + for (int i = 0; i < width; i++, pLine_data += 4, pDst += dst_stride) + { + pDst[0] = pLine_data[2]; + pDst[1] = pLine_data[1]; + pDst[2] = pLine_data[0]; + pDst[3] = pLine_data[3]; + } + break; + case 24: + assert(tga_bytes_per_pixel == 3 && n_chans == 3); + for (int i = 0; i < width; i++, pLine_data += 3, pDst += dst_stride) + { + pDst[0] = pLine_data[2]; + pDst[1] = pLine_data[1]; + pDst[2] = pLine_data[0]; + } + break; + case 16: + case 15: + if (image_type == cITRGB) + { + assert(tga_bytes_per_pixel == 2 && n_chans == 3); + for (int i = 0; i < width; i++, pLine_data += 2, pDst += dst_stride) + { + const uint32_t v = pLine_data[0] | (pLine_data[1] << 8); + pDst[0] = (((v >> 10) & 31) * 255 + 15) / 31; + pDst[1] = (((v >> 5) & 31) * 255 + 15) / 31; + pDst[2] = ((v & 31) * 255 + 15) / 31; + } + } + else + { + assert(image_type == cITGrayscale && tga_bytes_per_pixel == 2 && n_chans == 4); + for (int i = 0; i < width; i++, pLine_data += 2, pDst += dst_stride) + { + pDst[0] = pLine_data[0]; + pDst[1] = pLine_data[0]; + pDst[2] = pLine_data[0]; + pDst[3] = pLine_data[1]; + } + } + break; + case 8: + assert(tga_bytes_per_pixel == 1); + if (image_type == cITPalettized) + { + if (hdr.m_cmap_bpp == 32) + { + assert(n_chans == 4); + for (int i = 0; i < width; i++, pLine_data++, pDst += dst_stride) + { + const uint32_t c = *pLine_data; + pDst[0] = pal[c].r; + pDst[1] = pal[c].g; + pDst[2] = pal[c].b; + pDst[3] = pal[c].a; + } + } + else + { + assert(n_chans == 3); + for (int i = 0; i < width; i++, pLine_data++, pDst += dst_stride) + { + const uint32_t c = *pLine_data; + pDst[0] = pal[c].r; + pDst[1] = pal[c].g; + pDst[2] = pal[c].b; + } + } + } + else + { + assert(n_chans == 3); + for (int i = 0; i < width; i++, pLine_data++, pDst += dst_stride) + { + const uint8_t c = *pLine_data; + pDst[0] = c; + pDst[1] = c; + pDst[2] = c; + } + } + break; + default: + assert(0); + break; + } + } // y + + return pImage; + } + + uint8_t *read_tga(const char *pFilename, int &width, int &height, int &n_chans) + { + width = height = n_chans = 0; + + uint8_vec filedata; + if (!read_file_to_vec(pFilename, filedata)) + return nullptr; + + if (!filedata.size() || (filedata.size() > UINT32_MAX)) + return nullptr; + + return read_tga(&filedata[0], (uint32_t)filedata.size(), width, height, n_chans); + } + + void image::debug_text(uint32_t x_ofs, uint32_t y_ofs, uint32_t scale_x, uint32_t scale_y, const color_rgba& fg, const color_rgba* pBG, bool alpha_only, const char* pFmt, ...) + { + char buf[2048]; + + va_list args; + va_start(args, pFmt); +#ifdef _WIN32 + vsprintf_s(buf, sizeof(buf), pFmt, args); +#else + vsnprintf(buf, sizeof(buf), pFmt, args); +#endif + va_end(args); + + const char* p = buf; + + const uint32_t orig_x_ofs = x_ofs; + + while (*p) + { + uint8_t c = *p++; + if ((c < 32) || (c > 127)) + c = '.'; + + const uint8_t* pGlpyh = &g_debug_font8x8_basic[c - 32][0]; + + for (uint32_t y = 0; y < 8; y++) + { + uint32_t row_bits = pGlpyh[y]; + for (uint32_t x = 0; x < 8; x++) + { + const uint32_t q = row_bits & (1 << x); + + const color_rgba* pColor = q ? &fg : pBG; + if (!pColor) + continue; + + if (alpha_only) + fill_box_alpha(x_ofs + x * scale_x, y_ofs + y * scale_y, scale_x, scale_y, *pColor); + else + fill_box(x_ofs + x * scale_x, y_ofs + y * scale_y, scale_x, scale_y, *pColor); + } + } + + x_ofs += 8 * scale_x; + if ((x_ofs + 8 * scale_x) > m_width) + { + x_ofs = orig_x_ofs; + y_ofs += 8 * scale_y; + } + } + } + } // namespace basisu diff --git a/thirdparty/basis_universal/basisu_enc.h b/thirdparty/basis_universal/encoder/basisu_enc.h index 0a0c3c6fc0..05c95cbc3b 100644 --- a/thirdparty/basis_universal/basisu_enc.h +++ b/thirdparty/basis_universal/encoder/basisu_enc.h @@ -1,5 +1,5 @@ // basisu_enc.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. #pragma once -#include "transcoder/basisu.h" -#include "transcoder/basisu_transcoder_internal.h" +#include "../transcoder/basisu.h" +#include "../transcoder/basisu_transcoder_internal.h" #include <mutex> #include <atomic> @@ -28,13 +28,29 @@ #include <libgen.h> #endif +// This module is really just a huge grab bag of classes and helper functions needed by the encoder. + +// If BASISU_USE_HIGH_PRECISION_COLOR_DISTANCE is 1, quality in perceptual mode will be slightly greater, but at a large increase in encoding CPU time. +#define BASISU_USE_HIGH_PRECISION_COLOR_DISTANCE (0) + namespace basisu { extern uint8_t g_hamming_dist[256]; + extern const uint8_t g_debug_font8x8_basic[127 - 32 + 1][8]; - // Encoder library initialization + // Encoder library initialization. + // This function MUST be called before encoding anything! void basisu_encoder_init(); + // basisu_kernels_sse.cpp - will be a no-op and g_cpu_supports_sse41 will always be false unless compiled with BASISU_SUPPORT_SSE=1 + extern void detect_sse41(); + +#if BASISU_SUPPORT_SSE + extern bool g_cpu_supports_sse41; +#else + const bool g_cpu_supports_sse41 = false; +#endif + void error_printf(const char *pFmt, ...); // Helpers @@ -43,7 +59,68 @@ namespace basisu { return (uint8_t)((i & 0xFFFFFF00U) ? (~(i >> 31)) : i); } - + + inline int32_t clampi(int32_t value, int32_t low, int32_t high) + { + if (value < low) + value = low; + else if (value > high) + value = high; + return value; + } + + inline uint8_t mul_8(uint32_t v, uint32_t a) + { + v = v * a + 128; + return (uint8_t)((v + (v >> 8)) >> 8); + } + + inline uint64_t read_bits(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize) + { + assert(codesize <= 64); + uint64_t bits = 0; + uint32_t total_bits = 0; + + while (total_bits < codesize) + { + uint32_t byte_bit_offset = bit_offset & 7; + uint32_t bits_to_read = minimum<int>(codesize - total_bits, 8 - byte_bit_offset); + + uint32_t byte_bits = pBuf[bit_offset >> 3] >> byte_bit_offset; + byte_bits &= ((1 << bits_to_read) - 1); + + bits |= ((uint64_t)(byte_bits) << total_bits); + + total_bits += bits_to_read; + bit_offset += bits_to_read; + } + + return bits; + } + + inline uint32_t read_bits32(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize) + { + assert(codesize <= 32); + uint32_t bits = 0; + uint32_t total_bits = 0; + + while (total_bits < codesize) + { + uint32_t byte_bit_offset = bit_offset & 7; + uint32_t bits_to_read = minimum<int>(codesize - total_bits, 8 - byte_bit_offset); + + uint32_t byte_bits = pBuf[bit_offset >> 3] >> byte_bit_offset; + byte_bits &= ((1 << bits_to_read) - 1); + + bits |= (byte_bits << total_bits); + + total_bits += bits_to_read; + bit_offset += bits_to_read; + } + + return bits; + } + // Hashing inline uint32_t bitmix32c(uint32_t v) @@ -69,6 +146,16 @@ namespace basisu return v; } + inline uint32_t wang_hash(uint32_t seed) + { + seed = (seed ^ 61) ^ (seed >> 16); + seed *= 9; + seed = seed ^ (seed >> 4); + seed *= 0x27d4eb2d; + seed = seed ^ (seed >> 15); + return seed; + } + uint32_t hash_hsieh(const uint8_t* pBuf, size_t len); template <typename Key> @@ -80,6 +167,72 @@ namespace basisu } }; + class running_stat + { + public: + running_stat() : + m_n(0), + m_old_m(0), m_new_m(0), m_old_s(0), m_new_s(0) + { + } + void clear() + { + m_n = 0; + } + void push(double x) + { + m_n++; + if (m_n == 1) + { + m_old_m = m_new_m = x; + m_old_s = 0.0; + m_min = x; + m_max = x; + } + else + { + m_new_m = m_old_m + (x - m_old_m) / m_n; + m_new_s = m_old_s + (x - m_old_m) * (x - m_new_m); + m_old_m = m_new_m; + m_old_s = m_new_s; + m_min = basisu::minimum(x, m_min); + m_max = basisu::maximum(x, m_max); + } + } + uint32_t get_num() const + { + return m_n; + } + double get_mean() const + { + return (m_n > 0) ? m_new_m : 0.0; + } + + double get_variance() const + { + return ((m_n > 1) ? m_new_s / (m_n - 1) : 0.0); + } + + double get_std_dev() const + { + return sqrt(get_variance()); + } + + double get_min() const + { + return m_min; + } + + double get_max() const + { + return m_max; + } + + private: + uint32_t m_n; + double m_old_m, m_new_m, m_old_s, m_new_s, m_min, m_max; + }; + // Linear algebra template <uint32_t N, typename T> @@ -118,7 +271,7 @@ namespace basisu inline vec &set(const vec<OtherN, OtherT> &other) { uint32_t i; - if (static_cast<void *>(&other) == static_cast<void *>(this)) + if ((const void *)(&other) == (const void *)(this)) return *this; const uint32_t m = minimum(OtherN, N); for (i = 0; i < m; i++) @@ -358,6 +511,7 @@ namespace basisu BASISU_NO_EQUALS_OR_COPY_CONSTRUCT(job_pool); public: + // num_threads is the TOTAL number of job pool threads, including the calling thread! So 2=1 new thread, 3=2 new threads, etc. job_pool(uint32_t num_threads); ~job_pool(); @@ -370,7 +524,7 @@ namespace basisu private: std::vector<std::thread> m_threads; - std::vector<std::function<void()> > m_queue; + std::vector<std::function<void()> > m_queue; std::mutex m_mutex; std::condition_variable m_has_work; @@ -420,7 +574,7 @@ namespace basisu return *this; } }; - + class color_rgba { public: @@ -440,6 +594,25 @@ namespace basisu inline color_rgba() { static_assert(sizeof(*this) == 4, "sizeof(*this) != 4"); + static_assert(sizeof(*this) == sizeof(basist::color32), "sizeof(*this) != sizeof(basist::color32)"); + } + + // Not too hot about this idea. + inline color_rgba(const basist::color32& other) : + r(other.r), + g(other.g), + b(other.b), + a(other.a) + { + } + + color_rgba& operator= (const basist::color32& rhs) + { + r = rhs.r; + g = rhs.g; + b = rhs.b; + a = rhs.a; + return *this; } inline color_rgba(int y) @@ -563,11 +736,20 @@ namespace basisu inline int get_601_luma() const { return (19595U * m_comps[0] + 38470U * m_comps[1] + 7471U * m_comps[2] + 32768U) >> 16U; } inline int get_709_luma() const { return (13938U * m_comps[0] + 46869U * m_comps[1] + 4729U * m_comps[2] + 32768U) >> 16U; } inline int get_luma(bool luma_601) const { return luma_601 ? get_601_luma() : get_709_luma(); } + + inline basist::color32 get_color32() const + { + return basist::color32(r, g, b, a); + } + + static color_rgba comp_min(const color_rgba& a, const color_rgba& b) { return color_rgba(basisu::minimum(a[0], b[0]), basisu::minimum(a[1], b[1]), basisu::minimum(a[2], b[2]), basisu::minimum(a[3], b[3])); } + static color_rgba comp_max(const color_rgba& a, const color_rgba& b) { return color_rgba(basisu::maximum(a[0], b[0]), basisu::maximum(a[1], b[1]), basisu::maximum(a[2], b[2]), basisu::maximum(a[3], b[3])); } }; - typedef std::vector<color_rgba> color_rgba_vec; + typedef basisu::vector<color_rgba> color_rgba_vec; const color_rgba g_black_color(0, 0, 0, 255); + const color_rgba g_black_trans_color(0, 0, 0, 0); const color_rgba g_white_color(255, 255, 255, 255); inline int color_distance(int r0, int g0, int b0, int r1, int g1, int b1) @@ -595,6 +777,7 @@ namespace basisu { if (perceptual) { +#if BASISU_USE_HIGH_PRECISION_COLOR_DISTANCE const float l1 = e1.r * .2126f + e1.g * .715f + e1.b * .0722f; const float l2 = e2.r * .2126f + e2.g * .715f + e2.b * .0722f; @@ -617,11 +800,61 @@ namespace basisu } return d; +#elif 1 + int dr = e1.r - e2.r; + int dg = e1.g - e2.g; + int db = e1.b - e2.b; + + int delta_l = dr * 27 + dg * 92 + db * 9; + int delta_cr = dr * 128 - delta_l; + int delta_cb = db * 128 - delta_l; + + uint32_t id = ((uint32_t)(delta_l * delta_l) >> 7U) + + ((((uint32_t)(delta_cr * delta_cr) >> 7U) * 26U) >> 7U) + + ((((uint32_t)(delta_cb * delta_cb) >> 7U) * 3U) >> 7U); + + if (alpha) + { + int da = (e1.a - e2.a) << 7; + id += ((uint32_t)(da * da) >> 7U); + } + + return id; +#else + int dr = e1.r - e2.r; + int dg = e1.g - e2.g; + int db = e1.b - e2.b; + + int64_t delta_l = dr * 27 + dg * 92 + db * 9; + int64_t delta_cr = dr * 128 - delta_l; + int64_t delta_cb = db * 128 - delta_l; + + int64_t id = ((delta_l * delta_l) * 128) + + ((delta_cr * delta_cr) * 26) + + ((delta_cb * delta_cb) * 3); + + if (alpha) + { + int64_t da = (e1.a - e2.a); + id += (da * da) * 128; + } + + int d = (id + 8192) >> 14; + + return d; +#endif } else return color_distance(e1, e2, alpha); } + static inline uint32_t color_distance_la(const color_rgba& a, const color_rgba& b) + { + const int dl = a.r - b.r; + const int da = a.a - b.a; + return dl * dl + da * da; + } + // String helpers inline int string_find_right(const std::string& filename, char c) @@ -929,7 +1162,7 @@ namespace basisu float m_priority; }; - std::vector<entry> m_heap; + basisu::vector<entry> m_heap; uint32_t m_size; // Push down entry at index @@ -961,7 +1194,7 @@ namespace basisu public: typedef TrainingVectorType training_vec_type; typedef std::pair<TrainingVectorType, uint64_t> training_vec_with_weight; - typedef std::vector< training_vec_with_weight > array_of_weighted_training_vecs; + typedef basisu::vector< training_vec_with_weight > array_of_weighted_training_vecs; tree_vector_quant() : m_next_codebook_index(0) @@ -981,7 +1214,7 @@ namespace basisu const array_of_weighted_training_vecs &get_training_vecs() const { return m_training_vecs; } array_of_weighted_training_vecs &get_training_vecs() { return m_training_vecs; } - void retrieve(std::vector< std::vector<uint32_t> > &codebook) const + void retrieve(basisu::vector< basisu::vector<uint32_t> > &codebook) const { for (uint32_t i = 0; i < m_nodes.size(); i++) { @@ -994,7 +1227,7 @@ namespace basisu } } - void retrieve(std::vector<TrainingVectorType> &codebook) const + void retrieve(basisu::vector<TrainingVectorType> &codebook) const { for (uint32_t i = 0; i < m_nodes.size(); i++) { @@ -1007,7 +1240,7 @@ namespace basisu } } - void retrieve(uint32_t max_clusters, std::vector<uint_vec> &codebook) const + void retrieve(uint32_t max_clusters, basisu::vector<uint_vec> &codebook) const { uint_vec node_stack; node_stack.reserve(512); @@ -1054,7 +1287,7 @@ namespace basisu priority_queue var_heap; var_heap.init(max_size, 0, m_nodes[0].m_var); - std::vector<uint32_t> l_children, r_children; + basisu::vector<uint32_t> l_children, r_children; // Now split the worst nodes l_children.reserve(m_training_vecs.size() + 1); @@ -1092,7 +1325,7 @@ namespace basisu inline tsvq_node() : m_weight(0), m_origin(cZero), m_left_index(-1), m_right_index(-1), m_codebook_index(-1) { } // vecs is erased - inline void set(const TrainingVectorType &org, uint64_t weight, float var, std::vector<uint32_t> &vecs) { m_origin = org; m_weight = weight; m_var = var; m_training_vecs.swap(vecs); } + inline void set(const TrainingVectorType &org, uint64_t weight, float var, basisu::vector<uint32_t> &vecs) { m_origin = org; m_weight = weight; m_var = var; m_training_vecs.swap(vecs); } inline bool is_leaf() const { return m_left_index < 0; } @@ -1100,11 +1333,11 @@ namespace basisu uint64_t m_weight; TrainingVectorType m_origin; int32_t m_left_index, m_right_index; - std::vector<uint32_t> m_training_vecs; + basisu::vector<uint32_t> m_training_vecs; int m_codebook_index; }; - typedef std::vector<tsvq_node> tsvq_node_vec; + typedef basisu::vector<tsvq_node> tsvq_node_vec; tsvq_node_vec m_nodes; array_of_weighted_training_vecs m_training_vecs; @@ -1139,7 +1372,7 @@ namespace basisu return root; } - bool split_node(uint32_t node_index, priority_queue &var_heap, std::vector<uint32_t> &l_children, std::vector<uint32_t> &r_children) + bool split_node(uint32_t node_index, priority_queue &var_heap, basisu::vector<uint32_t> &l_children, basisu::vector<uint32_t> &r_children) { TrainingVectorType l_child_org, r_child_org; uint64_t l_weight = 0, r_weight = 0; @@ -1239,7 +1472,7 @@ namespace basisu bool prep_split(const tsvq_node &node, TrainingVectorType &l_child_result, TrainingVectorType &r_child_result) const { - const uint32_t N = TrainingVectorType::num_elements; + //const uint32_t N = TrainingVectorType::num_elements; if (2 == node.m_training_vecs.size()) { @@ -1304,7 +1537,7 @@ namespace basisu if (largest_axis_index < 0) return false; - std::vector<float> keys(node.m_training_vecs.size()); + basisu::vector<float> keys(node.m_training_vecs.size()); for (uint32_t i = 0; i < node.m_training_vecs.size(); i++) keys[i] = m_training_vecs[node.m_training_vecs[i]].first[largest_axis_index]; @@ -1352,8 +1585,8 @@ namespace basisu } bool refine_split(const tsvq_node &node, - TrainingVectorType &l_child, uint64_t &l_weight, float &l_var, std::vector<uint32_t> &l_children, - TrainingVectorType &r_child, uint64_t &r_weight, float &r_var, std::vector<uint32_t> &r_children) const + TrainingVectorType &l_child, uint64_t &l_weight, float &l_var, basisu::vector<uint32_t> &l_children, + TrainingVectorType &r_child, uint64_t &r_weight, float &r_var, basisu::vector<uint32_t> &r_children) const { l_children.reserve(node.m_training_vecs.size()); r_children.reserve(node.m_training_vecs.size()); @@ -1466,8 +1699,8 @@ namespace basisu template<typename Quantizer> bool generate_hierarchical_codebook_threaded_internal(Quantizer& q, uint32_t max_codebook_size, uint32_t max_parent_codebook_size, - std::vector<uint_vec>& codebook, - std::vector<uint_vec>& parent_codebook, + basisu::vector<uint_vec>& codebook, + basisu::vector<uint_vec>& parent_codebook, uint32_t max_threads, bool limit_clusterizers, job_pool *pJob_pool) { codebook.resize(0); @@ -1493,7 +1726,7 @@ namespace basisu if (!q.generate(max_threads)) return false; - std::vector<uint_vec> initial_codebook; + basisu::vector<uint_vec> initial_codebook; q.retrieve(initial_codebook); @@ -1512,12 +1745,14 @@ namespace basisu bool success_flags[cMaxThreads]; clear_obj(success_flags); - std::vector<uint_vec> local_clusters[cMaxThreads]; - std::vector<uint_vec> local_parent_clusters[cMaxThreads]; + basisu::vector<uint_vec> local_clusters[cMaxThreads]; + basisu::vector<uint_vec> local_parent_clusters[cMaxThreads]; for (uint32_t thread_iter = 0; thread_iter < max_threads; thread_iter++) { +#ifndef __EMSCRIPTEN__ pJob_pool->add_job( [thread_iter, &local_clusters, &local_parent_clusters, &success_flags, &quantizers, &initial_codebook, &q, &limit_clusterizers, &max_codebook_size, &max_threads, &max_parent_codebook_size] { +#endif Quantizer& lq = quantizers[thread_iter]; uint_vec& cluster_indices = initial_codebook[thread_iter]; @@ -1558,11 +1793,15 @@ namespace basisu } } +#ifndef __EMSCRIPTEN__ } ); +#endif } // thread_iter +#ifndef __EMSCRIPTEN__ pJob_pool->wait_for_all(); +#endif uint32_t total_clusters = 0, total_parent_clusters = 0; @@ -1598,8 +1837,8 @@ namespace basisu template<typename Quantizer> bool generate_hierarchical_codebook_threaded(Quantizer& q, uint32_t max_codebook_size, uint32_t max_parent_codebook_size, - std::vector<uint_vec>& codebook, - std::vector<uint_vec>& parent_codebook, + basisu::vector<uint_vec>& codebook, + basisu::vector<uint_vec>& parent_codebook, uint32_t max_threads, job_pool *pJob_pool) { typedef bit_hasher<typename Quantizer::training_vec_type> training_vec_bit_hasher; @@ -1629,7 +1868,7 @@ namespace basisu Quantizer group_quant; typedef typename group_hash::const_iterator group_hash_const_iter; - std::vector<group_hash_const_iter> unique_vec_iters; + basisu::vector<group_hash_const_iter> unique_vec_iters; unique_vec_iters.reserve(unique_vecs.size()); for (auto iter = unique_vecs.begin(); iter != unique_vecs.end(); ++iter) @@ -1644,7 +1883,7 @@ namespace basisu debug_printf("Limit clusterizers: %u\n", limit_clusterizers); - std::vector<uint_vec> group_codebook, group_parent_codebook; + basisu::vector<uint_vec> group_codebook, group_parent_codebook; bool status = generate_hierarchical_codebook_threaded_internal(group_quant, max_codebook_size, max_parent_codebook_size, group_codebook, @@ -1693,7 +1932,7 @@ namespace basisu class histogram { - std::vector<uint32_t> m_hist; + basisu::vector<uint32_t> m_hist; public: histogram(uint32_t size = 0) { init(size); } @@ -1754,7 +1993,8 @@ namespace basisu struct sym_freq { - uint16_t m_key, m_sym_index; + uint32_t m_key; + uint16_t m_sym_index; }; sym_freq *canonical_huffman_radix_sort_syms(uint32_t num_syms, sym_freq *pSyms0, sym_freq *pSyms1); @@ -1835,7 +2075,7 @@ namespace basisu { if (m_bit_buffer_size) { - m_total_bits += 8; + m_total_bits += 8 - (m_bit_buffer_size & 7); append_byte(static_cast<uint8_t>(m_bit_buffer)); m_bit_buffer = 0; @@ -2107,6 +2347,12 @@ namespace basisu resize(w, h, p); } + image(const uint8_t *pImage, uint32_t width, uint32_t height, uint32_t comps) : + m_width(0), m_height(0), m_pitch(0) + { + init(pImage, width, height, comps); + } + image(const image &other) : m_width(0), m_height(0), m_pitch(0) { @@ -2155,6 +2401,47 @@ namespace basisu return *this; } + void init(const uint8_t *pImage, uint32_t width, uint32_t height, uint32_t comps) + { + assert(comps >= 1 && comps <= 4); + + resize(width, height); + + for (uint32_t y = 0; y < height; y++) + { + for (uint32_t x = 0; x < width; x++) + { + const uint8_t *pSrc = &pImage[(x + y * width) * comps]; + color_rgba &dst = (*this)(x, y); + + if (comps == 1) + { + dst.r = pSrc[0]; + dst.g = pSrc[0]; + dst.b = pSrc[0]; + dst.a = 255; + } + else if (comps == 2) + { + dst.r = pSrc[0]; + dst.g = pSrc[0]; + dst.b = pSrc[0]; + dst.a = pSrc[1]; + } + else + { + dst.r = pSrc[0]; + dst.g = pSrc[1]; + dst.b = pSrc[2]; + if (comps == 4) + dst.a = pSrc[3]; + else + dst.a = 255; + } + } + } + } + image &fill_box(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const color_rgba &c) { for (uint32_t iy = 0; iy < h; iy++) @@ -2163,6 +2450,14 @@ namespace basisu return *this; } + image& fill_box_alpha(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const color_rgba& c) + { + for (uint32_t iy = 0; iy < h; iy++) + for (uint32_t ix = 0; ix < w; ix++) + set_clipped_alpha(x + ix, y + iy, c); + return *this; + } + image &crop_dup_borders(uint32_t w, uint32_t h) { const uint32_t orig_w = m_width, orig_h = m_height; @@ -2252,6 +2547,13 @@ namespace basisu return *this; } + inline image& set_clipped_alpha(int x, int y, const color_rgba& c) + { + if ((static_cast<uint32_t>(x) < m_width) && (static_cast<uint32_t>(y) < m_height)) + (*this)(x, y).m_comps[3] = c.m_comps[3]; + return *this; + } + // Very straightforward blit with full clipping. Not fast, but it works. image &blit(const image &src, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y) { @@ -2376,6 +2678,8 @@ namespace basisu } return *this; } + + void debug_text(uint32_t x_ofs, uint32_t y_ofs, uint32_t x_scale, uint32_t y_scale, const color_rgba &fg, const color_rgba *pBG, bool alpha_only, const char* p, ...); private: uint32_t m_width, m_height, m_pitch; // all in pixels @@ -2384,7 +2688,7 @@ namespace basisu // Float images - typedef std::vector<vec4F> vec4F_vec; + typedef basisu::vector<vec4F> vec4F_vec; class imagef { @@ -2635,10 +2939,27 @@ namespace basisu }; // Image saving/loading/resampling - + + bool load_png(const uint8_t* pBuf, size_t buf_size, image& img, const char* pFilename = nullptr); bool load_png(const char* pFilename, image& img); inline bool load_png(const std::string &filename, image &img) { return load_png(filename.c_str(), img); } + bool load_bmp(const char* pFilename, image& img); + inline bool load_bmp(const std::string &filename, image &img) { return load_bmp(filename.c_str(), img); } + + bool load_tga(const char* pFilename, image& img); + inline bool load_tga(const std::string &filename, image &img) { return load_tga(filename.c_str(), img); } + + bool load_jpg(const char *pFilename, image& img); + inline bool load_jpg(const std::string &filename, image &img) { return load_jpg(filename.c_str(), img); } + + // Currently loads .BMP, .PNG, or .TGA. + bool load_image(const char* pFilename, image& img); + inline bool load_image(const std::string &filename, image &img) { return load_image(filename.c_str(), img); } + + uint8_t *read_tga(const uint8_t *pBuf, uint32_t buf_size, int &width, int &height, int &n_chans); + uint8_t *read_tga(const char *pFilename, int &width, int &height, int &n_chans); + enum { cImageSaveGrayscale = 1, @@ -2697,7 +3018,7 @@ namespace basisu template<typename T> class vector2D { - typedef std::vector<T> TVec; + typedef basisu::vector<T> TVec; uint32_t m_width, m_height; TVec m_values; @@ -2800,7 +3121,7 @@ namespace basisu } void fill_buffer_with_random_bytes(void *pBuf, size_t size, uint32_t seed = 1); - + } // namespace basisu diff --git a/thirdparty/basis_universal/encoder/basisu_etc.cpp b/thirdparty/basis_universal/encoder/basisu_etc.cpp new file mode 100644 index 0000000000..232e8965b0 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_etc.cpp @@ -0,0 +1,1593 @@ +// basis_etc.cpp +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_etc.h" + +#if BASISU_SUPPORT_SSE +#define CPPSPMD_NAME(a) a##_sse41 +#include "basisu_kernels_declares.h" +#endif + +#define BASISU_DEBUG_ETC_ENCODER 0 +#define BASISU_DEBUG_ETC_ENCODER_DEEPER 0 + +namespace basisu +{ + const int8_t g_etc2_eac_tables[16][8] = + { + { -3, -6, -9, -15, 2, 5, 8, 14 }, { -3, -7, -10, -13, 2, 6, 9, 12 }, { -2, -5, -8, -13, 1, 4, 7, 12 }, { -2, -4, -6, -13, 1, 3, 5, 12 }, + { -3, -6, -8, -12, 2, 5, 7, 11 }, { -3, -7, -9, -11, 2, 6, 8, 10 }, { -4, -7, -8, -11, 3, 6, 7, 10 }, { -3, -5, -8, -11, 2, 4, 7, 10 }, + { -2, -6, -8, -10, 1, 5, 7, 9 }, { -2, -5, -8, -10, 1, 4, 7, 9 }, { -2, -4, -8, -10, 1, 3, 7, 9 }, { -2, -5, -7, -10, 1, 4, 6, 9 }, + { -3, -4, -7, -10, 2, 3, 6, 9 }, { -1, -2, -3, -10, 0, 1, 2, 9 }, { -4, -6, -8, -9, 3, 5, 7, 8 }, { -3, -5, -7, -9, 2, 4, 6, 8 } + }; + + const int8_t g_etc2_eac_tables8[16][8] = + { + { -24, -48, -72, -120, 16, 40, 64, 112 }, { -24,-56,-80,-104,16,48,72,96 }, { -16,-40,-64,-104,8,32,56,96 }, { -16,-32,-48,-104,8,24,40,96 }, + { -24,-48,-64,-96,16,40,56,88 }, { -24,-56,-72,-88,16,48,64,80 }, { -32,-56,-64,-88,24,48,56,80 }, { -24,-40,-64,-88,16,32,56,80 }, + { -16,-48,-64,-80,8,40,56,72 }, { -16,-40,-64,-80,8,32,56,72 }, { -16,-32,-64,-80,8,24,56,72 }, { -16,-40,-56,-80,8,32,48,72 }, + { -24,-32,-56,-80,16,24,48,72 }, { -8,-16,-24,-80,0,8,16,72 }, { -32,-48,-64,-72,24,40,56,64 }, { -24,-40,-56,-72,16,32,48,64 } + }; + + // Given an ETC1 diff/inten_table/selector, and an 8-bit desired color, this table encodes the best packed_color in the low byte, and the abs error in the high byte. + static uint16_t g_etc1_inverse_lookup[2 * 8 * 4][256]; // [ diff/inten_table/selector][desired_color ] + + // g_color8_to_etc_block_config[color][table_index] = Supplies for each 8-bit color value a list of packed ETC1 diff/intensity table/selectors/packed_colors that map to that color. + // To pack: diff | (inten << 1) | (selector << 4) | (packed_c << 8) + static const uint16_t g_etc1_color8_to_etc_block_config_0_255[2][33] = + { + { 0x0000, 0x0010, 0x0002, 0x0012, 0x0004, 0x0014, 0x0006, 0x0016, 0x0008, 0x0018, 0x000A, 0x001A, 0x000C, 0x001C, 0x000E, 0x001E, 0x0001, 0x0011, 0x0003, 0x0013, 0x0005, 0x0015, 0x0007, 0x0017, 0x0009, 0x0019, 0x000B, 0x001B, 0x000D, 0x001D, 0x000F, 0x001F, 0xFFFF }, + { 0x0F20, 0x0F30, 0x0E32, 0x0F22, 0x0E34, 0x0F24, 0x0D36, 0x0F26, 0x0C38, 0x0E28, 0x0B3A, 0x0E2A, 0x093C, 0x0E2C, 0x053E, 0x0D2E, 0x1E31, 0x1F21, 0x1D33, 0x1F23, 0x1C35, 0x1E25, 0x1A37, 0x1E27, 0x1839, 0x1D29, 0x163B, 0x1C2B, 0x133D, 0x1B2D, 0x093F, 0x1A2F, 0xFFFF }, + }; + + // Really only [254][11]. + static const uint16_t g_etc1_color8_to_etc_block_config_1_to_254[254][12] = + { + { 0x021C, 0x0D0D, 0xFFFF }, { 0x0020, 0x0021, 0x0A0B, 0x061F, 0xFFFF }, { 0x0113, 0x0217, 0xFFFF }, { 0x0116, 0x031E, 0x0B0E, 0x0405, 0xFFFF }, { 0x0022, 0x0204, 0x050A, 0x0023, 0xFFFF }, { 0x0111, 0x0319, 0x0809, 0x170F, 0xFFFF }, { + 0x0303, 0x0215, 0x0607, 0xFFFF }, { 0x0030, 0x0114, 0x0408, 0x0031, 0x0201, 0x051D, 0xFFFF }, { 0x0100, 0x0024, 0x0306, 0x0025, 0x041B, 0x0E0D, 0xFFFF }, { 0x021A, 0x0121, 0x0B0B, 0x071F, 0xFFFF }, { 0x0213, 0x0317, 0xFFFF }, { 0x0112, + 0x0505, 0xFFFF }, { 0x0026, 0x070C, 0x0123, 0x0027, 0xFFFF }, { 0x0211, 0x0909, 0xFFFF }, { 0x0110, 0x0315, 0x0707, 0x0419, 0x180F, 0xFFFF }, { 0x0218, 0x0131, 0x0301, 0x0403, 0x061D, 0xFFFF }, { 0x0032, 0x0202, 0x0033, 0x0125, 0x051B, + 0x0F0D, 0xFFFF }, { 0x0028, 0x031C, 0x0221, 0x0029, 0xFFFF }, { 0x0120, 0x0313, 0x0C0B, 0x081F, 0xFFFF }, { 0x0605, 0x0417, 0xFFFF }, { 0x0216, 0x041E, 0x0C0E, 0x0223, 0x0127, 0xFFFF }, { 0x0122, 0x0304, 0x060A, 0x0311, 0x0A09, 0xFFFF + }, { 0x0519, 0x190F, 0xFFFF }, { 0x002A, 0x0231, 0x0503, 0x0415, 0x0807, 0x002B, 0x071D, 0xFFFF }, { 0x0130, 0x0214, 0x0508, 0x0401, 0x0133, 0x0225, 0x061B, 0xFFFF }, { 0x0200, 0x0124, 0x0406, 0x0321, 0x0129, 0x100D, 0xFFFF }, { 0x031A, + 0x0D0B, 0x091F, 0xFFFF }, { 0x0413, 0x0705, 0x0517, 0xFFFF }, { 0x0212, 0x0034, 0x0323, 0x0035, 0x0227, 0xFFFF }, { 0x0126, 0x080C, 0x0B09, 0xFFFF }, { 0x0411, 0x0619, 0x1A0F, 0xFFFF }, { 0x0210, 0x0331, 0x0603, 0x0515, 0x0907, 0x012B, + 0xFFFF }, { 0x0318, 0x002C, 0x0501, 0x0233, 0x0325, 0x071B, 0x002D, 0x081D, 0xFFFF }, { 0x0132, 0x0302, 0x0229, 0x110D, 0xFFFF }, { 0x0128, 0x041C, 0x0421, 0x0E0B, 0x0A1F, 0xFFFF }, { 0x0220, 0x0513, 0x0617, 0xFFFF }, { 0x0135, 0x0805, + 0x0327, 0xFFFF }, { 0x0316, 0x051E, 0x0D0E, 0x0423, 0xFFFF }, { 0x0222, 0x0404, 0x070A, 0x0511, 0x0719, 0x0C09, 0x1B0F, 0xFFFF }, { 0x0703, 0x0615, 0x0A07, 0x022B, 0xFFFF }, { 0x012A, 0x0431, 0x0601, 0x0333, 0x012D, 0x091D, 0xFFFF }, { + 0x0230, 0x0314, 0x0036, 0x0608, 0x0425, 0x0037, 0x0329, 0x081B, 0x120D, 0xFFFF }, { 0x0300, 0x0224, 0x0506, 0x0521, 0x0F0B, 0x0B1F, 0xFFFF }, { 0x041A, 0x0613, 0x0717, 0xFFFF }, { 0x0235, 0x0905, 0xFFFF }, { 0x0312, 0x0134, 0x0523, + 0x0427, 0xFFFF }, { 0x0226, 0x090C, 0x002E, 0x0611, 0x0D09, 0x002F, 0xFFFF }, { 0x0715, 0x0B07, 0x0819, 0x032B, 0x1C0F, 0xFFFF }, { 0x0310, 0x0531, 0x0701, 0x0803, 0x022D, 0x0A1D, 0xFFFF }, { 0x0418, 0x012C, 0x0433, 0x0525, 0x0137, 0x091B, + 0x130D, 0xFFFF }, { 0x0232, 0x0402, 0x0621, 0x0429, 0xFFFF }, { 0x0228, 0x051C, 0x0713, 0x100B, 0x0C1F, 0xFFFF }, { 0x0320, 0x0335, 0x0A05, 0x0817, 0xFFFF }, { 0x0623, 0x0527, 0xFFFF }, { 0x0416, 0x061E, 0x0E0E, 0x0711, 0x0E09, 0x012F, + 0xFFFF }, { 0x0322, 0x0504, 0x080A, 0x0919, 0x1D0F, 0xFFFF }, { 0x0631, 0x0903, 0x0815, 0x0C07, 0x042B, 0x032D, 0x0B1D, 0xFFFF }, { 0x022A, 0x0801, 0x0533, 0x0625, 0x0237, 0x0A1B, 0xFFFF }, { 0x0330, 0x0414, 0x0136, 0x0708, 0x0721, 0x0529, + 0x140D, 0xFFFF }, { 0x0400, 0x0324, 0x0606, 0x0038, 0x0039, 0x110B, 0x0D1F, 0xFFFF }, { 0x051A, 0x0813, 0x0B05, 0x0917, 0xFFFF }, { 0x0723, 0x0435, 0x0627, 0xFFFF }, { 0x0412, 0x0234, 0x0F09, 0x022F, 0xFFFF }, { 0x0326, 0x0A0C, 0x012E, + 0x0811, 0x0A19, 0x1E0F, 0xFFFF }, { 0x0731, 0x0A03, 0x0915, 0x0D07, 0x052B, 0xFFFF }, { 0x0410, 0x0901, 0x0633, 0x0725, 0x0337, 0x0B1B, 0x042D, 0x0C1D, 0xFFFF }, { 0x0518, 0x022C, 0x0629, 0x150D, 0xFFFF }, { 0x0332, 0x0502, 0x0821, 0x0139, + 0x120B, 0x0E1F, 0xFFFF }, { 0x0328, 0x061C, 0x0913, 0x0A17, 0xFFFF }, { 0x0420, 0x0535, 0x0C05, 0x0727, 0xFFFF }, { 0x0823, 0x032F, 0xFFFF }, { 0x0516, 0x071E, 0x0F0E, 0x0911, 0x0B19, 0x1009, 0x1F0F, 0xFFFF }, { 0x0422, 0x0604, 0x090A, + 0x0B03, 0x0A15, 0x0E07, 0x062B, 0xFFFF }, { 0x0831, 0x0A01, 0x0733, 0x052D, 0x0D1D, 0xFFFF }, { 0x032A, 0x0825, 0x0437, 0x0729, 0x0C1B, 0x160D, 0xFFFF }, { 0x0430, 0x0514, 0x0236, 0x0808, 0x0921, 0x0239, 0x130B, 0x0F1F, 0xFFFF }, { 0x0500, + 0x0424, 0x0706, 0x0138, 0x0A13, 0x0B17, 0xFFFF }, { 0x061A, 0x0635, 0x0D05, 0xFFFF }, { 0x0923, 0x0827, 0xFFFF }, { 0x0512, 0x0334, 0x003A, 0x0A11, 0x1109, 0x003B, 0x042F, 0xFFFF }, { 0x0426, 0x0B0C, 0x022E, 0x0B15, 0x0F07, 0x0C19, + 0x072B, 0xFFFF }, { 0x0931, 0x0B01, 0x0C03, 0x062D, 0x0E1D, 0xFFFF }, { 0x0510, 0x0833, 0x0925, 0x0537, 0x0D1B, 0x170D, 0xFFFF }, { 0x0618, 0x032C, 0x0A21, 0x0339, 0x0829, 0xFFFF }, { 0x0432, 0x0602, 0x0B13, 0x140B, 0x101F, 0xFFFF }, { + 0x0428, 0x071C, 0x0735, 0x0E05, 0x0C17, 0xFFFF }, { 0x0520, 0x0A23, 0x0927, 0xFFFF }, { 0x0B11, 0x1209, 0x013B, 0x052F, 0xFFFF }, { 0x0616, 0x081E, 0x0D19, 0xFFFF }, { 0x0522, 0x0704, 0x0A0A, 0x0A31, 0x0D03, 0x0C15, 0x1007, 0x082B, 0x072D, + 0x0F1D, 0xFFFF }, { 0x0C01, 0x0933, 0x0A25, 0x0637, 0x0E1B, 0xFFFF }, { 0x042A, 0x0B21, 0x0929, 0x180D, 0xFFFF }, { 0x0530, 0x0614, 0x0336, 0x0908, 0x0439, 0x150B, 0x111F, 0xFFFF }, { 0x0600, 0x0524, 0x0806, 0x0238, 0x0C13, 0x0F05, + 0x0D17, 0xFFFF }, { 0x071A, 0x0B23, 0x0835, 0x0A27, 0xFFFF }, { 0x1309, 0x023B, 0x062F, 0xFFFF }, { 0x0612, 0x0434, 0x013A, 0x0C11, 0x0E19, 0xFFFF }, { 0x0526, 0x0C0C, 0x032E, 0x0B31, 0x0E03, 0x0D15, 0x1107, 0x092B, 0xFFFF }, { 0x0D01, + 0x0A33, 0x0B25, 0x0737, 0x0F1B, 0x082D, 0x101D, 0xFFFF }, { 0x0610, 0x0A29, 0x190D, 0xFFFF }, { 0x0718, 0x042C, 0x0C21, 0x0539, 0x160B, 0x121F, 0xFFFF }, { 0x0532, 0x0702, 0x0D13, 0x0E17, 0xFFFF }, { 0x0528, 0x081C, 0x0935, 0x1005, 0x0B27, + 0xFFFF }, { 0x0620, 0x0C23, 0x033B, 0x072F, 0xFFFF }, { 0x0D11, 0x0F19, 0x1409, 0xFFFF }, { 0x0716, 0x003C, 0x091E, 0x0F03, 0x0E15, 0x1207, 0x0A2B, 0x003D, 0xFFFF }, { 0x0622, 0x0804, 0x0B0A, 0x0C31, 0x0E01, 0x0B33, 0x092D, 0x111D, + 0xFFFF }, { 0x0C25, 0x0837, 0x0B29, 0x101B, 0x1A0D, 0xFFFF }, { 0x052A, 0x0D21, 0x0639, 0x170B, 0x131F, 0xFFFF }, { 0x0630, 0x0714, 0x0436, 0x0A08, 0x0E13, 0x0F17, 0xFFFF }, { 0x0700, 0x0624, 0x0906, 0x0338, 0x0A35, 0x1105, 0xFFFF }, { + 0x081A, 0x0D23, 0x0C27, 0xFFFF }, { 0x0E11, 0x1509, 0x043B, 0x082F, 0xFFFF }, { 0x0712, 0x0534, 0x023A, 0x0F15, 0x1307, 0x1019, 0x0B2B, 0x013D, 0xFFFF }, { 0x0626, 0x0D0C, 0x042E, 0x0D31, 0x0F01, 0x1003, 0x0A2D, 0x121D, 0xFFFF }, { 0x0C33, + 0x0D25, 0x0937, 0x111B, 0x1B0D, 0xFFFF }, { 0x0710, 0x0E21, 0x0739, 0x0C29, 0xFFFF }, { 0x0818, 0x052C, 0x0F13, 0x180B, 0x141F, 0xFFFF }, { 0x0632, 0x0802, 0x0B35, 0x1205, 0x1017, 0xFFFF }, { 0x0628, 0x091C, 0x0E23, 0x0D27, 0xFFFF }, { + 0x0720, 0x0F11, 0x1609, 0x053B, 0x092F, 0xFFFF }, { 0x1119, 0x023D, 0xFFFF }, { 0x0816, 0x013C, 0x0A1E, 0x0E31, 0x1103, 0x1015, 0x1407, 0x0C2B, 0x0B2D, 0x131D, 0xFFFF }, { 0x0722, 0x0904, 0x0C0A, 0x1001, 0x0D33, 0x0E25, 0x0A37, 0x121B, + 0xFFFF }, { 0x0F21, 0x0D29, 0x1C0D, 0xFFFF }, { 0x062A, 0x0839, 0x190B, 0x151F, 0xFFFF }, { 0x0730, 0x0814, 0x0536, 0x0B08, 0x1013, 0x1305, 0x1117, 0xFFFF }, { 0x0800, 0x0724, 0x0A06, 0x0438, 0x0F23, 0x0C35, 0x0E27, 0xFFFF }, { 0x091A, + 0x1709, 0x063B, 0x0A2F, 0xFFFF }, { 0x1011, 0x1219, 0x033D, 0xFFFF }, { 0x0812, 0x0634, 0x033A, 0x0F31, 0x1203, 0x1115, 0x1507, 0x0D2B, 0xFFFF }, { 0x0726, 0x0E0C, 0x052E, 0x1101, 0x0E33, 0x0F25, 0x0B37, 0x131B, 0x0C2D, 0x141D, 0xFFFF }, { + 0x0E29, 0x1D0D, 0xFFFF }, { 0x0810, 0x1021, 0x0939, 0x1A0B, 0x161F, 0xFFFF }, { 0x0918, 0x062C, 0x1113, 0x1217, 0xFFFF }, { 0x0732, 0x0902, 0x0D35, 0x1405, 0x0F27, 0xFFFF }, { 0x0728, 0x0A1C, 0x1023, 0x073B, 0x0B2F, 0xFFFF }, { 0x0820, + 0x1111, 0x1319, 0x1809, 0xFFFF }, { 0x1303, 0x1215, 0x1607, 0x0E2B, 0x043D, 0xFFFF }, { 0x0916, 0x023C, 0x0B1E, 0x1031, 0x1201, 0x0F33, 0x0D2D, 0x151D, 0xFFFF }, { 0x0822, 0x0A04, 0x0D0A, 0x1025, 0x0C37, 0x0F29, 0x141B, 0x1E0D, 0xFFFF }, { + 0x1121, 0x0A39, 0x1B0B, 0x171F, 0xFFFF }, { 0x072A, 0x1213, 0x1317, 0xFFFF }, { 0x0830, 0x0914, 0x0636, 0x0C08, 0x0E35, 0x1505, 0xFFFF }, { 0x0900, 0x0824, 0x0B06, 0x0538, 0x1123, 0x1027, 0xFFFF }, { 0x0A1A, 0x1211, 0x1909, 0x083B, 0x0C2F, + 0xFFFF }, { 0x1315, 0x1707, 0x1419, 0x0F2B, 0x053D, 0xFFFF }, { 0x0912, 0x0734, 0x043A, 0x1131, 0x1301, 0x1403, 0x0E2D, 0x161D, 0xFFFF }, { 0x0826, 0x0F0C, 0x062E, 0x1033, 0x1125, 0x0D37, 0x151B, 0x1F0D, 0xFFFF }, { 0x1221, 0x0B39, 0x1029, + 0xFFFF }, { 0x0910, 0x1313, 0x1C0B, 0x181F, 0xFFFF }, { 0x0A18, 0x072C, 0x0F35, 0x1605, 0x1417, 0xFFFF }, { 0x0832, 0x0A02, 0x1223, 0x1127, 0xFFFF }, { 0x0828, 0x0B1C, 0x1311, 0x1A09, 0x093B, 0x0D2F, 0xFFFF }, { 0x0920, 0x1519, 0x063D, + 0xFFFF }, { 0x1231, 0x1503, 0x1415, 0x1807, 0x102B, 0x0F2D, 0x171D, 0xFFFF }, { 0x0A16, 0x033C, 0x0C1E, 0x1401, 0x1133, 0x1225, 0x0E37, 0x161B, 0xFFFF }, { 0x0922, 0x0B04, 0x0E0A, 0x1321, 0x1129, 0xFFFF }, { 0x0C39, 0x1D0B, 0x191F, 0xFFFF + }, { 0x082A, 0x1413, 0x1705, 0x1517, 0xFFFF }, { 0x0930, 0x0A14, 0x0736, 0x0D08, 0x1323, 0x1035, 0x1227, 0xFFFF }, { 0x0A00, 0x0924, 0x0C06, 0x0638, 0x1B09, 0x0A3B, 0x0E2F, 0xFFFF }, { 0x0B1A, 0x1411, 0x1619, 0x073D, 0xFFFF }, { 0x1331, + 0x1603, 0x1515, 0x1907, 0x112B, 0xFFFF }, { 0x0A12, 0x0834, 0x053A, 0x1501, 0x1233, 0x1325, 0x0F37, 0x171B, 0x102D, 0x181D, 0xFFFF }, { 0x0926, 0x072E, 0x1229, 0xFFFF }, { 0x1421, 0x0D39, 0x1E0B, 0x1A1F, 0xFFFF }, { 0x0A10, 0x1513, + 0x1617, 0xFFFF }, { 0x0B18, 0x082C, 0x1135, 0x1805, 0x1327, 0xFFFF }, { 0x0932, 0x0B02, 0x1423, 0x0B3B, 0x0F2F, 0xFFFF }, { 0x0928, 0x0C1C, 0x1511, 0x1719, 0x1C09, 0xFFFF }, { 0x0A20, 0x1703, 0x1615, 0x1A07, 0x122B, 0x083D, 0xFFFF }, { + 0x1431, 0x1601, 0x1333, 0x112D, 0x191D, 0xFFFF }, { 0x0B16, 0x043C, 0x0D1E, 0x1425, 0x1037, 0x1329, 0x181B, 0xFFFF }, { 0x0A22, 0x0C04, 0x0F0A, 0x1521, 0x0E39, 0x1F0B, 0x1B1F, 0xFFFF }, { 0x1613, 0x1717, 0xFFFF }, { 0x092A, 0x1235, 0x1905, + 0xFFFF }, { 0x0A30, 0x0B14, 0x0836, 0x0E08, 0x1523, 0x1427, 0xFFFF }, { 0x0B00, 0x0A24, 0x0D06, 0x0738, 0x1611, 0x1D09, 0x0C3B, 0x102F, 0xFFFF }, { 0x0C1A, 0x1715, 0x1B07, 0x1819, 0x132B, 0x093D, 0xFFFF }, { 0x1531, 0x1701, 0x1803, 0x122D, + 0x1A1D, 0xFFFF }, { 0x0B12, 0x0934, 0x063A, 0x1433, 0x1525, 0x1137, 0x191B, 0xFFFF }, { 0x0A26, 0x003E, 0x082E, 0x1621, 0x0F39, 0x1429, 0x003F, 0xFFFF }, { 0x1713, 0x1C1F, 0xFFFF }, { 0x0B10, 0x1335, 0x1A05, 0x1817, 0xFFFF }, { 0x0C18, + 0x092C, 0x1623, 0x1527, 0xFFFF }, { 0x0A32, 0x0C02, 0x1711, 0x1E09, 0x0D3B, 0x112F, 0xFFFF }, { 0x0A28, 0x0D1C, 0x1919, 0x0A3D, 0xFFFF }, { 0x0B20, 0x1631, 0x1903, 0x1815, 0x1C07, 0x142B, 0x132D, 0x1B1D, 0xFFFF }, { 0x1801, 0x1533, 0x1625, + 0x1237, 0x1A1B, 0xFFFF }, { 0x0C16, 0x053C, 0x0E1E, 0x1721, 0x1529, 0x013F, 0xFFFF }, { 0x0B22, 0x0D04, 0x1039, 0x1D1F, 0xFFFF }, { 0x1813, 0x1B05, 0x1917, 0xFFFF }, { 0x0A2A, 0x1723, 0x1435, 0x1627, 0xFFFF }, { 0x0B30, 0x0C14, 0x0936, + 0x0F08, 0x1F09, 0x0E3B, 0x122F, 0xFFFF }, { 0x0C00, 0x0B24, 0x0E06, 0x0838, 0x1811, 0x1A19, 0x0B3D, 0xFFFF }, { 0x0D1A, 0x1731, 0x1A03, 0x1915, 0x1D07, 0x152B, 0xFFFF }, { 0x1901, 0x1633, 0x1725, 0x1337, 0x1B1B, 0x142D, 0x1C1D, 0xFFFF }, { + 0x0C12, 0x0A34, 0x073A, 0x1629, 0x023F, 0xFFFF }, { 0x0B26, 0x013E, 0x092E, 0x1821, 0x1139, 0x1E1F, 0xFFFF }, { 0x1913, 0x1A17, 0xFFFF }, { 0x0C10, 0x1535, 0x1C05, 0x1727, 0xFFFF }, { 0x0D18, 0x0A2C, 0x1823, 0x0F3B, 0x132F, 0xFFFF }, { + 0x0B32, 0x0D02, 0x1911, 0x1B19, 0xFFFF }, { 0x0B28, 0x0E1C, 0x1B03, 0x1A15, 0x1E07, 0x162B, 0x0C3D, 0xFFFF }, { 0x0C20, 0x1831, 0x1A01, 0x1733, 0x152D, 0x1D1D, 0xFFFF }, { 0x1825, 0x1437, 0x1729, 0x1C1B, 0x033F, 0xFFFF }, { 0x0D16, 0x063C, + 0x0F1E, 0x1921, 0x1239, 0x1F1F, 0xFFFF }, { 0x0C22, 0x0E04, 0x1A13, 0x1B17, 0xFFFF }, { 0x1635, 0x1D05, 0xFFFF }, { 0x0B2A, 0x1923, 0x1827, 0xFFFF }, { 0x0C30, 0x0D14, 0x0A36, 0x1A11, 0x103B, 0x142F, 0xFFFF }, { 0x0D00, 0x0C24, 0x0F06, + 0x0938, 0x1B15, 0x1F07, 0x1C19, 0x172B, 0x0D3D, 0xFFFF }, { 0x0E1A, 0x1931, 0x1B01, 0x1C03, 0x162D, 0x1E1D, 0xFFFF }, { 0x1833, 0x1925, 0x1537, 0x1D1B, 0xFFFF }, { 0x0D12, 0x0B34, 0x083A, 0x1A21, 0x1339, 0x1829, 0x043F, 0xFFFF }, { 0x0C26, + 0x023E, 0x0A2E, 0x1B13, 0xFFFF }, { 0x1735, 0x1E05, 0x1C17, 0xFFFF }, { 0x0D10, 0x1A23, 0x1927, 0xFFFF }, { 0x0E18, 0x0B2C, 0x1B11, 0x113B, 0x152F, 0xFFFF }, { 0x0C32, 0x0E02, 0x1D19, 0x0E3D, 0xFFFF }, { 0x0C28, 0x0F1C, 0x1A31, 0x1D03, + 0x1C15, 0x182B, 0x172D, 0x1F1D, 0xFFFF }, { 0x0D20, 0x1C01, 0x1933, 0x1A25, 0x1637, 0x1E1B, 0xFFFF }, { 0x1B21, 0x1929, 0x053F, 0xFFFF }, { 0x0E16, 0x073C, 0x1439, 0xFFFF }, { 0x0D22, 0x0F04, 0x1C13, 0x1F05, 0x1D17, 0xFFFF }, { 0x1B23, + 0x1835, 0x1A27, 0xFFFF }, { 0x0C2A, 0x123B, 0x162F, 0xFFFF }, { 0x0D30, 0x0E14, 0x0B36, 0x1C11, 0x1E19, 0x0F3D, 0xFFFF }, { 0x0E00, 0x0D24, 0x0A38, 0x1B31, 0x1E03, 0x1D15, 0x192B, 0xFFFF }, { 0x0F1A, 0x1D01, 0x1A33, 0x1B25, 0x1737, 0x1F1B, + 0x182D, 0xFFFF }, { 0x1A29, 0x063F, 0xFFFF }, { 0x0E12, 0x0C34, 0x093A, 0x1C21, 0x1539, 0xFFFF }, { 0x0D26, 0x033E, 0x0B2E, 0x1D13, 0x1E17, 0xFFFF }, { 0x1935, 0x1B27, 0xFFFF }, { 0x0E10, 0x1C23, 0x133B, 0x172F, 0xFFFF }, { 0x0F18, + 0x0C2C, 0x1D11, 0x1F19, 0xFFFF }, { 0x0D32, 0x0F02, 0x1F03, 0x1E15, 0x1A2B, 0x103D, 0xFFFF }, { 0x0D28, 0x1C31, 0x1E01, 0x1B33, 0x192D, 0xFFFF }, { 0x0E20, 0x1C25, 0x1837, 0x1B29, 0x073F, 0xFFFF }, { 0x1D21, 0x1639, 0xFFFF }, { 0x0F16, + 0x083C, 0x1E13, 0x1F17, 0xFFFF }, { 0x0E22, 0x1A35, 0xFFFF }, { 0x1D23, 0x1C27, 0xFFFF }, { 0x0D2A, 0x1E11, 0x143B, 0x182F, 0xFFFF }, { 0x0E30, 0x0F14, 0x0C36, 0x1F15, 0x1B2B, 0x113D, 0xFFFF }, { 0x0F00, 0x0E24, 0x0B38, 0x1D31, 0x1F01, + 0x1A2D, 0xFFFF }, { 0x1C33, 0x1D25, 0x1937, 0xFFFF }, { 0x1E21, 0x1739, 0x1C29, 0x083F, 0xFFFF }, { 0x0F12, 0x0D34, 0x0A3A, 0x1F13, 0xFFFF }, { 0x0E26, 0x043E, 0x0C2E, 0x1B35, 0xFFFF }, { 0x1E23, 0x1D27, 0xFFFF }, { 0x0F10, 0x1F11, 0x153B, 0x192F, 0xFFFF }, { 0x0D2C, 0x123D, 0xFFFF }, + }; + + static uint32_t etc1_decode_value(uint32_t diff, uint32_t inten, uint32_t selector, uint32_t packed_c) + { + const uint32_t limit = diff ? 32 : 16; + BASISU_NOTE_UNUSED(limit); + assert((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < limit)); + int c; + if (diff) + c = (packed_c >> 2) | (packed_c << 3); + else + c = packed_c | (packed_c << 4); + c += g_etc1_inten_tables[inten][selector]; + c = clamp<int>(c, 0, 255); + return c; + } + + void pack_etc1_solid_color_init() + { + for (uint32_t diff = 0; diff < 2; diff++) + { + const uint32_t limit = diff ? 32 : 16; + + for (uint32_t inten = 0; inten < 8; inten++) + { + for (uint32_t selector = 0; selector < 4; selector++) + { + const uint32_t inverse_table_index = diff + (inten << 1) + (selector << 4); + for (uint32_t color = 0; color < 256; color++) + { + uint32_t best_error = UINT32_MAX, best_packed_c = 0; + for (uint32_t packed_c = 0; packed_c < limit; packed_c++) + { + int v = etc1_decode_value(diff, inten, selector, packed_c); + uint32_t err = (uint32_t)labs(v - static_cast<int>(color)); + if (err < best_error) + { + best_error = err; + best_packed_c = packed_c; + if (!best_error) + break; + } + } + assert(best_error <= 255); + g_etc1_inverse_lookup[inverse_table_index][color] = static_cast<uint16_t>(best_packed_c | (best_error << 8)); + } + } + } + } + } + + // Packs solid color blocks efficiently using a set of small precomputed tables. + // For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time. + uint64_t pack_etc1_block_solid_color(etc_block& block, const uint8_t* pColor) + { + assert(g_etc1_inverse_lookup[0][255]); + + static uint32_t s_next_comp[4] = { 1, 2, 0, 1 }; + + uint32_t best_error = UINT32_MAX, best_i = 0; + int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0; + + // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations that allow that 8-bit value to be encoded with no error. + for (uint32_t i = 0; i < 3; i++) + { + const uint32_t c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]]; + + const int delta_range = 1; + for (int delta = -delta_range; delta <= delta_range; delta++) + { + const int c_plus_delta = clamp<int>(pColor[i] + delta, 0, 255); + + const uint16_t* pTable; + if (!c_plus_delta) + pTable = g_etc1_color8_to_etc_block_config_0_255[0]; + else if (c_plus_delta == 255) + pTable = g_etc1_color8_to_etc_block_config_0_255[1]; + else + pTable = g_etc1_color8_to_etc_block_config_1_to_254[c_plus_delta - 1]; + + do + { + const uint32_t x = *pTable++; + +#ifdef _DEBUG + const uint32_t diff = x & 1; + const uint32_t inten = (x >> 1) & 7; + const uint32_t selector = (x >> 4) & 3; + const uint32_t p0 = (x >> 8) & 255; + assert(etc1_decode_value(diff, inten, selector, p0) == (uint32_t)c_plus_delta); +#endif + + const uint16_t* pInverse_table = g_etc1_inverse_lookup[x & 0xFF]; + uint16_t p1 = pInverse_table[c1]; + uint16_t p2 = pInverse_table[c2]; + const uint32_t trial_error = square(c_plus_delta - pColor[i]) + square(p1 >> 8) + square(p2 >> 8); + if (trial_error < best_error) + { + best_error = trial_error; + best_x = x; + best_packed_c1 = p1 & 0xFF; + best_packed_c2 = p2 & 0xFF; + best_i = i; + if (!best_error) + goto found_perfect_match; + } + } while (*pTable != 0xFFFF); + } + } + found_perfect_match: + + const uint32_t diff = best_x & 1; + const uint32_t inten = (best_x >> 1) & 7; + + block.m_bytes[3] = static_cast<uint8_t>(((inten | (inten << 3)) << 2) | (diff << 1)); + + const uint32_t etc1_selector = g_selector_index_to_etc1[(best_x >> 4) & 3]; + *reinterpret_cast<uint16_t*>(&block.m_bytes[4]) = (etc1_selector & 2) ? 0xFFFF : 0; + *reinterpret_cast<uint16_t*>(&block.m_bytes[6]) = (etc1_selector & 1) ? 0xFFFF : 0; + + const uint32_t best_packed_c0 = (best_x >> 8) & 255; + if (diff) + { + block.m_bytes[best_i] = static_cast<uint8_t>(best_packed_c0 << 3); + block.m_bytes[s_next_comp[best_i]] = static_cast<uint8_t>(best_packed_c1 << 3); + block.m_bytes[s_next_comp[best_i + 1]] = static_cast<uint8_t>(best_packed_c2 << 3); + } + else + { + block.m_bytes[best_i] = static_cast<uint8_t>(best_packed_c0 | (best_packed_c0 << 4)); + block.m_bytes[s_next_comp[best_i]] = static_cast<uint8_t>(best_packed_c1 | (best_packed_c1 << 4)); + block.m_bytes[s_next_comp[best_i + 1]] = static_cast<uint8_t>(best_packed_c2 | (best_packed_c2 << 4)); + } + + return best_error; + } + + const uint32_t BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE = 165; + + static const struct { uint8_t m_v[4]; } g_cluster_fit_order_tab[BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE] = + { + { { 0, 0, 0, 8 } },{ { 0, 5, 2, 1 } },{ { 0, 6, 1, 1 } },{ { 0, 7, 0, 1 } },{ { 0, 7, 1, 0 } }, + { { 0, 0, 8, 0 } },{ { 0, 0, 3, 5 } },{ { 0, 1, 7, 0 } },{ { 0, 0, 4, 4 } },{ { 0, 0, 2, 6 } }, + { { 0, 0, 7, 1 } },{ { 0, 0, 1, 7 } },{ { 0, 0, 5, 3 } },{ { 1, 6, 0, 1 } },{ { 0, 0, 6, 2 } }, + { { 0, 2, 6, 0 } },{ { 2, 4, 2, 0 } },{ { 0, 3, 5, 0 } },{ { 3, 3, 1, 1 } },{ { 4, 2, 0, 2 } }, + { { 1, 5, 2, 0 } },{ { 0, 5, 3, 0 } },{ { 0, 6, 2, 0 } },{ { 2, 4, 1, 1 } },{ { 5, 1, 0, 2 } }, + { { 6, 1, 1, 0 } },{ { 3, 3, 0, 2 } },{ { 6, 0, 0, 2 } },{ { 0, 8, 0, 0 } },{ { 6, 1, 0, 1 } }, + { { 0, 1, 6, 1 } },{ { 1, 6, 1, 0 } },{ { 4, 1, 3, 0 } },{ { 0, 2, 5, 1 } },{ { 5, 0, 3, 0 } }, + { { 5, 3, 0, 0 } },{ { 0, 1, 5, 2 } },{ { 0, 3, 4, 1 } },{ { 2, 5, 1, 0 } },{ { 1, 7, 0, 0 } }, + { { 0, 1, 4, 3 } },{ { 6, 0, 2, 0 } },{ { 0, 4, 4, 0 } },{ { 2, 6, 0, 0 } },{ { 0, 2, 4, 2 } }, + { { 0, 5, 1, 2 } },{ { 0, 6, 0, 2 } },{ { 3, 5, 0, 0 } },{ { 0, 4, 3, 1 } },{ { 3, 4, 1, 0 } }, + { { 4, 3, 1, 0 } },{ { 1, 5, 0, 2 } },{ { 0, 3, 3, 2 } },{ { 1, 4, 1, 2 } },{ { 0, 4, 2, 2 } }, + { { 2, 3, 3, 0 } },{ { 4, 4, 0, 0 } },{ { 1, 2, 4, 1 } },{ { 0, 5, 0, 3 } },{ { 0, 1, 3, 4 } }, + { { 1, 5, 1, 1 } },{ { 1, 4, 2, 1 } },{ { 1, 3, 2, 2 } },{ { 5, 2, 1, 0 } },{ { 1, 3, 3, 1 } }, + { { 0, 1, 2, 5 } },{ { 1, 1, 5, 1 } },{ { 0, 3, 2, 3 } },{ { 2, 5, 0, 1 } },{ { 3, 2, 2, 1 } }, + { { 2, 3, 0, 3 } },{ { 1, 4, 3, 0 } },{ { 2, 2, 1, 3 } },{ { 6, 2, 0, 0 } },{ { 1, 0, 6, 1 } }, + { { 3, 3, 2, 0 } },{ { 7, 1, 0, 0 } },{ { 3, 1, 4, 0 } },{ { 0, 2, 3, 3 } },{ { 0, 4, 1, 3 } }, + { { 0, 4, 0, 4 } },{ { 0, 1, 0, 7 } },{ { 2, 0, 5, 1 } },{ { 2, 0, 4, 2 } },{ { 3, 0, 2, 3 } }, + { { 2, 2, 4, 0 } },{ { 2, 2, 3, 1 } },{ { 4, 0, 3, 1 } },{ { 3, 2, 3, 0 } },{ { 2, 3, 2, 1 } }, + { { 1, 3, 4, 0 } },{ { 7, 0, 1, 0 } },{ { 3, 0, 4, 1 } },{ { 1, 0, 5, 2 } },{ { 8, 0, 0, 0 } }, + { { 3, 0, 1, 4 } },{ { 4, 1, 1, 2 } },{ { 4, 0, 2, 2 } },{ { 1, 2, 5, 0 } },{ { 4, 2, 1, 1 } }, + { { 3, 4, 0, 1 } },{ { 2, 0, 3, 3 } },{ { 5, 0, 1, 2 } },{ { 5, 0, 0, 3 } },{ { 2, 4, 0, 2 } }, + { { 2, 1, 4, 1 } },{ { 4, 0, 1, 3 } },{ { 2, 1, 5, 0 } },{ { 4, 2, 2, 0 } },{ { 4, 0, 4, 0 } }, + { { 1, 0, 4, 3 } },{ { 1, 4, 0, 3 } },{ { 3, 0, 3, 2 } },{ { 4, 3, 0, 1 } },{ { 0, 1, 1, 6 } }, + { { 1, 3, 1, 3 } },{ { 0, 2, 2, 4 } },{ { 2, 0, 2, 4 } },{ { 5, 1, 1, 1 } },{ { 3, 0, 5, 0 } }, + { { 2, 3, 1, 2 } },{ { 3, 0, 0, 5 } },{ { 0, 3, 1, 4 } },{ { 5, 0, 2, 1 } },{ { 2, 1, 3, 2 } }, + { { 2, 0, 6, 0 } },{ { 3, 1, 3, 1 } },{ { 5, 1, 2, 0 } },{ { 1, 0, 3, 4 } },{ { 1, 1, 6, 0 } }, + { { 4, 0, 0, 4 } },{ { 2, 0, 1, 5 } },{ { 0, 3, 0, 5 } },{ { 1, 3, 0, 4 } },{ { 4, 1, 2, 1 } }, + { { 1, 2, 3, 2 } },{ { 3, 1, 0, 4 } },{ { 5, 2, 0, 1 } },{ { 1, 2, 2, 3 } },{ { 3, 2, 1, 2 } }, + { { 2, 2, 2, 2 } },{ { 6, 0, 1, 1 } },{ { 1, 2, 1, 4 } },{ { 1, 1, 4, 2 } },{ { 3, 2, 0, 3 } }, + { { 1, 2, 0, 5 } },{ { 1, 0, 7, 0 } },{ { 3, 1, 2, 2 } },{ { 1, 0, 2, 5 } },{ { 2, 0, 0, 6 } }, + { { 2, 1, 1, 4 } },{ { 2, 2, 0, 4 } },{ { 1, 1, 3, 3 } },{ { 7, 0, 0, 1 } },{ { 1, 0, 0, 7 } }, + { { 2, 1, 2, 3 } },{ { 4, 1, 0, 3 } },{ { 3, 1, 1, 3 } },{ { 1, 1, 2, 4 } },{ { 2, 1, 0, 5 } }, + { { 1, 0, 1, 6 } },{ { 0, 2, 1, 5 } },{ { 0, 2, 0, 6 } },{ { 1, 1, 1, 5 } },{ { 1, 1, 0, 6 } } + }; + + const int g_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = + { + { -8, -2, 2, 8 }, { -17, -5, 5, 17 }, { -29, -9, 9, 29 }, { -42, -13, 13, 42 }, + { -60, -18, 18, 60 }, { -80, -24, 24, 80 }, { -106, -33, 33, 106 }, { -183, -47, 47, 183 } + }; + + const uint8_t g_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 }; + const uint8_t g_selector_index_to_etc1[cETC1SelectorValues] = { 3, 2, 0, 1 }; + + // [flip][subblock][pixel_index] + const etc_coord2 g_etc1_pixel_coords[2][2][8] = + { + { + { + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 } + }, + { + { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, + { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 } + } + }, + { + { + { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, + { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 } + }, + { + { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 }, + { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 } + }, + } + }; + + // [flip][subblock][pixel_index] + const uint32_t g_etc1_pixel_indices[2][2][8] = + { + { + { + 0 + 4 * 0, 0 + 4 * 1, 0 + 4 * 2, 0 + 4 * 3, + 1 + 4 * 0, 1 + 4 * 1, 1 + 4 * 2, 1 + 4 * 3 + }, + { + 2 + 4 * 0, 2 + 4 * 1, 2 + 4 * 2, 2 + 4 * 3, + 3 + 4 * 0, 3 + 4 * 1, 3 + 4 * 2, 3 + 4 * 3 + } + }, + { + { + 0 + 4 * 0, 1 + 4 * 0, 2 + 4 * 0, 3 + 4 * 0, + 0 + 4 * 1, 1 + 4 * 1, 2 + 4 * 1, 3 + 4 * 1 + }, + { + 0 + 4 * 2, 1 + 4 * 2, 2 + 4 * 2, 3 + 4 * 2, + 0 + 4 * 3, 1 + 4 * 3, 2 + 4 * 3, 3 + 4 * 3 + }, + } + }; + + uint16_t etc_block::pack_color5(const color_rgba& color, bool scaled, uint32_t bias) + { + return pack_color5(color.r, color.g, color.b, scaled, bias); + } + + uint16_t etc_block::pack_color5(uint32_t r, uint32_t g, uint32_t b, bool scaled, uint32_t bias) + { + if (scaled) + { + r = (r * 31U + bias) / 255U; + g = (g * 31U + bias) / 255U; + b = (b * 31U + bias) / 255U; + } + + r = minimum(r, 31U); + g = minimum(g, 31U); + b = minimum(b, 31U); + + return static_cast<uint16_t>(b | (g << 5U) | (r << 10U)); + } + + color_rgba etc_block::unpack_color5(uint16_t packed_color5, bool scaled, uint32_t alpha) + { + uint32_t b = packed_color5 & 31U; + uint32_t g = (packed_color5 >> 5U) & 31U; + uint32_t r = (packed_color5 >> 10U) & 31U; + + if (scaled) + { + b = (b << 3U) | (b >> 2U); + g = (g << 3U) | (g >> 2U); + r = (r << 3U) | (r >> 2U); + } + + return color_rgba(cNoClamp, r, g, b, minimum(alpha, 255U)); + } + + void etc_block::unpack_color5(color_rgba& result, uint16_t packed_color5, bool scaled) + { + result = unpack_color5(packed_color5, scaled, 255); + } + + void etc_block::unpack_color5(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color5, bool scaled) + { + color_rgba c(unpack_color5(packed_color5, scaled, 0)); + r = c.r; + g = c.g; + b = c.b; + } + + bool etc_block::unpack_color5(color_rgba& result, uint16_t packed_color5, uint16_t packed_delta3, bool scaled, uint32_t alpha) + { + color_rgba_i16 dc(unpack_delta3(packed_delta3)); + + int b = (packed_color5 & 31U) + dc.b; + int g = ((packed_color5 >> 5U) & 31U) + dc.g; + int r = ((packed_color5 >> 10U) & 31U) + dc.r; + + bool success = true; + if (static_cast<uint32_t>(r | g | b) > 31U) + { + success = false; + r = clamp<int>(r, 0, 31); + g = clamp<int>(g, 0, 31); + b = clamp<int>(b, 0, 31); + } + + if (scaled) + { + b = (b << 3U) | (b >> 2U); + g = (g << 3U) | (g >> 2U); + r = (r << 3U) | (r >> 2U); + } + + result.set_noclamp_rgba(r, g, b, minimum(alpha, 255U)); + return success; + } + + bool etc_block::unpack_color5(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color5, uint16_t packed_delta3, bool scaled, uint32_t alpha) + { + color_rgba result; + const bool success = unpack_color5(result, packed_color5, packed_delta3, scaled, alpha); + r = result.r; + g = result.g; + b = result.b; + return success; + } + + uint16_t etc_block::pack_delta3(const color_rgba_i16& color) + { + return pack_delta3(color.r, color.g, color.b); + } + + uint16_t etc_block::pack_delta3(int r, int g, int b) + { + assert((r >= cETC1ColorDeltaMin) && (r <= cETC1ColorDeltaMax)); + assert((g >= cETC1ColorDeltaMin) && (g <= cETC1ColorDeltaMax)); + assert((b >= cETC1ColorDeltaMin) && (b <= cETC1ColorDeltaMax)); + if (r < 0) r += 8; + if (g < 0) g += 8; + if (b < 0) b += 8; + return static_cast<uint16_t>(b | (g << 3) | (r << 6)); + } + + color_rgba_i16 etc_block::unpack_delta3(uint16_t packed_delta3) + { + int r = (packed_delta3 >> 6) & 7; + int g = (packed_delta3 >> 3) & 7; + int b = packed_delta3 & 7; + if (r >= 4) r -= 8; + if (g >= 4) g -= 8; + if (b >= 4) b -= 8; + return color_rgba_i16(r, g, b, 255); + } + + void etc_block::unpack_delta3(int& r, int& g, int& b, uint16_t packed_delta3) + { + r = (packed_delta3 >> 6) & 7; + g = (packed_delta3 >> 3) & 7; + b = packed_delta3 & 7; + if (r >= 4) r -= 8; + if (g >= 4) g -= 8; + if (b >= 4) b -= 8; + } + + uint16_t etc_block::pack_color4(const color_rgba& color, bool scaled, uint32_t bias) + { + return pack_color4(color.r, color.g, color.b, scaled, bias); + } + + uint16_t etc_block::pack_color4(uint32_t r, uint32_t g, uint32_t b, bool scaled, uint32_t bias) + { + if (scaled) + { + r = (r * 15U + bias) / 255U; + g = (g * 15U + bias) / 255U; + b = (b * 15U + bias) / 255U; + } + + r = minimum(r, 15U); + g = minimum(g, 15U); + b = minimum(b, 15U); + + return static_cast<uint16_t>(b | (g << 4U) | (r << 8U)); + } + + color_rgba etc_block::unpack_color4(uint16_t packed_color4, bool scaled, uint32_t alpha) + { + uint32_t b = packed_color4 & 15U; + uint32_t g = (packed_color4 >> 4U) & 15U; + uint32_t r = (packed_color4 >> 8U) & 15U; + + if (scaled) + { + b = (b << 4U) | b; + g = (g << 4U) | g; + r = (r << 4U) | r; + } + + return color_rgba(cNoClamp, r, g, b, minimum(alpha, 255U)); + } + + void etc_block::unpack_color4(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color4, bool scaled) + { + color_rgba c(unpack_color4(packed_color4, scaled, 0)); + r = c.r; + g = c.g; + b = c.b; + } + + void etc_block::get_diff_subblock_colors(color_rgba* pDst, uint16_t packed_color5, uint32_t table_idx) + { + assert(table_idx < cETC1IntenModifierValues); + const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; + + uint32_t r, g, b; + unpack_color5(r, g, b, packed_color5, true); + + const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b); + + const int y0 = pInten_modifer_table[0]; + pDst[0].set(ir + y0, ig + y0, ib + y0, 255); + + const int y1 = pInten_modifer_table[1]; + pDst[1].set(ir + y1, ig + y1, ib + y1, 255); + + const int y2 = pInten_modifer_table[2]; + pDst[2].set(ir + y2, ig + y2, ib + y2, 255); + + const int y3 = pInten_modifer_table[3]; + pDst[3].set(ir + y3, ig + y3, ib + y3, 255); + } + + bool etc_block::get_diff_subblock_colors(color_rgba* pDst, uint16_t packed_color5, uint16_t packed_delta3, uint32_t table_idx) + { + assert(table_idx < cETC1IntenModifierValues); + const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; + + uint32_t r, g, b; + bool success = unpack_color5(r, g, b, packed_color5, packed_delta3, true); + + const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b); + + const int y0 = pInten_modifer_table[0]; + pDst[0].set(ir + y0, ig + y0, ib + y0, 255); + + const int y1 = pInten_modifer_table[1]; + pDst[1].set(ir + y1, ig + y1, ib + y1, 255); + + const int y2 = pInten_modifer_table[2]; + pDst[2].set(ir + y2, ig + y2, ib + y2, 255); + + const int y3 = pInten_modifer_table[3]; + pDst[3].set(ir + y3, ig + y3, ib + y3, 255); + + return success; + } + + void etc_block::get_abs_subblock_colors(color_rgba* pDst, uint16_t packed_color4, uint32_t table_idx) + { + assert(table_idx < cETC1IntenModifierValues); + const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0]; + + uint32_t r, g, b; + unpack_color4(r, g, b, packed_color4, true); + + const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b); + + const int y0 = pInten_modifer_table[0]; + pDst[0].set(ir + y0, ig + y0, ib + y0, 255); + + const int y1 = pInten_modifer_table[1]; + pDst[1].set(ir + y1, ig + y1, ib + y1, 255); + + const int y2 = pInten_modifer_table[2]; + pDst[2].set(ir + y2, ig + y2, ib + y2, 255); + + const int y3 = pInten_modifer_table[3]; + pDst[3].set(ir + y3, ig + y3, ib + y3, 255); + } + + bool unpack_etc1(const etc_block& block, color_rgba *pDst, bool preserve_alpha) + { + const bool diff_flag = block.get_diff_bit(); + const bool flip_flag = block.get_flip_bit(); + const uint32_t table_index0 = block.get_inten_table(0); + const uint32_t table_index1 = block.get_inten_table(1); + + color_rgba subblock_colors0[4]; + color_rgba subblock_colors1[4]; + + if (diff_flag) + { + const uint16_t base_color5 = block.get_base5_color(); + const uint16_t delta_color3 = block.get_delta3_color(); + etc_block::get_diff_subblock_colors(subblock_colors0, base_color5, table_index0); + + if (!etc_block::get_diff_subblock_colors(subblock_colors1, base_color5, delta_color3, table_index1)) + return false; + } + else + { + const uint16_t base_color4_0 = block.get_base4_color(0); + etc_block::get_abs_subblock_colors(subblock_colors0, base_color4_0, table_index0); + + const uint16_t base_color4_1 = block.get_base4_color(1); + etc_block::get_abs_subblock_colors(subblock_colors1, base_color4_1, table_index1); + } + + if (preserve_alpha) + { + if (flip_flag) + { + for (uint32_t y = 0; y < 2; y++) + { + pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]); + pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]); + pDst[2].set_rgb(subblock_colors0[block.get_selector(2, y)]); + pDst[3].set_rgb(subblock_colors0[block.get_selector(3, y)]); + pDst += 4; + } + + for (uint32_t y = 2; y < 4; y++) + { + pDst[0].set_rgb(subblock_colors1[block.get_selector(0, y)]); + pDst[1].set_rgb(subblock_colors1[block.get_selector(1, y)]); + pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]); + pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]); + pDst += 4; + } + } + else + { + for (uint32_t y = 0; y < 4; y++) + { + pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]); + pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]); + pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]); + pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]); + pDst += 4; + } + } + } + else + { + if (flip_flag) + { + // 0000 + // 0000 + // 1111 + // 1111 + for (uint32_t y = 0; y < 2; y++) + { + pDst[0] = subblock_colors0[block.get_selector(0, y)]; + pDst[1] = subblock_colors0[block.get_selector(1, y)]; + pDst[2] = subblock_colors0[block.get_selector(2, y)]; + pDst[3] = subblock_colors0[block.get_selector(3, y)]; + pDst += 4; + } + + for (uint32_t y = 2; y < 4; y++) + { + pDst[0] = subblock_colors1[block.get_selector(0, y)]; + pDst[1] = subblock_colors1[block.get_selector(1, y)]; + pDst[2] = subblock_colors1[block.get_selector(2, y)]; + pDst[3] = subblock_colors1[block.get_selector(3, y)]; + pDst += 4; + } + } + else + { + // 0011 + // 0011 + // 0011 + // 0011 + for (uint32_t y = 0; y < 4; y++) + { + pDst[0] = subblock_colors0[block.get_selector(0, y)]; + pDst[1] = subblock_colors0[block.get_selector(1, y)]; + pDst[2] = subblock_colors1[block.get_selector(2, y)]; + pDst[3] = subblock_colors1[block.get_selector(3, y)]; + pDst += 4; + } + } + } + + return true; + } + + inline int extend_6_to_8(uint32_t n) + { + return (n << 2) | (n >> 4); + } + + inline int extend_7_to_8(uint32_t n) + { + return (n << 1) | (n >> 6); + } + + inline int extend_4_to_8(uint32_t n) + { + return (n << 4) | n; + } + + uint64_t etc_block::evaluate_etc1_error(const color_rgba* pBlock_pixels, bool perceptual, int subblock_index) const + { + color_rgba unpacked_block[16]; + + unpack_etc1(*this, unpacked_block); + + uint64_t total_error = 0; + + if (subblock_index < 0) + { + for (uint32_t i = 0; i < 16; i++) + total_error += color_distance(perceptual, pBlock_pixels[i], unpacked_block[i], false); + } + else + { + const bool flip_bit = get_flip_bit(); + + for (uint32_t i = 0; i < 8; i++) + { + const uint32_t idx = g_etc1_pixel_indices[flip_bit][subblock_index][i]; + + total_error += color_distance(perceptual, pBlock_pixels[idx], unpacked_block[idx], false); + } + } + + return total_error; + } + + void etc_block::get_subblock_pixels(color_rgba* pPixels, int subblock_index) const + { + if (subblock_index < 0) + unpack_etc1(*this, pPixels); + else + { + color_rgba unpacked_block[16]; + + unpack_etc1(*this, unpacked_block); + + const bool flip_bit = get_flip_bit(); + + for (uint32_t i = 0; i < 8; i++) + { + const uint32_t idx = g_etc1_pixel_indices[flip_bit][subblock_index][i]; + + pPixels[i] = unpacked_block[idx]; + } + } + } + + bool etc1_optimizer::compute() + { + assert(m_pResult->m_pSelectors); + + if (m_pParams->m_pForce_selectors) + { + assert(m_pParams->m_quality >= cETCQualitySlow); + if (m_pParams->m_quality < cETCQualitySlow) + return false; + } + + const uint32_t n = m_pParams->m_num_src_pixels; + + if (m_pParams->m_cluster_fit) + { + if (m_pParams->m_quality == cETCQualityFast) + compute_internal_cluster_fit(4); + else if (m_pParams->m_quality == cETCQualityMedium) + compute_internal_cluster_fit(16); + else if (m_pParams->m_quality == cETCQualitySlow) + compute_internal_cluster_fit(64); + else + compute_internal_cluster_fit(BASISU_ETC1_CLUSTER_FIT_ORDER_TABLE_SIZE); + } + else + compute_internal_neighborhood(m_br, m_bg, m_bb); + + if (!m_best_solution.m_valid) + { + m_pResult->m_error = UINT32_MAX; + return false; + } + + //const uint8_t* pSelectors = &m_best_solution.m_selectors[0]; + const uint8_t* pSelectors = m_pParams->m_pForce_selectors ? m_pParams->m_pForce_selectors : &m_best_solution.m_selectors[0]; + +#if defined(DEBUG) || defined(_DEBUG) + { + // sanity check the returned error + color_rgba block_colors[4]; + m_best_solution.m_coords.get_block_colors(block_colors); + + const color_rgba* pSrc_pixels = m_pParams->m_pSrc_pixels; + uint64_t actual_error = 0; + + bool perceptual; + if (m_pParams->m_quality >= cETCQualityMedium) + perceptual = m_pParams->m_perceptual; + else + perceptual = (m_pParams->m_quality == cETCQualityFast) ? false : m_pParams->m_perceptual; + + for (uint32_t i = 0; i < n; i++) + actual_error += color_distance(perceptual, pSrc_pixels[i], block_colors[pSelectors[i]], false); + + assert(actual_error == m_best_solution.m_error); + } +#endif + + m_pResult->m_error = m_best_solution.m_error; + + m_pResult->m_block_color_unscaled = m_best_solution.m_coords.m_unscaled_color; + m_pResult->m_block_color4 = m_best_solution.m_coords.m_color4; + + m_pResult->m_block_inten_table = m_best_solution.m_coords.m_inten_table; + memcpy(m_pResult->m_pSelectors, pSelectors, n); + m_pResult->m_n = n; + + return true; + } + + void etc1_optimizer::refine_solution(uint32_t max_refinement_trials) + { + // Now we have the input block, the avg. color of the input pixels, a set of trial selector indices, and the block color+intensity index. + // Now, for each component, attempt to refine the current solution by solving a simple linear equation. For example, for 4 colors: + // The goal is: + // pixel0 - (block_color+inten_table[selector0]) + pixel1 - (block_color+inten_table[selector1]) + pixel2 - (block_color+inten_table[selector2]) + pixel3 - (block_color+inten_table[selector3]) = 0 + // Rearranging this: + // (pixel0 + pixel1 + pixel2 + pixel3) - (block_color+inten_table[selector0]) - (block_color+inten_table[selector1]) - (block_color+inten_table[selector2]) - (block_color+inten_table[selector3]) = 0 + // (pixel0 + pixel1 + pixel2 + pixel3) - block_color - inten_table[selector0] - block_color-inten_table[selector1] - block_color-inten_table[selector2] - block_color-inten_table[selector3] = 0 + // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - inten_table[selector0] - inten_table[selector1] - inten_table[selector2] - inten_table[selector3] = 0 + // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3]) = 0 + // (pixel0 + pixel1 + pixel2 + pixel3)/4 - block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 = 0 + // block_color = (pixel0 + pixel1 + pixel2 + pixel3)/4 - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 + // So what this means: + // optimal_block_color = avg_input - avg_inten_delta + // So the optimal block color can be computed by taking the average block color and subtracting the current average of the intensity delta. + // Unfortunately, optimal_block_color must then be quantized to 555 or 444 so it's not always possible to improve matters using this formula. + // Also, the above formula is for unclamped intensity deltas. The actual implementation takes into account clamping. + + const uint32_t n = m_pParams->m_num_src_pixels; + + for (uint32_t refinement_trial = 0; refinement_trial < max_refinement_trials; refinement_trial++) + { + const uint8_t* pSelectors = &m_best_solution.m_selectors[0]; + const int* pInten_table = g_etc1_inten_tables[m_best_solution.m_coords.m_inten_table]; + + int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0; + const color_rgba base_color(m_best_solution.m_coords.get_scaled_color()); + for (uint32_t r = 0; r < n; r++) + { + const uint32_t s = *pSelectors++; + const int yd_temp = pInten_table[s]; + // Compute actual delta being applied to each pixel, taking into account clamping. + delta_sum_r += clamp<int>(base_color.r + yd_temp, 0, 255) - base_color.r; + delta_sum_g += clamp<int>(base_color.g + yd_temp, 0, 255) - base_color.g; + delta_sum_b += clamp<int>(base_color.b + yd_temp, 0, 255) - base_color.b; + } + + if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b)) + break; + + const float avg_delta_r_f = static_cast<float>(delta_sum_r) / n; + const float avg_delta_g_f = static_cast<float>(delta_sum_g) / n; + const float avg_delta_b_f = static_cast<float>(delta_sum_b) / n; + const int br1 = clamp<int>(static_cast<int32_t>((m_avg_color[0] - avg_delta_r_f) * m_limit / 255.0f + .5f), 0, m_limit); + const int bg1 = clamp<int>(static_cast<int32_t>((m_avg_color[1] - avg_delta_g_f) * m_limit / 255.0f + .5f), 0, m_limit); + const int bb1 = clamp<int>(static_cast<int32_t>((m_avg_color[2] - avg_delta_b_f) * m_limit / 255.0f + .5f), 0, m_limit); + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Refinement trial %u, avg_delta %f %f %f\n", refinement_trial, avg_delta_r_f, avg_delta_g_f, avg_delta_b_f); +#endif + + if (!evaluate_solution(etc1_solution_coordinates(br1, bg1, bb1, 0, m_pParams->m_use_color4), m_trial_solution, &m_best_solution)) + break; + + } // refinement_trial + } + + void etc1_optimizer::compute_internal_neighborhood(int scan_r, int scan_g, int scan_b) + { + if (m_best_solution.m_error == 0) + return; + + //const uint32_t n = m_pParams->m_num_src_pixels; + const int scan_delta_size = m_pParams->m_scan_delta_size; + + // Scan through a subset of the 3D lattice centered around the avg block color trying each 3D (555 or 444) lattice point as a potential block color. + // Each time a better solution is found try to refine the current solution's block color based of the current selectors and intensity table index. + for (int zdi = 0; zdi < scan_delta_size; zdi++) + { + const int zd = m_pParams->m_pScan_deltas[zdi]; + const int mbb = scan_b + zd; + if (mbb < 0) continue; else if (mbb > m_limit) break; + + for (int ydi = 0; ydi < scan_delta_size; ydi++) + { + const int yd = m_pParams->m_pScan_deltas[ydi]; + const int mbg = scan_g + yd; + if (mbg < 0) continue; else if (mbg > m_limit) break; + + for (int xdi = 0; xdi < scan_delta_size; xdi++) + { + const int xd = m_pParams->m_pScan_deltas[xdi]; + const int mbr = scan_r + xd; + if (mbr < 0) continue; else if (mbr > m_limit) break; + + etc1_solution_coordinates coords(mbr, mbg, mbb, 0, m_pParams->m_use_color4); + + if (!evaluate_solution(coords, m_trial_solution, &m_best_solution)) + continue; + + if (m_pParams->m_refinement) + { + refine_solution((m_pParams->m_quality == cETCQualityFast) ? 2 : (((xd | yd | zd) == 0) ? 4 : 2)); + } + + } // xdi + } // ydi + } // zdi + } + + void etc1_optimizer::compute_internal_cluster_fit(uint32_t total_perms_to_try) + { + if ((!m_best_solution.m_valid) || ((m_br != m_best_solution.m_coords.m_unscaled_color.r) || (m_bg != m_best_solution.m_coords.m_unscaled_color.g) || (m_bb != m_best_solution.m_coords.m_unscaled_color.b))) + { + evaluate_solution(etc1_solution_coordinates(m_br, m_bg, m_bb, 0, m_pParams->m_use_color4), m_trial_solution, &m_best_solution); + } + + if ((m_best_solution.m_error == 0) || (!m_best_solution.m_valid)) + return; + + for (uint32_t i = 0; i < total_perms_to_try; i++) + { + int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0; + + const int *pInten_table = g_etc1_inten_tables[m_best_solution.m_coords.m_inten_table]; + const color_rgba base_color(m_best_solution.m_coords.get_scaled_color()); + + const uint8_t *pNum_selectors = g_cluster_fit_order_tab[i].m_v; + + for (uint32_t q = 0; q < 4; q++) + { + const int yd_temp = pInten_table[q]; + + delta_sum_r += pNum_selectors[q] * (clamp<int>(base_color.r + yd_temp, 0, 255) - base_color.r); + delta_sum_g += pNum_selectors[q] * (clamp<int>(base_color.g + yd_temp, 0, 255) - base_color.g); + delta_sum_b += pNum_selectors[q] * (clamp<int>(base_color.b + yd_temp, 0, 255) - base_color.b); + } + + if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b)) + continue; + + const float avg_delta_r_f = static_cast<float>(delta_sum_r) / 8; + const float avg_delta_g_f = static_cast<float>(delta_sum_g) / 8; + const float avg_delta_b_f = static_cast<float>(delta_sum_b) / 8; + + const int br1 = clamp<int>(static_cast<int32_t>((m_avg_color[0] - avg_delta_r_f) * m_limit / 255.0f + .5f), 0, m_limit); + const int bg1 = clamp<int>(static_cast<int32_t>((m_avg_color[1] - avg_delta_g_f) * m_limit / 255.0f + .5f), 0, m_limit); + const int bb1 = clamp<int>(static_cast<int32_t>((m_avg_color[2] - avg_delta_b_f) * m_limit / 255.0f + .5f), 0, m_limit); + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Second refinement trial %u, avg_delta %f %f %f\n", i, avg_delta_r_f, avg_delta_g_f, avg_delta_b_f); +#endif + + evaluate_solution(etc1_solution_coordinates(br1, bg1, bb1, 0, m_pParams->m_use_color4), m_trial_solution, &m_best_solution); + + if (m_best_solution.m_error == 0) + break; + } + } + + void etc1_optimizer::init(const params& params, results& result) + { + m_pParams = ¶ms; + m_pResult = &result; + + const uint32_t n = m_pParams->m_num_src_pixels; + + m_selectors.resize(n); + m_best_selectors.resize(n); + m_temp_selectors.resize(n); + m_trial_solution.m_selectors.resize(n); + m_best_solution.m_selectors.resize(n); + + m_limit = m_pParams->m_use_color4 ? 15 : 31; + + vec3F avg_color(0.0f); + + m_luma.resize(n); + m_sorted_luma_indices.resize(n); + m_sorted_luma.resize(n); + + int min_r = 255, min_g = 255, min_b = 255; + int max_r = 0, max_g = 0, max_b = 0; + + for (uint32_t i = 0; i < n; i++) + { + const color_rgba& c = m_pParams->m_pSrc_pixels[i]; + + min_r = basisu::minimum<int>(min_r, c.r); + min_g = basisu::minimum<int>(min_g, c.g); + min_b = basisu::minimum<int>(min_b, c.b); + + max_r = basisu::maximum<int>(max_r, c.r); + max_g = basisu::maximum<int>(max_g, c.g); + max_b = basisu::maximum<int>(max_b, c.b); + + const vec3F fc(c.r, c.g, c.b); + + avg_color += fc; + + m_luma[i] = static_cast<uint16_t>(c.r + c.g + c.b); + m_sorted_luma_indices[i] = i; + } + avg_color /= static_cast<float>(n); + m_avg_color = avg_color; + m_max_comp_spread = basisu::maximum(basisu::maximum(max_r - min_r, max_g - min_g), max_b - min_b); + + m_br = clamp<int>(static_cast<uint32_t>(m_avg_color[0] * m_limit / 255.0f + .5f), 0, m_limit); + m_bg = clamp<int>(static_cast<uint32_t>(m_avg_color[1] * m_limit / 255.0f + .5f), 0, m_limit); + m_bb = clamp<int>(static_cast<uint32_t>(m_avg_color[2] * m_limit / 255.0f + .5f), 0, m_limit); + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Avg block color: %u %u %u\n", m_br, m_bg, m_bb); +#endif + + if (m_pParams->m_quality == cETCQualityFast) + { + indirect_sort(n, &m_sorted_luma_indices[0], &m_luma[0]); + + m_pSorted_luma = &m_sorted_luma[0]; + m_pSorted_luma_indices = &m_sorted_luma_indices[0]; + + for (uint32_t i = 0; i < n; i++) + m_pSorted_luma[i] = m_luma[m_pSorted_luma_indices[i]]; + } + + m_best_solution.m_coords.clear(); + m_best_solution.m_valid = false; + m_best_solution.m_error = UINT64_MAX; + + clear_obj(m_solutions_tried); + } + + // Return false if we've probably already tried this solution, true if we have definitely not. + bool etc1_optimizer::check_for_redundant_solution(const etc1_solution_coordinates& coords) + { + // Hash first 3 bytes of color (RGB) + uint32_t kh = hash_hsieh((uint8_t*)&coords.m_unscaled_color.r, 3); + + uint32_t h0 = kh & cSolutionsTriedHashMask; + uint32_t h1 = (kh >> cSolutionsTriedHashBits) & cSolutionsTriedHashMask; + + // Simple Bloom filter lookup with k=2 + if ( ((m_solutions_tried[h0 >> 3] & (1 << (h0 & 7))) != 0) && + ((m_solutions_tried[h1 >> 3] & (1 << (h1 & 7))) != 0) ) + return false; + + m_solutions_tried[h0 >> 3] |= (1 << (h0 & 7)); + m_solutions_tried[h1 >> 3] |= (1 << (h1 & 7)); + + return true; + } + + static uint8_t g_eval_dist_tables[8][256] = + { + // 99% threshold + { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,}, + { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,}, + { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,}, + { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,}, + { 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,}, + { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}, + { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}, + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,} + }; + + bool etc1_optimizer::evaluate_solution_slow(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) + { + if (!check_for_redundant_solution(coords)) + return false; + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Eval solution: %u %u %u\n", coords.m_unscaled_color.r, coords.m_unscaled_color.g, coords.m_unscaled_color.b); +#endif + + trial_solution.m_valid = false; + + if (m_pParams->m_constrain_against_base_color5) + { + const int dr = (int)coords.m_unscaled_color.r - (int)m_pParams->m_base_color5.r; + const int dg = (int)coords.m_unscaled_color.g - (int)m_pParams->m_base_color5.g; + const int db = (int)coords.m_unscaled_color.b - (int)m_pParams->m_base_color5.b; + + if ((minimum(dr, dg, db) < cETC1ColorDeltaMin) || (maximum(dr, dg, db) > cETC1ColorDeltaMax)) + { +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Eval failed due to constraint from %u %u %u\n", m_pParams->m_base_color5.r, m_pParams->m_base_color5.g, m_pParams->m_base_color5.b); +#endif + return false; + } + } + + const color_rgba base_color(coords.get_scaled_color()); + + const uint32_t n = m_pParams->m_num_src_pixels; + assert(trial_solution.m_selectors.size() == n); + + trial_solution.m_error = INT64_MAX; + + const uint8_t *pSelectors_to_use = m_pParams->m_pForce_selectors; + + for (uint32_t inten_table = 0; inten_table < cETC1IntenModifierValues; inten_table++) + { + if (m_pParams->m_quality <= cETCQualityMedium) + { + if (!g_eval_dist_tables[inten_table][m_max_comp_spread]) + continue; + } +#if 0 + if (m_pParams->m_quality <= cETCQualityMedium) + { + // For tables 5-7, if the max component spread falls within certain ranges, skip the inten table. Statistically they are extremely unlikely to result in lower error. + if (inten_table == 7) + { + if (m_max_comp_spread < 42) + continue; + } + else if (inten_table == 6) + { + if ((m_max_comp_spread >= 12) && (m_max_comp_spread <= 31)) + continue; + } + else if (inten_table == 5) + { + if ((m_max_comp_spread >= 13) && (m_max_comp_spread <= 21)) + continue; + } + } +#endif + + const int* pInten_table = g_etc1_inten_tables[inten_table]; + + color_rgba block_colors[4]; + for (uint32_t s = 0; s < 4; s++) + { + const int yd = pInten_table[s]; + block_colors[s].set(base_color.r + yd, base_color.g + yd, base_color.b + yd, 255); + } + + uint64_t total_error = 0; + + const color_rgba* pSrc_pixels = m_pParams->m_pSrc_pixels; + + if (!g_cpu_supports_sse41) + { + for (uint32_t c = 0; c < n; c++) + { + const color_rgba& src_pixel = *pSrc_pixels++; + + uint32_t best_selector_index = 0; + uint32_t best_error = 0; + + if (pSelectors_to_use) + { + best_selector_index = pSelectors_to_use[c]; + best_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[best_selector_index], false); + } + else + { + best_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[0], false); + + uint32_t trial_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[1], false); + if (trial_error < best_error) + { + best_error = trial_error; + best_selector_index = 1; + } + + trial_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[2], false); + if (trial_error < best_error) + { + best_error = trial_error; + best_selector_index = 2; + } + + trial_error = color_distance(m_pParams->m_perceptual, src_pixel, block_colors[3], false); + if (trial_error < best_error) + { + best_error = trial_error; + best_selector_index = 3; + } + } + + m_temp_selectors[c] = static_cast<uint8_t>(best_selector_index); + + total_error += best_error; + if (total_error >= trial_solution.m_error) + break; + } + } + else + { +#if BASISU_SUPPORT_SSE + if (pSelectors_to_use) + { + if (m_pParams->m_perceptual) + perceptual_distance_rgb_4_N_sse41((int64_t*)&total_error, pSelectors_to_use, block_colors, pSrc_pixels, n, trial_solution.m_error); + else + linear_distance_rgb_4_N_sse41((int64_t*)&total_error, pSelectors_to_use, block_colors, pSrc_pixels, n, trial_solution.m_error); + } + else + { + if (m_pParams->m_perceptual) + find_selectors_perceptual_rgb_4_N_sse41((int64_t*)&total_error, &m_temp_selectors[0], block_colors, pSrc_pixels, n, trial_solution.m_error); + else + find_selectors_linear_rgb_4_N_sse41((int64_t*)&total_error, &m_temp_selectors[0], block_colors, pSrc_pixels, n, trial_solution.m_error); + } +#endif + } + + if (total_error < trial_solution.m_error) + { + trial_solution.m_error = total_error; + trial_solution.m_coords.m_inten_table = inten_table; + trial_solution.m_selectors.swap(m_temp_selectors); + trial_solution.m_valid = true; + } + } + trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color; + trial_solution.m_coords.m_color4 = m_pParams->m_use_color4; + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Eval done: %u error: %I64u best error so far: %I64u\n", (trial_solution.m_error < pBest_solution->m_error), trial_solution.m_error, pBest_solution->m_error); +#endif + + bool success = false; + if (pBest_solution) + { + if (trial_solution.m_error < pBest_solution->m_error) + { + *pBest_solution = trial_solution; + success = true; + } + } + + return success; + } + + bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) + { + if (!check_for_redundant_solution(coords)) + return false; + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Eval solution fast: %u %u %u\n", coords.m_unscaled_color.r, coords.m_unscaled_color.g, coords.m_unscaled_color.b); +#endif + + if (m_pParams->m_constrain_against_base_color5) + { + const int dr = (int)coords.m_unscaled_color.r - (int)m_pParams->m_base_color5.r; + const int dg = (int)coords.m_unscaled_color.g - (int)m_pParams->m_base_color5.g; + const int db = (int)coords.m_unscaled_color.b - (int)m_pParams->m_base_color5.b; + + if ((minimum(dr, dg, db) < cETC1ColorDeltaMin) || (maximum(dr, dg, db) > cETC1ColorDeltaMax)) + { + trial_solution.m_valid = false; + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Eval failed due to constraint from %u %u %u\n", m_pParams->m_base_color5.r, m_pParams->m_base_color5.g, m_pParams->m_base_color5.b); +#endif + return false; + } + } + + const color_rgba base_color(coords.get_scaled_color()); + + const uint32_t n = m_pParams->m_num_src_pixels; + assert(trial_solution.m_selectors.size() == n); + + trial_solution.m_error = UINT64_MAX; + + const bool perceptual = (m_pParams->m_quality == cETCQualityFast) ? false : m_pParams->m_perceptual; + + for (int inten_table = cETC1IntenModifierValues - 1; inten_table >= 0; --inten_table) + { + const int* pInten_table = g_etc1_inten_tables[inten_table]; + + uint32_t block_inten[4]; + color_rgba block_colors[4]; + for (uint32_t s = 0; s < 4; s++) + { + const int yd = pInten_table[s]; + color_rgba block_color(base_color.r + yd, base_color.g + yd, base_color.b + yd, 255); + block_colors[s] = block_color; + block_inten[s] = block_color.r + block_color.g + block_color.b; + } + + // evaluate_solution_fast() enforces/assumes a total ordering of the input colors along the intensity (1,1,1) axis to more quickly classify the inputs to selectors. + // The inputs colors have been presorted along the projection onto this axis, and ETC1 block colors are always ordered along the intensity axis, so this classification is fast. + // 0 1 2 3 + // 01 12 23 + const uint32_t block_inten_midpoints[3] = { block_inten[0] + block_inten[1], block_inten[1] + block_inten[2], block_inten[2] + block_inten[3] }; + + uint64_t total_error = 0; + const color_rgba* pSrc_pixels = m_pParams->m_pSrc_pixels; + + if (perceptual) + { + if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0]) + { + if (block_inten[0] > m_pSorted_luma[n - 1]) + { + const uint32_t min_error = iabs((int)block_inten[0] - (int)m_pSorted_luma[n - 1]); + if (min_error >= trial_solution.m_error) + continue; + } + + memset(&m_temp_selectors[0], 0, n); + + for (uint32_t c = 0; c < n; c++) + total_error += color_distance(true, block_colors[0], pSrc_pixels[c], false); + } + else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2]) + { + if (m_pSorted_luma[0] > block_inten[3]) + { + const uint32_t min_error = iabs((int)m_pSorted_luma[0] - (int)block_inten[3]); + if (min_error >= trial_solution.m_error) + continue; + } + + memset(&m_temp_selectors[0], 3, n); + + for (uint32_t c = 0; c < n; c++) + total_error += color_distance(true, block_colors[3], pSrc_pixels[c], false); + } + else + { + if (!g_cpu_supports_sse41) + { + uint32_t cur_selector = 0, c; + for (c = 0; c < n; c++) + { + const uint32_t y = m_pSorted_luma[c]; + while ((y * 2) >= block_inten_midpoints[cur_selector]) + if (++cur_selector > 2) + goto done; + const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = static_cast<uint8_t>(cur_selector); + total_error += color_distance(true, block_colors[cur_selector], pSrc_pixels[sorted_pixel_index], false); + } + done: + while (c < n) + { + const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = 3; + total_error += color_distance(true, block_colors[3], pSrc_pixels[sorted_pixel_index], false); + ++c; + } + } + else + { +#if BASISU_SUPPORT_SSE + uint32_t cur_selector = 0, c; + + for (c = 0; c < n; c++) + { + const uint32_t y = m_pSorted_luma[c]; + while ((y * 2) >= block_inten_midpoints[cur_selector]) + { + if (++cur_selector > 2) + goto done3; + } + const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = static_cast<uint8_t>(cur_selector); + } + done3: + + while (c < n) + { + const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = 3; + ++c; + } + + int64_t block_error; + perceptual_distance_rgb_4_N_sse41(&block_error, &m_temp_selectors[0], block_colors, pSrc_pixels, n, INT64_MAX); + total_error += block_error; +#endif + } + } + } + else + { + if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0]) + { + if (block_inten[0] > m_pSorted_luma[n - 1]) + { + const uint32_t min_error = iabs((int)block_inten[0] - (int)m_pSorted_luma[n - 1]); + if (min_error >= trial_solution.m_error) + continue; + } + + memset(&m_temp_selectors[0], 0, n); + + for (uint32_t c = 0; c < n; c++) + total_error += color_distance(block_colors[0], pSrc_pixels[c], false); + } + else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2]) + { + if (m_pSorted_luma[0] > block_inten[3]) + { + const uint32_t min_error = iabs((int)m_pSorted_luma[0] - (int)block_inten[3]); + if (min_error >= trial_solution.m_error) + continue; + } + + memset(&m_temp_selectors[0], 3, n); + + for (uint32_t c = 0; c < n; c++) + total_error += color_distance(block_colors[3], pSrc_pixels[c], false); + } + else + { + uint32_t cur_selector = 0, c; + for (c = 0; c < n; c++) + { + const uint32_t y = m_pSorted_luma[c]; + while ((y * 2) >= block_inten_midpoints[cur_selector]) + if (++cur_selector > 2) + goto done2; + const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = static_cast<uint8_t>(cur_selector); + total_error += color_distance(block_colors[cur_selector], pSrc_pixels[sorted_pixel_index], false); + } + done2: + while (c < n) + { + const uint32_t sorted_pixel_index = m_pSorted_luma_indices[c]; + m_temp_selectors[sorted_pixel_index] = 3; + total_error += color_distance(block_colors[3], pSrc_pixels[sorted_pixel_index], false); + ++c; + } + } + } + + if (total_error < trial_solution.m_error) + { + trial_solution.m_error = total_error; + trial_solution.m_coords.m_inten_table = inten_table; + trial_solution.m_selectors.swap(m_temp_selectors); + trial_solution.m_valid = true; + if (!total_error) + break; + } + } + trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color; + trial_solution.m_coords.m_color4 = m_pParams->m_use_color4; + +#if BASISU_DEBUG_ETC_ENCODER_DEEPER + printf("Eval done: %u error: %I64u best error so far: %I64u\n", (trial_solution.m_error < pBest_solution->m_error), trial_solution.m_error, pBest_solution->m_error); +#endif + + bool success = false; + if (pBest_solution) + { + if (trial_solution.m_error < pBest_solution->m_error) + { + *pBest_solution = trial_solution; + success = true; + } + } + + return success; + } + + uint64_t pack_eac_a8(pack_eac_a8_results& results, const uint8_t* pPixels, uint32_t num_pixels, uint32_t base_search_rad, uint32_t mul_search_rad, uint32_t table_mask) + { + results.m_selectors.resize(num_pixels); + results.m_selectors_temp.resize(num_pixels); + + uint32_t min_alpha = 255, max_alpha = 0; + for (uint32_t i = 0; i < num_pixels; i++) + { + const uint32_t a = pPixels[i]; + if (a < min_alpha) min_alpha = a; + if (a > max_alpha) max_alpha = a; + } + + if (min_alpha == max_alpha) + { + results.m_base = min_alpha; + results.m_table = 13; + results.m_multiplier = 1; + for (uint32_t i = 0; i < num_pixels; i++) + results.m_selectors[i] = 4; + return 0; + } + + const uint32_t alpha_range = max_alpha - min_alpha; + + uint64_t best_err = UINT64_MAX; + + for (uint32_t table = 0; table < 16; table++) + { + if ((table_mask & (1U << table)) == 0) + continue; + + const float range = (float)(g_etc2_eac_tables[table][ETC2_EAC_MAX_VALUE_SELECTOR] - g_etc2_eac_tables[table][ETC2_EAC_MIN_VALUE_SELECTOR]); + const int center = (int)roundf(lerp((float)min_alpha, (float)max_alpha, (float)(0 - g_etc2_eac_tables[table][ETC2_EAC_MIN_VALUE_SELECTOR]) / range)); + + const int base_min = clamp255(center - base_search_rad); + const int base_max = clamp255(center + base_search_rad); + + const int mul = (int)roundf(alpha_range / range); + const int mul_low = clamp<int>(mul - mul_search_rad, 1, 15); + const int mul_high = clamp<int>(mul + mul_search_rad, 1, 15); + + for (int base = base_min; base <= base_max; base++) + { + for (int multiplier = mul_low; multiplier <= mul_high; multiplier++) + { + uint64_t total_err = 0; + + for (uint32_t i = 0; i < num_pixels; i++) + { + const int a = pPixels[i]; + + uint32_t best_s_err = UINT32_MAX; + uint32_t best_s = 0; + for (uint32_t s = 0; s < 8; s++) + { + const int v = clamp255((int)multiplier * g_etc2_eac_tables[table][s] + (int)base); + + uint32_t err = iabs(a - v); + if (err < best_s_err) + { + best_s_err = err; + best_s = s; + } + } + + results.m_selectors_temp[i] = static_cast<uint8_t>(best_s); + + total_err += best_s_err * best_s_err; + if (total_err >= best_err) + break; + } + + if (total_err < best_err) + { + best_err = total_err; + results.m_base = base; + results.m_multiplier = multiplier; + results.m_table = table; + results.m_selectors.swap(results.m_selectors_temp); + if (!best_err) + return best_err; + } + + } // table + + } // multiplier + + } // base + + return best_err; + } + + void pack_eac_a8(eac_a8_block* pBlock, const uint8_t* pPixels, uint32_t base_search_rad, uint32_t mul_search_rad, uint32_t table_mask) + { + pack_eac_a8_results results; + pack_eac_a8(results, pPixels, 16, base_search_rad, mul_search_rad, table_mask); + + pBlock->m_base = results.m_base; + pBlock->m_multiplier = results.m_multiplier; + pBlock->m_table = results.m_table; + for (uint32_t y = 0; y < 4; y++) + for (uint32_t x = 0; x < 4; x++) + pBlock->set_selector(x, y, results.m_selectors[x + y * 4]); + } + +} // namespace basisu diff --git a/thirdparty/basis_universal/basisu_etc.h b/thirdparty/basis_universal/encoder/basisu_etc.h index a202d01f6e..1e3ece43b8 100644 --- a/thirdparty/basis_universal/basisu_etc.h +++ b/thirdparty/basis_universal/encoder/basisu_etc.h @@ -1,5 +1,5 @@ // basis_etc.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,9 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. #pragma once -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" #include "basisu_enc.h" -#include <set> namespace basisu { @@ -116,7 +115,7 @@ namespace basisu { assert((ofs + num) <= 64U); assert(num && (num < 32U)); - return (read_be64(&m_uint64) >> ofs) & ((1UL << num) - 1UL); + return (uint32_t)(read_be64(&m_uint64) >> ofs) & ((1UL << num) - 1UL); } inline void set_general_bits(uint32_t ofs, uint32_t num, uint32_t bits) @@ -266,6 +265,27 @@ namespace basisu p[-2] |= (msb << byte_bit_ofs); } + // Selector "etc1_val" ranges from 0-3 and is a direct (raw) ETC1 selector. + inline void set_raw_selector(uint32_t x, uint32_t y, uint32_t etc1_val) + { + assert((x | y | etc1_val) < 4); + const uint32_t bit_index = x * 4 + y; + + uint8_t* p = &m_bytes[7 - (bit_index >> 3)]; + + const uint32_t byte_bit_ofs = bit_index & 7; + const uint32_t mask = 1 << byte_bit_ofs; + + const uint32_t lsb = etc1_val & 1; + const uint32_t msb = etc1_val >> 1; + + p[0] &= ~mask; + p[0] |= (lsb << byte_bit_ofs); + + p[-2] &= ~mask; + p[-2] |= (msb << byte_bit_ofs); + } + inline uint32_t get_raw_selector_bits() const { return m_bytes[4] | (m_bytes[5] << 8) | (m_bytes[6] << 16) | (m_bytes[7] << 24); @@ -622,6 +642,23 @@ namespace basisu return true; } + bool set_block_color5_clamp(const color_rgba &c0_unscaled, const color_rgba &c1_unscaled) + { + set_diff_bit(true); + set_base5_color(pack_color5(c0_unscaled, false)); + + int dr = c1_unscaled.r - c0_unscaled.r; + int dg = c1_unscaled.g - c0_unscaled.g; + int db = c1_unscaled.b - c0_unscaled.b; + + dr = clamp<int>(dr, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + dg = clamp<int>(dg, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + db = clamp<int>(db, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + + set_delta3_color(pack_delta3(dr, dg, db)); + + return true; + } color_rgba get_selector_color(uint32_t x, uint32_t y, uint32_t s) const { color_rgba block_colors[4]; @@ -720,7 +757,7 @@ namespace basisu } }; - typedef std::vector<etc_block> etc_block_vec; + typedef basisu::vector<etc_block> etc_block_vec; // Returns false if the unpack fails (could be bogus data or ETC2) bool unpack_etc1(const etc_block& block, color_rgba *pDst, bool preserve_alpha = false); @@ -844,10 +881,10 @@ namespace basisu bb = (m_unscaled_color.b >> 2) | (m_unscaled_color.b << 3); } const int* pInten_table = g_etc1_inten_tables[m_inten_table]; - pBlock_colors[0].set((uint8_t)(br + pInten_table[0]), (uint8_t)(bg + pInten_table[0]), (uint8_t)(bb + pInten_table[0]), 255); - pBlock_colors[1].set((uint8_t)(br + pInten_table[1]), (uint8_t)(bg + pInten_table[1]), (uint8_t)(bb + pInten_table[1]), 255); - pBlock_colors[2].set((uint8_t)(br + pInten_table[2]), (uint8_t)(bg + pInten_table[2]), (uint8_t)(bb + pInten_table[2]), 255); - pBlock_colors[3].set((uint8_t)(br + pInten_table[3]), (uint8_t)(bg + pInten_table[3]), (uint8_t)(bb + pInten_table[3]), 255); + pBlock_colors[0].set(br + pInten_table[0], bg + pInten_table[0], bb + pInten_table[0], 255); + pBlock_colors[1].set(br + pInten_table[1], bg + pInten_table[1], bb + pInten_table[1], 255); + pBlock_colors[2].set(br + pInten_table[2], bg + pInten_table[2], bb + pInten_table[2], 255); + pBlock_colors[3].set(br + pInten_table[3], bg + pInten_table[3], bb + pInten_table[3], 255); } color_rgba m_unscaled_color; @@ -914,9 +951,6 @@ namespace basisu m_refinement = true; m_pForce_selectors = nullptr; - - m_pEval_solution_override = nullptr; - m_pEval_solution_override_data = nullptr; } uint32_t m_num_src_pixels; @@ -932,9 +966,6 @@ namespace basisu bool m_refinement; const uint8_t* m_pForce_selectors; - - evaluate_solution_override_func m_pEval_solution_override; - void *m_pEval_solution_override_data; }; struct results @@ -970,7 +1001,7 @@ namespace basisu } etc1_solution_coordinates m_coords; - std::vector<uint8_t> m_selectors; + basisu::vector<uint8_t> m_selectors; uint64_t m_error; bool m_valid; @@ -1001,33 +1032,36 @@ namespace basisu vec3F m_avg_color; int m_br, m_bg, m_bb; - std::vector<uint16_t> m_luma; - std::vector<uint32_t> m_sorted_luma; - std::vector<uint32_t> m_sorted_luma_indices; + int m_max_comp_spread; + basisu::vector<uint16_t> m_luma; + basisu::vector<uint32_t> m_sorted_luma; + basisu::vector<uint32_t> m_sorted_luma_indices; const uint32_t* m_pSorted_luma_indices; uint32_t* m_pSorted_luma; - std::vector<uint8_t> m_selectors; - std::vector<uint8_t> m_best_selectors; + basisu::vector<uint8_t> m_selectors; + basisu::vector<uint8_t> m_best_selectors; potential_solution m_best_solution; potential_solution m_trial_solution; - std::vector<uint8_t> m_temp_selectors; - - std::set<uint32_t> m_solutions_tried; + basisu::vector<uint8_t> m_temp_selectors; + enum { cSolutionsTriedHashBits = 10, cTotalSolutionsTriedHashSize = 1 << cSolutionsTriedHashBits, cSolutionsTriedHashMask = cTotalSolutionsTriedHashSize - 1 }; + uint8_t m_solutions_tried[cTotalSolutionsTriedHashSize / 8]; + void get_nearby_inten_tables(uint32_t idx, int &first_inten_table, int &last_inten_table) { first_inten_table = maximum<int>(idx - 1, 0); last_inten_table = minimum<int>(cETC1IntenModifierValues, idx + 1); } - + + bool check_for_redundant_solution(const etc1_solution_coordinates& coords); bool evaluate_solution_slow(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution); bool evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution); inline bool evaluate_solution(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution) { - if (m_pParams->m_quality >= cETCQualitySlow) + if (m_pParams->m_quality >= cETCQualityMedium) return evaluate_solution_slow(coords, trial_solution, pBest_solution); else return evaluate_solution_fast(coords, trial_solution, pBest_solution); @@ -1042,5 +1076,77 @@ namespace basisu { etc1_optimizer m_optimizer; }; + + void pack_etc1_solid_color_init(); + uint64_t pack_etc1_block_solid_color(etc_block& block, const uint8_t* pColor); + + // ETC EAC + extern const int8_t g_etc2_eac_tables[16][8]; + extern const int8_t g_etc2_eac_tables8[16][8]; + + const uint32_t ETC2_EAC_MIN_VALUE_SELECTOR = 3, ETC2_EAC_MAX_VALUE_SELECTOR = 7; + + struct eac_a8_block + { + uint16_t m_base : 8; + uint16_t m_table : 4; + uint16_t m_multiplier : 4; + + uint8_t m_selectors[6]; + + inline uint32_t get_selector(uint32_t x, uint32_t y, uint64_t selector_bits) const + { + assert((x < 4) && (y < 4)); + return static_cast<uint32_t>((selector_bits >> (45 - (y + x * 4) * 3)) & 7); + } + + inline uint64_t get_selector_bits() const + { + uint64_t pixels = ((uint64_t)m_selectors[0] << 40) | ((uint64_t)m_selectors[1] << 32) | ((uint64_t)m_selectors[2] << 24) | ((uint64_t)m_selectors[3] << 16) | ((uint64_t)m_selectors[4] << 8) | m_selectors[5]; + return pixels; + } + + inline void set_selector_bits(uint64_t pixels) + { + m_selectors[0] = (uint8_t)(pixels >> 40); + m_selectors[1] = (uint8_t)(pixels >> 32); + m_selectors[2] = (uint8_t)(pixels >> 24); + m_selectors[3] = (uint8_t)(pixels >> 16); + m_selectors[4] = (uint8_t)(pixels >> 8); + m_selectors[5] = (uint8_t)(pixels); + } + + void set_selector(uint32_t x, uint32_t y, uint32_t s) + { + assert((x < 4) && (y < 4) && (s < 8)); + + const uint32_t ofs = 45 - (y + x * 4) * 3; + + uint64_t pixels = get_selector_bits(); + + pixels &= ~(7ULL << ofs); + pixels |= (static_cast<uint64_t>(s) << ofs); + + set_selector_bits(pixels); + } + }; + + struct etc2_rgba_block + { + eac_a8_block m_alpha; + etc_block m_rgb; + }; + struct pack_eac_a8_results + { + uint32_t m_base; + uint32_t m_table; + uint32_t m_multiplier; + uint8_vec m_selectors; + uint8_vec m_selectors_temp; + }; + + uint64_t pack_eac_a8(pack_eac_a8_results& results, const uint8_t* pPixels, uint32_t num_pixels, uint32_t base_search_rad, uint32_t mul_search_rad, uint32_t table_mask = UINT32_MAX); + void pack_eac_a8(eac_a8_block* pBlock, const uint8_t* pPixels, uint32_t base_search_rad, uint32_t mul_search_rad, uint32_t table_mask = UINT32_MAX); + } // namespace basisu diff --git a/thirdparty/basis_universal/basisu_frontend.cpp b/thirdparty/basis_universal/encoder/basisu_frontend.cpp index 6f7a9bf889..324fc8e447 100644 --- a/thirdparty/basis_universal/basisu_frontend.cpp +++ b/thirdparty/basis_universal/encoder/basisu_frontend.cpp @@ -1,5 +1,5 @@ // basisu_frontend.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,11 +17,16 @@ // This code originally supported full ETC1 and ETC1S, so there's some legacy stuff to be cleaned up in here. // Add endpoint tiling support (where we force adjacent blocks to use the same endpoints during quantization), for a ~10% or more increase in bitrate at same SSIM. The backend already supports this. // -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" #include "basisu_frontend.h" #include <unordered_set> #include <unordered_map> +#if BASISU_SUPPORT_SSE +#define CPPSPMD_NAME(a) a##_sse41 +#include "basisu_kernels_declares.h" +#endif + #define BASISU_FRONTEND_VERIFY(c) do { if (!(c)) handle_verify_failure(__LINE__); } while(0) namespace basisu @@ -29,10 +34,11 @@ namespace basisu const uint32_t cMaxCodebookCreationThreads = 8; const uint32_t BASISU_MAX_ENDPOINT_REFINEMENT_STEPS = 3; - const uint32_t BASISU_MAX_SELECTOR_REFINEMENT_STEPS = 3; + //const uint32_t BASISU_MAX_SELECTOR_REFINEMENT_STEPS = 3; const uint32_t BASISU_ENDPOINT_PARENT_CODEBOOK_SIZE = 16; - const uint32_t BASISU_SELECTOR_PARENT_CODEBOOK_SIZE = 16; + const uint32_t BASISU_SELECTOR_PARENT_CODEBOOK_SIZE_COMP_LEVEL_01 = 32; + const uint32_t BASISU_SELECTOR_PARENT_CODEBOOK_SIZE_COMP_LEVEL_DEFAULT = 16; // TODO - How to handle internal verifies in the basisu lib static inline void handle_verify_failure(int line) @@ -57,14 +63,14 @@ namespace basisu uint32_t tv = size / sizeof(vec6F_quantizer::training_vec_with_weight); - std::vector<vec6F_quantizer::training_vec_with_weight> v(tv); + basisu::vector<vec6F_quantizer::training_vec_with_weight> v(tv); fread(&v[0], 1, sizeof(v[0]) * tv, pFile); for (uint32_t i = 0; i < tv; i++) m_endpoint_clusterizer.add_training_vec(v[i].first, v[i].second); m_endpoint_clusterizer.generate(16128); - std::vector<uint_vec> codebook; + basisu::vector<uint_vec> codebook; m_endpoint_clusterizer.retrieve(codebook); printf("Generated %u entries\n", (uint32_t)codebook.size()); @@ -78,6 +84,7 @@ namespace basisu { if (!p.m_pGlobal_sel_codebook) { + debug_printf("basisu_frontend::init: No global sel codebook!\n"); assert(0); return false; } @@ -128,11 +135,19 @@ namespace basisu case 2: { m_endpoint_refinement = true; + m_use_hierarchical_endpoint_codebooks = true; + m_use_hierarchical_selector_codebooks = true; + + break; + } + case 3: + { + m_endpoint_refinement = true; m_use_hierarchical_endpoint_codebooks = false; m_use_hierarchical_selector_codebooks = false; break; } - case 3: + case 4: { m_endpoint_refinement = true; m_use_hierarchical_endpoint_codebooks = true; @@ -141,7 +156,7 @@ namespace basisu m_num_selector_codebook_iterations = BASISU_MAX_ENDPOINT_REFINEMENT_STEPS; break; } - case 4: + case 5: { m_endpoint_refinement = true; m_use_hierarchical_endpoint_codebooks = false; @@ -150,7 +165,8 @@ namespace basisu m_num_selector_codebook_iterations = BASISU_MAX_ENDPOINT_REFINEMENT_STEPS; break; } - case 5: + case 6: + default: { m_endpoint_refinement = true; m_use_hierarchical_endpoint_codebooks = false; @@ -180,106 +196,113 @@ namespace basisu init_etc1_images(); - init_endpoint_training_vectors(); - - generate_endpoint_clusters(); - - for (uint32_t refine_endpoint_step = 0; refine_endpoint_step < m_num_endpoint_codebook_iterations; refine_endpoint_step++) + if (m_params.m_pGlobal_codebooks) { - BASISU_FRONTEND_VERIFY(check_etc1s_constraints()); - - if (refine_endpoint_step) - { - introduce_new_endpoint_clusters(); - } - - generate_endpoint_codebook(refine_endpoint_step); - - if ((m_params.m_debug_images) && (m_params.m_dump_endpoint_clusterization)) - { - char buf[256]; - snprintf(buf, sizeof(buf), "endpoint_cluster_vis_pre_%u.png", refine_endpoint_step); - dump_endpoint_clusterization_visualization(buf, false); - } - - bool early_out = false; + init_global_codebooks(); + } + else + { + init_endpoint_training_vectors(); - if (m_endpoint_refinement) + generate_endpoint_clusters(); + + for (uint32_t refine_endpoint_step = 0; refine_endpoint_step < m_num_endpoint_codebook_iterations; refine_endpoint_step++) { - //dump_endpoint_clusterization_visualization("endpoint_clusters_before_refinement.png"); - - if (!refine_endpoint_clusterization()) - early_out = true; + BASISU_FRONTEND_VERIFY(check_etc1s_constraints()); - if ((m_params.m_tex_type == basist::cBASISTexTypeVideoFrames) && (!refine_endpoint_step) && (m_num_endpoint_codebook_iterations == 1)) + if (refine_endpoint_step) { - eliminate_redundant_or_empty_endpoint_clusters(); - generate_endpoint_codebook(refine_endpoint_step); + introduce_new_endpoint_clusters(); } + generate_endpoint_codebook(refine_endpoint_step); + if ((m_params.m_debug_images) && (m_params.m_dump_endpoint_clusterization)) { char buf[256]; - snprintf(buf, sizeof(buf), "endpoint_cluster_vis_post_%u.png", refine_endpoint_step); - + snprintf(buf, sizeof(buf), "endpoint_cluster_vis_pre_%u.png", refine_endpoint_step); dump_endpoint_clusterization_visualization(buf, false); - snprintf(buf, sizeof(buf), "endpoint_cluster_colors_vis_post_%u.png", refine_endpoint_step); + } + + bool early_out = false; - dump_endpoint_clusterization_visualization(buf, true); + if (m_endpoint_refinement) + { + //dump_endpoint_clusterization_visualization("endpoint_clusters_before_refinement.png"); + + if (!refine_endpoint_clusterization()) + early_out = true; + + if ((m_params.m_tex_type == basist::cBASISTexTypeVideoFrames) && (!refine_endpoint_step) && (m_num_endpoint_codebook_iterations == 1)) + { + eliminate_redundant_or_empty_endpoint_clusters(); + generate_endpoint_codebook(refine_endpoint_step); + } + + if ((m_params.m_debug_images) && (m_params.m_dump_endpoint_clusterization)) + { + char buf[256]; + snprintf(buf, sizeof(buf), "endpoint_cluster_vis_post_%u.png", refine_endpoint_step); + + dump_endpoint_clusterization_visualization(buf, false); + snprintf(buf, sizeof(buf), "endpoint_cluster_colors_vis_post_%u.png", refine_endpoint_step); + + dump_endpoint_clusterization_visualization(buf, true); + } } - } - eliminate_redundant_or_empty_endpoint_clusters(); + eliminate_redundant_or_empty_endpoint_clusters(); - if (m_params.m_debug_stats) - debug_printf("Total endpoint clusters: %u\n", (uint32_t)m_endpoint_clusters.size()); + if (m_params.m_debug_stats) + debug_printf("Total endpoint clusters: %u\n", (uint32_t)m_endpoint_clusters.size()); - if (early_out) - break; - } + if (early_out) + break; + } - BASISU_FRONTEND_VERIFY(check_etc1s_constraints()); + BASISU_FRONTEND_VERIFY(check_etc1s_constraints()); - generate_block_endpoint_clusters(); + generate_block_endpoint_clusters(); - create_initial_packed_texture(); + create_initial_packed_texture(); - generate_selector_clusters(); + generate_selector_clusters(); - if (m_use_hierarchical_selector_codebooks) - compute_selector_clusters_within_each_parent_cluster(); + if (m_use_hierarchical_selector_codebooks) + compute_selector_clusters_within_each_parent_cluster(); - if (m_params.m_compression_level == 0) - { - create_optimized_selector_codebook(0); + if (m_params.m_compression_level == 0) + { + create_optimized_selector_codebook(0); - find_optimal_selector_clusters_for_each_block(); + find_optimal_selector_clusters_for_each_block(); - introduce_special_selector_clusters(); - } - else - { - const uint32_t num_refine_selector_steps = m_params.m_pGlobal_sel_codebook ? 1 : m_num_selector_codebook_iterations; - for (uint32_t refine_selector_steps = 0; refine_selector_steps < num_refine_selector_steps; refine_selector_steps++) + introduce_special_selector_clusters(); + } + else { - create_optimized_selector_codebook(refine_selector_steps); + const uint32_t num_refine_selector_steps = m_params.m_pGlobal_sel_codebook ? 1 : m_num_selector_codebook_iterations; + for (uint32_t refine_selector_steps = 0; refine_selector_steps < num_refine_selector_steps; refine_selector_steps++) + { + create_optimized_selector_codebook(refine_selector_steps); - find_optimal_selector_clusters_for_each_block(); + find_optimal_selector_clusters_for_each_block(); - introduce_special_selector_clusters(); + introduce_special_selector_clusters(); - if ((m_params.m_compression_level >= 3) || (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames)) - { - if (!refine_block_endpoints_given_selectors()) - break; + if ((m_params.m_compression_level >= 4) || (m_params.m_tex_type == basist::cBASISTexTypeVideoFrames)) + { + if (!refine_block_endpoints_given_selectors()) + break; + } } } - } - - optimize_selector_codebook(); + + optimize_selector_codebook(); - if (m_params.m_debug_stats) - debug_printf("Total selector clusters: %u\n", (uint32_t)m_selector_cluster_indices.size()); + if (m_params.m_debug_stats) + debug_printf("Total selector clusters: %u\n", (uint32_t)m_selector_cluster_block_indices.size()); + } finalize(); @@ -294,6 +317,259 @@ namespace basisu return true; } + bool basisu_frontend::init_global_codebooks() + { + const basist::basisu_lowlevel_etc1s_transcoder* pTranscoder = m_params.m_pGlobal_codebooks; + + const basist::basisu_lowlevel_etc1s_transcoder::endpoint_vec& endpoints = pTranscoder->get_endpoints(); + const basist::basisu_lowlevel_etc1s_transcoder::selector_vec& selectors = pTranscoder->get_selectors(); + + m_endpoint_cluster_etc_params.resize(endpoints.size()); + for (uint32_t i = 0; i < endpoints.size(); i++) + { + m_endpoint_cluster_etc_params[i].m_inten_table[0] = endpoints[i].m_inten5; + m_endpoint_cluster_etc_params[i].m_inten_table[1] = endpoints[i].m_inten5; + + m_endpoint_cluster_etc_params[i].m_color_unscaled[0].set(endpoints[i].m_color5.r, endpoints[i].m_color5.g, endpoints[i].m_color5.b, 255); + m_endpoint_cluster_etc_params[i].m_color_used[0] = true; + m_endpoint_cluster_etc_params[i].m_valid = true; + } + + m_optimized_cluster_selectors.resize(selectors.size()); + for (uint32_t i = 0; i < m_optimized_cluster_selectors.size(); i++) + { + for (uint32_t y = 0; y < 4; y++) + for (uint32_t x = 0; x < 4; x++) + m_optimized_cluster_selectors[i].set_selector(x, y, selectors[i].get_selector(x, y)); + } + + m_block_endpoint_clusters_indices.resize(m_total_blocks); + + m_orig_encoded_blocks.resize(m_total_blocks); + + m_block_selector_cluster_index.resize(m_total_blocks); + +#if 0 + for (uint32_t block_index_iter = 0; block_index_iter < m_total_blocks; block_index_iter += N) + { + const uint32_t first_index = block_index_iter; + const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->add_job([this, first_index, last_index] { +#endif + + for (uint32_t block_index = first_index; block_index < last_index; block_index++) + { + const etc_block& blk = m_etc1_blocks_etc1s[block_index]; + + const uint32_t block_endpoint_index = m_block_endpoint_clusters_indices[block_index][0]; + + etc_block trial_blk; + trial_blk.set_block_color5_etc1s(blk.m_color_unscaled[0]); + trial_blk.set_flip_bit(true); + + uint64_t best_err = UINT64_MAX; + uint32_t best_index = 0; + + for (uint32_t i = 0; i < m_optimized_cluster_selectors.size(); i++) + { + trial_blk.set_raw_selector_bits(m_optimized_cluster_selectors[i].get_raw_selector_bits()); + + const uint64_t cur_err = trial_blk.evaluate_etc1_error(get_source_pixel_block(block_index).get_ptr(), m_params.m_perceptual); + if (cur_err < best_err) + { + best_err = cur_err; + best_index = i; + if (!cur_err) + break; + } + + } // block_index + + m_block_selector_cluster_index[block_index] = best_index; + } + +#ifndef __EMSCRIPTEN__ + }); +#endif + + } + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->wait_for_all(); +#endif + + m_encoded_blocks.resize(m_total_blocks); + for (uint32_t block_index = 0; block_index < m_total_blocks; block_index++) + { + const uint32_t endpoint_index = m_block_endpoint_clusters_indices[block_index][0]; + const uint32_t selector_index = m_block_selector_cluster_index[block_index]; + + etc_block& blk = m_encoded_blocks[block_index]; + + blk.set_block_color5_etc1s(m_endpoint_cluster_etc_params[endpoint_index].m_color_unscaled[0]); + blk.set_inten_tables_etc1s(m_endpoint_cluster_etc_params[endpoint_index].m_inten_table[0]); + blk.set_flip_bit(true); + blk.set_raw_selector_bits(m_optimized_cluster_selectors[selector_index].get_raw_selector_bits()); + } +#endif + + // HACK HACK + const uint32_t NUM_PASSES = 3; + for (uint32_t pass = 0; pass < NUM_PASSES; pass++) + { + debug_printf("init_global_codebooks: pass %u\n", pass); + + const uint32_t N = 128; + for (uint32_t block_index_iter = 0; block_index_iter < m_total_blocks; block_index_iter += N) + { + const uint32_t first_index = block_index_iter; + const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->add_job([this, first_index, last_index, pass] { +#endif + + for (uint32_t block_index = first_index; block_index < last_index; block_index++) + { + const etc_block& blk = pass ? m_encoded_blocks[block_index] : m_etc1_blocks_etc1s[block_index]; + const uint32_t blk_raw_selector_bits = blk.get_raw_selector_bits(); + + etc_block trial_blk(blk); + trial_blk.set_raw_selector_bits(blk_raw_selector_bits); + trial_blk.set_flip_bit(true); + + uint64_t best_err = UINT64_MAX; + uint32_t best_index = 0; + etc_block best_block(trial_blk); + + for (uint32_t i = 0; i < m_endpoint_cluster_etc_params.size(); i++) + { + if (m_endpoint_cluster_etc_params[i].m_inten_table[0] > blk.get_inten_table(0)) + continue; + + trial_blk.set_block_color5_etc1s(m_endpoint_cluster_etc_params[i].m_color_unscaled[0]); + trial_blk.set_inten_tables_etc1s(m_endpoint_cluster_etc_params[i].m_inten_table[0]); + + const color_rgba* pSource_pixels = get_source_pixel_block(block_index).get_ptr(); + uint64_t cur_err; + if (!pass) + cur_err = trial_blk.determine_selectors(pSource_pixels, m_params.m_perceptual); + else + cur_err = trial_blk.evaluate_etc1_error(pSource_pixels, m_params.m_perceptual); + + if (cur_err < best_err) + { + best_err = cur_err; + best_index = i; + best_block = trial_blk; + + if (!cur_err) + break; + } + } + + m_block_endpoint_clusters_indices[block_index][0] = best_index; + m_block_endpoint_clusters_indices[block_index][1] = best_index; + + m_orig_encoded_blocks[block_index] = best_block; + + } // block_index + +#ifndef __EMSCRIPTEN__ + }); +#endif + + } + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->wait_for_all(); +#endif + + m_endpoint_clusters.resize(0); + m_endpoint_clusters.resize(endpoints.size()); + for (uint32_t block_index = 0; block_index < m_total_blocks; block_index++) + { + const uint32_t endpoint_cluster_index = m_block_endpoint_clusters_indices[block_index][0]; + m_endpoint_clusters[endpoint_cluster_index].push_back(block_index * 2); + m_endpoint_clusters[endpoint_cluster_index].push_back(block_index * 2 + 1); + } + + m_block_selector_cluster_index.resize(m_total_blocks); + + for (uint32_t block_index_iter = 0; block_index_iter < m_total_blocks; block_index_iter += N) + { + const uint32_t first_index = block_index_iter; + const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->add_job([this, first_index, last_index] { +#endif + + for (uint32_t block_index = first_index; block_index < last_index; block_index++) + { + const uint32_t block_endpoint_index = m_block_endpoint_clusters_indices[block_index][0]; + + etc_block trial_blk; + trial_blk.set_block_color5_etc1s(m_endpoint_cluster_etc_params[block_endpoint_index].m_color_unscaled[0]); + trial_blk.set_inten_tables_etc1s(m_endpoint_cluster_etc_params[block_endpoint_index].m_inten_table[0]); + trial_blk.set_flip_bit(true); + + uint64_t best_err = UINT64_MAX; + uint32_t best_index = 0; + + for (uint32_t i = 0; i < m_optimized_cluster_selectors.size(); i++) + { + trial_blk.set_raw_selector_bits(m_optimized_cluster_selectors[i].get_raw_selector_bits()); + + const uint64_t cur_err = trial_blk.evaluate_etc1_error(get_source_pixel_block(block_index).get_ptr(), m_params.m_perceptual); + if (cur_err < best_err) + { + best_err = cur_err; + best_index = i; + if (!cur_err) + break; + } + + } // block_index + + m_block_selector_cluster_index[block_index] = best_index; + } + +#ifndef __EMSCRIPTEN__ + }); +#endif + + } + +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->wait_for_all(); +#endif + + m_encoded_blocks.resize(m_total_blocks); + for (uint32_t block_index = 0; block_index < m_total_blocks; block_index++) + { + const uint32_t endpoint_index = m_block_endpoint_clusters_indices[block_index][0]; + const uint32_t selector_index = m_block_selector_cluster_index[block_index]; + + etc_block& blk = m_encoded_blocks[block_index]; + + blk.set_block_color5_etc1s(m_endpoint_cluster_etc_params[endpoint_index].m_color_unscaled[0]); + blk.set_inten_tables_etc1s(m_endpoint_cluster_etc_params[endpoint_index].m_inten_table[0]); + blk.set_flip_bit(true); + blk.set_raw_selector_bits(m_optimized_cluster_selectors[selector_index].get_raw_selector_bits()); + } + + } // pass + + m_selector_cluster_block_indices.resize(selectors.size()); + for (uint32_t block_index = 0; block_index < m_etc1_blocks_etc1s.size(); block_index++) + m_selector_cluster_block_indices[m_block_selector_cluster_index[block_index]].push_back(block_index); + + return true; + } + void basisu_frontend::introduce_special_selector_clusters() { debug_printf("introduce_special_selector_clusters\n"); @@ -302,7 +578,7 @@ namespace basisu return; uint32_t total_blocks_relocated = 0; - const uint32_t initial_selector_clusters = (uint32_t)m_selector_cluster_indices.size(); + const uint32_t initial_selector_clusters = (uint32_t)m_selector_cluster_block_indices.size(); bool_vec block_relocated_flags(m_total_blocks); @@ -328,7 +604,7 @@ namespace basisu m_optimized_cluster_selectors.push_back(blk); - vector_ensure_element_is_valid(m_selector_cluster_indices, new_selector_cluster_index); + vector_ensure_element_is_valid(m_selector_cluster_block_indices, new_selector_cluster_index); for (uint32_t block_index = 0; block_index < m_total_blocks; block_index++) { @@ -357,14 +633,14 @@ namespace basisu // Change the block to use the new cluster m_block_selector_cluster_index[block_index] = new_selector_cluster_index; - m_selector_cluster_indices[new_selector_cluster_index].push_back(block_index); + m_selector_cluster_block_indices[new_selector_cluster_index].push_back(block_index); block_relocated_flags[block_index] = true; #if 0 - int j = vector_find(m_selector_cluster_indices[old_selector_cluster_index], block_index); + int j = vector_find(m_selector_cluster_block_indices[old_selector_cluster_index], block_index); if (j >= 0) - m_selector_cluster_indices[old_selector_cluster_index].erase(m_selector_cluster_indices[old_selector_cluster_index].begin() + j); + m_selector_cluster_block_indices[old_selector_cluster_index].erase(m_selector_cluster_block_indices[old_selector_cluster_index].begin() + j); #endif total_blocks_relocated++; @@ -381,7 +657,7 @@ namespace basisu for (int selector_cluster_index = 0; selector_cluster_index < (int)initial_selector_clusters; selector_cluster_index++) { - uint_vec& block_indices = m_selector_cluster_indices[selector_cluster_index]; + uint_vec& block_indices = m_selector_cluster_block_indices[selector_cluster_index]; uint32_t dst_ofs = 0; @@ -399,6 +675,7 @@ namespace basisu debug_printf("Total blocks relocated to new flat selector clusters: %u\n", total_blocks_relocated); } + // This method will change the number and ordering of the selector codebook clusters. void basisu_frontend::optimize_selector_codebook() { debug_printf("optimize_selector_codebook\n"); @@ -436,15 +713,17 @@ namespace basisu new_to_old.push_back(i); } + debug_printf("Original selector clusters: %u, new cluster selectors: %u\n", orig_total_selector_clusters, total_new_entries); + for (uint32_t i = 0; i < m_block_selector_cluster_index.size(); i++) { BASISU_FRONTEND_VERIFY((old_to_new[m_block_selector_cluster_index[i]] >= 0) && (old_to_new[m_block_selector_cluster_index[i]] < (int)total_new_entries)); m_block_selector_cluster_index[i] = old_to_new[m_block_selector_cluster_index[i]]; } - std::vector<etc_block> new_optimized_cluster_selectors(m_optimized_cluster_selectors.size() ? total_new_entries : 0); + basisu::vector<etc_block> new_optimized_cluster_selectors(m_optimized_cluster_selectors.size() ? total_new_entries : 0); basist::etc1_global_selector_codebook_entry_id_vec new_optimized_cluster_selector_global_cb_ids(m_optimized_cluster_selector_global_cb_ids.size() ? total_new_entries : 0); - std::vector<uint_vec> new_selector_cluster_indices(m_selector_cluster_indices.size() ? total_new_entries : 0); + basisu::vector<uint_vec> new_selector_cluster_indices(m_selector_cluster_block_indices.size() ? total_new_entries : 0); bool_vec new_selector_cluster_uses_global_cb(m_selector_cluster_uses_global_cb.size() ? total_new_entries : 0); for (uint32_t i = 0; i < total_new_entries; i++) @@ -455,24 +734,40 @@ namespace basisu if (m_optimized_cluster_selector_global_cb_ids.size()) new_optimized_cluster_selector_global_cb_ids[i] = m_optimized_cluster_selector_global_cb_ids[new_to_old[i]]; - if (m_selector_cluster_indices.size()) - new_selector_cluster_indices[i] = m_selector_cluster_indices[new_to_old[i]]; + //if (m_selector_cluster_block_indices.size()) + // new_selector_cluster_indices[i] = m_selector_cluster_block_indices[new_to_old[i]]; if (m_selector_cluster_uses_global_cb.size()) new_selector_cluster_uses_global_cb[i] = m_selector_cluster_uses_global_cb[new_to_old[i]]; } + for (uint32_t i = 0; i < m_block_selector_cluster_index.size(); i++) + { + new_selector_cluster_indices[m_block_selector_cluster_index[i]].push_back(i); + } + m_optimized_cluster_selectors.swap(new_optimized_cluster_selectors); m_optimized_cluster_selector_global_cb_ids.swap(new_optimized_cluster_selector_global_cb_ids); - m_selector_cluster_indices.swap(new_selector_cluster_indices); + m_selector_cluster_block_indices.swap(new_selector_cluster_indices); m_selector_cluster_uses_global_cb.swap(new_selector_cluster_uses_global_cb); - + + // This isn't strictly necessary - doing it for completeness/future sanity. + if (m_selector_clusters_within_each_parent_cluster.size()) + { + for (uint32_t i = 0; i < m_selector_clusters_within_each_parent_cluster.size(); i++) + for (uint32_t j = 0; j < m_selector_clusters_within_each_parent_cluster[i].size(); j++) + m_selector_clusters_within_each_parent_cluster[i][j] = old_to_new[m_selector_clusters_within_each_parent_cluster[i][j]]; + } + debug_printf("optimize_selector_codebook: Before: %u After: %u\n", orig_total_selector_clusters, total_new_entries); } void basisu_frontend::init_etc1_images() { debug_printf("basisu_frontend::init_etc1_images\n"); + + interval_timer tm; + tm.start(); m_etc1_blocks_etc1s.resize(m_total_blocks); @@ -481,8 +776,10 @@ namespace basisu { const uint32_t first_index = block_index_iter; const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index] { +#endif for (uint32_t block_index = first_index; block_index < last_index; block_index++) { @@ -494,6 +791,8 @@ namespace basisu if (m_params.m_compression_level == 0) optimizer_params.m_quality = cETCQualityFast; + else if (m_params.m_compression_level == 1) + optimizer_params.m_quality = cETCQualityMedium; else if (m_params.m_compression_level == BASISU_MAX_COMPRESSION_LEVEL) optimizer_params.m_quality = cETCQualityUber; @@ -506,8 +805,9 @@ namespace basisu optimizer_results.m_n = 16; optimizer.init(optimizer_params, optimizer_results); - optimizer.compute(); - + if (!optimizer.compute()) + BASISU_FRONTEND_VERIFY(false); + etc_block &blk = m_etc1_blocks_etc1s[block_index]; memset(&blk, 0, sizeof(blk)); @@ -520,10 +820,17 @@ namespace basisu blk.set_selector(x, y, selectors[x + y * 4]); } +#ifndef __EMSCRIPTEN__ } ); +#endif + } - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif + + debug_printf("Elapsed time: %3.3f secs\n", tm.get_elapsed_secs()); } void basisu_frontend::init_endpoint_training_vectors() @@ -540,7 +847,9 @@ namespace basisu const uint32_t first_index = block_index_iter; const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, &training_vecs] { +#endif for (uint32_t block_index = first_index; block_index < last_index; block_index++) { @@ -562,11 +871,15 @@ namespace basisu } // block_index; +#ifndef __EMSCRIPTEN__ } ); +#endif } // block_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif } void basisu_frontend::generate_endpoint_clusters() @@ -649,7 +962,7 @@ namespace basisu for (int cluster_index = 0; cluster_index < static_cast<int>(m_endpoint_clusters.size()); cluster_index++) { - const std::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; + const basisu::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; for (uint32_t cluster_indices_iter = 0; cluster_indices_iter < cluster_indices.size(); cluster_indices_iter++) { @@ -707,17 +1020,19 @@ namespace basisu const uint32_t first_index = cluster_index_iter; const uint32_t last_index = minimum<uint32_t>((uint32_t)m_endpoint_clusters.size(), cluster_index_iter + N); +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index] { +#endif for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++) { - const std::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; + const basisu::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; assert(cluster_indices.size()); for (uint32_t cluster_indices_iter = 0; cluster_indices_iter < cluster_indices.size(); cluster_indices_iter++) { - std::vector<color_rgba> cluster_pixels(8); + basisu::vector<color_rgba> cluster_pixels(8); const uint32_t block_index = cluster_indices[cluster_indices_iter] >> 1; const uint32_t subblock_index = cluster_indices[cluster_indices_iter] & 1; @@ -775,10 +1090,15 @@ namespace basisu } } // cluster_index +#ifndef __EMSCRIPTEN__ } ); +#endif + } // cluster_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif vector_sort(m_subblock_endpoint_quant_err_vec); } @@ -837,7 +1157,7 @@ namespace basisu continue; #endif - const uint32_t new_endpoint_cluster_index = (uint32_t)m_endpoint_clusters.size(); + //const uint32_t new_endpoint_cluster_index = (uint32_t)m_endpoint_clusters.size(); enlarge_vector(m_endpoint_clusters, 1)->push_back(training_vector_index); enlarge_vector(m_endpoint_cluster_etc_params, 1); @@ -893,18 +1213,20 @@ namespace basisu { const uint32_t first_index = cluster_index_iter; const uint32_t last_index = minimum<uint32_t>((uint32_t)m_endpoint_clusters.size(), cluster_index_iter + N); - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, step ] { +#endif for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++) { - const std::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; + const basisu::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; BASISU_FRONTEND_VERIFY(cluster_indices.size()); const uint32_t total_pixels = (uint32_t)cluster_indices.size() * 8; - std::vector<color_rgba> cluster_pixels(total_pixels); + basisu::vector<color_rgba> cluster_pixels(total_pixels); for (uint32_t cluster_indices_iter = 0; cluster_indices_iter < cluster_indices.size(); cluster_indices_iter++) { @@ -935,20 +1257,21 @@ namespace basisu cluster_optimizer_params.m_use_color4 = false; cluster_optimizer_params.m_perceptual = m_params.m_perceptual; - if (m_params.m_compression_level == 0) + if (m_params.m_compression_level <= 1) cluster_optimizer_params.m_quality = cETCQualityMedium; else if (m_params.m_compression_level == BASISU_MAX_COMPRESSION_LEVEL) cluster_optimizer_params.m_quality = cETCQualityUber; etc1_optimizer::results cluster_optimizer_results; - std::vector<uint8_t> cluster_selectors(total_pixels); + basisu::vector<uint8_t> cluster_selectors(total_pixels); cluster_optimizer_results.m_n = total_pixels; cluster_optimizer_results.m_pSelectors = &cluster_selectors[0]; optimizer.init(cluster_optimizer_params, cluster_optimizer_results); - optimizer.compute(); + if (!optimizer.compute()) + BASISU_FRONTEND_VERIFY(false); new_subblock_params.m_color_unscaled[0] = cluster_optimizer_results.m_block_color_unscaled; new_subblock_params.m_inten_table[0] = cluster_optimizer_results.m_block_inten_table; @@ -1012,20 +1335,24 @@ namespace basisu } // cluster_index +#ifndef __EMSCRIPTEN__ } ); +#endif } // cluster_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif } bool basisu_frontend::check_etc1s_constraints() const { - std::vector<vec2U> block_clusters(m_total_blocks); + basisu::vector<vec2U> block_clusters(m_total_blocks); for (int cluster_index = 0; cluster_index < static_cast<int>(m_endpoint_clusters.size()); cluster_index++) { - const std::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; + const basisu::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; for (uint32_t cluster_indices_iter = 0; cluster_indices_iter < cluster_indices.size(); cluster_indices_iter++) { @@ -1053,11 +1380,11 @@ namespace basisu if (m_use_hierarchical_endpoint_codebooks) compute_endpoint_clusters_within_each_parent_cluster(); - std::vector<vec2U> block_clusters(m_total_blocks); + basisu::vector<vec2U> block_clusters(m_total_blocks); for (int cluster_index = 0; cluster_index < static_cast<int>(m_endpoint_clusters.size()); cluster_index++) { - const std::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; + const basisu::vector<uint32_t>& cluster_indices = m_endpoint_clusters[cluster_index]; for (uint32_t cluster_indices_iter = 0; cluster_indices_iter < cluster_indices.size(); cluster_indices_iter++) { @@ -1081,19 +1408,19 @@ namespace basisu const uint32_t first_index = block_index_iter; const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, &best_cluster_indices, &block_clusters] { +#endif for (uint32_t block_index = first_index; block_index < last_index; block_index++) { - const bool is_flipped = true; - const uint32_t cluster_index = block_clusters[block_index][0]; BASISU_FRONTEND_VERIFY(cluster_index == block_clusters[block_index][1]); - const color_rgba *subblock_pixels = get_source_pixel_block(block_index).get_ptr(); + const color_rgba *pSubblock_pixels = get_source_pixel_block(block_index).get_ptr(); const uint32_t num_subblock_pixels = 16; - uint64_t best_cluster_err = UINT64_MAX; + uint64_t best_cluster_err = INT64_MAX; uint32_t best_cluster_index = 0; const uint32_t block_parent_endpoint_cluster_index = m_block_parent_endpoint_cluster.size() ? m_block_parent_endpoint_cluster[block_index] : 0; @@ -1116,19 +1443,20 @@ namespace basisu // Can't assign it here - may result in too much error when selector quant occurs if (cluster_etc_inten > m_endpoint_cluster_etc_params[cluster_index].m_inten_table[0]) { - total_err = UINT64_MAX; + total_err = INT64_MAX; goto skip_cluster; } etc_block::get_block_colors5(subblock_colors, cluster_etc_base_color, cluster_etc_inten); - + +#if 0 for (uint32_t p = 0; p < num_subblock_pixels; p++) { uint64_t best_err = UINT64_MAX; for (uint32_t r = low_selector; r <= high_selector; r++) { - uint64_t err = color_distance(m_params.m_perceptual, subblock_pixels[p], subblock_colors[r], false); + uint64_t err = color_distance(m_params.m_perceptual, pSubblock_pixels[p], subblock_colors[r], false); best_err = minimum(best_err, err); if (!best_err) break; @@ -1138,6 +1466,64 @@ namespace basisu if (total_err > best_cluster_err) break; } // p +#else + if (m_params.m_perceptual) + { + if (!g_cpu_supports_sse41) + { + for (uint32_t p = 0; p < num_subblock_pixels; p++) + { + uint64_t best_err = UINT64_MAX; + + for (uint32_t r = low_selector; r <= high_selector; r++) + { + uint64_t err = color_distance(true, pSubblock_pixels[p], subblock_colors[r], false); + best_err = minimum(best_err, err); + if (!best_err) + break; + } + + total_err += best_err; + if (total_err > best_cluster_err) + break; + } // p + } + else + { +#if BASISU_SUPPORT_SSE + find_lowest_error_perceptual_rgb_4_N_sse41((int64_t*)&total_err, subblock_colors, pSubblock_pixels, num_subblock_pixels, best_cluster_err); +#endif + } + } + else + { + if (!g_cpu_supports_sse41) + { + for (uint32_t p = 0; p < num_subblock_pixels; p++) + { + uint64_t best_err = UINT64_MAX; + + for (uint32_t r = low_selector; r <= high_selector; r++) + { + uint64_t err = color_distance(false, pSubblock_pixels[p], subblock_colors[r], false); + best_err = minimum(best_err, err); + if (!best_err) + break; + } + + total_err += best_err; + if (total_err > best_cluster_err) + break; + } // p + } + else + { +#if BASISU_SUPPORT_SSE + find_lowest_error_linear_rgb_4_N_sse41((int64_t*)&total_err, subblock_colors, pSubblock_pixels, num_subblock_pixels, best_cluster_err); +#endif + } + } +#endif skip_cluster: if ((total_err < best_cluster_err) || @@ -1154,14 +1540,18 @@ namespace basisu best_cluster_indices[block_index] = best_cluster_index; } // block_index - + +#ifndef __EMSCRIPTEN__ } ); +#endif } // block_index_iter - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif - std::vector<typename std::vector<uint32_t> > optimized_endpoint_clusters(m_endpoint_clusters.size()); + basisu::vector<typename basisu::vector<uint32_t> > optimized_endpoint_clusters(m_endpoint_clusters.size()); uint32_t total_subblocks_reassigned = 0; for (uint32_t block_index = 0; block_index < m_total_blocks; block_index++) @@ -1199,8 +1589,8 @@ namespace basisu indirect_sort((uint32_t)m_endpoint_clusters.size(), &sorted_endpoint_cluster_indices[0], &m_endpoint_cluster_etc_params[0]); - std::vector<std::vector<uint32_t> > new_endpoint_clusters(m_endpoint_clusters.size()); - std::vector<endpoint_cluster_etc_params> new_subblock_etc_params(m_endpoint_clusters.size()); + basisu::vector<basisu::vector<uint32_t> > new_endpoint_clusters(m_endpoint_clusters.size()); + basisu::vector<endpoint_cluster_etc_params> new_subblock_etc_params(m_endpoint_clusters.size()); for (uint32_t i = 0; i < m_endpoint_clusters.size(); i++) { @@ -1264,7 +1654,9 @@ namespace basisu const uint32_t first_index = block_index_iter; const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index] { +#endif for (uint32_t block_index = first_index; block_index < last_index; block_index++) { @@ -1288,12 +1680,16 @@ namespace basisu blk.determine_selectors(pSource_pixels, m_params.m_perceptual); } // block_index - + +#ifndef __EMSCRIPTEN__ } ); +#endif } // block_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif m_orig_encoded_blocks = m_encoded_blocks; } @@ -1302,9 +1698,9 @@ namespace basisu { uint_vec block_selector_cluster_indices(m_total_blocks); - for (int cluster_index = 0; cluster_index < static_cast<int>(m_selector_cluster_indices.size()); cluster_index++) + for (int cluster_index = 0; cluster_index < static_cast<int>(m_selector_cluster_block_indices.size()); cluster_index++) { - const std::vector<uint32_t>& cluster_indices = m_selector_cluster_indices[cluster_index]; + const basisu::vector<uint32_t>& cluster_indices = m_selector_cluster_block_indices[cluster_index]; for (uint32_t cluster_indices_iter = 0; cluster_indices_iter < cluster_indices.size(); cluster_indices_iter++) { @@ -1317,7 +1713,7 @@ namespace basisu } // cluster_index m_selector_clusters_within_each_parent_cluster.resize(0); - m_selector_clusters_within_each_parent_cluster.resize(m_selector_parent_cluster_indices.size()); + m_selector_clusters_within_each_parent_cluster.resize(m_selector_parent_cluster_block_indices.size()); for (uint32_t block_index = 0; block_index < m_total_blocks; block_index++) { @@ -1355,7 +1751,9 @@ namespace basisu const uint32_t first_index = block_index_iter; const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, &training_vecs] { +#endif for (uint32_t block_index = first_index; block_index < last_index; block_index++) { @@ -1382,47 +1780,54 @@ namespace basisu } // block_index +#ifndef __EMSCRIPTEN__ } ); +#endif } // block_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif vec16F_clusterizer selector_clusterizer; for (uint32_t i = 0; i < m_total_blocks; i++) selector_clusterizer.add_training_vec(training_vecs[i].first, training_vecs[i].second); - const uint32_t parent_codebook_size = (m_params.m_max_selector_clusters >= 256) ? BASISU_SELECTOR_PARENT_CODEBOOK_SIZE : 0; + const int selector_parent_codebook_size = (m_params.m_compression_level <= 1) ? BASISU_SELECTOR_PARENT_CODEBOOK_SIZE_COMP_LEVEL_01 : BASISU_SELECTOR_PARENT_CODEBOOK_SIZE_COMP_LEVEL_DEFAULT; + const uint32_t parent_codebook_size = (m_params.m_max_selector_clusters >= 256) ? selector_parent_codebook_size : 0; + debug_printf("Using selector parent codebook size %u\n", parent_codebook_size); uint32_t max_threads = 0; max_threads = m_params.m_multithreaded ? minimum<int>(std::thread::hardware_concurrency(), cMaxCodebookCreationThreads) : 0; bool status = generate_hierarchical_codebook_threaded(selector_clusterizer, m_params.m_max_selector_clusters, m_use_hierarchical_selector_codebooks ? parent_codebook_size : 0, - m_selector_cluster_indices, - m_selector_parent_cluster_indices, + m_selector_cluster_block_indices, + m_selector_parent_cluster_block_indices, max_threads, m_params.m_pJob_pool); BASISU_FRONTEND_VERIFY(status); if (m_use_hierarchical_selector_codebooks) { - if (!m_selector_parent_cluster_indices.size()) + if (!m_selector_parent_cluster_block_indices.size()) { - m_selector_parent_cluster_indices.resize(0); - m_selector_parent_cluster_indices.resize(1); + m_selector_parent_cluster_block_indices.resize(0); + m_selector_parent_cluster_block_indices.resize(1); for (uint32_t i = 0; i < m_total_blocks; i++) - m_selector_parent_cluster_indices[0].push_back(i); + m_selector_parent_cluster_block_indices[0].push_back(i); } - BASISU_ASSUME(BASISU_SELECTOR_PARENT_CODEBOOK_SIZE <= UINT8_MAX); + BASISU_ASSUME(BASISU_SELECTOR_PARENT_CODEBOOK_SIZE_COMP_LEVEL_01 <= UINT8_MAX); + BASISU_ASSUME(BASISU_SELECTOR_PARENT_CODEBOOK_SIZE_COMP_LEVEL_DEFAULT <= UINT8_MAX); m_block_parent_selector_cluster.resize(0); m_block_parent_selector_cluster.resize(m_total_blocks); vector_set_all(m_block_parent_selector_cluster, 0xFF); - for (uint32_t parent_cluster_index = 0; parent_cluster_index < m_selector_parent_cluster_indices.size(); parent_cluster_index++) + for (uint32_t parent_cluster_index = 0; parent_cluster_index < m_selector_parent_cluster_block_indices.size(); parent_cluster_index++) { - const uint_vec &cluster = m_selector_parent_cluster_indices[parent_cluster_index]; + const uint_vec &cluster = m_selector_parent_cluster_block_indices[parent_cluster_index]; for (uint32_t j = 0; j < cluster.size(); j++) m_block_parent_selector_cluster[cluster[j]] = static_cast<uint8_t>(parent_cluster_index); } @@ -1432,9 +1837,9 @@ namespace basisu } // Ensure that all the blocks within each cluster are all in the same parent cluster, or something is very wrong. - for (uint32_t cluster_index = 0; cluster_index < m_selector_cluster_indices.size(); cluster_index++) + for (uint32_t cluster_index = 0; cluster_index < m_selector_cluster_block_indices.size(); cluster_index++) { - const uint_vec &cluster = m_selector_cluster_indices[cluster_index]; + const uint_vec &cluster = m_selector_cluster_block_indices[cluster_index]; uint32_t parent_cluster_index = 0; for (uint32_t j = 0; j < cluster.size(); j++) @@ -1452,14 +1857,16 @@ namespace basisu } } - debug_printf("Total selector clusters: %u, total parent selector clusters: %u\n", (uint32_t)m_selector_cluster_indices.size(), (uint32_t)m_selector_parent_cluster_indices.size()); + debug_printf("Total selector clusters: %u, total parent selector clusters: %u\n", (uint32_t)m_selector_cluster_block_indices.size(), (uint32_t)m_selector_parent_cluster_block_indices.size()); } void basisu_frontend::create_optimized_selector_codebook(uint32_t iter) { debug_printf("create_optimized_selector_codebook\n"); - const uint32_t total_selector_clusters = (uint32_t)m_selector_cluster_indices.size(); + const uint32_t total_selector_clusters = (uint32_t)m_selector_cluster_block_indices.size(); + + debug_printf("Total selector clusters (from m_selector_cluster_block_indices.size()): %u\n", (uint32_t)m_selector_cluster_block_indices.size()); m_optimized_cluster_selectors.resize(total_selector_clusters); @@ -1474,12 +1881,14 @@ namespace basisu { const uint32_t first_index = cluster_index_iter; const uint32_t last_index = minimum<uint32_t>((uint32_t)total_selector_clusters, cluster_index_iter + N); - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, &total_clusters_processed, &total_selector_clusters] { +#endif for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++) { - const std::vector<uint32_t> &cluster_block_indices = m_selector_cluster_indices[cluster_index]; + const basisu::vector<uint32_t> &cluster_block_indices = m_selector_cluster_block_indices[cluster_index]; if (!cluster_block_indices.size()) continue; @@ -1528,11 +1937,15 @@ namespace basisu } // cluster_index +#ifndef __EMSCRIPTEN__ } ); +#endif } // cluster_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif } else { @@ -1552,12 +1965,14 @@ namespace basisu { const uint32_t first_index = cluster_index_iter; const uint32_t last_index = minimum<uint32_t>((uint32_t)total_selector_clusters, cluster_index_iter + N); - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, &uses_hybrid_sel_codebook, &total_clusters_processed, &total_selector_clusters] { +#endif for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++) { - const std::vector<uint32_t> &cluster_block_indices = m_selector_cluster_indices[cluster_index]; + const basisu::vector<uint32_t> &cluster_block_indices = m_selector_cluster_block_indices[cluster_index]; if (!cluster_block_indices.size()) continue; @@ -1667,29 +2082,33 @@ namespace basisu } // cluster_index +#ifndef __EMSCRIPTEN__ } ); +#endif } // cluster_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif } // if (m_params.m_pGlobal_sel_codebook) - + if (m_params.m_debug_images) { uint32_t max_selector_cluster_size = 0; - for (uint32_t i = 0; i < m_selector_cluster_indices.size(); i++) - max_selector_cluster_size = maximum<uint32_t>(max_selector_cluster_size, (uint32_t)m_selector_cluster_indices[i].size()); + for (uint32_t i = 0; i < m_selector_cluster_block_indices.size(); i++) + max_selector_cluster_size = maximum<uint32_t>(max_selector_cluster_size, (uint32_t)m_selector_cluster_block_indices[i].size()); if ((max_selector_cluster_size * 5) < 32768) { const uint32_t x_spacer_len = 16; - image selector_cluster_vis(x_spacer_len + max_selector_cluster_size * 5, (uint32_t)m_selector_cluster_indices.size() * 5); + image selector_cluster_vis(x_spacer_len + max_selector_cluster_size * 5, (uint32_t)m_selector_cluster_block_indices.size() * 5); - for (uint32_t selector_cluster_index = 0; selector_cluster_index < m_selector_cluster_indices.size(); selector_cluster_index++) + for (uint32_t selector_cluster_index = 0; selector_cluster_index < m_selector_cluster_block_indices.size(); selector_cluster_index++) { - const std::vector<uint32_t> &cluster_block_indices = m_selector_cluster_indices[selector_cluster_index]; + const basisu::vector<uint32_t> &cluster_block_indices = m_selector_cluster_block_indices[selector_cluster_index]; for (uint32_t y = 0; y < 4; y++) for (uint32_t x = 0; x < 4; x++) @@ -1717,31 +2136,56 @@ namespace basisu void basisu_frontend::find_optimal_selector_clusters_for_each_block() { debug_printf("find_optimal_selector_clusters_for_each_block\n"); - + + // Sanity checks + BASISU_FRONTEND_VERIFY(m_selector_cluster_block_indices.size() == m_optimized_cluster_selectors.size()); + for (uint32_t i = 0; i < m_selector_clusters_within_each_parent_cluster.size(); i++) + { + for (uint32_t j = 0; j < m_selector_clusters_within_each_parent_cluster[i].size(); j++) + { + BASISU_FRONTEND_VERIFY(m_selector_clusters_within_each_parent_cluster[i][j] < m_optimized_cluster_selectors.size()); + } + } + m_block_selector_cluster_index.resize(m_total_blocks); - + if (m_params.m_compression_level == 0) { // Don't do anything, just leave the blocks in their original selector clusters. - for (uint32_t i = 0; i < m_selector_cluster_indices.size(); i++) + for (uint32_t i = 0; i < m_selector_cluster_block_indices.size(); i++) { - for (uint32_t j = 0; j < m_selector_cluster_indices[i].size(); j++) - m_block_selector_cluster_index[m_selector_cluster_indices[i][j]] = i; + for (uint32_t j = 0; j < m_selector_cluster_block_indices[i].size(); j++) + m_block_selector_cluster_index[m_selector_cluster_block_indices[i][j]] = i; } } else { - std::vector< std::vector<uint32_t> > new_cluster_indices; - + // Note that this method may leave some empty clusters (i.e. arrays with no block indices), including at the end. + basisu::vector< basisu::vector<uint32_t> > new_cluster_indices(m_optimized_cluster_selectors.size()); + // For each block: Determine which quantized selectors best encode that block, given its quantized endpoints. + basisu::vector<uint8_t> unpacked_optimized_cluster_selectors(16 * m_optimized_cluster_selectors.size()); + for (uint32_t cluster_index = 0; cluster_index < m_optimized_cluster_selectors.size(); cluster_index++) + { + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + unpacked_optimized_cluster_selectors[cluster_index * 16 + y * 4 + x] = (uint8_t)m_optimized_cluster_selectors[cluster_index].get_selector(x, y); + } + } + } + const uint32_t N = 1024; for (uint32_t block_index_iter = 0; block_index_iter < m_total_blocks; block_index_iter += N) { const uint32_t first_index = block_index_iter; const uint32_t last_index = minimum<uint32_t>(m_total_blocks, first_index + N); - m_params.m_pJob_pool->add_job( [this, first_index, last_index, &new_cluster_indices] { +#ifndef __EMSCRIPTEN__ + m_params.m_pJob_pool->add_job( [this, first_index, last_index, &new_cluster_indices, &unpacked_optimized_cluster_selectors] { +#endif for (uint32_t block_index = first_index; block_index < last_index; block_index++) { @@ -1752,20 +2196,32 @@ namespace basisu color_rgba trial_block_colors[4]; blk.get_block_colors(trial_block_colors, 0); - uint64_t best_cluster_err = UINT64_MAX; + // precompute errors for the i-th block pixel and selector sel: [sel][i] + uint32_t trial_errors[4][16]; + + for (int sel = 0; sel < 4; ++sel) + { + for (int i = 0; i < 16; ++i) + { + trial_errors[sel][i] = color_distance(m_params.m_perceptual, pBlock_pixels[i], trial_block_colors[sel], false); + } + } + + uint64_t best_cluster_err = INT64_MAX; uint32_t best_cluster_index = 0; const uint32_t parent_selector_cluster = m_block_parent_selector_cluster.size() ? m_block_parent_selector_cluster[block_index] : 0; const uint_vec *pCluster_indices = m_selector_clusters_within_each_parent_cluster.size() ? &m_selector_clusters_within_each_parent_cluster[parent_selector_cluster] : nullptr; - const uint32_t total_clusters = m_use_hierarchical_selector_codebooks ? (uint32_t)pCluster_indices->size() : (uint32_t)m_selector_cluster_indices.size(); + const uint32_t total_clusters = m_use_hierarchical_selector_codebooks ? (uint32_t)pCluster_indices->size() : (uint32_t)m_selector_cluster_block_indices.size(); +#if 0 for (uint32_t cluster_iter = 0; cluster_iter < total_clusters; cluster_iter++) { const uint32_t cluster_index = m_use_hierarchical_selector_codebooks ? (*pCluster_indices)[cluster_iter] : cluster_iter; const etc_block& cluster_blk = m_optimized_cluster_selectors[cluster_index]; - + uint64_t trial_err = 0; for (int y = 0; y < 4; y++) { @@ -1778,18 +2234,82 @@ namespace basisu goto early_out; } } - + if (trial_err < best_cluster_err) { best_cluster_err = trial_err; best_cluster_index = cluster_index; - if (!best_cluster_err) + if (!best_cluster_err) break; } early_out: ; } +#else + if (m_params.m_perceptual) + { + for (uint32_t cluster_iter = 0; cluster_iter < total_clusters; cluster_iter++) + { + const uint32_t cluster_index = m_use_hierarchical_selector_codebooks ? (*pCluster_indices)[cluster_iter] : cluster_iter; + //const etc_block& cluster_blk = m_optimized_cluster_selectors[cluster_index]; + + uint64_t trial_err = 0; + + for (int i = 0; i < 16; i++) + { + const uint32_t sel = unpacked_optimized_cluster_selectors[cluster_index * 16 + i]; + + trial_err += trial_errors[sel][i]; + if (trial_err > best_cluster_err) + goto early_out; + } + + if (trial_err < best_cluster_err) + { + best_cluster_err = trial_err; + best_cluster_index = cluster_index; + if (!best_cluster_err) + break; + } + + early_out: + ; + + } // cluster_iter + } + else + { + for (uint32_t cluster_iter = 0; cluster_iter < total_clusters; cluster_iter++) + { + const uint32_t cluster_index = m_use_hierarchical_selector_codebooks ? (*pCluster_indices)[cluster_iter] : cluster_iter; + //const etc_block& cluster_blk = m_optimized_cluster_selectors[cluster_index]; + + uint64_t trial_err = 0; + + for (int i = 0; i < 16; i++) + { + const uint32_t sel = unpacked_optimized_cluster_selectors[cluster_index * 16 + i]; + + trial_err += trial_errors[sel][i]; + if (trial_err > best_cluster_err) + goto early_out2; + } + + if (trial_err < best_cluster_err) + { + best_cluster_err = trial_err; + best_cluster_index = cluster_index; + if (!best_cluster_err) + break; + } + + early_out2: + ; + + } // cluster_iter + } +#endif blk.set_raw_selector_bits(m_optimized_cluster_selectors[best_cluster_index].get_raw_selector_bits()); @@ -1804,17 +2324,21 @@ namespace basisu } // block_index +#ifndef __EMSCRIPTEN__ } ); +#endif } // block_index_iter - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); - - m_selector_cluster_indices.swap(new_cluster_indices); +#endif + + m_selector_cluster_block_indices.swap(new_cluster_indices); } - for (uint32_t i = 0; i < m_selector_cluster_indices.size(); i++) - vector_sort(m_selector_cluster_indices[i]); + for (uint32_t i = 0; i < m_selector_cluster_block_indices.size(); i++) + vector_sort(m_selector_cluster_block_indices[i]); } // TODO: Remove old ETC1 specific stuff, and thread this. @@ -1842,7 +2366,7 @@ namespace basisu const uint_vec &subblocks = subblock_params.m_subblocks; //uint32_t total_pixels = subblock.m_subblocks.size() * 8; - std::vector<color_rgba> subblock_colors[2]; // [use_individual_mode] + basisu::vector<color_rgba> subblock_colors[2]; // [use_individual_mode] uint8_vec subblock_selectors[2]; uint64_t cur_subblock_err[2] = { 0, 0 }; @@ -1882,7 +2406,7 @@ namespace basisu clear_obj(cluster_optimizer_results); - std::vector<uint8_t> cluster_selectors[2]; + basisu::vector<uint8_t> cluster_selectors[2]; for (uint32_t use_individual_mode = 0; use_individual_mode < 2; use_individual_mode++) { @@ -1938,7 +2462,7 @@ namespace basisu const uint32_t block_index = training_vector_index >> 1; const uint32_t subblock_index = training_vector_index & 1; - const bool is_flipped = true; + //const bool is_flipped = true; etc_block &blk = m_encoded_blocks[block_index]; @@ -2002,7 +2526,7 @@ namespace basisu if (m_params.m_debug_stats) debug_printf("Total subblock endpoints refined: %u (%3.1f%%)\n", total_subblocks_refined, total_subblocks_refined * 100.0f / total_subblocks_examined); - + return total_subblocks_refined; } @@ -2012,8 +2536,8 @@ namespace basisu uint32_t max_endpoint_cluster_size = 0; - std::vector<uint32_t> cluster_sizes(m_endpoint_clusters.size()); - std::vector<uint32_t> sorted_cluster_indices(m_endpoint_clusters.size()); + basisu::vector<uint32_t> cluster_sizes(m_endpoint_clusters.size()); + basisu::vector<uint32_t> sorted_cluster_indices(m_endpoint_clusters.size()); for (uint32_t i = 0; i < m_endpoint_clusters.size(); i++) { max_endpoint_cluster_size = maximum<uint32_t>(max_endpoint_cluster_size, (uint32_t)m_endpoint_clusters[i].size()); @@ -2100,30 +2624,33 @@ namespace basisu { debug_printf("reoptimize_remapped_endpoints\n"); - std::vector<uint_vec> new_endpoint_cluster_block_indices(m_endpoint_clusters.size()); + basisu::vector<uint_vec> new_endpoint_cluster_block_indices(m_endpoint_clusters.size()); for (uint32_t i = 0; i < new_block_endpoints.size(); i++) new_endpoint_cluster_block_indices[new_block_endpoints[i]].push_back(i); - std::vector<uint8_t> cluster_valid(new_endpoint_cluster_block_indices.size()); - std::vector<uint8_t> cluster_improved(new_endpoint_cluster_block_indices.size()); + basisu::vector<uint8_t> cluster_valid(new_endpoint_cluster_block_indices.size()); + basisu::vector<uint8_t> cluster_improved(new_endpoint_cluster_block_indices.size()); const uint32_t N = 256; for (uint32_t cluster_index_iter = 0; cluster_index_iter < new_endpoint_cluster_block_indices.size(); cluster_index_iter += N) { const uint32_t first_index = cluster_index_iter; const uint32_t last_index = minimum<uint32_t>((uint32_t)new_endpoint_cluster_block_indices.size(), cluster_index_iter + N); - + +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->add_job( [this, first_index, last_index, &cluster_improved, &cluster_valid, &new_endpoint_cluster_block_indices, &pBlock_selector_indices ] { +#endif + for (uint32_t cluster_index = first_index; cluster_index < last_index; cluster_index++) { - const std::vector<uint32_t>& cluster_block_indices = new_endpoint_cluster_block_indices[cluster_index]; + const basisu::vector<uint32_t>& cluster_block_indices = new_endpoint_cluster_block_indices[cluster_index]; if (!cluster_block_indices.size()) continue; const uint32_t total_pixels = (uint32_t)cluster_block_indices.size() * 16; - std::vector<color_rgba> cluster_pixels(total_pixels); + basisu::vector<color_rgba> cluster_pixels(total_pixels); uint8_vec force_selectors(total_pixels); etc_block blk; @@ -2170,16 +2697,19 @@ namespace basisu if (m_params.m_compression_level == BASISU_MAX_COMPRESSION_LEVEL) cluster_optimizer_params.m_quality = cETCQualityUber; + else + cluster_optimizer_params.m_quality = cETCQualitySlow; etc1_optimizer::results cluster_optimizer_results; - std::vector<uint8_t> cluster_selectors(total_pixels); + basisu::vector<uint8_t> cluster_selectors(total_pixels); cluster_optimizer_results.m_n = total_pixels; cluster_optimizer_results.m_pSelectors = &cluster_selectors[0]; optimizer.init(cluster_optimizer_params, cluster_optimizer_results); - optimizer.compute(); + if (!optimizer.compute()) + BASISU_FRONTEND_VERIFY(false); new_endpoint_cluster_etc_params.m_color_unscaled[0] = cluster_optimizer_results.m_block_color_unscaled; new_endpoint_cluster_etc_params.m_inten_table[0] = cluster_optimizer_results.m_block_inten_table; @@ -2198,11 +2728,16 @@ namespace basisu cluster_valid[cluster_index] = true; } // cluster_index + +#ifndef __EMSCRIPTEN__ } ); +#endif } // cluster_index_iter +#ifndef __EMSCRIPTEN__ m_params.m_pJob_pool->wait_for_all(); +#endif uint32_t total_unused_clusters = 0; uint32_t total_improved_clusters = 0; @@ -2239,7 +2774,7 @@ namespace basisu debug_printf("basisu_frontend::reoptimize_remapped_endpoints: stage 1\n"); - std::vector<uint_vec> new_endpoint_clusters(total_new_endpoint_clusters); + basisu::vector<uint_vec> new_endpoint_clusters(total_new_endpoint_clusters); for (uint32_t block_index = 0; block_index < new_block_endpoints.size(); block_index++) { diff --git a/thirdparty/basis_universal/basisu_frontend.h b/thirdparty/basis_universal/encoder/basisu_frontend.h index c3f5d23c71..4ff6d40466 100644 --- a/thirdparty/basis_universal/basisu_frontend.h +++ b/thirdparty/basis_universal/encoder/basisu_frontend.h @@ -1,5 +1,5 @@ // basisu_frontend.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,8 @@ #include "basisu_etc.h" #include "basisu_gpu_texture.h" #include "basisu_global_selector_palette_helpers.h" -#include "transcoder/basisu_file_headers.h" +#include "../transcoder/basisu_file_headers.h" +#include "../transcoder/basisu_transcoder.h" namespace basisu { @@ -34,8 +35,8 @@ namespace basisu uint32_t &operator[] (uint32_t i) { assert(i < 2); return m_comps[i]; } }; - const uint32_t BASISU_DEFAULT_COMPRESSION_LEVEL = 1; - const uint32_t BASISU_MAX_COMPRESSION_LEVEL = 5; + const uint32_t BASISU_DEFAULT_COMPRESSION_LEVEL = 2; + const uint32_t BASISU_MAX_COMPRESSION_LEVEL = 6; class basisu_frontend { @@ -72,16 +73,19 @@ namespace basisu m_perceptual(true), m_debug_stats(false), m_debug_images(false), + m_dump_endpoint_clusterization(true), + m_validate(false), + m_multithreaded(false), + m_disable_hierarchical_endpoint_codebooks(false), m_pGlobal_sel_codebook(NULL), m_num_global_sel_codebook_pal_bits(0), m_num_global_sel_codebook_mod_bits(0), m_use_hybrid_selector_codebooks(false), m_hybrid_codebook_quality_thresh(0.0f), - m_validate(false), m_tex_type(basist::cBASISTexType2D), - m_multithreaded(false), - m_disable_hierarchical_endpoint_codebooks(false), + m_pGlobal_codebooks(nullptr), + m_pJob_pool(nullptr) { } @@ -108,6 +112,7 @@ namespace basisu bool m_use_hybrid_selector_codebooks; float m_hybrid_codebook_quality_thresh; basist::basis_texture_type m_tex_type; + const basist::basisu_lowlevel_etc1s_transcoder *m_pGlobal_codebooks; job_pool *m_pJob_pool; }; @@ -142,7 +147,7 @@ namespace basisu bool get_endpoint_cluster_color_is_used(uint32_t cluster_index, bool individual_mode) const { return m_endpoint_cluster_etc_params[cluster_index].m_color_used[individual_mode]; } // Selector clusters - uint32_t get_total_selector_clusters() const { return static_cast<uint32_t>(m_selector_cluster_indices.size()); } + uint32_t get_total_selector_clusters() const { return static_cast<uint32_t>(m_selector_cluster_block_indices.size()); } uint32_t get_block_selector_cluster_index(uint32_t block_index) const { return m_block_selector_cluster_index[block_index]; } const etc_block &get_selector_cluster_selector_bits(uint32_t cluster_index) const { return m_optimized_cluster_selectors[cluster_index]; } @@ -150,7 +155,7 @@ namespace basisu const bool_vec &get_selector_cluster_uses_global_cb_vec() const { return m_selector_cluster_uses_global_cb; } // Returns block indices using each selector cluster - const uint_vec &get_selector_cluster_block_indices(uint32_t selector_cluster_index) const { return m_selector_cluster_indices[selector_cluster_index]; } + const uint_vec &get_selector_cluster_block_indices(uint32_t selector_cluster_index) const { return m_selector_cluster_block_indices[selector_cluster_index]; } void dump_debug_image(const char *pFilename, uint32_t first_block, uint32_t num_blocks_x, uint32_t num_blocks_y, bool output_blocks); @@ -188,16 +193,16 @@ namespace basisu // For each endpoint cluster: An array of which subblock indices (block_index*2+subblock) are located in that cluster. // Array of block indices for each endpoint cluster - std::vector<uint_vec> m_endpoint_clusters; + basisu::vector<uint_vec> m_endpoint_clusters; // Array of block indices for each parent endpoint cluster - std::vector<uint_vec> m_endpoint_parent_clusters; + basisu::vector<uint_vec> m_endpoint_parent_clusters; // Each block's parent cluster index uint8_vec m_block_parent_endpoint_cluster; // Array of endpoint cluster indices for each parent endpoint cluster - std::vector<uint_vec> m_endpoint_clusters_within_each_parent_cluster; + basisu::vector<uint_vec> m_endpoint_clusters_within_each_parent_cluster; struct endpoint_cluster_etc_params { @@ -267,35 +272,35 @@ namespace basisu } }; - typedef std::vector<endpoint_cluster_etc_params> cluster_subblock_etc_params_vec; + typedef basisu::vector<endpoint_cluster_etc_params> cluster_subblock_etc_params_vec; // Each endpoint cluster's ETC1S parameters cluster_subblock_etc_params_vec m_endpoint_cluster_etc_params; // The endpoint cluster index used by each ETC1 subblock. - std::vector<vec2U> m_block_endpoint_clusters_indices; + basisu::vector<vec2U> m_block_endpoint_clusters_indices; // The block(s) within each selector cluster // Note: If you add anything here that uses selector cluster indicies, be sure to update optimize_selector_codebook()! - std::vector<uint_vec> m_selector_cluster_indices; + basisu::vector<uint_vec> m_selector_cluster_block_indices; // The selector bits for each selector cluster. - std::vector<etc_block> m_optimized_cluster_selectors; + basisu::vector<etc_block> m_optimized_cluster_selectors; // The block(s) within each parent selector cluster. - std::vector<uint_vec> m_selector_parent_cluster_indices; + basisu::vector<uint_vec> m_selector_parent_cluster_block_indices; // Each block's parent selector cluster uint8_vec m_block_parent_selector_cluster; // Array of selector cluster indices for each parent selector cluster - std::vector<uint_vec> m_selector_clusters_within_each_parent_cluster; + basisu::vector<uint_vec> m_selector_clusters_within_each_parent_cluster; basist::etc1_global_selector_codebook_entry_id_vec m_optimized_cluster_selector_global_cb_ids; bool_vec m_selector_cluster_uses_global_cb; // Each block's selector cluster index - std::vector<uint32_t> m_block_selector_cluster_index; + basisu::vector<uint32_t> m_block_selector_cluster_index; struct subblock_endpoint_quant_err { @@ -321,13 +326,14 @@ namespace basisu }; // The sorted subblock endpoint quant error for each endpoint cluster - std::vector<subblock_endpoint_quant_err> m_subblock_endpoint_quant_err_vec; + basisu::vector<subblock_endpoint_quant_err> m_subblock_endpoint_quant_err_vec; std::mutex m_lock; //----------------------------------------------------------------------------- void init_etc1_images(); + bool init_global_codebooks(); void init_endpoint_training_vectors(); void dump_endpoint_clusterization_visualization(const char *pFilename, bool vis_endpoint_colors); void generate_endpoint_clusters(); diff --git a/thirdparty/basis_universal/basisu_global_selector_palette_helpers.cpp b/thirdparty/basis_universal/encoder/basisu_global_selector_palette_helpers.cpp index 102fc24980..102fc24980 100644 --- a/thirdparty/basis_universal/basisu_global_selector_palette_helpers.cpp +++ b/thirdparty/basis_universal/encoder/basisu_global_selector_palette_helpers.cpp diff --git a/thirdparty/basis_universal/basisu_global_selector_palette_helpers.h b/thirdparty/basis_universal/encoder/basisu_global_selector_palette_helpers.h index 32692c516b..7c35439df8 100644 --- a/thirdparty/basis_universal/basisu_global_selector_palette_helpers.h +++ b/thirdparty/basis_universal/encoder/basisu_global_selector_palette_helpers.h @@ -14,9 +14,9 @@ // limitations under the License. #pragma once -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" #include "basisu_etc.h" -#include "transcoder/basisu_global_selector_palette.h" +#include "../transcoder/basisu_global_selector_palette.h" namespace basisu { @@ -36,7 +36,7 @@ namespace basisu void clear() { clear_obj(*this); } }; - typedef std::vector<pixel_block> pixel_block_vec; + typedef basisu::vector<pixel_block> pixel_block_vec; uint64_t etc1_global_selector_codebook_find_best_entry(const basist::etc1_global_selector_codebook &codebook, uint32_t num_src_pixel_blocks, const pixel_block *pSrc_pixel_blocks, const etc_block *pBlock_endpoints, diff --git a/thirdparty/basis_universal/basisu_gpu_texture.cpp b/thirdparty/basis_universal/encoder/basisu_gpu_texture.cpp index 117668c5e2..3f9fb67bdd 100644 --- a/thirdparty/basis_universal/basisu_gpu_texture.cpp +++ b/thirdparty/basis_universal/encoder/basisu_gpu_texture.cpp @@ -1,5 +1,5 @@ // basisu_gpu_texture.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,38 +16,10 @@ #include "basisu_enc.h" #include "basisu_pvrtc1_4.h" #include "basisu_astc_decomp.h" +#include "basisu_bc7enc.h" namespace basisu { - const int8_t g_etc2_eac_tables[16][8] = - { - { -3, -6, -9, -15, 2, 5, 8, 14 }, { -3, -7, -10, -13, 2, 6, 9, 12 }, { -2, -5, -8, -13, 1, 4, 7, 12 }, { -2, -4, -6, -13, 1, 3, 5, 12 }, - { -3, -6, -8, -12, 2, 5, 7, 11 }, { -3, -7, -9, -11, 2, 6, 8, 10 }, { -4, -7, -8, -11, 3, 6, 7, 10 }, { -3, -5, -8, -11, 2, 4, 7, 10 }, - { -2, -6, -8, -10, 1, 5, 7, 9 }, { -2, -5, -8, -10, 1, 4, 7, 9 }, { -2, -4, -8, -10, 1, 3, 7, 9 }, { -2, -5, -7, -10, 1, 4, 6, 9 }, - { -3, -4, -7, -10, 2, 3, 6, 9 }, { -1, -2, -3, -10, 0, 1, 2, 9 }, { -4, -6, -8, -9, 3, 5, 7, 8 }, { -3, -5, -7, -9, 2, 4, 6, 8 } - }; - - struct eac_a8_block - { - uint16_t m_base : 8; - uint16_t m_table : 4; - uint16_t m_multiplier : 4; - - uint8_t m_selectors[6]; - - inline uint32_t get_selector(uint32_t x, uint32_t y, uint64_t selector_bits) const - { - assert((x < 4) && (y < 4)); - return static_cast<uint32_t>((selector_bits >> (45 - (y + x * 4) * 3)) & 7); - } - - inline uint64_t get_selector_bits() const - { - uint64_t pixels = ((uint64_t)m_selectors[0] << 40) | ((uint64_t)m_selectors[1] << 32) | ((uint64_t)m_selectors[2] << 24) | ((uint64_t)m_selectors[3] << 16) | ((uint64_t)m_selectors[4] << 8) | m_selectors[5]; - return pixels; - } - }; - void unpack_etc2_eac(const void *pBlock_bits, color_rgba *pPixels) { static_assert(sizeof(eac_a8_block) == 8, "sizeof(eac_a8_block) == 8"); @@ -123,19 +95,18 @@ namespace basisu bc1_block::unpack_color(l, r0, g0, b0); bc1_block::unpack_color(h, r1, g1, b1); + c[0].set_noclamp_rgba(r0, g0, b0, 255); + c[1].set_noclamp_rgba(r1, g1, b1, 255); + bool used_punchthrough = false; if (l > h) { - c[0].set_noclamp_rgba(r0, g0, b0, 255); - c[1].set_noclamp_rgba(r1, g1, b1, 255); c[2].set_noclamp_rgba((r0 * 2 + r1) / 3, (g0 * 2 + g1) / 3, (b0 * 2 + b1) / 3, 255); c[3].set_noclamp_rgba((r1 * 2 + r0) / 3, (g1 * 2 + g0) / 3, (b1 * 2 + b0) / 3, 255); } else { - c[0].set_noclamp_rgba(r0, g0, b0, 255); - c[1].set_noclamp_rgba(r1, g1, b1, 255); c[2].set_noclamp_rgba((r0 + r1) / 2, (g0 + g1) / 2, (b0 + b1) / 2, 255); c[3].set_noclamp_rgba(0, 0, 0, 0); used_punchthrough = true; @@ -165,6 +136,142 @@ namespace basisu return used_punchthrough; } + bool unpack_bc1_nv(const void *pBlock_bits, color_rgba *pPixels, bool set_alpha) + { + static_assert(sizeof(bc1_block) == 8, "sizeof(bc1_block) == 8"); + + const bc1_block *pBlock = static_cast<const bc1_block *>(pBlock_bits); + + const uint32_t l = pBlock->get_low_color(); + const uint32_t h = pBlock->get_high_color(); + + color_rgba c[4]; + + int r0 = (l >> 11) & 31; + int g0 = (l >> 5) & 63; + int b0 = l & 31; + int r1 = (h >> 11) & 31; + int g1 = (h >> 5) & 63; + int b1 = h & 31; + + c[0].b = (uint8_t)((3 * b0 * 22) / 8); + c[0].g = (uint8_t)((g0 << 2) | (g0 >> 4)); + c[0].r = (uint8_t)((3 * r0 * 22) / 8); + c[0].a = 0xFF; + + c[1].r = (uint8_t)((3 * r1 * 22) / 8); + c[1].g = (uint8_t)((g1 << 2) | (g1 >> 4)); + c[1].b = (uint8_t)((3 * b1 * 22) / 8); + c[1].a = 0xFF; + + int gdiff = c[1].g - c[0].g; + + bool used_punchthrough = false; + + if (l > h) + { + c[2].r = (uint8_t)(((2 * r0 + r1) * 22) / 8); + c[2].g = (uint8_t)(((256 * c[0].g + gdiff/4 + 128 + gdiff * 80) / 256)); + c[2].b = (uint8_t)(((2 * b0 + b1) * 22) / 8); + c[2].a = 0xFF; + + c[3].r = (uint8_t)(((2 * r1 + r0) * 22) / 8); + c[3].g = (uint8_t)((256 * c[1].g - gdiff/4 + 128 - gdiff * 80) / 256); + c[3].b = (uint8_t)(((2 * b1 + b0) * 22) / 8); + c[3].a = 0xFF; + } + else + { + c[2].r = (uint8_t)(((r0 + r1) * 33) / 8); + c[2].g = (uint8_t)((256 * c[0].g + gdiff/4 + 128 + gdiff * 128) / 256); + c[2].b = (uint8_t)(((b0 + b1) * 33) / 8); + c[2].a = 0xFF; + + c[3].set_noclamp_rgba(0, 0, 0, 0); + used_punchthrough = true; + } + + if (set_alpha) + { + for (uint32_t y = 0; y < 4; y++, pPixels += 4) + { + pPixels[0] = c[pBlock->get_selector(0, y)]; + pPixels[1] = c[pBlock->get_selector(1, y)]; + pPixels[2] = c[pBlock->get_selector(2, y)]; + pPixels[3] = c[pBlock->get_selector(3, y)]; + } + } + else + { + for (uint32_t y = 0; y < 4; y++, pPixels += 4) + { + pPixels[0].set_rgb(c[pBlock->get_selector(0, y)]); + pPixels[1].set_rgb(c[pBlock->get_selector(1, y)]); + pPixels[2].set_rgb(c[pBlock->get_selector(2, y)]); + pPixels[3].set_rgb(c[pBlock->get_selector(3, y)]); + } + } + + return used_punchthrough; + } + + static inline int interp_5_6_amd(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 * 43 + c1 * 21 + 32) >> 6; } + static inline int interp_half_5_6_amd(int c0, int c1) { assert(c0 < 256 && c1 < 256); return (c0 + c1 + 1) >> 1; } + + bool unpack_bc1_amd(const void *pBlock_bits, color_rgba *pPixels, bool set_alpha) + { + const bc1_block *pBlock = static_cast<const bc1_block *>(pBlock_bits); + + const uint32_t l = pBlock->get_low_color(); + const uint32_t h = pBlock->get_high_color(); + + color_rgba c[4]; + + uint32_t r0, g0, b0, r1, g1, b1; + bc1_block::unpack_color(l, r0, g0, b0); + bc1_block::unpack_color(h, r1, g1, b1); + + c[0].set_noclamp_rgba(r0, g0, b0, 255); + c[1].set_noclamp_rgba(r1, g1, b1, 255); + + bool used_punchthrough = false; + + if (l > h) + { + c[2].set_noclamp_rgba(interp_5_6_amd(r0, r1), interp_5_6_amd(g0, g1), interp_5_6_amd(b0, b1), 255); + c[3].set_noclamp_rgba(interp_5_6_amd(r1, r0), interp_5_6_amd(g1, g0), interp_5_6_amd(b1, b0), 255); + } + else + { + c[2].set_noclamp_rgba(interp_half_5_6_amd(r0, r1), interp_half_5_6_amd(g0, g1), interp_half_5_6_amd(b0, b1), 255); + c[3].set_noclamp_rgba(0, 0, 0, 0); + used_punchthrough = true; + } + + if (set_alpha) + { + for (uint32_t y = 0; y < 4; y++, pPixels += 4) + { + pPixels[0] = c[pBlock->get_selector(0, y)]; + pPixels[1] = c[pBlock->get_selector(1, y)]; + pPixels[2] = c[pBlock->get_selector(2, y)]; + pPixels[3] = c[pBlock->get_selector(3, y)]; + } + } + else + { + for (uint32_t y = 0; y < 4; y++, pPixels += 4) + { + pPixels[0].set_rgb(c[pBlock->get_selector(0, y)]); + pPixels[1].set_rgb(c[pBlock->get_selector(1, y)]); + pPixels[2].set_rgb(c[pBlock->get_selector(2, y)]); + pPixels[3].set_rgb(c[pBlock->get_selector(3, y)]); + } + } + + return used_punchthrough; + } + struct bc4_block { enum { cBC4SelectorBits = 3, cTotalSelectorBytes = 6, cMaxSelectorValues = 8 }; @@ -292,7 +399,7 @@ namespace basisu if (mode) { - c[1].set(std::max(0, c[0].r - (c[3].r >> 2)), std::max(0, c[0].g - (c[3].g >> 2)), std::max(0, c[0].b - (c[3].b >> 2)), 255); + c[1].set(basisu::maximum(0, c[0].r - (c[3].r >> 2)), basisu::maximum(0, c[0].g - (c[3].g >> 2)), basisu::maximum(0, c[0].b - (c[3].b >> 2)), 255); c[2] = c[0]; c[0].set(0, 0, 0, 255); } @@ -317,6 +424,191 @@ namespace basisu } } + // BC7 mode 0-7 decompression. + // Instead of one monster routine to unpack all the BC7 modes, we're lumping the 3 subset, 2 subset, 1 subset, and dual plane modes together into simple shared routines. + + static inline uint32_t bc7_dequant(uint32_t val, uint32_t pbit, uint32_t val_bits) { assert(val < (1U << val_bits)); assert(pbit < 2); assert(val_bits >= 4 && val_bits <= 8); const uint32_t total_bits = val_bits + 1; val = (val << 1) | pbit; val <<= (8 - total_bits); val |= (val >> total_bits); assert(val <= 255); return val; } + static inline uint32_t bc7_dequant(uint32_t val, uint32_t val_bits) { assert(val < (1U << val_bits)); assert(val_bits >= 4 && val_bits <= 8); val <<= (8 - val_bits); val |= (val >> val_bits); assert(val <= 255); return val; } + + static inline uint32_t bc7_interp2(uint32_t l, uint32_t h, uint32_t w) { assert(w < 4); return (l * (64 - basist::g_bc7_weights2[w]) + h * basist::g_bc7_weights2[w] + 32) >> 6; } + static inline uint32_t bc7_interp3(uint32_t l, uint32_t h, uint32_t w) { assert(w < 8); return (l * (64 - basist::g_bc7_weights3[w]) + h * basist::g_bc7_weights3[w] + 32) >> 6; } + static inline uint32_t bc7_interp4(uint32_t l, uint32_t h, uint32_t w) { assert(w < 16); return (l * (64 - basist::g_bc7_weights4[w]) + h * basist::g_bc7_weights4[w] + 32) >> 6; } + static inline uint32_t bc7_interp(uint32_t l, uint32_t h, uint32_t w, uint32_t bits) + { + assert(l <= 255 && h <= 255); + switch (bits) + { + case 2: return bc7_interp2(l, h, w); + case 3: return bc7_interp3(l, h, w); + case 4: return bc7_interp4(l, h, w); + default: + break; + } + return 0; + } + + bool unpack_bc7_mode0_2(uint32_t mode, const void* pBlock_bits, color_rgba* pPixels) + { + //const uint32_t SUBSETS = 3; + const uint32_t ENDPOINTS = 6; + const uint32_t COMPS = 3; + const uint32_t WEIGHT_BITS = (mode == 0) ? 3 : 2; + const uint32_t ENDPOINT_BITS = (mode == 0) ? 4 : 5; + const uint32_t PBITS = (mode == 0) ? 6 : 0; + const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS; + + uint32_t bit_offset = 0; + const uint8_t* pBuf = static_cast<const uint8_t*>(pBlock_bits); + + if (read_bits32(pBuf, bit_offset, mode + 1) != (1U << mode)) return false; + + const uint32_t part = read_bits32(pBuf, bit_offset, (mode == 0) ? 4 : 6); + + color_rgba endpoints[ENDPOINTS]; + for (uint32_t c = 0; c < COMPS; c++) + for (uint32_t e = 0; e < ENDPOINTS; e++) + endpoints[e][c] = (uint8_t)read_bits32(pBuf, bit_offset, ENDPOINT_BITS); + + uint32_t pbits[6]; + for (uint32_t p = 0; p < PBITS; p++) + pbits[p] = read_bits32(pBuf, bit_offset, 1); + + uint32_t weights[16]; + for (uint32_t i = 0; i < 16; i++) + weights[i] = read_bits32(pBuf, bit_offset, ((!i) || (i == basist::g_bc7_table_anchor_index_third_subset_1[part]) || (i == basist::g_bc7_table_anchor_index_third_subset_2[part])) ? (WEIGHT_BITS - 1) : WEIGHT_BITS); + + assert(bit_offset == 128); + + for (uint32_t e = 0; e < ENDPOINTS; e++) + for (uint32_t c = 0; c < 4; c++) + endpoints[e][c] = (uint8_t)((c == 3) ? 255 : (PBITS ? bc7_dequant(endpoints[e][c], pbits[e], ENDPOINT_BITS) : bc7_dequant(endpoints[e][c], ENDPOINT_BITS))); + + color_rgba block_colors[3][8]; + for (uint32_t s = 0; s < 3; s++) + for (uint32_t i = 0; i < WEIGHT_VALS; i++) + { + for (uint32_t c = 0; c < 3; c++) + block_colors[s][i][c] = (uint8_t)bc7_interp(endpoints[s * 2 + 0][c], endpoints[s * 2 + 1][c], i, WEIGHT_BITS); + block_colors[s][i][3] = 255; + } + + for (uint32_t i = 0; i < 16; i++) + pPixels[i] = block_colors[basist::g_bc7_partition3[part * 16 + i]][weights[i]]; + + return true; + } + + bool unpack_bc7_mode1_3_7(uint32_t mode, const void* pBlock_bits, color_rgba* pPixels) + { + //const uint32_t SUBSETS = 2; + const uint32_t ENDPOINTS = 4; + const uint32_t COMPS = (mode == 7) ? 4 : 3; + const uint32_t WEIGHT_BITS = (mode == 1) ? 3 : 2; + const uint32_t ENDPOINT_BITS = (mode == 7) ? 5 : ((mode == 1) ? 6 : 7); + const uint32_t PBITS = (mode == 1) ? 2 : 4; + const uint32_t SHARED_PBITS = (mode == 1) ? true : false; + const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS; + + uint32_t bit_offset = 0; + const uint8_t* pBuf = static_cast<const uint8_t*>(pBlock_bits); + + if (read_bits32(pBuf, bit_offset, mode + 1) != (1U << mode)) return false; + + const uint32_t part = read_bits32(pBuf, bit_offset, 6); + + color_rgba endpoints[ENDPOINTS]; + for (uint32_t c = 0; c < COMPS; c++) + for (uint32_t e = 0; e < ENDPOINTS; e++) + endpoints[e][c] = (uint8_t)read_bits32(pBuf, bit_offset, ENDPOINT_BITS); + + uint32_t pbits[4]; + for (uint32_t p = 0; p < PBITS; p++) + pbits[p] = read_bits32(pBuf, bit_offset, 1); + + uint32_t weights[16]; + for (uint32_t i = 0; i < 16; i++) + weights[i] = read_bits32(pBuf, bit_offset, ((!i) || (i == basist::g_bc7_table_anchor_index_second_subset[part])) ? (WEIGHT_BITS - 1) : WEIGHT_BITS); + + assert(bit_offset == 128); + + for (uint32_t e = 0; e < ENDPOINTS; e++) + for (uint32_t c = 0; c < 4; c++) + endpoints[e][c] = (uint8_t)((c == ((mode == 7U) ? 4U : 3U)) ? 255 : bc7_dequant(endpoints[e][c], pbits[SHARED_PBITS ? (e >> 1) : e], ENDPOINT_BITS)); + + color_rgba block_colors[2][8]; + for (uint32_t s = 0; s < 2; s++) + for (uint32_t i = 0; i < WEIGHT_VALS; i++) + { + for (uint32_t c = 0; c < COMPS; c++) + block_colors[s][i][c] = (uint8_t)bc7_interp(endpoints[s * 2 + 0][c], endpoints[s * 2 + 1][c], i, WEIGHT_BITS); + block_colors[s][i][3] = (COMPS == 3) ? 255 : block_colors[s][i][3]; + } + + for (uint32_t i = 0; i < 16; i++) + pPixels[i] = block_colors[basist::g_bc7_partition2[part * 16 + i]][weights[i]]; + + return true; + } + + bool unpack_bc7_mode4_5(uint32_t mode, const void* pBlock_bits, color_rgba* pPixels) + { + const uint32_t ENDPOINTS = 2; + const uint32_t COMPS = 4; + const uint32_t WEIGHT_BITS = 2; + const uint32_t A_WEIGHT_BITS = (mode == 4) ? 3 : 2; + const uint32_t ENDPOINT_BITS = (mode == 4) ? 5 : 7; + const uint32_t A_ENDPOINT_BITS = (mode == 4) ? 6 : 8; + //const uint32_t WEIGHT_VALS = 1 << WEIGHT_BITS; + //const uint32_t A_WEIGHT_VALS = 1 << A_WEIGHT_BITS; + + uint32_t bit_offset = 0; + const uint8_t* pBuf = static_cast<const uint8_t*>(pBlock_bits); + + if (read_bits32(pBuf, bit_offset, mode + 1) != (1U << mode)) return false; + + const uint32_t comp_rot = read_bits32(pBuf, bit_offset, 2); + const uint32_t index_mode = (mode == 4) ? read_bits32(pBuf, bit_offset, 1) : 0; + + color_rgba endpoints[ENDPOINTS]; + for (uint32_t c = 0; c < COMPS; c++) + for (uint32_t e = 0; e < ENDPOINTS; e++) + endpoints[e][c] = (uint8_t)read_bits32(pBuf, bit_offset, (c == 3) ? A_ENDPOINT_BITS : ENDPOINT_BITS); + + const uint32_t weight_bits[2] = { index_mode ? A_WEIGHT_BITS : WEIGHT_BITS, index_mode ? WEIGHT_BITS : A_WEIGHT_BITS }; + + uint32_t weights[16], a_weights[16]; + + for (uint32_t i = 0; i < 16; i++) + (index_mode ? a_weights : weights)[i] = read_bits32(pBuf, bit_offset, weight_bits[index_mode] - ((!i) ? 1 : 0)); + + for (uint32_t i = 0; i < 16; i++) + (index_mode ? weights : a_weights)[i] = read_bits32(pBuf, bit_offset, weight_bits[1 - index_mode] - ((!i) ? 1 : 0)); + + assert(bit_offset == 128); + + for (uint32_t e = 0; e < ENDPOINTS; e++) + for (uint32_t c = 0; c < 4; c++) + endpoints[e][c] = (uint8_t)bc7_dequant(endpoints[e][c], (c == 3) ? A_ENDPOINT_BITS : ENDPOINT_BITS); + + color_rgba block_colors[8]; + for (uint32_t i = 0; i < (1U << weight_bits[0]); i++) + for (uint32_t c = 0; c < 3; c++) + block_colors[i][c] = (uint8_t)bc7_interp(endpoints[0][c], endpoints[1][c], i, weight_bits[0]); + + for (uint32_t i = 0; i < (1U << weight_bits[1]); i++) + block_colors[i][3] = (uint8_t)bc7_interp(endpoints[0][3], endpoints[1][3], i, weight_bits[1]); + + for (uint32_t i = 0; i < 16; i++) + { + pPixels[i] = block_colors[weights[i]]; + pPixels[i].a = block_colors[a_weights[i]].a; + if (comp_rot >= 1) + std::swap(pPixels[i].a, pPixels[i].m_comps[comp_rot - 1]); + } + + return true; + } + struct bc7_mode_6 { struct @@ -364,9 +656,6 @@ namespace basisu }; }; - static const uint32_t g_bc7_weights4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; - - // The transcoder only outputs mode 6 at the moment, so this is easy. bool unpack_bc7_mode6(const void *pBlock_bits, color_rgba *pPixels) { static_assert(sizeof(bc7_mode_6) == 16, "sizeof(bc7_mode_6) == 16"); @@ -388,7 +677,7 @@ namespace basisu color_rgba vals[16]; for (uint32_t i = 0; i < 16; i++) { - const uint32_t w = g_bc7_weights4[i]; + const uint32_t w = basist::g_bc7_weights4[i]; const uint32_t iw = 64 - w; vals[i].set_noclamp_rgba( (r0 * iw + r1 * w + 32) >> 6, @@ -420,183 +709,37 @@ namespace basisu return true; } - static inline uint32_t get_block_bits(const uint8_t* pBytes, uint32_t bit_ofs, uint32_t bits_wanted) + bool unpack_bc7(const void *pBlock, color_rgba *pPixels) { - assert(bits_wanted < 32); + const uint32_t first_byte = static_cast<const uint8_t*>(pBlock)[0]; - uint32_t v = 0; - uint32_t total_bits = 0; - - while (total_bits < bits_wanted) + for (uint32_t mode = 0; mode <= 7; mode++) { - uint32_t k = pBytes[bit_ofs >> 3]; - k >>= (bit_ofs & 7); - uint32_t num_bits_in_byte = 8 - (bit_ofs & 7); - - v |= (k << total_bits); - total_bits += num_bits_in_byte; - bit_ofs += num_bits_in_byte; - } - - return v & ((1 << bits_wanted) - 1); - } - - struct bc7_mode_5 - { - union - { - struct + if (first_byte & (1U << mode)) { - uint64_t m_mode : 6; - uint64_t m_rot : 2; - - uint64_t m_r0 : 7; - uint64_t m_r1 : 7; - uint64_t m_g0 : 7; - uint64_t m_g1 : 7; - uint64_t m_b0 : 7; - uint64_t m_b1 : 7; - uint64_t m_a0 : 8; - uint64_t m_a1_0 : 6; - - } m_lo; - - uint64_t m_lo_bits; - }; - - union - { - struct - { - uint64_t m_a1_1 : 2; - - // bit 2 - uint64_t m_c00 : 1; - uint64_t m_c10 : 2; - uint64_t m_c20 : 2; - uint64_t m_c30 : 2; - - uint64_t m_c01 : 2; - uint64_t m_c11 : 2; - uint64_t m_c21 : 2; - uint64_t m_c31 : 2; - - uint64_t m_c02 : 2; - uint64_t m_c12 : 2; - uint64_t m_c22 : 2; - uint64_t m_c32 : 2; - - uint64_t m_c03 : 2; - uint64_t m_c13 : 2; - uint64_t m_c23 : 2; - uint64_t m_c33 : 2; - - // bit 33 - uint64_t m_a00 : 1; - uint64_t m_a10 : 2; - uint64_t m_a20 : 2; - uint64_t m_a30 : 2; - - uint64_t m_a01 : 2; - uint64_t m_a11 : 2; - uint64_t m_a21 : 2; - uint64_t m_a31 : 2; - - uint64_t m_a02 : 2; - uint64_t m_a12 : 2; - uint64_t m_a22 : 2; - uint64_t m_a32 : 2; - - uint64_t m_a03 : 2; - uint64_t m_a13 : 2; - uint64_t m_a23 : 2; - uint64_t m_a33 : 2; - - } m_hi; - - uint64_t m_hi_bits; - }; - - color_rgba get_low_color() const - { - return color_rgba(cNoClamp, - (int)((m_lo.m_r0 << 1) | (m_lo.m_r0 >> 6)), - (int)((m_lo.m_g0 << 1) | (m_lo.m_g0 >> 6)), - (int)((m_lo.m_b0 << 1) | (m_lo.m_b0 >> 6)), - m_lo.m_a0); - } - - color_rgba get_high_color() const - { - return color_rgba(cNoClamp, - (int)((m_lo.m_r1 << 1) | (m_lo.m_r1 >> 6)), - (int)((m_lo.m_g1 << 1) | (m_lo.m_g1 >> 6)), - (int)((m_lo.m_b1 << 1) | (m_lo.m_b1 >> 6)), - (int)m_lo.m_a1_0 | ((int)m_hi.m_a1_1 << 6)); - } - - void get_block_colors(color_rgba* pColors) const - { - const color_rgba low_color(get_low_color()); - const color_rgba high_color(get_high_color()); - - for (uint32_t i = 0; i < 4; i++) - { - static const uint32_t s_bc7_weights2[4] = { 0, 21, 43, 64 }; - - pColors[i].set_noclamp_rgba( - (low_color.r * (64 - s_bc7_weights2[i]) + high_color.r * s_bc7_weights2[i] + 32) >> 6, - (low_color.g * (64 - s_bc7_weights2[i]) + high_color.g * s_bc7_weights2[i] + 32) >> 6, - (low_color.b * (64 - s_bc7_weights2[i]) + high_color.b * s_bc7_weights2[i] + 32) >> 6, - (low_color.a * (64 - s_bc7_weights2[i]) + high_color.a * s_bc7_weights2[i] + 32) >> 6); + switch (mode) + { + case 0: + case 2: + return unpack_bc7_mode0_2(mode, pBlock, pPixels); + case 1: + case 3: + case 7: + return unpack_bc7_mode1_3_7(mode, pBlock, pPixels); + case 4: + case 5: + return unpack_bc7_mode4_5(mode, pBlock, pPixels); + case 6: + return unpack_bc7_mode6(pBlock, pPixels); + default: + break; + } } - } - - uint32_t get_selector(uint32_t idx, bool alpha) const - { - const uint32_t size = (idx == 0) ? 1 : 2; - - uint32_t ofs = alpha ? 97 : 66; - - if (idx) - ofs += 1 + 2 * (idx - 1); - - return get_block_bits(reinterpret_cast<const uint8_t*>(this), ofs, size); - } - }; - - bool unpack_bc7_mode5(const void* pBlock_bits, color_rgba* pPixels) - { - static_assert(sizeof(bc7_mode_5) == 16, "sizeof(bc7_mode_5) == 16"); - - const bc7_mode_5& block = *static_cast<const bc7_mode_5*>(pBlock_bits); - - if (block.m_lo.m_mode != (1 << 5)) - return false; - - color_rgba block_colors[4]; - block.get_block_colors(block_colors); - - const uint32_t rot = block.m_lo.m_rot; - - for (uint32_t i = 0; i < 16; i++) - { - const uint32_t cs = block.get_selector(i, false); - - color_rgba c(block_colors[cs]); - - const uint32_t as = block.get_selector(i, true); - c.a = block_colors[as].a; - - if (rot > 0) - std::swap(c[3], c[rot - 1]); - - pPixels[i] = c; } - return true; + return false; } - + struct fxt1_block { union @@ -903,13 +1046,14 @@ namespace basisu etc2_eac_r11 m_c[2]; }; - static void unpack_etc2_eac_r(const etc2_eac_r11* p, color_rgba* pPixels, uint32_t c) + void unpack_etc2_eac_r(const void *p, color_rgba* pPixels, uint32_t c) { - const uint64_t sels = p->get_sels(); + const etc2_eac_r11* pBlock = static_cast<const etc2_eac_r11*>(p); + const uint64_t sels = pBlock->get_sels(); - const int base = (int)p->m_base * 8 + 4; - const int mul = p->m_mul ? ((int)p->m_mul * 8) : 1; - const int table = (int)p->m_table; + const int base = (int)pBlock->m_base * 8 + 4; + const int mul = pBlock->m_mul ? ((int)pBlock->m_mul * 8) : 1; + const int table = (int)pBlock->m_table; for (uint32_t y = 0; y < 4; y++) { @@ -923,7 +1067,8 @@ namespace basisu val = clamp<int>(val, 0, 2047); // Convert to 8-bits with rounding - pPixels[x + y * 4].m_comps[c] = static_cast<uint8_t>((val * 255 + 1024) / 2047); + //pPixels[x + y * 4].m_comps[c] = static_cast<uint8_t>((val * 255 + 1024) / 2047); + pPixels[x + y * 4].m_comps[c] = static_cast<uint8_t>((val * 255 + 1023) / 2047); } // x } // y @@ -939,6 +1084,11 @@ namespace basisu } } + void unpack_uastc(const void* p, color_rgba* pPixels) + { + basist::unpack_uastc(*static_cast<const basist::uastc_block*>(p), (basist::color32 *)pPixels, false); + } + // Unpacks to RGBA, R, RG, or A bool unpack_block(texture_format fmt, const void* pBlock, color_rgba* pPixels) { @@ -949,6 +1099,16 @@ namespace basisu unpack_bc1(pBlock, pPixels, true); break; } + case texture_format::cBC1_NV: + { + unpack_bc1_nv(pBlock, pPixels, true); + break; + } + case texture_format::cBC1_AMD: + { + unpack_bc1_amd(pBlock, pPixels, true); + break; + } case texture_format::cBC3: { return unpack_bc3(pBlock, pPixels); @@ -966,14 +1126,7 @@ namespace basisu } case texture_format::cBC7: { - // We only support modes 5 and 6. - if (!unpack_bc7_mode5(pBlock, pPixels)) - { - if (!unpack_bc7_mode6(pBlock, pPixels)) - return false; - } - - break; + return unpack_bc7(pBlock, pPixels); } // Full ETC2 color blocks (planar/T/H modes) is currently unsupported in basisu, but we do support ETC2 with alpha (using ETC1 for color) case texture_format::cETC2_RGB: @@ -1032,6 +1185,11 @@ namespace basisu unpack_etc2_eac_rg(pBlock, pPixels); break; } + case texture_format::cUASTC4x4: + { + unpack_uastc(pBlock, pPixels); + break; + } default: { assert(0); @@ -1113,6 +1271,7 @@ namespace basisu KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02, KTX_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, + KTX_COMPRESSED_RGBA_UASTC_4x4_KHR = 0x94CC, // TODO - Use proper value! KTX_ATC_RGB_AMD = 0x8C92, KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE, KTX_COMPRESSED_RGB_FXT1_3DFX = 0x86B0, @@ -1143,7 +1302,7 @@ namespace basisu }; // Input is a texture array of mipmapped gpu_image's: gpu_images[array_index][level_index] - bool create_ktx_texture_file(uint8_vec &ktx_data, const std::vector<gpu_image_vec>& gpu_images, bool cubemap_flag) + bool create_ktx_texture_file(uint8_vec &ktx_data, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag) { if (!gpu_images.size()) { @@ -1220,6 +1379,8 @@ namespace basisu switch (fmt) { case texture_format::cBC1: + case texture_format::cBC1_NV: + case texture_format::cBC1_AMD: { internal_fmt = KTX_COMPRESSED_RGB_S3TC_DXT1_EXT; break; @@ -1305,6 +1466,12 @@ namespace basisu base_internal_fmt = KTX_RG; break; } + case texture_format::cUASTC4x4: + { + internal_fmt = KTX_COMPRESSED_RGBA_UASTC_4x4_KHR; + base_internal_fmt = KTX_RGBA; + break; + } case texture_format::cFXT1_RGB: { internal_fmt = KTX_COMPRESSED_RGB_FXT1_3DFX; @@ -1378,7 +1545,7 @@ namespace basisu return true; } - bool write_compressed_texture_file(const char* pFilename, const std::vector<gpu_image_vec>& g, bool cubemap_flag) + bool write_compressed_texture_file(const char* pFilename, const basisu::vector<gpu_image_vec>& g, bool cubemap_flag) { std::string extension(string_tolower(string_get_extension(pFilename))); @@ -1410,12 +1577,12 @@ namespace basisu bool write_compressed_texture_file(const char* pFilename, const gpu_image& g) { - std::vector<gpu_image_vec> v; + basisu::vector<gpu_image_vec> v; enlarge_vector(v, 1)->push_back(g); return write_compressed_texture_file(pFilename, v, false); } - const uint32_t OUT_FILE_MAGIC = 'TEXC'; + //const uint32_t OUT_FILE_MAGIC = 'TEXC'; struct out_file_header { packed_uint<4> m_magic; @@ -1428,7 +1595,11 @@ namespace basisu bool write_3dfx_out_file(const char* pFilename, const gpu_image& gi) { out_file_header hdr; - hdr.m_magic = OUT_FILE_MAGIC; + //hdr.m_magic = OUT_FILE_MAGIC; + hdr.m_magic.m_bytes[0] = 67; + hdr.m_magic.m_bytes[1] = 88; + hdr.m_magic.m_bytes[2] = 69; + hdr.m_magic.m_bytes[3] = 84; hdr.m_pad = 0; hdr.m_width = gi.get_blocks_x() * 8; hdr.m_height = gi.get_blocks_y() * 4; diff --git a/thirdparty/basis_universal/basisu_gpu_texture.h b/thirdparty/basis_universal/encoder/basisu_gpu_texture.h index 8a49757ca7..619926f5f9 100644 --- a/thirdparty/basis_universal/basisu_gpu_texture.h +++ b/thirdparty/basis_universal/encoder/basisu_gpu_texture.h @@ -1,5 +1,5 @@ // basisu_gpu_texture.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,13 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. #pragma once -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" #include "basisu_etc.h" namespace basisu { - // GPU texture image - + // GPU texture "image" class gpu_image { public: @@ -115,17 +114,17 @@ namespace basisu uint64_vec m_blocks; }; - typedef std::vector<gpu_image> gpu_image_vec; + typedef basisu::vector<gpu_image> gpu_image_vec; // KTX file writing - bool create_ktx_texture_file(uint8_vec &ktx_data, const std::vector<gpu_image_vec>& gpu_images, bool cubemap_flag); + bool create_ktx_texture_file(uint8_vec &ktx_data, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag); - bool write_compressed_texture_file(const char *pFilename, const std::vector<gpu_image_vec>& g, bool cubemap_flag); + bool write_compressed_texture_file(const char *pFilename, const basisu::vector<gpu_image_vec>& g, bool cubemap_flag); inline bool write_compressed_texture_file(const char *pFilename, const gpu_image_vec &g) { - std::vector<gpu_image_vec> a; + basisu::vector<gpu_image_vec> a; a.push_back(g); return write_compressed_texture_file(pFilename, a, false); } @@ -133,22 +132,23 @@ namespace basisu bool write_compressed_texture_file(const char *pFilename, const gpu_image &g); bool write_3dfx_out_file(const char* pFilename, const gpu_image& gi); - // GPU texture block unpacking + // GPU texture block unpacking void unpack_etc2_eac(const void *pBlock_bits, color_rgba *pPixels); bool unpack_bc1(const void *pBlock_bits, color_rgba *pPixels, bool set_alpha); void unpack_bc4(const void *pBlock_bits, uint8_t *pPixels, uint32_t stride); bool unpack_bc3(const void *pBlock_bits, color_rgba *pPixels); void unpack_bc5(const void *pBlock_bits, color_rgba *pPixels); bool unpack_bc7_mode6(const void *pBlock_bits, color_rgba *pPixels); - bool unpack_bc7_mode5(const void* pBlock_bits, color_rgba* pPixels); + bool unpack_bc7(const void* pBlock_bits, color_rgba* pPixels); void unpack_atc(const void* pBlock_bits, color_rgba* pPixels); bool unpack_fxt1(const void* p, color_rgba* pPixels); bool unpack_pvrtc2(const void* p, color_rgba* pPixels); + void unpack_etc2_eac_r(const void *p, color_rgba* pPixels, uint32_t c); void unpack_etc2_eac_rg(const void* p, color_rgba* pPixels); - // unpack_block() is only capable of unpacking texture data created by the transcoder. - // For some texture formats (like BC7, or ETC2) it's not a complete implementation. + // unpack_block() is primarily intended to unpack texture data created by the transcoder. + // For some texture formats (like ETC2 RGB, PVRTC2, FXT1) it's not a complete implementation. bool unpack_block(texture_format fmt, const void *pBlock, color_rgba *pPixels); } // namespace basisu diff --git a/thirdparty/basis_universal/encoder/basisu_kernels_declares.h b/thirdparty/basis_universal/encoder/basisu_kernels_declares.h new file mode 100644 index 0000000000..e24bdd7978 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_kernels_declares.h @@ -0,0 +1,25 @@ +// basisu_kernels_declares.h +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if BASISU_SUPPORT_SSE +void CPPSPMD_NAME(perceptual_distance_rgb_4_N)(int64_t* pDistance, const uint8_t* pSelectors, const basisu::color_rgba* pBlock_colors, const basisu::color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err); +void CPPSPMD_NAME(linear_distance_rgb_4_N)(int64_t* pDistance, const uint8_t* pSelectors, const basisu::color_rgba* pBlock_colors, const basisu::color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err); + +void CPPSPMD_NAME(find_selectors_perceptual_rgb_4_N)(int64_t* pDistance, uint8_t* pSelectors, const basisu::color_rgba* pBlock_colors, const basisu::color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err); +void CPPSPMD_NAME(find_selectors_linear_rgb_4_N)(int64_t* pDistance, uint8_t* pSelectors, const basisu::color_rgba* pBlock_colors, const basisu::color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err); + +void CPPSPMD_NAME(find_lowest_error_perceptual_rgb_4_N)(int64_t* pDistance, const basisu::color_rgba* pBlock_colors, const basisu::color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_error); +void CPPSPMD_NAME(find_lowest_error_linear_rgb_4_N)(int64_t* pDistance, const basisu::color_rgba* pBlock_colors, const basisu::color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_error); +#endif diff --git a/thirdparty/basis_universal/encoder/basisu_kernels_imp.h b/thirdparty/basis_universal/encoder/basisu_kernels_imp.h new file mode 100644 index 0000000000..046880517b --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_kernels_imp.h @@ -0,0 +1,584 @@ +// basisu_kernels_imp.h - Do not directly include +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using namespace CPPSPMD; + +namespace CPPSPMD_NAME(basisu_kernels_namespace) +{ + struct perceptual_distance_rgb_4_N : spmd_kernel + { + void _call(int64_t* pDistance, + const uint8_t* pSelectors, + const color_rgba* pBlock_colors, + const color_rgba* pSrc_pixels, uint32_t n, + int64_t early_out_err) + { + assert(early_out_err >= 0); + + *pDistance = 0; + + __m128i block_colors[4]; + vint block_colors_r[4], block_colors_g[4], block_colors_b[4]; + for (uint32_t i = 0; i < 4; i++) + { + block_colors[i] = load_rgba32(&pBlock_colors[i]); + store_all(block_colors_r[i], (int)pBlock_colors[i].r); + store_all(block_colors_g[i], (int)pBlock_colors[i].g); + store_all(block_colors_b[i], (int)pBlock_colors[i].b); + } + + uint32_t i; + for (i = 0; (i + 4) <= n; i += 4) + { + __m128i c0 = load_rgba32(&pSrc_pixels[i + 0]), c1 = load_rgba32(&pSrc_pixels[i + 1]), c2 = load_rgba32(&pSrc_pixels[i + 2]), c3 = load_rgba32(&pSrc_pixels[i + 3]); + + vint r, g, b, a; + transpose4x4(r.m_value, g.m_value, b.m_value, a.m_value, c0, c1, c2, c3); + + int s0 = pSelectors[i], s1 = pSelectors[i + 1], s2 = pSelectors[i + 2], s3 = pSelectors[i + 3]; + + vint base_r, base_g, base_b, base_a; + if ((s0 == s1) && (s0 == s2) && (s0 == s3)) + { + store_all(base_r, block_colors_r[s0]); + store_all(base_g, block_colors_g[s0]); + store_all(base_b, block_colors_b[s0]); + } + else + { + __m128i k0 = block_colors[s0], k1 = block_colors[s1], k2 = block_colors[s2], k3 = block_colors[s3]; + transpose4x4(base_r.m_value, base_g.m_value, base_b.m_value, base_a.m_value, k0, k1, k2, k3); + } + + vint dr = base_r - r; + vint dg = base_g - g; + vint db = base_b - b; + + vint delta_l = dr * 27 + dg * 92 + db * 9; + vint delta_cr = dr * 128 - delta_l; + vint delta_cb = db * 128 - delta_l; + + vint id = ((delta_l * delta_l) >> 7) + + ((((delta_cr * delta_cr) >> 7) * 26) >> 7) + + ((((delta_cb * delta_cb) >> 7) * 3) >> 7); + + *pDistance += reduce_add(id); + if (*pDistance >= early_out_err) + return; + } + + for (; i < n; i++) + { + int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + + int sel = pSelectors[i]; + int base_r = pBlock_colors[sel].r, base_g = pBlock_colors[sel].g, base_b = pBlock_colors[sel].b; + + int dr = base_r - r; + int dg = base_g - g; + int db = base_b - b; + + int delta_l = dr * 27 + dg * 92 + db * 9; + int delta_cr = dr * 128 - delta_l; + int delta_cb = db * 128 - delta_l; + + int id = ((delta_l * delta_l) >> 7) + + ((((delta_cr * delta_cr) >> 7) * 26) >> 7) + + ((((delta_cb * delta_cb) >> 7) * 3) >> 7); + + *pDistance += id; + if (*pDistance >= early_out_err) + return; + } + } + }; + + struct linear_distance_rgb_4_N : spmd_kernel + { + void _call(int64_t* pDistance, + const uint8_t* pSelectors, + const color_rgba* pBlock_colors, + const color_rgba* pSrc_pixels, uint32_t n, + int64_t early_out_err) + { + assert(early_out_err >= 0); + + *pDistance = 0; + + __m128i block_colors[4]; + vint block_colors_r[4], block_colors_g[4], block_colors_b[4]; + for (uint32_t i = 0; i < 4; i++) + { + block_colors[i] = load_rgba32(&pBlock_colors[i]); + store_all(block_colors_r[i], (int)pBlock_colors[i].r); + store_all(block_colors_g[i], (int)pBlock_colors[i].g); + store_all(block_colors_b[i], (int)pBlock_colors[i].b); + } + + uint32_t i; + for (i = 0; (i + 4) <= n; i += 4) + { + __m128i c0 = load_rgba32(&pSrc_pixels[i + 0]), c1 = load_rgba32(&pSrc_pixels[i + 1]), c2 = load_rgba32(&pSrc_pixels[i + 2]), c3 = load_rgba32(&pSrc_pixels[i + 3]); + + vint r, g, b, a; + transpose4x4(r.m_value, g.m_value, b.m_value, a.m_value, c0, c1, c2, c3); + + int s0 = pSelectors[i], s1 = pSelectors[i + 1], s2 = pSelectors[i + 2], s3 = pSelectors[i + 3]; + + vint base_r, base_g, base_b, base_a; + if ((s0 == s1) && (s0 == s2) && (s0 == s3)) + { + store_all(base_r, block_colors_r[s0]); + store_all(base_g, block_colors_g[s0]); + store_all(base_b, block_colors_b[s0]); + } + else + { + __m128i k0 = block_colors[s0], k1 = block_colors[s1], k2 = block_colors[s2], k3 = block_colors[s3]; + transpose4x4(base_r.m_value, base_g.m_value, base_b.m_value, base_a.m_value, k0, k1, k2, k3); + } + + vint dr = base_r - r; + vint dg = base_g - g; + vint db = base_b - b; + + vint id = dr * dr + dg * dg + db * db; + + *pDistance += reduce_add(id); + if (*pDistance >= early_out_err) + return; + } + + for (; i < n; i++) + { + int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + + int sel = pSelectors[i]; + int base_r = pBlock_colors[sel].r, base_g = pBlock_colors[sel].g, base_b = pBlock_colors[sel].b; + + int dr = base_r - r; + int dg = base_g - g; + int db = base_b - b; + + int id = dr * dr + dg * dg + db * db; + + *pDistance += id; + if (*pDistance >= early_out_err) + return; + } + } + }; + + struct find_selectors_perceptual_rgb_4_N : spmd_kernel + { + inline vint compute_dist( + const vint& base_r, const vint& base_g, const vint& base_b, + const vint& r, const vint& g, const vint& b) + { + vint dr = base_r - r; + vint dg = base_g - g; + vint db = base_b - b; + + vint delta_l = dr * 27 + dg * 92 + db * 9; + vint delta_cr = dr * 128 - delta_l; + vint delta_cb = db * 128 - delta_l; + + vint id = VINT_SHIFT_RIGHT(delta_l * delta_l, 7) + + VINT_SHIFT_RIGHT(VINT_SHIFT_RIGHT(delta_cr * delta_cr, 7) * 26, 7) + + VINT_SHIFT_RIGHT(VINT_SHIFT_RIGHT(delta_cb * delta_cb, 7) * 3, 7); + + return id; + } + + void _call(int64_t* pDistance, + uint8_t* pSelectors, + const color_rgba* pBlock_colors, + const color_rgba* pSrc_pixels, uint32_t n, + int64_t early_out_err) + { + assert(early_out_err >= 0); + + *pDistance = 0; + + vint block_colors_r[4], block_colors_g[4], block_colors_b[4]; + for (uint32_t i = 0; i < 4; i++) + { + store_all(block_colors_r[i], (int)pBlock_colors[i].r); + store_all(block_colors_g[i], (int)pBlock_colors[i].g); + store_all(block_colors_b[i], (int)pBlock_colors[i].b); + } + + const __m128i shuf = _mm_set_epi8(-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 12, 8, 4, 0); + + uint32_t i; + + for (i = 0; (i + 4) <= n; i += 4) + { + __m128i c0 = load_rgba32(&pSrc_pixels[i + 0]), c1 = load_rgba32(&pSrc_pixels[i + 1]), c2 = load_rgba32(&pSrc_pixels[i + 2]), c3 = load_rgba32(&pSrc_pixels[i + 3]); + + vint r, g, b, a; + transpose4x4(r.m_value, g.m_value, b.m_value, a.m_value, c0, c1, c2, c3); + + vint dist0 = compute_dist(block_colors_r[0], block_colors_g[0], block_colors_b[0], r, g, b); + vint dist1 = compute_dist(block_colors_r[1], block_colors_g[1], block_colors_b[1], r, g, b); + vint dist2 = compute_dist(block_colors_r[2], block_colors_g[2], block_colors_b[2], r, g, b); + vint dist3 = compute_dist(block_colors_r[3], block_colors_g[3], block_colors_b[3], r, g, b); + + vint min_dist = min(min(min(dist0, dist1), dist2), dist3); + + vint sels = spmd_ternaryi(min_dist == dist0, 0, spmd_ternaryi(min_dist == dist1, 1, spmd_ternaryi(min_dist == dist2, 2, 3))); + + __m128i vsels = shuffle_epi8(sels.m_value, shuf); + storeu_si32((void *)(pSelectors + i), vsels); + + *pDistance += reduce_add(min_dist); + if (*pDistance >= early_out_err) + return; + } + + for (; i < n; i++) + { + int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + + int best_err = INT_MAX, best_sel = 0; + for (int sel = 0; sel < 4; sel++) + { + int base_r = pBlock_colors[sel].r, base_g = pBlock_colors[sel].g, base_b = pBlock_colors[sel].b; + + int dr = base_r - r; + int dg = base_g - g; + int db = base_b - b; + + int delta_l = dr * 27 + dg * 92 + db * 9; + int delta_cr = dr * 128 - delta_l; + int delta_cb = db * 128 - delta_l; + + int id = ((delta_l * delta_l) >> 7) + + ((((delta_cr * delta_cr) >> 7) * 26) >> 7) + + ((((delta_cb * delta_cb) >> 7) * 3) >> 7); + if (id < best_err) + { + best_err = id; + best_sel = sel; + } + } + + pSelectors[i] = (uint8_t)best_sel; + + *pDistance += best_err; + if (*pDistance >= early_out_err) + return; + } + } + }; + + struct find_selectors_linear_rgb_4_N : spmd_kernel + { + inline vint compute_dist( + const vint& base_r, const vint& base_g, const vint& base_b, + const vint& r, const vint& g, const vint& b) + { + vint dr = base_r - r; + vint dg = base_g - g; + vint db = base_b - b; + + vint id = dr * dr + dg * dg + db * db; + return id; + } + + void _call(int64_t* pDistance, + uint8_t* pSelectors, + const color_rgba* pBlock_colors, + const color_rgba* pSrc_pixels, uint32_t n, + int64_t early_out_err) + { + assert(early_out_err >= 0); + + *pDistance = 0; + + vint block_colors_r[4], block_colors_g[4], block_colors_b[4]; + for (uint32_t i = 0; i < 4; i++) + { + store_all(block_colors_r[i], (int)pBlock_colors[i].r); + store_all(block_colors_g[i], (int)pBlock_colors[i].g); + store_all(block_colors_b[i], (int)pBlock_colors[i].b); + } + + const __m128i shuf = _mm_set_epi8(-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 12, 8, 4, 0); + + uint32_t i; + + for (i = 0; (i + 4) <= n; i += 4) + { + __m128i c0 = load_rgba32(&pSrc_pixels[i + 0]), c1 = load_rgba32(&pSrc_pixels[i + 1]), c2 = load_rgba32(&pSrc_pixels[i + 2]), c3 = load_rgba32(&pSrc_pixels[i + 3]); + + vint r, g, b, a; + transpose4x4(r.m_value, g.m_value, b.m_value, a.m_value, c0, c1, c2, c3); + + vint dist0 = compute_dist(block_colors_r[0], block_colors_g[0], block_colors_b[0], r, g, b); + vint dist1 = compute_dist(block_colors_r[1], block_colors_g[1], block_colors_b[1], r, g, b); + vint dist2 = compute_dist(block_colors_r[2], block_colors_g[2], block_colors_b[2], r, g, b); + vint dist3 = compute_dist(block_colors_r[3], block_colors_g[3], block_colors_b[3], r, g, b); + + vint min_dist = min(min(min(dist0, dist1), dist2), dist3); + + vint sels = spmd_ternaryi(min_dist == dist0, 0, spmd_ternaryi(min_dist == dist1, 1, spmd_ternaryi(min_dist == dist2, 2, 3))); + + __m128i vsels = shuffle_epi8(sels.m_value, shuf); + storeu_si32((void *)(pSelectors + i), vsels); + + *pDistance += reduce_add(min_dist); + if (*pDistance >= early_out_err) + return; + } + + for (; i < n; i++) + { + int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + + int best_err = INT_MAX, best_sel = 0; + for (int sel = 0; sel < 4; sel++) + { + int base_r = pBlock_colors[sel].r, base_g = pBlock_colors[sel].g, base_b = pBlock_colors[sel].b; + + int dr = base_r - r; + int dg = base_g - g; + int db = base_b - b; + + int id = dr * dr + dg * dg + db * db; + if (id < best_err) + { + best_err = id; + best_sel = sel; + } + } + + pSelectors[i] = (uint8_t)best_sel; + + *pDistance += best_err; + if (*pDistance >= early_out_err) + return; + } + } + }; + + struct find_lowest_error_perceptual_rgb_4_N : spmd_kernel + { + inline vint compute_dist( + const vint& base_r, const vint& base_g, const vint& base_b, + const vint& r, const vint& g, const vint& b) + { + vint dr = base_r - r; + vint dg = base_g - g; + vint db = base_b - b; + + vint delta_l = dr * 27 + dg * 92 + db * 9; + vint delta_cr = dr * 128 - delta_l; + vint delta_cb = db * 128 - delta_l; + + vint id = VINT_SHIFT_RIGHT(delta_l * delta_l, 7) + + VINT_SHIFT_RIGHT(VINT_SHIFT_RIGHT(delta_cr * delta_cr, 7) * 26, 7) + + VINT_SHIFT_RIGHT(VINT_SHIFT_RIGHT(delta_cb * delta_cb, 7) * 3, 7); + + return id; + } + + void _call(int64_t* pDistance, + const color_rgba* pBlock_colors, + const color_rgba* pSrc_pixels, uint32_t n, + int64_t early_out_error) + { + assert(early_out_error >= 0); + + *pDistance = 0; + + vint block_colors_r[4], block_colors_g[4], block_colors_b[4]; + for (uint32_t i = 0; i < 4; i++) + { + store_all(block_colors_r[i], (int)pBlock_colors[i].r); + store_all(block_colors_g[i], (int)pBlock_colors[i].g); + store_all(block_colors_b[i], (int)pBlock_colors[i].b); + } + + uint32_t i; + + for (i = 0; (i + 4) <= n; i += 4) + { + __m128i c0 = load_rgba32(&pSrc_pixels[i + 0]), c1 = load_rgba32(&pSrc_pixels[i + 1]), c2 = load_rgba32(&pSrc_pixels[i + 2]), c3 = load_rgba32(&pSrc_pixels[i + 3]); + + vint r, g, b, a; + transpose4x4(r.m_value, g.m_value, b.m_value, a.m_value, c0, c1, c2, c3); + + vint dist0 = compute_dist(block_colors_r[0], block_colors_g[0], block_colors_b[0], r, g, b); + vint dist1 = compute_dist(block_colors_r[1], block_colors_g[1], block_colors_b[1], r, g, b); + vint dist2 = compute_dist(block_colors_r[2], block_colors_g[2], block_colors_b[2], r, g, b); + vint dist3 = compute_dist(block_colors_r[3], block_colors_g[3], block_colors_b[3], r, g, b); + + vint min_dist = min(min(min(dist0, dist1), dist2), dist3); + + *pDistance += reduce_add(min_dist); + if (*pDistance > early_out_error) + return; + } + + for (; i < n; i++) + { + int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + + int best_err = INT_MAX; + for (int sel = 0; sel < 4; sel++) + { + int base_r = pBlock_colors[sel].r, base_g = pBlock_colors[sel].g, base_b = pBlock_colors[sel].b; + + int dr = base_r - r; + int dg = base_g - g; + int db = base_b - b; + + int delta_l = dr * 27 + dg * 92 + db * 9; + int delta_cr = dr * 128 - delta_l; + int delta_cb = db * 128 - delta_l; + + int id = ((delta_l * delta_l) >> 7) + + ((((delta_cr * delta_cr) >> 7) * 26) >> 7) + + ((((delta_cb * delta_cb) >> 7) * 3) >> 7); + + if (id < best_err) + { + best_err = id; + } + } + + *pDistance += best_err; + if (*pDistance > early_out_error) + return; + } + } + }; + + struct find_lowest_error_linear_rgb_4_N : spmd_kernel + { + inline vint compute_dist( + const vint& base_r, const vint& base_g, const vint& base_b, + const vint& r, const vint& g, const vint& b) + { + vint dr = base_r - r; + vint dg = base_g - g; + vint db = base_b - b; + + vint id = dr * dr + dg * dg + db * db; + + return id; + } + + void _call(int64_t* pDistance, + const color_rgba* pBlock_colors, + const color_rgba* pSrc_pixels, uint32_t n, + int64_t early_out_error) + { + assert(early_out_error >= 0); + + *pDistance = 0; + + vint block_colors_r[4], block_colors_g[4], block_colors_b[4]; + for (uint32_t i = 0; i < 4; i++) + { + store_all(block_colors_r[i], (int)pBlock_colors[i].r); + store_all(block_colors_g[i], (int)pBlock_colors[i].g); + store_all(block_colors_b[i], (int)pBlock_colors[i].b); + } + + uint32_t i; + + for (i = 0; (i + 4) <= n; i += 4) + { + __m128i c0 = load_rgba32(&pSrc_pixels[i + 0]), c1 = load_rgba32(&pSrc_pixels[i + 1]), c2 = load_rgba32(&pSrc_pixels[i + 2]), c3 = load_rgba32(&pSrc_pixels[i + 3]); + + vint r, g, b, a; + transpose4x4(r.m_value, g.m_value, b.m_value, a.m_value, c0, c1, c2, c3); + + vint dist0 = compute_dist(block_colors_r[0], block_colors_g[0], block_colors_b[0], r, g, b); + vint dist1 = compute_dist(block_colors_r[1], block_colors_g[1], block_colors_b[1], r, g, b); + vint dist2 = compute_dist(block_colors_r[2], block_colors_g[2], block_colors_b[2], r, g, b); + vint dist3 = compute_dist(block_colors_r[3], block_colors_g[3], block_colors_b[3], r, g, b); + + vint min_dist = min(min(min(dist0, dist1), dist2), dist3); + + *pDistance += reduce_add(min_dist); + if (*pDistance > early_out_error) + return; + } + + for (; i < n; i++) + { + int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + + int best_err = INT_MAX; + for (int sel = 0; sel < 4; sel++) + { + int base_r = pBlock_colors[sel].r, base_g = pBlock_colors[sel].g, base_b = pBlock_colors[sel].b; + + int dr = base_r - r; + int dg = base_g - g; + int db = base_b - b; + + int id = dr * dr + dg * dg + db * db; + + if (id < best_err) + { + best_err = id; + } + } + + *pDistance += best_err; + if (*pDistance > early_out_error) + return; + } + } + }; + +} // namespace + +using namespace CPPSPMD_NAME(basisu_kernels_namespace); + +void CPPSPMD_NAME(perceptual_distance_rgb_4_N)(int64_t* pDistance, const uint8_t* pSelectors, const color_rgba* pBlock_colors, const color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err) +{ + spmd_call< perceptual_distance_rgb_4_N >(pDistance, pSelectors, pBlock_colors, pSrc_pixels, n, early_out_err); +} + +void CPPSPMD_NAME(linear_distance_rgb_4_N)(int64_t* pDistance, const uint8_t* pSelectors, const color_rgba* pBlock_colors, const color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err) +{ + spmd_call< linear_distance_rgb_4_N >(pDistance, pSelectors, pBlock_colors, pSrc_pixels, n, early_out_err); +} + +void CPPSPMD_NAME(find_selectors_perceptual_rgb_4_N)(int64_t *pDistance, uint8_t* pSelectors, const color_rgba* pBlock_colors, const color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err) +{ + spmd_call< find_selectors_perceptual_rgb_4_N >(pDistance, pSelectors, pBlock_colors, pSrc_pixels, n, early_out_err); +} + +void CPPSPMD_NAME(find_selectors_linear_rgb_4_N)(int64_t* pDistance, uint8_t* pSelectors, const color_rgba* pBlock_colors, const color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_err) +{ + spmd_call< find_selectors_linear_rgb_4_N >(pDistance, pSelectors, pBlock_colors, pSrc_pixels, n, early_out_err); +} + +void CPPSPMD_NAME(find_lowest_error_perceptual_rgb_4_N)(int64_t* pDistance, const color_rgba* pBlock_colors, const color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_error) +{ + spmd_call< find_lowest_error_perceptual_rgb_4_N >(pDistance, pBlock_colors, pSrc_pixels, n, early_out_error); +} + +void CPPSPMD_NAME(find_lowest_error_linear_rgb_4_N)(int64_t* pDistance, const color_rgba* pBlock_colors, const color_rgba* pSrc_pixels, uint32_t n, int64_t early_out_error) +{ + spmd_call< find_lowest_error_linear_rgb_4_N >(pDistance, pBlock_colors, pSrc_pixels, n, early_out_error); +} + diff --git a/thirdparty/basis_universal/encoder/basisu_kernels_sse.cpp b/thirdparty/basis_universal/encoder/basisu_kernels_sse.cpp new file mode 100644 index 0000000000..12d2321f20 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_kernels_sse.cpp @@ -0,0 +1,161 @@ +// basisu_kernels_sse.cpp +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_enc.h" + +#if BASISU_SUPPORT_SSE + +#define CPPSPMD_SSE2 0 + +#ifdef _MSC_VER +#include <intrin.h> +#endif + +#if !defined(_MSC_VER) + #if __AVX__ || __AVX2__ || __AVX512F__ + #error Please check your compiler options + #endif + + #if CPPSPMD_SSE2 + #if __SSE4_1__ || __SSE3__ || __SSE4_2__ || __SSSE3__ + #error SSE4.1/SSE3/SSE4.2/SSSE3 cannot be enabled to use this file + #endif + #else + #if !__SSE4_1__ || !__SSE3__ || __SSE4_2__ || !__SSSE3__ + #error Please check your compiler options + #endif + #endif +#endif + +#include "cppspmd_sse.h" + +#include "cppspmd_type_aliases.h" + +using namespace basisu; + +#include "basisu_kernels_declares.h" +#include "basisu_kernels_imp.h" + +namespace basisu +{ + +struct cpu_info +{ + cpu_info() { memset(this, 0, sizeof(*this)); } + + bool m_has_fpu; + bool m_has_mmx; + bool m_has_sse; + bool m_has_sse2; + bool m_has_sse3; + bool m_has_ssse3; + bool m_has_sse41; + bool m_has_sse42; + bool m_has_avx; + bool m_has_avx2; + bool m_has_pclmulqdq; +}; + +static void extract_x86_flags(cpu_info &info, uint32_t ecx, uint32_t edx) +{ + info.m_has_fpu = (edx & (1 << 0)) != 0; + info.m_has_mmx = (edx & (1 << 23)) != 0; + info.m_has_sse = (edx & (1 << 25)) != 0; + info.m_has_sse2 = (edx & (1 << 26)) != 0; + info.m_has_sse3 = (ecx & (1 << 0)) != 0; + info.m_has_ssse3 = (ecx & (1 << 9)) != 0; + info.m_has_sse41 = (ecx & (1 << 19)) != 0; + info.m_has_sse42 = (ecx & (1 << 20)) != 0; + info.m_has_pclmulqdq = (ecx & (1 << 1)) != 0; + info.m_has_avx = (ecx & (1 << 28)) != 0; +} + +static void extract_x86_extended_flags(cpu_info &info, uint32_t ebx) +{ + info.m_has_avx2 = (ebx & (1 << 5)) != 0; +} + +#ifndef _MSC_VER +static void do_cpuid(uint32_t eax, uint32_t ecx, uint32_t* regs) +{ + uint32_t ebx = 0, edx = 0; + +#if defined(__PIC__) && defined(__i386__) + __asm__("movl %%ebx, %%edi;" + "cpuid;" + "xchgl %%ebx, %%edi;" + : "=D"(ebx), "+a"(eax), "+c"(ecx), "=d"(edx)); +#else + __asm__("cpuid;" : "+b"(ebx), "+a"(eax), "+c"(ecx), "=d"(edx)); +#endif + + regs[0] = eax; regs[1] = ebx; regs[2] = ecx; regs[3] = edx; +} +#endif + +static void get_cpuinfo(cpu_info &info) +{ + int regs[4]; + +#ifdef _MSC_VER + __cpuid(regs, 0); +#else + do_cpuid(0, 0, (uint32_t *)regs); +#endif + + const uint32_t max_eax = regs[0]; + + if (max_eax >= 1U) + { +#ifdef _MSC_VER + __cpuid(regs, 1); +#else + do_cpuid(1, 0, (uint32_t*)regs); +#endif + extract_x86_flags(info, regs[2], regs[3]); + } + + if (max_eax >= 7U) + { +#ifdef _MSC_VER + __cpuidex(regs, 7, 0); +#else + do_cpuid(7, 0, (uint32_t*)regs); +#endif + + extract_x86_extended_flags(info, regs[1]); + } +} + +void detect_sse41() +{ + cpu_info info; + get_cpuinfo(info); + + // Check for everything from SSE to SSE 4.1 + g_cpu_supports_sse41 = info.m_has_sse && info.m_has_sse2 && info.m_has_sse3 && info.m_has_ssse3 && info.m_has_sse41; +} + +} // namespace basisu +#else // #if BASISU_SUPPORT_SSE +namespace basisu +{ + +void detect_sse41() +{ +} + +} // namespace basisu +#endif // #if BASISU_SUPPORT_SSE + diff --git a/thirdparty/basis_universal/encoder/basisu_miniz.h b/thirdparty/basis_universal/encoder/basisu_miniz.h new file mode 100644 index 0000000000..8627abe893 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_miniz.h @@ -0,0 +1,2514 @@ +/* miniz.c v1.15 - deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + + Forked from the public domain/unlicense version at: https://code.google.com/archive/p/miniz/ + + Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef MINIZ_HEADER_INCLUDED +#define MINIZ_HEADER_INCLUDED + +#include <stdlib.h> + +// Defines to completely disable specific portions of miniz.c: +// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. + +// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. +//#define MINIZ_NO_STDIO + +// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or +// get/set file times, and the C run-time funcs that get/set times won't be called. +// The current downside is the times written to your archives will be from 1979. +//#define MINIZ_NO_TIME + +// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. +//#define MINIZ_NO_ARCHIVE_APIS + +// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's. +//#define MINIZ_NO_ARCHIVE_WRITING_APIS + +// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. +//#define MINIZ_NO_ZLIB_APIS + +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. +//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc +// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user +// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. +//#define MINIZ_NO_MALLOC + +#if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) + // TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux + #define MINIZ_NO_TIME +#endif + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) + #include <time.h> +#endif + +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) +// MINIZ_X86_OR_X64_CPU is only used to help set the below macros. +#define MINIZ_X86_OR_X64_CPU 1 +#endif + +#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#endif + +#if MINIZ_X86_OR_X64_CPU +// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +#endif + +#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) +// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). +#define MINIZ_HAS_64BIT_REGISTERS 1 +#endif + +namespace buminiz { + +// ------------------- zlib-style API Definitions. + +// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! +typedef unsigned long mz_ulong; + +// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. +void mz_free(void *p); + +#define MZ_ADLER32_INIT (1) +// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); + +#define MZ_CRC32_INIT (0) +// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. +mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); + +// Compression strategies. +enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 }; + +// Method +#define MZ_DEFLATED 8 + +#ifndef MINIZ_NO_ZLIB_APIS + +// Heap allocation callbacks. +// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. +typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); +typedef void (*mz_free_func)(void *opaque, void *address); +typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); + +#define MZ_VERSION "9.1.15" +#define MZ_VERNUM 0x91F0 +#define MZ_VER_MAJOR 9 +#define MZ_VER_MINOR 1 +#define MZ_VER_REVISION 15 +#define MZ_VER_SUBREVISION 0 + +// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). +enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; + +// Return status codes. MZ_PARAM_ERROR is non-standard. +enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; + +// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. +enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 }; + +// Window bits +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +// Compression/decompression stream struct. +typedef struct mz_stream_s +{ + const unsigned char *next_in; // pointer to next byte to read + unsigned int avail_in; // number of bytes available at next_in + mz_ulong total_in; // total number of bytes consumed so far + + unsigned char *next_out; // pointer to next byte to write + unsigned int avail_out; // number of bytes that can be written to next_out + mz_ulong total_out; // total number of bytes produced so far + + char *msg; // error msg (unused) + struct mz_internal_state *state; // internal state, allocated by zalloc/zfree + + mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc) + mz_free_func zfree; // optional heap free function (defaults to free) + void *opaque; // heap alloc function user pointer + + int data_type; // data_type (unused) + mz_ulong adler; // adler32 of the source or uncompressed data + mz_ulong reserved; // not used +} mz_stream; + +typedef mz_stream *mz_streamp; + +// Returns the version string of miniz.c. +const char *mz_version(void); + +// mz_deflateInit() initializes a compressor with default options: +// Parameters: +// pStream must point to an initialized mz_stream struct. +// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. +// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. +// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if the input parameters are bogus. +// MZ_MEM_ERROR on out of memory. +int mz_deflateInit(mz_streamp pStream, int level); + +// mz_deflateInit2() is like mz_deflate(), except with more control: +// Additional parameters: +// method must be MZ_DEFLATED +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) +// mem_level must be between [1, 9] (it's checked but ignored by miniz.c) +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); + +// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). +int mz_deflateReset(mz_streamp pStream); + +// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. +// Return values: +// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). +// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) +int mz_deflate(mz_streamp pStream, int flush); + +// mz_deflateEnd() deinitializes a compressor: +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +int mz_deflateEnd(mz_streamp pStream); + +// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); + +// Single-call compression functions mz_compress() and mz_compress2(): +// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); + +// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). +mz_ulong mz_compressBound(mz_ulong source_len); + +// Initializes a decompressor. +int mz_inflateInit(mz_streamp pStream); + +// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). +int mz_inflateInit2(mz_streamp pStream, int window_bits); + +// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. +// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). +// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. +// Return values: +// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. +// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_DATA_ERROR if the deflate stream is invalid. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again +// with more input data, or with more room in the output buffer (except when using single call decompression, described above). +int mz_inflate(mz_streamp pStream, int flush); + +// Deinitializes a decompressor. +int mz_inflateEnd(mz_streamp pStream); + +// Single-call decompression. +// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); + +// Returns a string description of the specified error code, or NULL if the error code is invalid. +const char *mz_error(int err); + +// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. +#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + typedef unsigned char Byte; + typedef unsigned int uInt; + typedef mz_ulong uLong; + typedef Byte Bytef; + typedef uInt uIntf; + typedef char charf; + typedef int intf; + typedef void *voidpf; + typedef uLong uLongf; + typedef void *voidp; + typedef void *const voidpc; + #define Z_NULL 0 + #define Z_NO_FLUSH MZ_NO_FLUSH + #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH + #define Z_SYNC_FLUSH MZ_SYNC_FLUSH + #define Z_FULL_FLUSH MZ_FULL_FLUSH + #define Z_FINISH MZ_FINISH + #define Z_BLOCK MZ_BLOCK + #define Z_OK MZ_OK + #define Z_STREAM_END MZ_STREAM_END + #define Z_NEED_DICT MZ_NEED_DICT + #define Z_ERRNO MZ_ERRNO + #define Z_STREAM_ERROR MZ_STREAM_ERROR + #define Z_DATA_ERROR MZ_DATA_ERROR + #define Z_MEM_ERROR MZ_MEM_ERROR + #define Z_BUF_ERROR MZ_BUF_ERROR + #define Z_VERSION_ERROR MZ_VERSION_ERROR + #define Z_PARAM_ERROR MZ_PARAM_ERROR + #define Z_NO_COMPRESSION MZ_NO_COMPRESSION + #define Z_BEST_SPEED MZ_BEST_SPEED + #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION + #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION + #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY + #define Z_FILTERED MZ_FILTERED + #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY + #define Z_RLE MZ_RLE + #define Z_FIXED MZ_FIXED + #define Z_DEFLATED MZ_DEFLATED + #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS + #define alloc_func mz_alloc_func + #define free_func mz_free_func + #define internal_state mz_internal_state + #define z_stream mz_stream + #define deflateInit mz_deflateInit + #define deflateInit2 mz_deflateInit2 + #define deflateReset mz_deflateReset + #define deflate mz_deflate + #define deflateEnd mz_deflateEnd + #define deflateBound mz_deflateBound + #define compress mz_compress + #define compress2 mz_compress2 + #define compressBound mz_compressBound + #define inflateInit mz_inflateInit + #define inflateInit2 mz_inflateInit2 + #define inflate mz_inflate + #define inflateEnd mz_inflateEnd + #define uncompress mz_uncompress + #define crc32 mz_crc32 + #define adler32 mz_adler32 + #define MAX_WBITS 15 + #define MAX_MEM_LEVEL 9 + #define zError mz_error + #define ZLIB_VERSION MZ_VERSION + #define ZLIB_VERNUM MZ_VERNUM + #define ZLIB_VER_MAJOR MZ_VER_MAJOR + #define ZLIB_VER_MINOR MZ_VER_MINOR + #define ZLIB_VER_REVISION MZ_VER_REVISION + #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION + #define zlibVersion mz_version + #define zlib_version mz_version() +#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +#endif // MINIZ_NO_ZLIB_APIS + +// ------------------- Types and macros + +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef long long mz_int64; +typedef unsigned long long mz_uint64; +typedef int mz_bool; + +#define MZ_FALSE (0) +#define MZ_TRUE (1) + +// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message. +#ifdef _MSC_VER + #define MZ_MACRO_END while (0, 0) +#else + #define MZ_MACRO_END while (0) +#endif + +// ------------------- Low-level Decompression API Definitions + +// Decompression flags used by tinfl_decompress(). +// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. +// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. +// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). +// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +// High level decompression functions: +// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. +// On return: +// Function returns a pointer to the decompressed data, or NULL on failure. +// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must call mz_free() on the returned block when it's no longer needed. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. +// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. +// Returns 1 on success or 0 on failure. +typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; + +// Max size of LZ dictionary. +#define TINFL_LZ_DICT_SIZE 32768 + +// Return status. +typedef enum +{ + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +// Initializes the decompressor to its initial state. +#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 + +// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. +// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +// Internal/private bits follow. +enum +{ + TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct +{ + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS + #define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF + typedef mz_uint64 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (64) +#else + typedef mz_uint32 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +// ------------------- Low-level Compression API Definitions + +// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). +#define TDEFL_LESS_MEMORY 0 + +// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): +// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). +enum +{ + TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF +}; + +// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. +// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). +// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. +// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). +// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) +// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. +// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. +// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. +// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). +enum +{ + TDEFL_WRITE_ZLIB_HEADER = 0x01000, + TDEFL_COMPUTE_ADLER32 = 0x02000, + TDEFL_GREEDY_PARSING_FLAG = 0x04000, + TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, + TDEFL_RLE_MATCHES = 0x10000, + TDEFL_FILTER_MATCHES = 0x20000, + TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, + TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 +}; + +// High level compression functions: +// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of source block to compress. +// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. +// Returns 0 on failure. +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// Compresses an image to a compressed PNG file in memory. +// On entry: +// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. +// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. +// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL +// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pLen_out will be set to the size of the PNG image file. +// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip); +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); + +// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. +typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); + +// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 }; + +// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). +#if TDEFL_LESS_MEMORY +enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#else +enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#endif + +// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. +typedef enum +{ + TDEFL_STATUS_BAD_PARAM = -2, + TDEFL_STATUS_PUT_BUF_FAILED = -1, + TDEFL_STATUS_OKAY = 0, + TDEFL_STATUS_DONE = 1, +} tdefl_status; + +// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums +typedef enum +{ + TDEFL_NO_FLUSH = 0, + TDEFL_SYNC_FLUSH = 2, + TDEFL_FULL_FLUSH = 3, + TDEFL_FINISH = 4 +} tdefl_flush; + +// tdefl's compression state structure. +typedef struct +{ + tdefl_put_buf_func_ptr m_pPut_buf_func; + void *m_pPut_buf_user; + mz_uint m_flags, m_max_probes[2]; + int m_greedy_parsing; + mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; + mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; + mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; + mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; + tdefl_status m_prev_return_status; + const void *m_pIn_buf; + void *m_pOut_buf; + size_t *m_pIn_buf_size, *m_pOut_buf_size; + tdefl_flush m_flush; + const mz_uint8 *m_pSrc; + size_t m_src_buf_left, m_out_buf_ofs; + mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; + mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; + mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; + mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; + mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; +} tdefl_compressor; + +// Initializes the compressor. +// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. +// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. +// If pBut_buf_func is NULL the user should always call the tdefl_compress() API. +// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); + +// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. +// tdefl_compress_buffer() always consumes the entire input buffer. +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); +mz_uint32 tdefl_get_adler32(tdefl_compressor *d); + +// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros. +#ifndef MINIZ_NO_ZLIB_APIS +// Create tdefl_compress() flags given zlib-style compression parameters. +// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) +// window_bits may be -15 (raw deflate) or 15 (zlib) +// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); +#endif // #ifndef MINIZ_NO_ZLIB_APIS + +} // namespace buminiz + +#endif // MINIZ_HEADER_INCLUDED + +// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) + +#ifndef MINIZ_HEADER_FILE_ONLY + +#include <string.h> +#include <assert.h> + +namespace buminiz { + +typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1]; +typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1]; +typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; + +#define MZ_ASSERT(x) assert(x) + +#ifdef MINIZ_NO_MALLOC + #define MZ_MALLOC(x) NULL + #define MZ_FREE(x) (void)x, ((void)0) + #define MZ_REALLOC(p, x) NULL +#else + #define MZ_MALLOC(x) malloc(x) + #define MZ_FREE(x) free(x) + #define MZ_REALLOC(p, x) realloc(p, x) +#endif + +#define MZ_MAX(a,b) (((a)>(b))?(a):(b)) +#define MZ_MIN(a,b) (((a)<(b))?(a):(b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) + #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else + #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) + #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#ifdef _MSC_VER + #define MZ_FORCEINLINE __forceinline +#elif defined(__GNUC__) + #define MZ_FORCEINLINE inline __attribute__((__always_inline__)) +#else + #define MZ_FORCEINLINE inline +#endif + +// ------------------- zlib-style API's + +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) +{ + mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552; + if (!ptr) return MZ_ADLER32_INIT; + while (buf_len) { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + return (s2 << 16) + s1; +} + +// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) +{ + static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; + mz_uint32 crcu32 = (mz_uint32)crc; + if (!ptr) return MZ_CRC32_INIT; + crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; } + return ~crcu32; +} + +void mz_free(void *p) +{ + MZ_FREE(p); +} + +#ifndef MINIZ_NO_ZLIB_APIS + +static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); } +static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); } +//static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); } + +const char *mz_version(void) +{ + return MZ_VERSION; +} + +int mz_deflateInit(mz_streamp pStream, int level) +{ + return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); +} + +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) +{ + tdefl_compressor *pComp; + mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); + + if (!pStream) return MZ_STREAM_ERROR; + if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = MZ_ADLER32_INIT; + pStream->msg = NULL; + pStream->reserved = 0; + pStream->total_in = 0; + pStream->total_out = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pComp; + + if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) + { + mz_deflateEnd(pStream); + return MZ_PARAM_ERROR; + } + + return MZ_OK; +} + +int mz_deflateReset(mz_streamp pStream) +{ + if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR; + pStream->total_in = pStream->total_out = 0; + tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags); + return MZ_OK; +} + +int mz_deflate(mz_streamp pStream, int flush) +{ + size_t in_bytes, out_bytes; + mz_ulong orig_total_in, orig_total_out; + int mz_status = MZ_OK; + + if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR; + if (!pStream->avail_out) return MZ_BUF_ERROR; + + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + + if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) + return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; + + orig_total_in = pStream->total_in; orig_total_out = pStream->total_out; + for ( ; ; ) + { + tdefl_status defl_status; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + + defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state); + + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (defl_status < 0) + { + mz_status = MZ_STREAM_ERROR; + break; + } + else if (defl_status == TDEFL_STATUS_DONE) + { + mz_status = MZ_STREAM_END; + break; + } + else if (!pStream->avail_out) + break; + else if ((!pStream->avail_in) && (flush != MZ_FINISH)) + { + if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) + break; + return MZ_BUF_ERROR; // Can't make forward progress without some input. + } + } + return mz_status; +} + +int mz_deflateEnd(mz_streamp pStream) +{ + if (!pStream) return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) +{ + (void)pStream; + // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) + mz_uint64 a = 128ULL + (source_len * 110ULL) / 100ULL; + mz_uint64 b = 128ULL + (mz_uint64)source_len + ((source_len / (31 * 1024)) + 1ULL) * 5ULL; + + mz_uint64 t = MZ_MAX(a, b); + if (((mz_ulong)t) != t) + t = (mz_ulong)(-1); + + return (mz_ulong)t; +} + +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) +{ + int status; + mz_stream stream; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_deflateInit(&stream, level); + if (status != MZ_OK) return status; + + status = mz_deflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_deflateEnd(&stream); + return (status == MZ_OK) ? MZ_BUF_ERROR : status; + } + + *pDest_len = stream.total_out; + return mz_deflateEnd(&stream); +} + +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); +} + +mz_ulong mz_compressBound(mz_ulong source_len) +{ + return mz_deflateBound(NULL, source_len); +} + +typedef struct +{ + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +int mz_inflateInit2(mz_streamp pStream, int window_bits) +{ + inflate_state *pDecomp; + if (!pStream) return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); + if (!pDecomp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +int mz_inflateInit(mz_streamp pStream) +{ + return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); +} + +int mz_inflate(mz_streamp pStream, int flush) +{ + inflate_state* pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + + pState = (inflate_state*)pStream->state; + if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; pState->m_first_call = 0; + if (pState->m_last_status < 0) return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) + { + // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) + { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + // flush != MZ_FINISH then we must assume there's more input. + if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) + { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; + } + + for ( ; ; ) + { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. + else if (flush == MZ_FINISH) + { + // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } + else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; +} + +int mz_inflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + mz_stream stream; + int status; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_inflateInit(&stream); + if (status != MZ_OK) + return status; + + status = mz_inflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_inflateEnd(&stream); + return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; + } + *pDest_len = stream.total_out; + + return mz_inflateEnd(&stream); +} + +const char *mz_error(int err) +{ + static struct { int m_err; const char *m_pDesc; } s_error_descs[] = + { + { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, + { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } + }; + mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; + return NULL; +} + +#endif //MINIZ_NO_ZLIB_APIS + +// ------------------- Low-level Decompression (completely independent from all compression API's) + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN switch(r->m_state) { case 0: +#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END +#define TINFL_CR_FINISH } + +// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never +// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. +#define TINFL_GET_BYTE(state_index, c) do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for ( ; ; ) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else c = *pIn_buf_cur++; } MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END + +// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. +// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a +// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the +// bit buffer contains >=15 bits (deflate's max. Huffman code size). +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ + } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ + } while (num_bits < 15); + +// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read +// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully +// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. +// The slow path is only executed at the very end of the input buffer. +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ + int temp; mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ + } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END + +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; + static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const int s_min_table_sizes[3] = { 257, 1, 4 }; + + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } + + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1ULL << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } + while (pIn_buf_cur >= pIn_buf_end) + { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) + { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } + else + { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; + r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } + r->m_table_sizes[2] = 19; + } + for ( ; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; + cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } + if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) + { + mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for ( ; ; ) + { + mz_uint8 *pSrc; + for ( ; ; ) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } +#else + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + counter = sym2; bit_buf >>= code_len; num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + bit_buf >>= code_len; num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +// Higher level helper functions. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) break; + new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); + status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) + return TINFL_STATUS_FAILED; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) + { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +// ------------------- Low-level Compression (independent from all decompression API's) + +// Purposely making these tables static for faster init and thread safety. +static const mz_uint16 s_tdefl_len_sym[256] = { + 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272, + 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276, + 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, + 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, + 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, + 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, + 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283, + 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 }; + +static const mz_uint8 s_tdefl_len_extra[256] = { + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 }; + +static const mz_uint8 s_tdefl_small_dist_sym[512] = { + 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 }; + +static const mz_uint8 s_tdefl_small_dist_extra[512] = { + 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7 }; + +static const mz_uint8 s_tdefl_large_dist_sym[128] = { + 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, + 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 }; + +static const mz_uint8 s_tdefl_large_dist_extra[128] = { + 0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 }; + +// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. +typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1) +{ + mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist); + for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } + while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; + for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) + { + const mz_uint32* pHist = &hist[pass << 8]; + mz_uint offsets[256], cur_ofs = 0; + for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } + for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; + { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; } + } + return pCur_syms; +} + +// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. +static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) +{ + int root, leaf, next, avbl, used, dpth; + if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } + A[0].m_key += A[1].m_key; root = 0; leaf = 2; + for (next=1; next < n-1; next++) + { + if (leaf>=n || A[root].m_key<A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (mz_uint16)next; } else A[next].m_key = A[leaf++].m_key; + if (leaf>=n || (root<next && A[root].m_key<A[leaf].m_key)) { A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); A[root++].m_key = (mz_uint16)next; } else A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key); + } + A[n-2].m_key = 0; for (next=n-3; next>=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; + avbl = 1; used = dpth = 0; root = n-2; next = n-1; + while (avbl>0) + { + while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } + while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; } + avbl = 2*used; dpth++; used = 0; + } +} + +// Limits canonical Huffman code table's max code size. +enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; +static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) +{ + int i; mz_uint32 total = 0; if (code_list_len <= 1) return; + for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; + for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); + while (total != (1UL << max_code_size)) + { + pNum_codes[max_code_size]--; + for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } + total--; + } +} + +static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) +{ + int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes); + if (static_table) + { + for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; + } + else + { + tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; + int num_used_syms = 0; + const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; + for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; } + + pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); + + for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; + + tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); + + MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); + for (i = 1, j = num_used_syms; i <= code_size_limit; i++) + for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); + } + + next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1); + + for (i = 0; i < table_len; i++) + { + mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; + code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1); + d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; + } +} + +#define TDEFL_PUT_BITS(b, l) do { \ + mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \ + d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \ + while (d->m_bits_in >= 8) { \ + if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ + *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ + d->m_bit_buffer >>= 8; \ + d->m_bits_in -= 8; \ + } \ +} MZ_MACRO_END + +#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \ + if (rle_repeat_count < 3) { \ + d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ + while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ + } else { \ + d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ +} rle_repeat_count = 0; } } + +#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \ + if (rle_z_count < 3) { \ + d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ + } else if (rle_z_count <= 10) { \ + d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ + } else { \ + d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ +} rle_z_count = 0; } } + +static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + +static void tdefl_start_dynamic_block(tdefl_compressor *d) +{ + int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; + mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; + + d->m_huff_count[0][256] = 1; + + tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); + tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); + + for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; + for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; + + memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); + memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); + total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0; + + memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); + for (i = 0; i < total_code_sizes_to_pack; i++) + { + mz_uint8 code_size = code_sizes_to_pack[i]; + if (!code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); } + } + else + { + TDEFL_RLE_ZERO_CODE_SIZE(); + if (code_size != prev_code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size; + } + else if (++rle_repeat_count == 6) + { + TDEFL_RLE_PREV_CODE_SIZE(); + } + } + prev_code_size = code_size; + } + if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); } + + tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); + + TDEFL_PUT_BITS(2, 2); + + TDEFL_PUT_BITS(num_lit_codes - 257, 5); + TDEFL_PUT_BITS(num_dist_codes - 1, 5); + + for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break; + num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4); + for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); + + for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; ) + { + mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); + TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); + if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); + } +} + +static void tdefl_start_static_block(tdefl_compressor *d) +{ + mz_uint i; + mz_uint8 *p = &d->m_huff_code_sizes[0][0]; + + for (i = 0; i <= 143; ++i) *p++ = 8; + for ( ; i <= 255; ++i) *p++ = 9; + for ( ; i <= 279; ++i) *p++ = 7; + for ( ; i <= 287; ++i) *p++ = 8; + + memset(d->m_huff_code_sizes[1], 5, 32); + + tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); + tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); + + TDEFL_PUT_BITS(1, 2); +} + +static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + mz_uint8 *pOutput_buf = d->m_pOutput_buf; + mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; + mz_uint64 bit_buffer = d->m_bit_buffer; + mz_uint bits_in = d->m_bits_in; + +#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); } + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + + if (flags & 1) + { + mz_uint s0, s1, n0, n1, sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + // This sequence coaxes MSVC into using cmov's vs. jmp's. + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + n0 = s_tdefl_small_dist_extra[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + n1 = s_tdefl_large_dist_extra[match_dist >> 8]; + sym = (match_dist < 512) ? s0 : s1; + num_extra_bits = (match_dist < 512) ? n0 : n1; + + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + } + + if (pOutput_buf >= d->m_pOutput_buf_end) + return MZ_FALSE; + + *(mz_uint64*)pOutput_buf = bit_buffer; + pOutput_buf += (bits_in >> 3); + bit_buffer >>= (bits_in & ~7); + bits_in &= 7; + } + +#undef TDEFL_PUT_BITS_FAST + + d->m_pOutput_buf = pOutput_buf; + d->m_bits_in = 0; + d->m_bit_buffer = 0; + + while (bits_in) + { + mz_uint32 n = MZ_MIN(bits_in, 16); + TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); + bit_buffer >>= n; + bits_in -= n; + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#else +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + if (flags & 1) + { + mz_uint sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + if (match_dist < 512) + { + sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist]; + } + else + { + sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; + } + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS + +static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) +{ + if (static_block) + tdefl_start_static_block(d); + else + tdefl_start_dynamic_block(d); + return tdefl_compress_lz_codes(d); +} + +static int tdefl_flush_block(tdefl_compressor *d, int flush) +{ + mz_uint saved_bit_buf, saved_bits_in; + mz_uint8 *pSaved_output_buf; + mz_bool comp_block_succeeded = MZ_FALSE; + int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; + + d->m_pOutput_buf = pOutput_buf_start; + d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; + + MZ_ASSERT(!d->m_output_flush_remaining); + d->m_output_flush_ofs = 0; + d->m_output_flush_remaining = 0; + + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); + d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); + + if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) + { + TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8); + } + + TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); + + pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in; + + if (!use_raw_block) + comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); + + // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. + if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && + ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) ) + { + mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + TDEFL_PUT_BITS(0, 2); + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) + { + TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); + } + for (i = 0; i < d->m_total_lz_bytes; ++i) + { + TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); + } + } + // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. + else if (!comp_block_succeeded) + { + d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + tdefl_compress_block(d, MZ_TRUE); + } + + if (flush) + { + if (flush == TDEFL_FINISH) + { + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } } + } + else + { + mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); } + } + } + + MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); + + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++; + + if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) + { + if (d->m_pPut_buf_func) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) + return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); + } + else if (pOutput_buf_start == d->m_output_buf) + { + int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); + d->m_out_buf_ofs += bytes_to_copy; + if ((n -= bytes_to_copy) != 0) + { + d->m_output_flush_ofs = bytes_to_copy; + d->m_output_flush_remaining = n; + } + } + else + { + d->m_out_buf_ofs += n; + } + } + + return d->m_output_flush_remaining; +} + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES +#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p) +static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q; + mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + if (!probe_len) + { + *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break; + } + else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break; + c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); + } + } +} +#else +static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint8 *s = d->m_dict + pos, *p, *q; + mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break; + if (probe_len > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return; + c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1]; + } + } +} +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +static mz_bool tdefl_compress_fast(tdefl_compressor *d) +{ + // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. + mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; + mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; + mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + + while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) + { + const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; + mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); + d->m_src_buf_left -= num_bytes_to_process; + lookahead_size += num_bytes_to_process; + + while (num_bytes_to_process) + { + mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); + memcpy(d->m_dict + dst_pos, d->m_pSrc, n); + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); + d->m_pSrc += n; + dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; + num_bytes_to_process -= n; + } + + dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); + if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break; + + while (lookahead_size >= 4) + { + mz_uint cur_match_dist, cur_match_len = 1; + mz_uint8 *pCur_dict = d->m_dict + cur_pos; + mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; + mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; + mz_uint probe_pos = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)lookahead_pos; + + if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) + { + const mz_uint16 *p = (const mz_uint16 *)pCur_dict; + const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); + mz_uint32 probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); + if (!probe_len) + cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; + + if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U))) + { + cur_match_len = 1; + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + else + { + mz_uint32 s0, s1; + cur_match_len = MZ_MIN(cur_match_len, lookahead_size); + + MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); + + cur_match_dist--; + + pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); + *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; + pLZ_code_buf += 3; + *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); + + s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; + s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; + d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; + } + } + else + { + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + total_lz_bytes += cur_match_len; + lookahead_pos += cur_match_len; + dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; + MZ_ASSERT(lookahead_size >= cur_match_len); + lookahead_size -= cur_match_len; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + + while (lookahead_size) + { + mz_uint8 lit = d->m_dict[cur_pos]; + + total_lz_bytes++; + *pLZ_code_buf++ = lit; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + d->m_huff_count[0][lit]++; + + lookahead_pos++; + dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + lookahead_size--; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + } + + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + return MZ_TRUE; +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + +static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) +{ + d->m_total_lz_bytes++; + *d->m_pLZ_code_buf++ = lit; + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + d->m_huff_count[0][lit]++; +} + +static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) +{ + mz_uint32 s0, s1; + + MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); + + d->m_total_lz_bytes += match_len; + + d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); + + match_dist -= 1; + d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); + d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3; + + *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + + s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; + d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; + + if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; +} + +static mz_bool tdefl_compress_normal(tdefl_compressor *d) +{ + const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left; + tdefl_flush flush = d->m_flush; + + while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) + { + mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; + // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. + if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) + { + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; + mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); + const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; + src_buf_left -= num_bytes_to_process; + d->m_lookahead_size += num_bytes_to_process; + while (pSrc != pSrc_end) + { + mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++; + } + } + else + { + while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + { + mz_uint8 c = *pSrc++; + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + src_buf_left--; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) + { + mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; + mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + } + } + } + d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); + if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + break; + + // Simple lazy/greedy parsing state machine. + len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) + { + if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) + { + mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; + cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; } + if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1; + } + } + else + { + tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); + } + if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) + { + cur_match_dist = cur_match_len = 0; + } + if (d->m_saved_match_len) + { + if (cur_match_len > d->m_saved_match_len) + { + tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); + if (cur_match_len >= 128) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + d->m_saved_match_len = 0; len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + } + else + { + tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); + len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0; + } + } + else if (!cur_match_dist) + tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); + else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + // Move the lookahead forward by len_to_move bytes. + d->m_lookahead_pos += len_to_move; + MZ_ASSERT(d->m_lookahead_size >= len_to_move); + d->m_lookahead_size -= len_to_move; + d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE); + // Check if it's time to flush the current LZ codes to the internal output buffer. + if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || + ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) ) + { + int n; + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + } + } + + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + return MZ_TRUE; +} + +static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) +{ + if (d->m_pIn_buf_size) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + } + + if (d->m_pOut_buf_size) + { + size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); + d->m_output_flush_ofs += (mz_uint)n; + d->m_output_flush_remaining -= (mz_uint)n; + d->m_out_buf_ofs += n; + + *d->m_pOut_buf_size = d->m_out_buf_ofs; + } + + return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) +{ + if (!d) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return TDEFL_STATUS_BAD_PARAM; + } + + d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size; + d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size; + d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; + d->m_out_buf_ofs = 0; + d->m_flush = flush; + + if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || + (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) ) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); + } + d->m_wants_to_finish |= (flush == TDEFL_FINISH); + + if ((d->m_output_flush_remaining) || (d->m_finished)) + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && + ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && + ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) + { + if (!tdefl_compress_fast(d)) + return d->m_prev_return_status; + } + else +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + { + if (!tdefl_compress_normal(d)) + return d->m_prev_return_status; + } + + if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) + d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) + { + if (tdefl_flush_block(d, flush) < 0) + return d->m_prev_return_status; + d->m_finished = (flush == TDEFL_FINISH); + if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; } + } + + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); +} + +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) +{ + MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); +} + +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user; + d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; + d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); + d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; + d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; + d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY; + d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1; + d->m_pIn_buf = NULL; d->m_pOut_buf = NULL; + d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL; + d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + return TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) +{ + return d->m_prev_return_status; +} + +mz_uint32 tdefl_get_adler32(tdefl_compressor *d) +{ + return d->m_adler32; +} + +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; + pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE; + succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); + succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); + MZ_FREE(pComp); return succeeded; +} + +typedef struct +{ + size_t m_size, m_capacity; + mz_uint8 *m_pBuf; + mz_bool m_expandable; +} tdefl_output_buffer; + +static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) +{ + tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; + size_t new_size = p->m_size + len; + if (new_size > p->m_capacity) + { + size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE; + do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity); + pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE; + p->m_pBuf = pNew_buf; p->m_capacity = new_capacity; + } + memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size; + return MZ_TRUE; +} + +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_len) return MZ_FALSE; else *pOut_len = 0; + out_buf.m_expandable = MZ_TRUE; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL; + *pOut_len = out_buf.m_size; return out_buf.m_pBuf; +} + +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_buf) return 0; + out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0; + return out_buf.m_size; +} + +#ifndef MINIZ_NO_ZLIB_APIS +static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + +// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) +{ + mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; + + if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES; + else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK; + else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; + else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES; + + return comp_flags; +} +#endif //MINIZ_NO_ZLIB_APIS + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) +#endif + +// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at +// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. +// This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip) +{ + // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. + static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; + if (!pComp) return NULL; + MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } + // write dummy header + for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); + // compress image data + tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); } + if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + // write real header + *pLen_out = out_buf.m_size-41; + { + static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06}; + mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, + 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0, + (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; + c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); + memcpy(out_buf.m_pBuf, pnghdr, 41); + } + // write footer (IDAT CRC-32, followed by IEND chunk) + if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24); + // compute final size of file, grab compressed data buffer and return + *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; +} +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +{ + // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) + return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE); +} + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +} // namespace buminiz + +#endif // MINIZ_HEADER_FILE_ONLY + diff --git a/thirdparty/basis_universal/encoder/basisu_pvrtc1_4.cpp b/thirdparty/basis_universal/encoder/basisu_pvrtc1_4.cpp new file mode 100644 index 0000000000..596fc197e6 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_pvrtc1_4.cpp @@ -0,0 +1,564 @@ +// basisu_pvrtc1_4.cpp +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_pvrtc1_4.h" + +namespace basisu +{ +#if 0 + static const uint8_t g_pvrtc_5[32] = { 0,8,16,24,33,41,49,57,66,74,82,90,99,107,115,123,132,140,148,156,165,173,181,189,198,206,214,222,231,239,247,255 }; + static const uint8_t g_pvrtc_4[16] = { 0,16,33,49,66,82,99,115,140,156,173,189,206,222,239,255 }; + static const uint8_t g_pvrtc_3[8] = { 0,33,74,107,148,181,222,255 }; + static const uint8_t g_pvrtc_alpha[9] = { 0,34,68,102,136,170,204,238,255 }; +#endif + + static const uint8_t g_pvrtc_5_nearest[256] = { 0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31,31,31,31 }; + static const uint8_t g_pvrtc_4_nearest[256] = { 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15 }; +#if 0 + static const uint8_t g_pvrtc_3_nearest[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }; + static const uint8_t g_pvrtc_alpha_nearest[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8 }; +#endif + +#if 0 + static const uint8_t g_pvrtc_5_floor[256] = + { + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3, + 3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7, + 7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15, + 15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19, + 19,19,19,19,19,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23, + 23,23,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,27,27, + 27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31 + }; + + static const uint8_t g_pvrtc_5_ceil[256] = + { + 0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4, + 4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8, + 8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12, + 12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,16,16,16,16, + 16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20, + 20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24, + 24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,28, + 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31 + }; + + static const uint8_t g_pvrtc_4_floor[256] = + { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15 + }; + + static const uint8_t g_pvrtc_4_ceil[256] = + { + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 + }; + + static const uint8_t g_pvrtc_3_floor[256] = + { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7 + }; + + static const uint8_t g_pvrtc_3_ceil[256] = + { + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + }; + + static const uint8_t g_pvrtc_alpha_floor[256] = + { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8 + }; + + static const uint8_t g_pvrtc_alpha_ceil[256] = + { + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; +#endif + + uint32_t pvrtc4_swizzle_uv(uint32_t width, uint32_t height, uint32_t x, uint32_t y) + { + assert((x < width) && (y < height) && basisu::is_pow2(height) && basisu::is_pow2(width)); + + uint32_t min_d = width, max_v = y; + if (height < width) + { + min_d = height; + max_v = x; + } + + // Interleave the XY LSB's + uint32_t shift_ofs = 0, swizzled = 0; + for (uint32_t s_bit = 1, d_bit = 1; s_bit < min_d; s_bit <<= 1, d_bit <<= 2, ++shift_ofs) + { + if (y & s_bit) swizzled |= d_bit; + if (x & s_bit) swizzled |= (2 * d_bit); + } + + max_v >>= shift_ofs; + + // OR in the rest of the bits from the largest dimension + swizzled |= (max_v << (2 * shift_ofs)); + + return swizzled; + } + + color_rgba pvrtc4_block::get_endpoint(uint32_t endpoint_index, bool unpack) const + { + assert(endpoint_index < 2); + const uint32_t packed = m_endpoints >> (endpoint_index * 16); + + uint32_t r, g, b, a; + if (packed & 0x8000) + { + // opaque 554 or 555 + if (!endpoint_index) + { + r = (packed >> 10) & 31; + g = (packed >> 5) & 31; + b = (packed >> 1) & 15; + + if (unpack) + { + b = (b << 1) | (b >> 3); + } + } + else + { + r = (packed >> 10) & 31; + g = (packed >> 5) & 31; + b = packed & 31; + } + + a = unpack ? 255 : 7; + } + else + { + // translucent 4433 or 4443 + if (!endpoint_index) + { + a = (packed >> 12) & 7; + r = (packed >> 8) & 15; + g = (packed >> 4) & 15; + b = (packed >> 1) & 7; + + if (unpack) + { + a = (a << 1); + a = (a << 4) | a; + + r = (r << 1) | (r >> 3); + g = (g << 1) | (g >> 3); + b = (b << 2) | (b >> 1); + } + } + else + { + a = (packed >> 12) & 7; + r = (packed >> 8) & 15; + g = (packed >> 4) & 15; + b = packed & 15; + + if (unpack) + { + a = (a << 1); + a = (a << 4) | a; + + r = (r << 1) | (r >> 3); + g = (g << 1) | (g >> 3); + b = (b << 1) | (b >> 3); + } + } + } + + if (unpack) + { + r = (r << 3) | (r >> 2); + g = (g << 3) | (g >> 2); + b = (b << 3) | (b >> 2); + } + + assert((r < 256) && (g < 256) && (b < 256) && (a < 256)); + + return color_rgba(r, g, b, a); + } + + color_rgba pvrtc4_block::get_endpoint_5554(uint32_t endpoint_index) const + { + assert(endpoint_index < 2); + const uint32_t packed = m_endpoints >> (endpoint_index * 16); + + uint32_t r, g, b, a; + if (packed & 0x8000) + { + // opaque 554 or 555 + if (!endpoint_index) + { + r = (packed >> 10) & 31; + g = (packed >> 5) & 31; + b = (packed >> 1) & 15; + + b = (b << 1) | (b >> 3); + } + else + { + r = (packed >> 10) & 31; + g = (packed >> 5) & 31; + b = packed & 31; + } + + a = 15; + } + else + { + // translucent 4433 or 4443 + if (!endpoint_index) + { + a = (packed >> 12) & 7; + r = (packed >> 8) & 15; + g = (packed >> 4) & 15; + b = (packed >> 1) & 7; + + a = a << 1; + + r = (r << 1) | (r >> 3); + g = (g << 1) | (g >> 3); + b = (b << 2) | (b >> 1); + } + else + { + a = (packed >> 12) & 7; + r = (packed >> 8) & 15; + g = (packed >> 4) & 15; + b = packed & 15; + + a = a << 1; + + r = (r << 1) | (r >> 3); + g = (g << 1) | (g >> 3); + b = (b << 1) | (b >> 3); + } + } + + assert((r < 32) && (g < 32) && (b < 32) && (a < 16)); + + return color_rgba(r, g, b, a); + } + + bool pvrtc4_image::get_interpolated_colors(uint32_t x, uint32_t y, color_rgba* pColors) const + { + assert((x < m_width) && (y < m_height)); + + int block_x0 = (static_cast<int>(x) - 2) >> 2; + int block_x1 = block_x0 + 1; + int block_y0 = (static_cast<int>(y) - 2) >> 2; + int block_y1 = block_y0 + 1; + + block_x0 = posmod(block_x0, m_block_width); + block_x1 = posmod(block_x1, m_block_width); + block_y0 = posmod(block_y0, m_block_height); + block_y1 = posmod(block_y1, m_block_height); + + pColors[0] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); + pColors[3] = interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); + + if (get_block_uses_transparent_modulation(x >> 2, y >> 2)) + { + for (uint32_t c = 0; c < 4; c++) + { + uint32_t m = (pColors[0][c] + pColors[3][c]) / 2; + pColors[1][c] = static_cast<uint8_t>(m); + pColors[2][c] = static_cast<uint8_t>(m); + } + pColors[2][3] = 0; + return true; + } + + for (uint32_t c = 0; c < 4; c++) + { + pColors[1][c] = static_cast<uint8_t>((pColors[0][c] * 5 + pColors[3][c] * 3) / 8); + pColors[2][c] = static_cast<uint8_t>((pColors[0][c] * 3 + pColors[3][c] * 5) / 8); + } + + return false; + } + + color_rgba pvrtc4_image::get_pixel(uint32_t x, uint32_t y, uint32_t m) const + { + assert((x < m_width) && (y < m_height)); + + int block_x0 = (static_cast<int>(x) - 2) >> 2; + int block_x1 = block_x0 + 1; + int block_y0 = (static_cast<int>(y) - 2) >> 2; + int block_y1 = block_y0 + 1; + + block_x0 = posmod(block_x0, m_block_width); + block_x1 = posmod(block_x1, m_block_width); + block_y0 = posmod(block_y0, m_block_height); + block_y1 = posmod(block_y1, m_block_height); + + if (get_block_uses_transparent_modulation(x >> 2, y >> 2)) + { + if (m == 0) + return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); + else if (m == 3) + return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); + + color_rgba l(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0))); + color_rgba h(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1))); + + return color_rgba((l[0] + h[0]) / 2, (l[1] + h[1]) / 2, (l[2] + h[2]) / 2, (m == 2) ? 0 : (l[3] + h[3]) / 2); + } + else + { + if (m == 0) + return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0)); + else if (m == 3) + return interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1)); + + color_rgba l(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(0), m_blocks(block_x1, block_y0).get_endpoint_5554(0), m_blocks(block_x0, block_y1).get_endpoint_5554(0), m_blocks(block_x1, block_y1).get_endpoint_5554(0))); + color_rgba h(interpolate(x, y, m_blocks(block_x0, block_y0).get_endpoint_5554(1), m_blocks(block_x1, block_y0).get_endpoint_5554(1), m_blocks(block_x0, block_y1).get_endpoint_5554(1), m_blocks(block_x1, block_y1).get_endpoint_5554(1))); + + if (m == 2) + return color_rgba((l[0] * 3 + h[0] * 5) / 8, (l[1] * 3 + h[1] * 5) / 8, (l[2] * 3 + h[2] * 5) / 8, (l[3] * 3 + h[3] * 5) / 8); + else + return color_rgba((l[0] * 5 + h[0] * 3) / 8, (l[1] * 5 + h[1] * 3) / 8, (l[2] * 5 + h[2] * 3) / 8, (l[3] * 5 + h[3] * 3) / 8); + } + } + + uint64_t pvrtc4_image::local_endpoint_optimization_opaque(uint32_t bx, uint32_t by, const image& orig_img, bool perceptual) + { + uint64_t initial_error = evaluate_1x1_endpoint_error(bx, by, orig_img, perceptual, false); + if (!initial_error) + return initial_error; + + vec3F c_avg_orig(0); + + for (int y = 0; y < 7; y++) + { + const uint32_t py = wrap_y(by * 4 + y - 1); + for (uint32_t x = 0; x < 7; x++) + { + const uint32_t px = wrap_x(bx * 4 + x - 1); + + const color_rgba& c = orig_img(px, py); + + c_avg_orig[0] += c[0]; + c_avg_orig[1] += c[1]; + c_avg_orig[2] += c[2]; + } + } + + c_avg_orig *= 1.0f / 49.0f; + + vec3F quant_colors[2]; + quant_colors[0].set(c_avg_orig); + quant_colors[0] -= vec3F(.0125f); + + quant_colors[1].set(c_avg_orig); + quant_colors[1] += vec3F(.0125f); + + float total_weight[2]; + + bool success = true; + + for (uint32_t pass = 0; pass < 4; pass++) + { + vec3F new_colors[2] = { vec3F(0), vec3F(0) }; + memset(total_weight, 0, sizeof(total_weight)); + + static const float s_weights[7][7] = + { + { 1.000000f, 1.637089f, 2.080362f, 2.242640f, 2.080362f, 1.637089f, 1.000000f }, + { 1.637089f, 2.414213f, 3.006572f, 3.242640f, 3.006572f, 2.414213f, 1.637089f }, + { 2.080362f, 3.006572f, 3.828426f, 4.242640f, 3.828426f, 3.006572f, 2.080362f }, + { 2.242640f, 3.242640f, 4.242640f, 5.000000f, 4.242640f, 3.242640f, 2.242640f }, + { 2.080362f, 3.006572f, 3.828426f, 4.242640f, 3.828426f, 3.006572f, 2.080362f }, + { 1.637089f, 2.414213f, 3.006572f, 3.242640f, 3.006572f, 2.414213f, 1.637089f }, + { 1.000000f, 1.637089f, 2.080362f, 2.242640f, 2.080362f, 1.637089f, 1.000000f } + }; + + for (int y = 0; y < 7; y++) + { + const uint32_t py = wrap_y(by * 4 + y - 1); + for (uint32_t x = 0; x < 7; x++) + { + const uint32_t px = wrap_x(bx * 4 + x - 1); + + const color_rgba& orig_c = orig_img(px, py); + + vec3F color(orig_c[0], orig_c[1], orig_c[2]); + + uint32_t c = quant_colors[0].squared_distance(color) > quant_colors[1].squared_distance(color); + + const float weight = s_weights[y][x]; + new_colors[c] += color * weight; + + total_weight[c] += weight; + } + } + + if (!total_weight[0] || !total_weight[1]) + success = false; + + quant_colors[0] = new_colors[0] / (float)total_weight[0]; + quant_colors[1] = new_colors[1] / (float)total_weight[1]; + } + + if (!success) + { + quant_colors[0] = c_avg_orig; + quant_colors[1] = c_avg_orig; + } + + vec4F colors[2] = { quant_colors[0], quant_colors[1] }; + + colors[0] += vec3F(.5f); + colors[1] += vec3F(.5f); + color_rgba color_0((int)colors[0][0], (int)colors[0][1], (int)colors[0][2], 0); + color_rgba color_1((int)colors[1][0], (int)colors[1][1], (int)colors[1][2], 0); + + pvrtc4_block cur_blocks[3][3]; + + for (int y = -1; y <= 1; y++) + { + for (int x = -1; x <= 1; x++) + { + const uint32_t block_x = wrap_block_x(bx + x); + const uint32_t block_y = wrap_block_y(by + y); + cur_blocks[x + 1][y + 1] = m_blocks(block_x, block_y); + } + } + + color_rgba l1(0), h1(0); + + l1[0] = g_pvrtc_5_nearest[color_0[0]]; + h1[0] = g_pvrtc_5_nearest[color_1[0]]; + + l1[1] = g_pvrtc_5_nearest[color_0[1]]; + h1[1] = g_pvrtc_5_nearest[color_1[1]]; + + l1[2] = g_pvrtc_4_nearest[color_0[2]]; + h1[2] = g_pvrtc_5_nearest[color_0[2]]; + + l1[3] = 0; + h1[3] = 0; + + m_blocks(bx, by).set_endpoint_raw(0, l1, true); + m_blocks(bx, by).set_endpoint_raw(1, h1, true); + + uint64_t e03_err_0 = remap_pixels_influenced_by_endpoint(bx, by, orig_img, perceptual, false); + + pvrtc4_block blocks0[3][3]; + for (int y = -1; y <= 1; y++) + { + for (int x = -1; x <= 1; x++) + { + const uint32_t block_x = wrap_block_x(bx + x); + const uint32_t block_y = wrap_block_y(by + y); + blocks0[x + 1][y + 1] = m_blocks(block_x, block_y); + } + } + + l1[0] = g_pvrtc_5_nearest[color_1[0]]; + h1[0] = g_pvrtc_5_nearest[color_0[0]]; + + l1[1] = g_pvrtc_5_nearest[color_1[1]]; + h1[1] = g_pvrtc_5_nearest[color_0[1]]; + + l1[2] = g_pvrtc_4_nearest[color_1[2]]; + h1[2] = g_pvrtc_5_nearest[color_0[2]]; + + l1[3] = 0; + h1[3] = 0; + + m_blocks(bx, by).set_endpoint_raw(0, l1, true); + m_blocks(bx, by).set_endpoint_raw(1, h1, true); + + uint64_t e03_err_1 = remap_pixels_influenced_by_endpoint(bx, by, orig_img, perceptual, false); + + if (initial_error < basisu::minimum(e03_err_0, e03_err_1)) + { + for (int y = -1; y <= 1; y++) + { + for (int x = -1; x <= 1; x++) + { + const uint32_t block_x = wrap_block_x(bx + x); + const uint32_t block_y = wrap_block_y(by + y); + m_blocks(block_x, block_y) = cur_blocks[x + 1][y + 1]; + } + } + return initial_error; + } + else if (e03_err_0 < e03_err_1) + { + for (int y = -1; y <= 1; y++) + { + for (int x = -1; x <= 1; x++) + { + const uint32_t block_x = wrap_block_x(bx + x); + const uint32_t block_y = wrap_block_y(by + y); + m_blocks(block_x, block_y) = blocks0[x + 1][y + 1]; + } + } + assert(e03_err_0 == evaluate_1x1_endpoint_error(bx, by, orig_img, perceptual, false)); + return e03_err_0; + } + + assert(e03_err_1 == evaluate_1x1_endpoint_error(bx, by, orig_img, perceptual, false)); + return e03_err_1; + } + +} // basisu diff --git a/thirdparty/basis_universal/basisu_pvrtc1_4.h b/thirdparty/basis_universal/encoder/basisu_pvrtc1_4.h index 80b4413351..db6985a439 100644 --- a/thirdparty/basis_universal/basisu_pvrtc1_4.h +++ b/thirdparty/basis_universal/encoder/basisu_pvrtc1_4.h @@ -1,5 +1,5 @@ // basisu_pvrtc1_4.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -87,6 +87,14 @@ namespace basisu return (m_modulation >> ((y * 4 + x) * 2)) & 3; } + inline void set_modulation(uint32_t x, uint32_t y, uint32_t s) + { + assert((x < 4) && (y < 4) && (s < 4)); + uint32_t n = (y * 4 + x) * 2; + m_modulation = (m_modulation & (~(3 << n))) | (s << n); + assert(get_modulation(x, y) == s); + } + // Scaled by 8 inline const uint32_t* get_scaled_modulation_values(bool block_uses_transparent_modulation) const { @@ -107,7 +115,7 @@ namespace basisu } // opaque endpoints: 554, 555 - // transparent endpoints: 3443 or 3444 + // transparent endpoints: 3443, 3444 inline void set_endpoint_raw(uint32_t endpoint_index, const color_rgba& c, bool opaque_endpoint) { assert(endpoint_index < 2); @@ -352,7 +360,93 @@ namespace basisu return result; } - + + inline void set_modulation(uint32_t x, uint32_t y, uint32_t s) + { + assert((x < m_width) && (y < m_height)); + return m_blocks(x >> 2, y >> 2).set_modulation(x & 3, y & 3, s); + } + + inline uint64_t map_pixel(uint32_t x, uint32_t y, const color_rgba& c, bool perceptual, bool alpha_is_significant, bool record = true) + { + color_rgba v[4]; + get_interpolated_colors(x, y, v); + + uint64_t best_dist = color_distance(perceptual, c, v[0], alpha_is_significant); + uint32_t best_v = 0; + for (uint32_t i = 1; i < 4; i++) + { + uint64_t dist = color_distance(perceptual, c, v[i], alpha_is_significant); + if (dist < best_dist) + { + best_dist = dist; + best_v = i; + } + } + + if (record) + set_modulation(x, y, best_v); + + return best_dist; + } + + inline uint64_t remap_pixels_influenced_by_endpoint(uint32_t bx, uint32_t by, const image& orig_img, bool perceptual, bool alpha_is_significant) + { + uint64_t total_error = 0; + + for (int yd = -3; yd <= 3; yd++) + { + const int y = wrap_y((int)by * 4 + 2 + yd); + + for (int xd = -3; xd <= 3; xd++) + { + const int x = wrap_x((int)bx * 4 + 2 + xd); + + total_error += map_pixel(x, y, orig_img(x, y), perceptual, alpha_is_significant); + } + } + + return total_error; + } + + inline uint64_t evaluate_1x1_endpoint_error(uint32_t bx, uint32_t by, const image& orig_img, bool perceptual, bool alpha_is_significant, uint64_t threshold_error = 0) const + { + uint64_t total_error = 0; + + for (int yd = -3; yd <= 3; yd++) + { + const int y = wrap_y((int)by * 4 + 2 + yd); + + for (int xd = -3; xd <= 3; xd++) + { + const int x = wrap_x((int)bx * 4 + 2 + xd); + + total_error += color_distance(perceptual, get_pixel(x, y), orig_img(x, y), alpha_is_significant); + + if ((threshold_error) && (total_error >= threshold_error)) + return total_error; + } + } + + return total_error; + } + + uint64_t local_endpoint_optimization_opaque(uint32_t bx, uint32_t by, const image& orig_img, bool perceptual); + + inline uint64_t map_all_pixels(const image& img, bool perceptual, bool alpha_is_significant) + { + assert(m_width == img.get_width()); + assert(m_height == img.get_height()); + + uint64_t total_error = 0; + for (uint32_t y = 0; y < img.get_height(); y++) + for (uint32_t x = 0; x < img.get_width(); x++) + total_error += map_pixel(x, y, img(x, y), perceptual, alpha_is_significant); + + return total_error; + } + + public: uint32_t m_width, m_height; pvrtc4_block_vector2D m_blocks; uint32_t m_block_width, m_block_height; diff --git a/thirdparty/basis_universal/basisu_resample_filters.cpp b/thirdparty/basis_universal/encoder/basisu_resample_filters.cpp index d0b2fd77bb..597cb3f618 100644 --- a/thirdparty/basis_universal/basisu_resample_filters.cpp +++ b/thirdparty/basis_universal/encoder/basisu_resample_filters.cpp @@ -1,5 +1,5 @@ // basisu_resampler_filters.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -283,7 +283,7 @@ namespace basisu return sum; } - static const float KAISER_ALPHA = 4.0; + //static const float KAISER_ALPHA = 4.0; static double kaiser(double alpha, double half_width, double x) { const double ratio = (x / half_width); @@ -310,10 +310,22 @@ namespace basisu const resample_filter g_resample_filters[] = { - { "box", box_filter, BOX_FILTER_SUPPORT }, { "tent", tent_filter, TENT_FILTER_SUPPORT }, { "bell", bell_filter, BELL_SUPPORT }, { "b-spline", B_spline_filter, B_SPLINE_SUPPORT }, - { "mitchell", mitchell_filter, MITCHELL_SUPPORT }, { "lanczos3", lanczos3_filter, LANCZOS3_SUPPORT }, { "blackman", blackman_filter, BLACKMAN_SUPPORT }, { "lanczos4", lanczos4_filter, LANCZOS4_SUPPORT }, - { "lanczos6", lanczos6_filter, LANCZOS6_SUPPORT }, { "lanczos12", lanczos12_filter, LANCZOS12_SUPPORT }, { "kaiser", kaiser_filter, KAISER_SUPPORT }, { "gaussian", gaussian_filter, GAUSSIAN_SUPPORT }, - { "catmullrom", catmull_rom_filter, CATMULL_ROM_SUPPORT }, { "quadratic_interp", quadratic_interp_filter, QUADRATIC_SUPPORT }, { "quadratic_approx", quadratic_approx_filter, QUADRATIC_SUPPORT }, { "quadratic_mix", quadratic_mix_filter, QUADRATIC_SUPPORT }, + { "box", box_filter, BOX_FILTER_SUPPORT }, + { "tent", tent_filter, TENT_FILTER_SUPPORT }, + { "bell", bell_filter, BELL_SUPPORT }, + { "b-spline", B_spline_filter, B_SPLINE_SUPPORT }, + { "mitchell", mitchell_filter, MITCHELL_SUPPORT }, + { "blackman", blackman_filter, BLACKMAN_SUPPORT }, + { "lanczos3", lanczos3_filter, LANCZOS3_SUPPORT }, + { "lanczos4", lanczos4_filter, LANCZOS4_SUPPORT }, + { "lanczos6", lanczos6_filter, LANCZOS6_SUPPORT }, + { "lanczos12", lanczos12_filter, LANCZOS12_SUPPORT }, + { "kaiser", kaiser_filter, KAISER_SUPPORT }, + { "gaussian", gaussian_filter, GAUSSIAN_SUPPORT }, + { "catmullrom", catmull_rom_filter, CATMULL_ROM_SUPPORT }, + { "quadratic_interp", quadratic_interp_filter, QUADRATIC_SUPPORT }, + { "quadratic_approx", quadratic_approx_filter, QUADRATIC_SUPPORT }, + { "quadratic_mix", quadratic_mix_filter, QUADRATIC_SUPPORT }, }; const int g_num_resample_filters = BASISU_ARRAY_SIZE(g_resample_filters); diff --git a/thirdparty/basis_universal/basisu_resampler.cpp b/thirdparty/basis_universal/encoder/basisu_resampler.cpp index e193ce83ff..e193ce83ff 100644 --- a/thirdparty/basis_universal/basisu_resampler.cpp +++ b/thirdparty/basis_universal/encoder/basisu_resampler.cpp diff --git a/thirdparty/basis_universal/basisu_resampler.h b/thirdparty/basis_universal/encoder/basisu_resampler.h index c3f2e05c25..dc0978caeb 100644 --- a/thirdparty/basis_universal/basisu_resampler.h +++ b/thirdparty/basis_universal/encoder/basisu_resampler.h @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #pragma once -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" #define BASISU_RESAMPLER_DEBUG_OPS (0) #define BASISU_RESAMPLER_DEFAULT_FILTER "lanczos4" diff --git a/thirdparty/basis_universal/basisu_resampler_filters.h b/thirdparty/basis_universal/encoder/basisu_resampler_filters.h index 5659c5fe86..0ebb51c334 100644 --- a/thirdparty/basis_universal/basisu_resampler_filters.h +++ b/thirdparty/basis_universal/encoder/basisu_resampler_filters.h @@ -14,7 +14,7 @@ // limitations under the License. #pragma once -#include "transcoder/basisu.h" +#include "../transcoder/basisu.h" namespace basisu { diff --git a/thirdparty/basis_universal/basisu_ssim.cpp b/thirdparty/basis_universal/encoder/basisu_ssim.cpp index cceb400b88..cceb400b88 100644 --- a/thirdparty/basis_universal/basisu_ssim.cpp +++ b/thirdparty/basis_universal/encoder/basisu_ssim.cpp diff --git a/thirdparty/basis_universal/basisu_ssim.h b/thirdparty/basis_universal/encoder/basisu_ssim.h index 986ca3bbdf..986ca3bbdf 100644 --- a/thirdparty/basis_universal/basisu_ssim.h +++ b/thirdparty/basis_universal/encoder/basisu_ssim.h diff --git a/thirdparty/basis_universal/encoder/basisu_uastc_enc.cpp b/thirdparty/basis_universal/encoder/basisu_uastc_enc.cpp new file mode 100644 index 0000000000..ca2b325693 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_uastc_enc.cpp @@ -0,0 +1,4189 @@ +// basisu_uastc_enc.cpp +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "basisu_uastc_enc.h" +#include "basisu_astc_decomp.h" +#include "basisu_gpu_texture.h" +#include "basisu_bc7enc.h" + +#ifdef _DEBUG +// When BASISU_VALIDATE_UASTC_ENC is 1, we pack and unpack to/from UASTC and ASTC, then validate that each codec returns the exact same results. This is slower. +#define BASISU_VALIDATE_UASTC_ENC 1 +#endif + +#define BASISU_SUPPORT_FORCE_MODE 0 + +using namespace basist; + +namespace basisu +{ + const uint32_t MAX_ENCODE_RESULTS = 512; + +#if BASISU_VALIDATE_UASTC_ENC + static void validate_func(bool condition, int line) + { + if (!condition) + { + fprintf(stderr, "basisu_uastc_enc: Internal validation failed on line %u!\n", line); + } + } + + #define VALIDATE(c) validate_func(c, __LINE__); +#else + #define VALIDATE(c) +#endif + + enum dxt_constants + { + cDXT1SelectorBits = 2U, cDXT1SelectorValues = 1U << cDXT1SelectorBits, cDXT1SelectorMask = cDXT1SelectorValues - 1U, + cDXT5SelectorBits = 3U, cDXT5SelectorValues = 1U << cDXT5SelectorBits, cDXT5SelectorMask = cDXT5SelectorValues - 1U, + }; + + struct dxt1_block + { + enum { cTotalEndpointBytes = 2, cTotalSelectorBytes = 4 }; + + uint8_t m_low_color[cTotalEndpointBytes]; + uint8_t m_high_color[cTotalEndpointBytes]; + uint8_t m_selectors[cTotalSelectorBytes]; + + inline void clear() { basisu::clear_obj(*this); } + + inline uint32_t get_high_color() const { return m_high_color[0] | (m_high_color[1] << 8U); } + inline uint32_t get_low_color() const { return m_low_color[0] | (m_low_color[1] << 8U); } + inline void set_low_color(uint16_t c) { m_low_color[0] = static_cast<uint8_t>(c & 0xFF); m_low_color[1] = static_cast<uint8_t>((c >> 8) & 0xFF); } + inline void set_high_color(uint16_t c) { m_high_color[0] = static_cast<uint8_t>(c & 0xFF); m_high_color[1] = static_cast<uint8_t>((c >> 8) & 0xFF); } + inline uint32_t get_selector(uint32_t x, uint32_t y) const { assert((x < 4U) && (y < 4U)); return (m_selectors[y] >> (x * cDXT1SelectorBits))& cDXT1SelectorMask; } + inline void set_selector(uint32_t x, uint32_t y, uint32_t val) { assert((x < 4U) && (y < 4U) && (val < 4U)); m_selectors[y] &= (~(cDXT1SelectorMask << (x * cDXT1SelectorBits))); m_selectors[y] |= (val << (x * cDXT1SelectorBits)); } + + static uint16_t pack_color(const color_rgba& color, bool scaled, uint32_t bias = 127U) + { + uint32_t r = color.r, g = color.g, b = color.b; + if (scaled) + { + r = (r * 31U + bias) / 255U; + g = (g * 63U + bias) / 255U; + b = (b * 31U + bias) / 255U; + } + return static_cast<uint16_t>(basisu::minimum(b, 31U) | (basisu::minimum(g, 63U) << 5U) | (basisu::minimum(r, 31U) << 11U)); + } + + static uint16_t pack_unscaled_color(uint32_t r, uint32_t g, uint32_t b) { return static_cast<uint16_t>(b | (g << 5U) | (r << 11U)); } + }; + +#define UASTC_WRITE_MODE_DESCS 0 + + static inline void uastc_write_bits(uint8_t* pBuf, uint32_t& bit_offset, uint64_t code, uint32_t codesize, const char* pDesc) + { + (void)pDesc; + +#if UASTC_WRITE_MODE_DESCS + if (pDesc) + printf("%s: %u %u\n", pDesc, bit_offset, codesize); +#endif + + assert((codesize == 64) || (code < (1ULL << codesize))); + + while (codesize) + { + uint32_t byte_bit_offset = bit_offset & 7; + uint32_t bits_to_write = basisu::minimum<int>(codesize, 8 - byte_bit_offset); + + pBuf[bit_offset >> 3] |= (code << byte_bit_offset); + + code >>= bits_to_write; + codesize -= bits_to_write; + bit_offset += bits_to_write; + } + } + + void pack_uastc(basist::uastc_block& blk, const uastc_encode_results& result, const etc_block& etc1_blk, uint32_t etc1_bias, const eac_a8_block& etc_eac_a8_blk, bool bc1_hint0, bool bc1_hint1) + { + if ((g_uastc_mode_has_alpha[result.m_uastc_mode]) && (result.m_uastc_mode != UASTC_MODE_INDEX_SOLID_COLOR)) + { + assert(etc_eac_a8_blk.m_multiplier >= 1); + } + + uint8_t buf[32]; + memset(buf, 0, sizeof(buf)); + + uint32_t block_bit_offset = 0; + +#if UASTC_WRITE_MODE_DESCS + printf("**** Mode: %u\n", result.m_uastc_mode); +#endif + + uastc_write_bits(buf, block_bit_offset, g_uastc_mode_huff_codes[result.m_uastc_mode][0], g_uastc_mode_huff_codes[result.m_uastc_mode][1], "mode"); + + if (result.m_uastc_mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + uastc_write_bits(buf, block_bit_offset, result.m_solid_color.r, 8, "R"); + uastc_write_bits(buf, block_bit_offset, result.m_solid_color.g, 8, "G"); + uastc_write_bits(buf, block_bit_offset, result.m_solid_color.b, 8, "B"); + uastc_write_bits(buf, block_bit_offset, result.m_solid_color.a, 8, "A"); + + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_diff_bit(), 1, "ETC1D"); + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_inten_table(0), 3, "ETC1I"); + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_selector(0, 0), 2, "ETC1S"); + + uint32_t r, g, b; + if (etc1_blk.get_diff_bit()) + etc_block::unpack_color5(r, g, b, etc1_blk.get_base5_color(), false); + else + etc_block::unpack_color4(r, g, b, etc1_blk.get_base4_color(0), false); + + uastc_write_bits(buf, block_bit_offset, r, 5, "ETC1R"); + uastc_write_bits(buf, block_bit_offset, g, 5, "ETC1G"); + uastc_write_bits(buf, block_bit_offset, b, 5, "ETC1B"); + + memcpy(&blk, buf, sizeof(blk)); + return; + } + + if (g_uastc_mode_has_bc1_hint0[result.m_uastc_mode]) + uastc_write_bits(buf, block_bit_offset, bc1_hint0, 1, "BC1H0"); + else + { + assert(bc1_hint0 == false); + } + + if (g_uastc_mode_has_bc1_hint1[result.m_uastc_mode]) + uastc_write_bits(buf, block_bit_offset, bc1_hint1, 1, "BC1H1"); + else + { + assert(bc1_hint1 == false); + } + + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_flip_bit(), 1, "ETC1F"); + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_diff_bit(), 1, "ETC1D"); + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_inten_table(0), 3, "ETC1I0"); + uastc_write_bits(buf, block_bit_offset, etc1_blk.get_inten_table(1), 3, "ETC1I1"); + + if (g_uastc_mode_has_etc1_bias[result.m_uastc_mode]) + uastc_write_bits(buf, block_bit_offset, etc1_bias, 5, "ETC1BIAS"); + else + { + assert(etc1_bias == 0); + } + + if (g_uastc_mode_has_alpha[result.m_uastc_mode]) + { + const uint32_t etc2_hints = etc_eac_a8_blk.m_table | (etc_eac_a8_blk.m_multiplier << 4); + + assert(etc2_hints > 0 && etc2_hints <= 0xFF); + uastc_write_bits(buf, block_bit_offset, etc2_hints, 8, "ETC2TM"); + } + + uint32_t subsets = 1; + switch (result.m_uastc_mode) + { + case 2: + case 4: + case 7: + case 9: + case 16: + uastc_write_bits(buf, block_bit_offset, result.m_common_pattern, 5, "PAT"); + subsets = 2; + break; + case 3: + uastc_write_bits(buf, block_bit_offset, result.m_common_pattern, 4, "PAT"); + subsets = 3; + break; + default: + break; + } + +#ifdef _DEBUG + uint32_t part_seed = 0; + switch (result.m_uastc_mode) + { + case 2: + case 4: + case 9: + case 16: + part_seed = g_astc_bc7_common_partitions2[result.m_common_pattern].m_astc; + break; + case 3: + part_seed = g_astc_bc7_common_partitions3[result.m_common_pattern].m_astc; + break; + case 7: + part_seed = g_bc7_3_astc2_common_partitions[result.m_common_pattern].m_astc2; + break; + default: + break; + } +#endif + + uint32_t total_planes = 1; + switch (result.m_uastc_mode) + { + case 6: + case 11: + case 13: + uastc_write_bits(buf, block_bit_offset, result.m_astc.m_ccs, 2, "COMPSEL"); + total_planes = 2; + break; + case 17: + // CCS field is always 3 for dual plane LA. + assert(result.m_astc.m_ccs == 3); + total_planes = 2; + break; + default: + break; + } + + uint8_t weights[32]; + memcpy(weights, result.m_astc.m_weights, 16 * total_planes); + + uint8_t endpoints[18]; + memcpy(endpoints, result.m_astc.m_endpoints, sizeof(endpoints)); + + const uint32_t total_comps = g_uastc_mode_comps[result.m_uastc_mode]; + + // LLAA + // LLAA LLAA + // LLAA LLAA LLAA + // RRGGBB + // RRGGBB RRGGBB + // RRGGBB RRGGBB RRGGBB + // RRGGBBAA + // RRGGBBAA RRGGBBAA + + const uint32_t weight_bits = g_uastc_mode_weight_bits[result.m_uastc_mode]; + + const uint8_t* pPartition_pattern; + const uint8_t* pSubset_anchor_indices = basist::get_anchor_indices(subsets, result.m_uastc_mode, result.m_common_pattern, pPartition_pattern); + + for (uint32_t plane_index = 0; plane_index < total_planes; plane_index++) + { + for (uint32_t subset_index = 0; subset_index < subsets; subset_index++) + { + const uint32_t anchor_index = pSubset_anchor_indices[subset_index]; + +#ifdef _DEBUG + if (subsets >= 2) + { + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t part_index = astc_compute_texel_partition(part_seed, i & 3, i >> 2, 0, subsets, true); + if (part_index == subset_index) + { + assert(anchor_index == i); + break; + } + } + } + else + { + assert(!anchor_index); + } +#endif + + // Check anchor weight's MSB - if it's set then invert this subset's weights and swap the endpoints + if (weights[anchor_index * total_planes + plane_index] & (1 << (weight_bits - 1))) + { + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t part_index = pPartition_pattern[i]; + +#ifdef _DEBUG + if (subsets >= 2) + { + assert(part_index == (uint32_t)astc_compute_texel_partition(part_seed, i & 3, i >> 2, 0, subsets, true)); + } + else + { + assert(!part_index); + } +#endif + + if (part_index == subset_index) + weights[i * total_planes + plane_index] = ((1 << weight_bits) - 1) - weights[i * total_planes + plane_index]; + } + + if (total_planes == 2) + { + for (int c = 0; c < (int)total_comps; c++) + { + const uint32_t comp_plane = (total_comps == 2) ? c : ((c == result.m_astc.m_ccs) ? 1 : 0); + + if (comp_plane == plane_index) + std::swap(endpoints[c * 2 + 0], endpoints[c * 2 + 1]); + } + } + else + { + for (uint32_t c = 0; c < total_comps; c++) + std::swap(endpoints[subset_index * total_comps * 2 + c * 2 + 0], endpoints[subset_index * total_comps * 2 + c * 2 + 1]); + } + } + } // subset_index + } // plane_index + + const uint32_t total_values = total_comps * 2 * subsets; + const uint32_t endpoint_range = g_uastc_mode_endpoint_ranges[result.m_uastc_mode]; + + uint32_t bit_values[18]; + uint32_t tq_values[8]; + uint32_t total_tq_values = 0; + uint32_t tq_accum = 0; + uint32_t tq_mul = 1; + + const uint32_t ep_bits = g_astc_bise_range_table[endpoint_range][0]; + const uint32_t ep_trits = g_astc_bise_range_table[endpoint_range][1]; + const uint32_t ep_quints = g_astc_bise_range_table[endpoint_range][2]; + + for (uint32_t i = 0; i < total_values; i++) + { + uint32_t val = endpoints[i]; + + uint32_t bits = val & ((1 << ep_bits) - 1); + uint32_t tq = val >> ep_bits; + + bit_values[i] = bits; + + if (ep_trits) + { + assert(tq < 3); + tq_accum += tq * tq_mul; + tq_mul *= 3; + if (tq_mul == 243) + { + tq_values[total_tq_values++] = tq_accum; + tq_accum = 0; + tq_mul = 1; + } + } + else if (ep_quints) + { + assert(tq < 5); + tq_accum += tq * tq_mul; + tq_mul *= 5; + if (tq_mul == 125) + { + tq_values[total_tq_values++] = tq_accum; + tq_accum = 0; + tq_mul = 1; + } + } + } + + uint32_t total_endpoint_bits = 0; + + for (uint32_t i = 0; i < total_tq_values; i++) + { + const uint32_t num_bits = ep_trits ? 8 : 7; + uastc_write_bits(buf, block_bit_offset, tq_values[i], num_bits, "ETQ"); + total_endpoint_bits += num_bits; + } + + if (tq_mul > 1) + { + uint32_t num_bits; + if (ep_trits) + { + if (tq_mul == 3) + num_bits = 2; + else if (tq_mul == 9) + num_bits = 4; + else if (tq_mul == 27) + num_bits = 5; + else //if (tq_mul == 81) + num_bits = 7; + } + else + { + if (tq_mul == 5) + num_bits = 3; + else //if (tq_mul == 25) + num_bits = 5; + } + uastc_write_bits(buf, block_bit_offset, tq_accum, num_bits, "ETQ"); + total_endpoint_bits += num_bits; + } + + for (uint32_t i = 0; i < total_values; i++) + { + uastc_write_bits(buf, block_bit_offset, bit_values[i], ep_bits, "EBITS"); + total_endpoint_bits += ep_bits; + } + +#if UASTC_WRITE_MODE_DESCS + uint32_t weight_start = block_bit_offset; +#endif + + uint32_t total_weight_bits = 0; + const uint32_t plane_shift = (total_planes == 2) ? 1 : 0; + for (uint32_t i = 0; i < 16 * total_planes; i++) + { + uint32_t numbits = weight_bits; + for (uint32_t s = 0; s < subsets; s++) + { + if (pSubset_anchor_indices[s] == (i >> plane_shift)) + { + numbits--; + break; + } + } + + uastc_write_bits(buf, block_bit_offset, weights[i], numbits, nullptr); + + total_weight_bits += numbits; + } + +#if UASTC_WRITE_MODE_DESCS + printf("WEIGHTS: %u %u\n", weight_start, total_weight_bits); +#endif + + assert(block_bit_offset <= 128); + memcpy(&blk, buf, sizeof(blk)); + +#if UASTC_WRITE_MODE_DESCS + printf("Total bits: %u, endpoint bits: %u, weight bits: %u\n", block_bit_offset, total_endpoint_bits, total_weight_bits); +#endif + } + + // MODE 0 + // 0. DualPlane: 0, WeightRange: 8 (16), Subsets: 1, CEM: 8 (RGB Direct ), EndpointRange: 19 (192) MODE6 RGB + // 18. DualPlane: 0, WeightRange: 11 (32), Subsets: 1, CEM: 8 (RGB Direct ), EndpointRange: 11 (32) MODE6 RGB + static void astc_mode0_or_18(uint32_t mode, const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params, const uint8_t *pForce_selectors = nullptr) + { + const uint32_t endpoint_range = (mode == 18) ? 11 : 19; + const uint32_t weight_range = (mode == 18) ? 11 : 8; + + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + ccell_params.m_num_pixels = 16; + ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_num_selector_weights = (mode == 18) ? 32 : 16; + ccell_params.m_pSelector_weights = (mode == 18) ? g_astc_weights5 : g_astc_weights4; + ccell_params.m_pSelector_weightsx = (mode == 18) ? (const bc7enc_vec4F*)g_astc_weights5x : (const bc7enc_vec4F*)g_astc_weights4x; + ccell_params.m_astc_endpoint_range = endpoint_range; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + ccell_params.m_pForce_selectors = pForce_selectors; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = weight_range;// (mode == 18) ? 11 : 8; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 1; + astc_results.m_partition_seed = 0; + astc_results.m_cem = 8; + + astc_results.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results.m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results.m_astc_high_endpoint.m_c[2]; + + bool invert = false; + + if (pForce_selectors == nullptr) + { + int s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + invert = true; + } + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + astc_results.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + if (invert) + astc_results.m_weights[x + y * 4] = ((mode == 18) ? 31 : 15) - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = mode; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = part_err; + total_results++; + } + } + + // MODE 1 + // 1-subset, 2-bit indices, 8-bit endpoints, BC7 mode 3 + // DualPlane: 0, WeightRange: 2 (4), Subsets: 1, CEM: 8 (RGB Direct ), EndpointRange: 20 (256) MODE3 or MODE5 RGB + static void astc_mode1(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + ccell_params.m_num_pixels = 16; + ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_num_selector_weights = 4; + ccell_params.m_pSelector_weights = g_bc7_weights2; + ccell_params.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params.m_astc_endpoint_range = 20; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = 2; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 1; + astc_results.m_partition_seed = 0; + astc_results.m_cem = 8; + + astc_results.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results.m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results.m_astc_high_endpoint.m_c[2]; + + const uint32_t range = 20; + + bool invert = false; + + int s0 = g_astc_unquant[range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + astc_results.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + if (invert) + astc_results.m_weights[x + y * 4] = 3 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 1; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = part_err; + total_results++; + } + } + + static uint32_t estimate_partition2(uint32_t num_weights, uint32_t num_comps, const uint32_t* pWeights, const color_rgba block[4][4], const uint32_t weights[4]) + { + assert(pWeights[0] == 0 && pWeights[num_weights - 1] == 64); + + uint64_t best_err = UINT64_MAX; + uint32_t best_common_pattern = 0; + + for (uint32_t common_pattern = 0; common_pattern < TOTAL_ASTC_BC7_COMMON_PARTITIONS2; common_pattern++) + { + const uint32_t bc7_pattern = g_astc_bc7_common_partitions2[common_pattern].m_bc7; + + const uint8_t* pPartition = &g_bc7_partition2[bc7_pattern * 16]; + + color_quad_u8 subset_colors[2][16]; + uint32_t subset_total_colors[2] = { 0, 0 }; + for (uint32_t index = 0; index < 16; index++) + subset_colors[pPartition[index]][subset_total_colors[pPartition[index]]++] = ((const color_quad_u8*)block)[index]; + + uint64_t total_subset_err = 0; + for (uint32_t subset = 0; (subset < 2) && (total_subset_err < best_err); subset++) + total_subset_err += color_cell_compression_est_astc(num_weights, num_comps, pWeights, subset_total_colors[subset], &subset_colors[subset][0], best_err, weights); + + if (total_subset_err < best_err) + { + best_err = total_subset_err; + best_common_pattern = common_pattern; + } + } + + return best_common_pattern; + } + + // MODE 2 + // 2-subset, 3-bit indices, 4-bit endpoints, BC7 mode 1 + // DualPlane: 0, WeightRange: 5 (8), Subsets: 2, CEM: 8 (RGB Direct ), EndpointRange: 8 (16) MODE1 + static void astc_mode2(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params, bool estimate_partition) + { + uint32_t first_common_pattern = 0; + uint32_t last_common_pattern = TOTAL_ASTC_BC7_COMMON_PARTITIONS2; + + if (estimate_partition) + { + const uint32_t weights[4] = { 1, 1, 1, 1 }; + first_common_pattern = estimate_partition2(8, 3, g_bc7_weights3, block, weights); + last_common_pattern = first_common_pattern + 1; + } + + for (uint32_t common_pattern = first_common_pattern; common_pattern < last_common_pattern; common_pattern++) + { + const uint32_t bc7_pattern = g_astc_bc7_common_partitions2[common_pattern].m_bc7; + + color_rgba part_pixels[2][16]; + uint32_t part_pixel_index[4][4]; + uint32_t num_part_pixels[2] = { 0, 0 }; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t part = g_bc7_partition2[16 * bc7_pattern + x + y * 4]; + part_pixel_index[y][x] = num_part_pixels[part]; + part_pixels[part][num_part_pixels[part]++] = block[y][x]; + } + } + + color_cell_compressor_params ccell_params[2]; + color_cell_compressor_results ccell_results[2]; + uint8_t ccell_result_selectors[2][16]; + uint8_t ccell_result_selectors_temp[2][16]; + + uint64_t total_part_err = 0; + for (uint32_t part = 0; part < 2; part++) + { + memset(&ccell_params[part], 0, sizeof(ccell_params[part])); + + ccell_params[part].m_num_pixels = num_part_pixels[part]; + ccell_params[part].m_pPixels = (color_quad_u8*)&part_pixels[part][0]; + ccell_params[part].m_num_selector_weights = 8; + ccell_params[part].m_pSelector_weights = g_bc7_weights3; + ccell_params[part].m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights3x; + ccell_params[part].m_astc_endpoint_range = 8; + ccell_params[part].m_weights[0] = 1; + ccell_params[part].m_weights[1] = 1; + ccell_params[part].m_weights[2] = 1; + ccell_params[part].m_weights[3] = 1; + + memset(&ccell_results[part], 0, sizeof(ccell_results[part])); + ccell_results[part].m_pSelectors = &ccell_result_selectors[part][0]; + ccell_results[part].m_pSelectors_temp = &ccell_result_selectors_temp[part][0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params[part], &ccell_results[part], &comp_params); + total_part_err += part_err; + } // part + + { + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = 5; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 2; + astc_results.m_partition_seed = g_astc_bc7_common_partitions2[common_pattern].m_astc; + astc_results.m_cem = 8; + + uint32_t p0 = 0; + uint32_t p1 = 1; + if (g_astc_bc7_common_partitions2[common_pattern].m_invert) + std::swap(p0, p1); + + astc_results.m_endpoints[0] = ccell_results[p0].m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results[p0].m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results[p0].m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results[p0].m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results[p0].m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results[p0].m_astc_high_endpoint.m_c[2]; + + const uint32_t range = 8; + + bool invert[2] = { false, false }; + + int s0 = g_astc_unquant[range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + invert[0] = true; + } + + astc_results.m_endpoints[6] = ccell_results[p1].m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[7] = ccell_results[p1].m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[8] = ccell_results[p1].m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[9] = ccell_results[p1].m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[10] = ccell_results[p1].m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[11] = ccell_results[p1].m_astc_high_endpoint.m_c[2]; + + s0 = g_astc_unquant[range][astc_results.m_endpoints[0 + 6]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[2 + 6]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[4 + 6]].m_unquant; + s1 = g_astc_unquant[range][astc_results.m_endpoints[1 + 6]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[3 + 6]].m_unquant + g_astc_unquant[range][astc_results.m_endpoints[5 + 6]].m_unquant; + + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0 + 6], astc_results.m_endpoints[1 + 6]); + std::swap(astc_results.m_endpoints[2 + 6], astc_results.m_endpoints[3 + 6]); + std::swap(astc_results.m_endpoints[4 + 6], astc_results.m_endpoints[5 + 6]); + invert[1] = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t bc7_part = g_bc7_partition2[16 * bc7_pattern + x + y * 4]; + + astc_results.m_weights[x + y * 4] = ccell_result_selectors[bc7_part][part_pixel_index[y][x]]; + + uint32_t astc_part = bc7_part; + if (g_astc_bc7_common_partitions2[common_pattern].m_invert) + astc_part = 1 - astc_part; + + if (invert[astc_part]) + astc_results.m_weights[x + y * 4] = 7 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 2; + pResults[total_results].m_common_pattern = common_pattern; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = total_part_err; + total_results++; + } + } + + } // common_pattern + } + + // MODE 3 + // 3-subsets, 2-bit indices, [0,11] endpoints, BC7 mode 2 + // DualPlane: 0, WeightRange: 2 (4), Subsets: 3, CEM: 8 (RGB Direct ), EndpointRange: 7 (12) MODE2 + static void astc_mode3(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params, bool estimate_partition) + { + uint32_t first_common_pattern = 0; + uint32_t last_common_pattern = TOTAL_ASTC_BC7_COMMON_PARTITIONS3; + + if (estimate_partition) + { + uint64_t best_err = UINT64_MAX; + uint32_t best_common_pattern = 0; + const uint32_t weights[4] = { 1, 1, 1, 1 }; + + for (uint32_t common_pattern = 0; common_pattern < TOTAL_ASTC_BC7_COMMON_PARTITIONS3; common_pattern++) + { + const uint32_t bc7_pattern = g_astc_bc7_common_partitions3[common_pattern].m_bc7; + + const uint8_t* pPartition = &g_bc7_partition3[bc7_pattern * 16]; + + color_quad_u8 subset_colors[3][16]; + uint32_t subset_total_colors[3] = { 0, 0 }; + for (uint32_t index = 0; index < 16; index++) + subset_colors[pPartition[index]][subset_total_colors[pPartition[index]]++] = ((const color_quad_u8*)block)[index]; + + uint64_t total_subset_err = 0; + for (uint32_t subset = 0; (subset < 3) && (total_subset_err < best_err); subset++) + total_subset_err += color_cell_compression_est_astc(4, 3, g_bc7_weights2, subset_total_colors[subset], &subset_colors[subset][0], best_err, weights); + + if (total_subset_err < best_err) + { + best_err = total_subset_err; + best_common_pattern = common_pattern; + } + } + + first_common_pattern = best_common_pattern; + last_common_pattern = best_common_pattern + 1; + } + + for (uint32_t common_pattern = first_common_pattern; common_pattern < last_common_pattern; common_pattern++) + { + const uint32_t endpoint_range = 7; + + const uint32_t bc7_pattern = g_astc_bc7_common_partitions3[common_pattern].m_bc7; + + color_rgba part_pixels[3][16]; + uint32_t part_pixel_index[4][4]; + uint32_t num_part_pixels[3] = { 0, 0, 0 }; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t bc7_part = g_bc7_partition3[16 * bc7_pattern + x + y * 4]; + part_pixel_index[y][x] = num_part_pixels[bc7_part]; + part_pixels[bc7_part][num_part_pixels[bc7_part]++] = block[y][x]; + } + } + + color_cell_compressor_params ccell_params[3]; + color_cell_compressor_results ccell_results[3]; + uint8_t ccell_result_selectors[3][16]; + uint8_t ccell_result_selectors_temp[3][16]; + + uint64_t total_part_err = 0; + for (uint32_t bc7_part = 0; bc7_part < 3; bc7_part++) + { + memset(&ccell_params[bc7_part], 0, sizeof(ccell_params[bc7_part])); + + ccell_params[bc7_part].m_num_pixels = num_part_pixels[bc7_part]; + ccell_params[bc7_part].m_pPixels = (color_quad_u8*)&part_pixels[bc7_part][0]; + ccell_params[bc7_part].m_num_selector_weights = 4; + ccell_params[bc7_part].m_pSelector_weights = g_bc7_weights2; + ccell_params[bc7_part].m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params[bc7_part].m_astc_endpoint_range = endpoint_range; + ccell_params[bc7_part].m_weights[0] = 1; + ccell_params[bc7_part].m_weights[1] = 1; + ccell_params[bc7_part].m_weights[2] = 1; + ccell_params[bc7_part].m_weights[3] = 1; + + memset(&ccell_results[bc7_part], 0, sizeof(ccell_results[bc7_part])); + ccell_results[bc7_part].m_pSelectors = &ccell_result_selectors[bc7_part][0]; + ccell_results[bc7_part].m_pSelectors_temp = &ccell_result_selectors_temp[bc7_part][0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params[bc7_part], &ccell_results[bc7_part], &comp_params); + total_part_err += part_err; + } // part + + { + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = 2; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 3; + astc_results.m_partition_seed = g_astc_bc7_common_partitions3[common_pattern].m_astc; + astc_results.m_cem = 8; + + uint32_t astc_to_bc7_part[3]; // converts ASTC to BC7 partition index + const uint32_t perm = g_astc_bc7_common_partitions3[common_pattern].m_astc_to_bc7_perm; + astc_to_bc7_part[0] = g_astc_to_bc7_partition_index_perm_tables[perm][0]; + astc_to_bc7_part[1] = g_astc_to_bc7_partition_index_perm_tables[perm][1]; + astc_to_bc7_part[2] = g_astc_to_bc7_partition_index_perm_tables[perm][2]; + + bool invert_astc_part[3] = { false, false, false }; + + for (uint32_t astc_part = 0; astc_part < 3; astc_part++) + { + uint8_t* pEndpoints = &astc_results.m_endpoints[6 * astc_part]; + + pEndpoints[0] = ccell_results[astc_to_bc7_part[astc_part]].m_astc_low_endpoint.m_c[0]; + pEndpoints[1] = ccell_results[astc_to_bc7_part[astc_part]].m_astc_high_endpoint.m_c[0]; + pEndpoints[2] = ccell_results[astc_to_bc7_part[astc_part]].m_astc_low_endpoint.m_c[1]; + pEndpoints[3] = ccell_results[astc_to_bc7_part[astc_part]].m_astc_high_endpoint.m_c[1]; + pEndpoints[4] = ccell_results[astc_to_bc7_part[astc_part]].m_astc_low_endpoint.m_c[2]; + pEndpoints[5] = ccell_results[astc_to_bc7_part[astc_part]].m_astc_high_endpoint.m_c[2]; + + int s0 = g_astc_unquant[endpoint_range][pEndpoints[0]].m_unquant + g_astc_unquant[endpoint_range][pEndpoints[2]].m_unquant + g_astc_unquant[endpoint_range][pEndpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][pEndpoints[1]].m_unquant + g_astc_unquant[endpoint_range][pEndpoints[3]].m_unquant + g_astc_unquant[endpoint_range][pEndpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(pEndpoints[0], pEndpoints[1]); + std::swap(pEndpoints[2], pEndpoints[3]); + std::swap(pEndpoints[4], pEndpoints[5]); + invert_astc_part[astc_part] = true; + } + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t bc7_part = g_bc7_partition3[16 * bc7_pattern + x + y * 4]; + + astc_results.m_weights[x + y * 4] = ccell_result_selectors[bc7_part][part_pixel_index[y][x]]; + + uint32_t astc_part = 0; + for (uint32_t i = 0; i < 3; i++) + { + if (astc_to_bc7_part[i] == bc7_part) + { + astc_part = i; + break; + } + } + + if (invert_astc_part[astc_part]) + astc_results.m_weights[x + y * 4] = 3 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 3; + pResults[total_results].m_common_pattern = common_pattern; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = total_part_err; + total_results++; + } + + } + + } // common_pattern + } + + // MODE 4 + // DualPlane: 0, WeightRange: 2 (4), Subsets: 2, CEM: 8 (RGB Direct ), EndpointRange: 12 (40) MODE3 + static void astc_mode4(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params, bool estimate_partition) + { + //const uint32_t weight_range = 2; + const uint32_t endpoint_range = 12; + + uint32_t first_common_pattern = 0; + uint32_t last_common_pattern = TOTAL_ASTC_BC7_COMMON_PARTITIONS2; + + if (estimate_partition) + { + const uint32_t weights[4] = { 1, 1, 1, 1 }; + first_common_pattern = estimate_partition2(4, 3, g_bc7_weights2, block, weights); + last_common_pattern = first_common_pattern + 1; + } + + for (uint32_t common_pattern = first_common_pattern; common_pattern < last_common_pattern; common_pattern++) + { + const uint32_t bc7_pattern = g_astc_bc7_common_partitions2[common_pattern].m_bc7; + + color_rgba part_pixels[2][16]; + uint32_t part_pixel_index[4][4]; + uint32_t num_part_pixels[2] = { 0, 0 }; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t part = g_bc7_partition2[16 * bc7_pattern + x + y * 4]; + part_pixel_index[y][x] = num_part_pixels[part]; + part_pixels[part][num_part_pixels[part]++] = block[y][x]; + } + } + + color_cell_compressor_params ccell_params[2]; + color_cell_compressor_results ccell_results[2]; + uint8_t ccell_result_selectors[2][16]; + uint8_t ccell_result_selectors_temp[2][16]; + + uint64_t total_part_err = 0; + for (uint32_t part = 0; part < 2; part++) + { + memset(&ccell_params[part], 0, sizeof(ccell_params[part])); + + ccell_params[part].m_num_pixels = num_part_pixels[part]; + ccell_params[part].m_pPixels = (color_quad_u8*)&part_pixels[part][0]; + ccell_params[part].m_num_selector_weights = 4; + ccell_params[part].m_pSelector_weights = g_bc7_weights2; + ccell_params[part].m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params[part].m_astc_endpoint_range = endpoint_range; + ccell_params[part].m_weights[0] = 1; + ccell_params[part].m_weights[1] = 1; + ccell_params[part].m_weights[2] = 1; + ccell_params[part].m_weights[3] = 1; + + memset(&ccell_results[part], 0, sizeof(ccell_results[part])); + ccell_results[part].m_pSelectors = &ccell_result_selectors[part][0]; + ccell_results[part].m_pSelectors_temp = &ccell_result_selectors_temp[part][0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params[part], &ccell_results[part], &comp_params); + total_part_err += part_err; + } // part + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = 2; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 2; + astc_results.m_partition_seed = g_astc_bc7_common_partitions2[common_pattern].m_astc; + astc_results.m_cem = 8; + + uint32_t p0 = 0; + uint32_t p1 = 1; + if (g_astc_bc7_common_partitions2[common_pattern].m_invert) + std::swap(p0, p1); + + astc_results.m_endpoints[0] = ccell_results[p0].m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results[p0].m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results[p0].m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results[p0].m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results[p0].m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results[p0].m_astc_high_endpoint.m_c[2]; + + bool invert[2] = { false, false }; + + int s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + invert[0] = true; + } + + astc_results.m_endpoints[6] = ccell_results[p1].m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[7] = ccell_results[p1].m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[8] = ccell_results[p1].m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[9] = ccell_results[p1].m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[10] = ccell_results[p1].m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[11] = ccell_results[p1].m_astc_high_endpoint.m_c[2]; + + s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[0 + 6]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[2 + 6]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[4 + 6]].m_unquant; + s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[1 + 6]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[3 + 6]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[5 + 6]].m_unquant; + + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0 + 6], astc_results.m_endpoints[1 + 6]); + std::swap(astc_results.m_endpoints[2 + 6], astc_results.m_endpoints[3 + 6]); + std::swap(astc_results.m_endpoints[4 + 6], astc_results.m_endpoints[5 + 6]); + invert[1] = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t bc7_part = g_bc7_partition2[16 * bc7_pattern + x + y * 4]; + + astc_results.m_weights[x + y * 4] = ccell_result_selectors[bc7_part][part_pixel_index[y][x]]; + + uint32_t astc_part = bc7_part; + if (g_astc_bc7_common_partitions2[common_pattern].m_invert) + astc_part = 1 - astc_part; + + if (invert[astc_part]) + astc_results.m_weights[x + y * 4] = 3 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 4; + pResults[total_results].m_common_pattern = common_pattern; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = total_part_err; + total_results++; + } + + } // common_pattern + } + + // MODE 5 + // DualPlane: 0, WeightRange: 5 (8), Subsets: 1, CEM: 8 (RGB Direct ), EndpointRange: 20 (256) BC7 MODE 6 (or MODE 1 1-subset) + static void astc_mode5(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + const uint32_t weight_range = 5; + const uint32_t endpoint_range = 20; + + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + ccell_params.m_num_pixels = 16; + ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_num_selector_weights = 8; + ccell_params.m_pSelector_weights = g_bc7_weights3; + ccell_params.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights3x; + ccell_params.m_astc_endpoint_range = endpoint_range; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc blk; + memset(&blk, 0, sizeof(blk)); + + blk.m_dual_plane = false; + blk.m_weight_range = weight_range; + + blk.m_ccs = 0; + blk.m_subsets = 1; + blk.m_partition_seed = 0; + blk.m_cem = 8; + + blk.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + blk.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[1]; + blk.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[1]; + blk.m_endpoints[4] = ccell_results.m_astc_low_endpoint.m_c[2]; + blk.m_endpoints[5] = ccell_results.m_astc_high_endpoint.m_c[2]; + + bool invert = false; + + int s0 = g_astc_unquant[endpoint_range][blk.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][blk.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(blk.m_endpoints[0], blk.m_endpoints[1]); + std::swap(blk.m_endpoints[2], blk.m_endpoints[3]); + std::swap(blk.m_endpoints[4], blk.m_endpoints[5]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + blk.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + if (invert) + blk.m_weights[x + y * 4] = 7 - blk.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 5; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = blk; + pResults[total_results].m_astc_err = part_err; + total_results++; + } + } + + // MODE 6 + // DualPlane: 1, WeightRange: 2 (4), Subsets: 1, CEM: 8 (RGB Direct ), EndpointRange: 18 (160) BC7 MODE5 + static void astc_mode6(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + for (uint32_t rot_comp = 0; rot_comp < 3; rot_comp++) + { + const uint32_t weight_range = 2; + const uint32_t endpoint_range = 18; + + color_quad_u8 block_rgb[16]; + color_quad_u8 block_a[16]; + for (uint32_t i = 0; i < 16; i++) + { + block_rgb[i] = ((color_quad_u8*)&block[0][0])[i]; + block_a[i] = block_rgb[i]; + + uint8_t c = block_a[i].m_c[rot_comp]; + block_a[i].m_c[0] = c; + block_a[i].m_c[1] = c; + block_a[i].m_c[2] = c; + block_a[i].m_c[3] = 255; + + block_rgb[i].m_c[rot_comp] = 255; + } + + uint8_t ccell_result_selectors_temp[16]; + + color_cell_compressor_params ccell_params_rgb; + memset(&ccell_params_rgb, 0, sizeof(ccell_params_rgb)); + + ccell_params_rgb.m_num_pixels = 16; + ccell_params_rgb.m_pPixels = block_rgb; + ccell_params_rgb.m_num_selector_weights = 4; + ccell_params_rgb.m_pSelector_weights = g_bc7_weights2; + ccell_params_rgb.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params_rgb.m_astc_endpoint_range = endpoint_range; + ccell_params_rgb.m_weights[0] = 1; + ccell_params_rgb.m_weights[1] = 1; + ccell_params_rgb.m_weights[2] = 1; + ccell_params_rgb.m_weights[3] = 1; + + color_cell_compressor_results ccell_results_rgb; + uint8_t ccell_result_selectors_rgb[16]; + memset(&ccell_results_rgb, 0, sizeof(ccell_results_rgb)); + ccell_results_rgb.m_pSelectors = &ccell_result_selectors_rgb[0]; + ccell_results_rgb.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err_rgb = color_cell_compression(255, &ccell_params_rgb, &ccell_results_rgb, &comp_params); + + color_cell_compressor_params ccell_params_a; + memset(&ccell_params_a, 0, sizeof(ccell_params_a)); + + ccell_params_a.m_num_pixels = 16; + ccell_params_a.m_pPixels = block_a; + ccell_params_a.m_num_selector_weights = 4; + ccell_params_a.m_pSelector_weights = g_bc7_weights2; + ccell_params_a.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params_a.m_astc_endpoint_range = endpoint_range; + ccell_params_a.m_weights[0] = 1; + ccell_params_a.m_weights[1] = 1; + ccell_params_a.m_weights[2] = 1; + ccell_params_a.m_weights[3] = 1; + + color_cell_compressor_results ccell_results_a; + uint8_t ccell_result_selectors_a[16]; + memset(&ccell_results_a, 0, sizeof(ccell_results_a)); + ccell_results_a.m_pSelectors = &ccell_result_selectors_a[0]; + ccell_results_a.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err_a = color_cell_compression(255, &ccell_params_a, &ccell_results_a, &comp_params) / 3; + + uint64_t total_err = part_err_rgb + part_err_a; + + // ASTC + astc_block_desc blk; + memset(&blk, 0, sizeof(blk)); + + blk.m_dual_plane = true; + blk.m_weight_range = weight_range; + + blk.m_ccs = rot_comp; + blk.m_subsets = 1; + blk.m_partition_seed = 0; + blk.m_cem = 8; + + blk.m_endpoints[0] = (rot_comp == 0 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[1] = (rot_comp == 0 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[0]; + blk.m_endpoints[2] = (rot_comp == 1 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[1]; + blk.m_endpoints[3] = (rot_comp == 1 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[1]; + blk.m_endpoints[4] = (rot_comp == 2 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[2]; + blk.m_endpoints[5] = (rot_comp == 2 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[2]; + + bool invert = false; + + int s0 = g_astc_unquant[endpoint_range][blk.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][blk.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(blk.m_endpoints[0], blk.m_endpoints[1]); + std::swap(blk.m_endpoints[2], blk.m_endpoints[3]); + std::swap(blk.m_endpoints[4], blk.m_endpoints[5]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t rgb_index = ccell_result_selectors_rgb[x + y * 4]; + uint32_t a_index = ccell_result_selectors_a[x + y * 4]; + + if (invert) + { + rgb_index = 3 - rgb_index; + a_index = 3 - a_index; + } + + blk.m_weights[(x + y * 4) * 2 + 0] = (uint8_t)rgb_index; + blk.m_weights[(x + y * 4) * 2 + 1] = (uint8_t)a_index; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 6; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = blk; + pResults[total_results].m_astc_err = total_err; + total_results++; + } + } // rot_comp + } + + // MODE 7 - 2 subset ASTC, 3 subset BC7 + // DualPlane: 0, WeightRange: 2 (4), Subsets: 2, CEM: 8 (RGB Direct ), EndpointRange: 12 (40) MODE2 + static void astc_mode7(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params, bool estimate_partition) + { + uint32_t first_common_pattern = 0; + uint32_t last_common_pattern = TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS; + + if (estimate_partition) + { + uint64_t best_err = UINT64_MAX; + uint32_t best_common_pattern = 0; + const uint32_t weights[4] = { 1, 1, 1, 1 }; + + for (uint32_t common_pattern = 0; common_pattern < TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS; common_pattern++) + { + const uint8_t* pPartition = &g_bc7_3_astc2_patterns2[common_pattern][0]; + +#ifdef _DEBUG + const uint32_t astc_pattern = g_bc7_3_astc2_common_partitions[common_pattern].m_astc2; + const uint32_t bc7_pattern = g_bc7_3_astc2_common_partitions[common_pattern].m_bc73; + const uint32_t common_pattern_k = g_bc7_3_astc2_common_partitions[common_pattern].k; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t astc_part = bc7_convert_partition_index_3_to_2(g_bc7_partition3[16 * bc7_pattern + x + y * 4], common_pattern_k); + assert((int)astc_part == astc_compute_texel_partition(astc_pattern, x, y, 0, 2, true)); + assert(astc_part == pPartition[x + y * 4]); + } + } +#endif + + color_quad_u8 subset_colors[2][16]; + uint32_t subset_total_colors[2] = { 0, 0 }; + for (uint32_t index = 0; index < 16; index++) + subset_colors[pPartition[index]][subset_total_colors[pPartition[index]]++] = ((const color_quad_u8*)block)[index]; + + uint64_t total_subset_err = 0; + for (uint32_t subset = 0; (subset < 2) && (total_subset_err < best_err); subset++) + total_subset_err += color_cell_compression_est_astc(4, 3, g_bc7_weights2, subset_total_colors[subset], &subset_colors[subset][0], best_err, weights); + + if (total_subset_err < best_err) + { + best_err = total_subset_err; + best_common_pattern = common_pattern; + } + } + + first_common_pattern = best_common_pattern; + last_common_pattern = best_common_pattern + 1; + } + + //const uint32_t weight_range = 2; + const uint32_t endpoint_range = 12; + + for (uint32_t common_pattern = first_common_pattern; common_pattern < last_common_pattern; common_pattern++) + { + const uint32_t astc_pattern = g_bc7_3_astc2_common_partitions[common_pattern].m_astc2; + const uint32_t bc7_pattern = g_bc7_3_astc2_common_partitions[common_pattern].m_bc73; + const uint32_t common_pattern_k = g_bc7_3_astc2_common_partitions[common_pattern].k; + + color_rgba part_pixels[2][16]; + uint32_t part_pixel_index[4][4]; + uint32_t num_part_pixels[2] = { 0, 0 }; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t astc_part = bc7_convert_partition_index_3_to_2(g_bc7_partition3[16 * bc7_pattern + x + y * 4], common_pattern_k); +#ifdef _DEBUG + assert((int)astc_part == astc_compute_texel_partition(astc_pattern, x, y, 0, 2, true)); +#endif + + part_pixel_index[y][x] = num_part_pixels[astc_part]; + part_pixels[astc_part][num_part_pixels[astc_part]++] = block[y][x]; + } + } + + color_cell_compressor_params ccell_params[2]; + color_cell_compressor_results ccell_results[2]; + uint8_t ccell_result_selectors[2][16]; + uint8_t ccell_result_selectors_temp[2][16]; + + uint64_t total_part_err = 0; + for (uint32_t part = 0; part < 2; part++) + { + memset(&ccell_params[part], 0, sizeof(ccell_params[part])); + + ccell_params[part].m_num_pixels = num_part_pixels[part]; + ccell_params[part].m_pPixels = (color_quad_u8*)&part_pixels[part][0]; + ccell_params[part].m_num_selector_weights = 4; + ccell_params[part].m_pSelector_weights = g_bc7_weights2; + ccell_params[part].m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params[part].m_astc_endpoint_range = endpoint_range; + ccell_params[part].m_weights[0] = 1; + ccell_params[part].m_weights[1] = 1; + ccell_params[part].m_weights[2] = 1; + ccell_params[part].m_weights[3] = 1; + + memset(&ccell_results[part], 0, sizeof(ccell_results[part])); + ccell_results[part].m_pSelectors = &ccell_result_selectors[part][0]; + ccell_results[part].m_pSelectors_temp = &ccell_result_selectors_temp[part][0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params[part], &ccell_results[part], &comp_params); + total_part_err += part_err; + } // part + + // ASTC + astc_block_desc blk; + memset(&blk, 0, sizeof(blk)); + + blk.m_dual_plane = false; + blk.m_weight_range = 2; + + blk.m_ccs = 0; + blk.m_subsets = 2; + blk.m_partition_seed = astc_pattern; + blk.m_cem = 8; + + const uint32_t p0 = 0; + const uint32_t p1 = 1; + + blk.m_endpoints[0] = ccell_results[p0].m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[1] = ccell_results[p0].m_astc_high_endpoint.m_c[0]; + blk.m_endpoints[2] = ccell_results[p0].m_astc_low_endpoint.m_c[1]; + blk.m_endpoints[3] = ccell_results[p0].m_astc_high_endpoint.m_c[1]; + blk.m_endpoints[4] = ccell_results[p0].m_astc_low_endpoint.m_c[2]; + blk.m_endpoints[5] = ccell_results[p0].m_astc_high_endpoint.m_c[2]; + + bool invert[2] = { false, false }; + + int s0 = g_astc_unquant[endpoint_range][blk.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][blk.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(blk.m_endpoints[0], blk.m_endpoints[1]); + std::swap(blk.m_endpoints[2], blk.m_endpoints[3]); + std::swap(blk.m_endpoints[4], blk.m_endpoints[5]); + invert[0] = true; + } + + blk.m_endpoints[6] = ccell_results[p1].m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[7] = ccell_results[p1].m_astc_high_endpoint.m_c[0]; + blk.m_endpoints[8] = ccell_results[p1].m_astc_low_endpoint.m_c[1]; + blk.m_endpoints[9] = ccell_results[p1].m_astc_high_endpoint.m_c[1]; + blk.m_endpoints[10] = ccell_results[p1].m_astc_low_endpoint.m_c[2]; + blk.m_endpoints[11] = ccell_results[p1].m_astc_high_endpoint.m_c[2]; + + s0 = g_astc_unquant[endpoint_range][blk.m_endpoints[0 + 6]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[2 + 6]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[4 + 6]].m_unquant; + s1 = g_astc_unquant[endpoint_range][blk.m_endpoints[1 + 6]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[3 + 6]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[5 + 6]].m_unquant; + + if (s1 < s0) + { + std::swap(blk.m_endpoints[0 + 6], blk.m_endpoints[1 + 6]); + std::swap(blk.m_endpoints[2 + 6], blk.m_endpoints[3 + 6]); + std::swap(blk.m_endpoints[4 + 6], blk.m_endpoints[5 + 6]); + invert[1] = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t astc_part = bc7_convert_partition_index_3_to_2(g_bc7_partition3[16 * bc7_pattern + x + y * 4], common_pattern_k); + + blk.m_weights[x + y * 4] = ccell_result_selectors[astc_part][part_pixel_index[y][x]]; + + if (invert[astc_part]) + blk.m_weights[x + y * 4] = 3 - blk.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 7; + pResults[total_results].m_common_pattern = common_pattern; + pResults[total_results].m_astc = blk; + pResults[total_results].m_astc_err = total_part_err; + total_results++; + } + + } // common_pattern + } + + static void estimate_partition2_list(uint32_t num_weights, uint32_t num_comps, const uint32_t* pWeights, const color_rgba block[4][4], uint32_t* pParts, uint32_t max_parts, const uint32_t weights[4]) + { + assert(pWeights[0] == 0 && pWeights[num_weights - 1] == 64); + + const uint32_t MAX_PARTS = 8; + assert(max_parts <= MAX_PARTS); + + uint64_t part_error[MAX_PARTS]; + memset(part_error, 0xFF, sizeof(part_error)); + memset(pParts, 0, sizeof(pParts[0]) * max_parts); + + for (uint32_t common_pattern = 0; common_pattern < TOTAL_ASTC_BC7_COMMON_PARTITIONS2; common_pattern++) + { + const uint32_t bc7_pattern = g_astc_bc7_common_partitions2[common_pattern].m_bc7; + + const uint8_t* pPartition = &g_bc7_partition2[bc7_pattern * 16]; + + color_quad_u8 subset_colors[2][16]; + uint32_t subset_total_colors[2] = { 0, 0 }; + for (uint32_t index = 0; index < 16; index++) + subset_colors[pPartition[index]][subset_total_colors[pPartition[index]]++] = ((const color_quad_u8*)block)[index]; + + uint64_t total_subset_err = 0; + for (uint32_t subset = 0; subset < 2; subset++) + total_subset_err += color_cell_compression_est_astc(num_weights, num_comps, pWeights, subset_total_colors[subset], &subset_colors[subset][0], UINT64_MAX, weights); + + for (int i = 0; i < (int)max_parts; i++) + { + if (total_subset_err < part_error[i]) + { + for (int j = max_parts - 1; j > i; --j) + { + pParts[j] = pParts[j - 1]; + part_error[j] = part_error[j - 1]; + } + + pParts[i] = common_pattern; + part_error[i] = total_subset_err; + + break; + } + } + } + +#ifdef _DEBUG + for (uint32_t i = 0; i < max_parts - 1; i++) + { + assert(part_error[i] <= part_error[i + 1]); + } +#endif + } + + // 9. DualPlane: 0, WeightRange: 2 (4), Subsets: 2, CEM: 12 (RGBA Direct), EndpointRange: 8 (16) - BC7 MODE 7 + // 16. DualPlane: 0, WeightRange : 2 (4), Subsets : 2, CEM: 4 (LA Direct), EndpointRange : 20 (256) - BC7 MODE 7 + static void astc_mode9_or_16(uint32_t mode, const color_rgba source_block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params, uint32_t estimate_partition_list_size) + { + assert(mode == 9 || mode == 16); + + const color_rgba* pBlock = &source_block[0][0]; + + color_rgba temp_block[16]; + if (mode == 16) + { + for (uint32_t i = 0; i < 16; i++) + { + if (mode == 16) + { + assert(pBlock[i].r == pBlock[i].g); + assert(pBlock[i].r == pBlock[i].b); + } + + const uint32_t l = pBlock[i].r; + const uint32_t a = pBlock[i].a; + + // Use (l,0,0,a) not (l,l,l,a) so both components are treated equally. + temp_block[i].set_noclamp_rgba(l, 0, 0, a); + } + + pBlock = temp_block; + } + + const uint32_t weights[4] = { 1, 1, 1, 1 }; + + //const uint32_t weight_range = 2; + const uint32_t endpoint_range = (mode == 16) ? 20 : 8; + + uint32_t first_common_pattern = 0; + uint32_t last_common_pattern = TOTAL_ASTC_BC7_COMMON_PARTITIONS2; + bool use_part_list = false; + + const uint32_t MAX_PARTS = 8; + uint32_t parts[MAX_PARTS]; + + if (estimate_partition_list_size == 1) + { + first_common_pattern = estimate_partition2(4, 4, g_bc7_weights2, (const color_rgba(*)[4])pBlock, weights); + last_common_pattern = first_common_pattern + 1; + } + else if (estimate_partition_list_size > 0) + { + assert(estimate_partition_list_size <= MAX_PARTS); + estimate_partition_list_size = basisu::minimum(estimate_partition_list_size, MAX_PARTS); + + estimate_partition2_list(4, 4, g_bc7_weights2, (const color_rgba(*)[4])pBlock, parts, estimate_partition_list_size, weights); + + first_common_pattern = 0; + last_common_pattern = estimate_partition_list_size; + use_part_list = true; + +#ifdef _DEBUG + assert(parts[0] == estimate_partition2(4, 4, g_bc7_weights2, (const color_rgba(*)[4])pBlock, weights)); +#endif + } + + for (uint32_t common_pattern_iter = first_common_pattern; common_pattern_iter < last_common_pattern; common_pattern_iter++) + { + const uint32_t common_pattern = use_part_list ? parts[common_pattern_iter] : common_pattern_iter; + + const uint32_t bc7_pattern = g_astc_bc7_common_partitions2[common_pattern].m_bc7; + + color_rgba part_pixels[2][16]; + uint32_t part_pixel_index[4][4]; + uint32_t num_part_pixels[2] = { 0, 0 }; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t part = g_bc7_partition2[16 * bc7_pattern + x + y * 4]; + part_pixel_index[y][x] = num_part_pixels[part]; + part_pixels[part][num_part_pixels[part]++] = pBlock[y * 4 + x]; + } + } + + color_cell_compressor_params ccell_params[2]; + color_cell_compressor_results ccell_results[2]; + uint8_t ccell_result_selectors[2][16]; + uint8_t ccell_result_selectors_temp[2][16]; + + uint64_t total_err = 0; + for (uint32_t subset = 0; subset < 2; subset++) + { + memset(&ccell_params[subset], 0, sizeof(ccell_params[subset])); + + ccell_params[subset].m_num_pixels = num_part_pixels[subset]; + ccell_params[subset].m_pPixels = (color_quad_u8*)&part_pixels[subset][0]; + ccell_params[subset].m_num_selector_weights = 4; + ccell_params[subset].m_pSelector_weights = g_bc7_weights2; + ccell_params[subset].m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params[subset].m_astc_endpoint_range = endpoint_range; + ccell_params[subset].m_weights[0] = weights[0]; + ccell_params[subset].m_weights[1] = weights[1]; + ccell_params[subset].m_weights[2] = weights[2]; + ccell_params[subset].m_weights[3] = weights[3]; + ccell_params[subset].m_has_alpha = true; + + memset(&ccell_results[subset], 0, sizeof(ccell_results[subset])); + ccell_results[subset].m_pSelectors = &ccell_result_selectors[subset][0]; + ccell_results[subset].m_pSelectors_temp = &ccell_result_selectors_temp[subset][0]; + + uint64_t subset_err = color_cell_compression(255, &ccell_params[subset], &ccell_results[subset], &comp_params); + + if (mode == 16) + { + color_rgba colors[4]; + for (uint32_t c = 0; c < 4; c++) + { + colors[0].m_comps[c] = g_astc_unquant[endpoint_range][ccell_results[subset].m_astc_low_endpoint.m_c[(c < 3) ? 0 : 3]].m_unquant; + colors[3].m_comps[c] = g_astc_unquant[endpoint_range][ccell_results[subset].m_astc_high_endpoint.m_c[(c < 3) ? 0 : 3]].m_unquant; + } + + for (uint32_t i = 1; i < 4 - 1; i++) + for (uint32_t c = 0; c < 4; c++) + colors[i].m_comps[c] = (uint8_t)astc_interpolate(colors[0].m_comps[c], colors[3].m_comps[c], g_bc7_weights2[i], false); + + for (uint32_t p = 0; p < ccell_params[subset].m_num_pixels; p++) + { + color_rgba orig_pix(part_pixels[subset][p]); + orig_pix.g = orig_pix.r; + orig_pix.b = orig_pix.r; + total_err += color_distance_la(orig_pix, colors[ccell_result_selectors[subset][p]]); + } + } + else + { + total_err += subset_err; + } + } // subset + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = 2; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 2; + astc_results.m_partition_seed = g_astc_bc7_common_partitions2[common_pattern].m_astc; + astc_results.m_cem = (mode == 16) ? 4 : 12; + + uint32_t part[2] = { 0, 1 }; + if (g_astc_bc7_common_partitions2[common_pattern].m_invert) + std::swap(part[0], part[1]); + + bool invert[2] = { false, false }; + + for (uint32_t p = 0; p < 2; p++) + { + if (mode == 16) + { + astc_results.m_endpoints[p * 4 + 0] = ccell_results[part[p]].m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[p * 4 + 1] = ccell_results[part[p]].m_astc_high_endpoint.m_c[0]; + + astc_results.m_endpoints[p * 4 + 2] = ccell_results[part[p]].m_astc_low_endpoint.m_c[3]; + astc_results.m_endpoints[p * 4 + 3] = ccell_results[part[p]].m_astc_high_endpoint.m_c[3]; + } + else + { + for (uint32_t c = 0; c < 4; c++) + { + astc_results.m_endpoints[p * 8 + c * 2] = ccell_results[part[p]].m_astc_low_endpoint.m_c[c]; + astc_results.m_endpoints[p * 8 + c * 2 + 1] = ccell_results[part[p]].m_astc_high_endpoint.m_c[c]; + } + + int s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[p * 8 + 0]].m_unquant + + g_astc_unquant[endpoint_range][astc_results.m_endpoints[p * 8 + 2]].m_unquant + + g_astc_unquant[endpoint_range][astc_results.m_endpoints[p * 8 + 4]].m_unquant; + + int s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[p * 8 + 1]].m_unquant + + g_astc_unquant[endpoint_range][astc_results.m_endpoints[p * 8 + 3]].m_unquant + + g_astc_unquant[endpoint_range][astc_results.m_endpoints[p * 8 + 5]].m_unquant; + + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[p * 8 + 0], astc_results.m_endpoints[p * 8 + 1]); + std::swap(astc_results.m_endpoints[p * 8 + 2], astc_results.m_endpoints[p * 8 + 3]); + std::swap(astc_results.m_endpoints[p * 8 + 4], astc_results.m_endpoints[p * 8 + 5]); + std::swap(astc_results.m_endpoints[p * 8 + 6], astc_results.m_endpoints[p * 8 + 7]); + invert[p] = true; + } + } + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t bc7_part = g_bc7_partition2[16 * bc7_pattern + x + y * 4]; + + astc_results.m_weights[x + y * 4] = ccell_result_selectors[bc7_part][part_pixel_index[y][x]]; + + uint32_t astc_part = bc7_part; + if (g_astc_bc7_common_partitions2[common_pattern].m_invert) + astc_part = 1 - astc_part; + + if (invert[astc_part]) + astc_results.m_weights[x + y * 4] = 3 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = mode; + pResults[total_results].m_common_pattern = common_pattern; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = total_err; + total_results++; + } + + } // common_pattern + } + + // MODE 10 + // DualPlane: 0, WeightRange: 8 (16), Subsets: 1, CEM: 12 (RGBA Direct ), EndpointRange: 13 (48) MODE6 + static void astc_mode10(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + const uint32_t weight_range = 8; + const uint32_t endpoint_range = 13; + + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + ccell_params.m_num_pixels = 16; + ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_num_selector_weights = 16; + ccell_params.m_pSelector_weights = g_astc_weights4; + ccell_params.m_pSelector_weightsx = (const bc7enc_vec4F*)g_astc_weights4x; + ccell_params.m_astc_endpoint_range = endpoint_range; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + ccell_params.m_has_alpha = true; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = weight_range; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 1; + astc_results.m_partition_seed = 0; + astc_results.m_cem = 12; + + astc_results.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results.m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results.m_astc_high_endpoint.m_c[2]; + astc_results.m_endpoints[6] = ccell_results.m_astc_low_endpoint.m_c[3]; + astc_results.m_endpoints[7] = ccell_results.m_astc_high_endpoint.m_c[3]; + + bool invert = false; + + int s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + std::swap(astc_results.m_endpoints[6], astc_results.m_endpoints[7]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + astc_results.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + if (invert) + astc_results.m_weights[x + y * 4] = 15 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 10; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = part_err; + total_results++; + } + } + + // 11. DualPlane: 1, WeightRange: 2 (4), Subsets: 1, CEM: 12 (RGBA Direct), EndpointRange: 13 (48) MODE5 + // 17. DualPlane: 1, WeightRange : 2 (4), Subsets : 1, CEM : 4 (LA Direct), EndpointRange : 20 (256) BC7 MODE5 + static void astc_mode11_or_17(uint32_t mode, const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + assert((mode == 11) || (mode == 17)); + + const uint32_t weight_range = 2; + const uint32_t endpoint_range = (mode == 17) ? 20 : 13; + + bc7enc_compress_block_params local_comp_params(comp_params); + local_comp_params.m_perceptual = false; + local_comp_params.m_weights[0] = 1; + local_comp_params.m_weights[1] = 1; + local_comp_params.m_weights[2] = 1; + local_comp_params.m_weights[3] = 1; + + const uint32_t last_rot_comp = (mode == 17) ? 1 : 4; + + for (uint32_t rot_comp = 0; rot_comp < last_rot_comp; rot_comp++) + { + color_quad_u8 block_rgb[16]; + color_quad_u8 block_a[16]; + for (uint32_t i = 0; i < 16; i++) + { + block_rgb[i] = ((color_quad_u8*)&block[0][0])[i]; + block_a[i] = block_rgb[i]; + + if (mode == 17) + { + assert(block_rgb[i].m_c[0] == block_rgb[i].m_c[1]); + assert(block_rgb[i].m_c[0] == block_rgb[i].m_c[2]); + + block_a[i].m_c[0] = block_rgb[i].m_c[3]; + block_a[i].m_c[1] = block_rgb[i].m_c[3]; + block_a[i].m_c[2] = block_rgb[i].m_c[3]; + block_a[i].m_c[3] = 255; + + block_rgb[i].m_c[1] = block_rgb[i].m_c[0]; + block_rgb[i].m_c[2] = block_rgb[i].m_c[0]; + block_rgb[i].m_c[3] = 255; + } + else + { + uint8_t c = block_a[i].m_c[rot_comp]; + block_a[i].m_c[0] = c; + block_a[i].m_c[1] = c; + block_a[i].m_c[2] = c; + block_a[i].m_c[3] = 255; + + block_rgb[i].m_c[rot_comp] = block_rgb[i].m_c[3]; + block_rgb[i].m_c[3] = 255; + } + } + + uint8_t ccell_result_selectors_temp[16]; + + color_cell_compressor_params ccell_params_rgb; + memset(&ccell_params_rgb, 0, sizeof(ccell_params_rgb)); + + ccell_params_rgb.m_num_pixels = 16; + ccell_params_rgb.m_pPixels = block_rgb; + ccell_params_rgb.m_num_selector_weights = 4; + ccell_params_rgb.m_pSelector_weights = g_bc7_weights2; + ccell_params_rgb.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params_rgb.m_astc_endpoint_range = endpoint_range; + ccell_params_rgb.m_weights[0] = 1; + ccell_params_rgb.m_weights[1] = 1; + ccell_params_rgb.m_weights[2] = 1; + ccell_params_rgb.m_weights[3] = 1; + + color_cell_compressor_results ccell_results_rgb; + uint8_t ccell_result_selectors_rgb[16]; + memset(&ccell_results_rgb, 0, sizeof(ccell_results_rgb)); + ccell_results_rgb.m_pSelectors = &ccell_result_selectors_rgb[0]; + ccell_results_rgb.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err_rgb = color_cell_compression(255, &ccell_params_rgb, &ccell_results_rgb, &local_comp_params); + + color_cell_compressor_params ccell_params_a; + memset(&ccell_params_a, 0, sizeof(ccell_params_a)); + + ccell_params_a.m_num_pixels = 16; + ccell_params_a.m_pPixels = block_a; + ccell_params_a.m_num_selector_weights = 4; + ccell_params_a.m_pSelector_weights = g_bc7_weights2; + ccell_params_a.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params_a.m_astc_endpoint_range = endpoint_range; + ccell_params_a.m_weights[0] = 1; + ccell_params_a.m_weights[1] = 1; + ccell_params_a.m_weights[2] = 1; + ccell_params_a.m_weights[3] = 1; + + color_cell_compressor_results ccell_results_a; + uint8_t ccell_result_selectors_a[16]; + memset(&ccell_results_a, 0, sizeof(ccell_results_a)); + ccell_results_a.m_pSelectors = &ccell_result_selectors_a[0]; + ccell_results_a.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err_a = color_cell_compression(255, &ccell_params_a, &ccell_results_a, &local_comp_params) / 3; + + uint64_t total_err = (mode == 17) ? ((part_err_rgb / 3) + part_err_a) : (part_err_rgb + part_err_a); + + // ASTC + astc_block_desc blk; + memset(&blk, 0, sizeof(blk)); + + blk.m_dual_plane = true; + blk.m_weight_range = weight_range; + + blk.m_ccs = (mode == 17) ? 3 : rot_comp; + blk.m_subsets = 1; + blk.m_partition_seed = 0; + blk.m_cem = (mode == 17) ? 4 : 12; + + bool invert = false; + + if (mode == 17) + { + assert(ccell_results_rgb.m_astc_low_endpoint.m_c[0] == ccell_results_rgb.m_astc_low_endpoint.m_c[1]); + assert(ccell_results_rgb.m_astc_low_endpoint.m_c[0] == ccell_results_rgb.m_astc_low_endpoint.m_c[2]); + + assert(ccell_results_rgb.m_astc_high_endpoint.m_c[0] == ccell_results_rgb.m_astc_high_endpoint.m_c[1]); + assert(ccell_results_rgb.m_astc_high_endpoint.m_c[0] == ccell_results_rgb.m_astc_high_endpoint.m_c[2]); + + blk.m_endpoints[0] = ccell_results_rgb.m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[1] = ccell_results_rgb.m_astc_high_endpoint.m_c[0]; + + blk.m_endpoints[2] = ccell_results_a.m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[3] = ccell_results_a.m_astc_high_endpoint.m_c[0]; + } + else + { + blk.m_endpoints[0] = (rot_comp == 0 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[1] = (rot_comp == 0 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[0]; + blk.m_endpoints[2] = (rot_comp == 1 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[1]; + blk.m_endpoints[3] = (rot_comp == 1 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[1]; + blk.m_endpoints[4] = (rot_comp == 2 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[2]; + blk.m_endpoints[5] = (rot_comp == 2 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[2]; + if (rot_comp == 3) + { + blk.m_endpoints[6] = ccell_results_a.m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[7] = ccell_results_a.m_astc_high_endpoint.m_c[0]; + } + else + { + blk.m_endpoints[6] = ccell_results_rgb.m_astc_low_endpoint.m_c[rot_comp]; + blk.m_endpoints[7] = ccell_results_rgb.m_astc_high_endpoint.m_c[rot_comp]; + } + + int s0 = g_astc_unquant[endpoint_range][blk.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][blk.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(blk.m_endpoints[0], blk.m_endpoints[1]); + std::swap(blk.m_endpoints[2], blk.m_endpoints[3]); + std::swap(blk.m_endpoints[4], blk.m_endpoints[5]); + std::swap(blk.m_endpoints[6], blk.m_endpoints[7]); + invert = true; + } + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t rgb_index = ccell_result_selectors_rgb[x + y * 4]; + uint32_t a_index = ccell_result_selectors_a[x + y * 4]; + + if (invert) + { + rgb_index = 3 - rgb_index; + a_index = 3 - a_index; + } + + blk.m_weights[(x + y * 4) * 2 + 0] = (uint8_t)rgb_index; + blk.m_weights[(x + y * 4) * 2 + 1] = (uint8_t)a_index; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = mode; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = blk; + pResults[total_results].m_astc_err = total_err; + total_results++; + } + } // rot_comp + } + + // MODE 12 + // DualPlane: 0, WeightRange: 5 (8), Subsets: 1, CEM: 12 (RGBA Direct ), EndpointRange: 19 (192) MODE6 + static void astc_mode12(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + const uint32_t weight_range = 5; + const uint32_t endpoint_range = 19; + + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + ccell_params.m_num_pixels = 16; + ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_num_selector_weights = 8; + ccell_params.m_pSelector_weights = g_bc7_weights3; + ccell_params.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights3x; + ccell_params.m_astc_endpoint_range = endpoint_range; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + ccell_params.m_has_alpha = true; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = weight_range; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 1; + astc_results.m_partition_seed = 0; + astc_results.m_cem = 12; + + astc_results.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results.m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results.m_astc_high_endpoint.m_c[2]; + astc_results.m_endpoints[6] = ccell_results.m_astc_low_endpoint.m_c[3]; + astc_results.m_endpoints[7] = ccell_results.m_astc_high_endpoint.m_c[3]; + + bool invert = false; + + int s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + std::swap(astc_results.m_endpoints[6], astc_results.m_endpoints[7]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + astc_results.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + if (invert) + astc_results.m_weights[x + y * 4] = 7 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 12; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = part_err; + total_results++; + } + } + + // 13. DualPlane: 1, WeightRange: 0 (2), Subsets: 1, CEM: 12 (RGBA Direct ), EndpointRange: 20 (256) MODE5 + static void astc_mode13(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + bc7enc_compress_block_params local_comp_params(comp_params); + local_comp_params.m_perceptual = false; + local_comp_params.m_weights[0] = 1; + local_comp_params.m_weights[1] = 1; + local_comp_params.m_weights[2] = 1; + local_comp_params.m_weights[3] = 1; + + for (uint32_t rot_comp = 0; rot_comp < 4; rot_comp++) + { + const uint32_t weight_range = 0; + const uint32_t endpoint_range = 20; + + color_quad_u8 block_rgb[16]; + color_quad_u8 block_a[16]; + for (uint32_t i = 0; i < 16; i++) + { + block_rgb[i] = ((color_quad_u8*)&block[0][0])[i]; + block_a[i] = block_rgb[i]; + + uint8_t c = block_a[i].m_c[rot_comp]; + block_a[i].m_c[0] = c; + block_a[i].m_c[1] = c; + block_a[i].m_c[2] = c; + block_a[i].m_c[3] = 255; + + block_rgb[i].m_c[rot_comp] = block_rgb[i].m_c[3]; + block_rgb[i].m_c[3] = 255; + } + + uint8_t ccell_result_selectors_temp[16]; + + color_cell_compressor_params ccell_params_rgb; + memset(&ccell_params_rgb, 0, sizeof(ccell_params_rgb)); + + ccell_params_rgb.m_num_pixels = 16; + ccell_params_rgb.m_pPixels = block_rgb; + ccell_params_rgb.m_num_selector_weights = 2; + ccell_params_rgb.m_pSelector_weights = g_bc7_weights1; + ccell_params_rgb.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights1x; + ccell_params_rgb.m_astc_endpoint_range = endpoint_range; + ccell_params_rgb.m_weights[0] = 1; + ccell_params_rgb.m_weights[1] = 1; + ccell_params_rgb.m_weights[2] = 1; + ccell_params_rgb.m_weights[3] = 1; + + color_cell_compressor_results ccell_results_rgb; + uint8_t ccell_result_selectors_rgb[16]; + memset(&ccell_results_rgb, 0, sizeof(ccell_results_rgb)); + ccell_results_rgb.m_pSelectors = &ccell_result_selectors_rgb[0]; + ccell_results_rgb.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err_rgb = color_cell_compression(255, &ccell_params_rgb, &ccell_results_rgb, &local_comp_params); + + color_cell_compressor_params ccell_params_a; + memset(&ccell_params_a, 0, sizeof(ccell_params_a)); + + ccell_params_a.m_num_pixels = 16; + ccell_params_a.m_pPixels = block_a; + ccell_params_a.m_num_selector_weights = 2; + ccell_params_a.m_pSelector_weights = g_bc7_weights1; + ccell_params_a.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights1x; + ccell_params_a.m_astc_endpoint_range = endpoint_range; + ccell_params_a.m_weights[0] = 1; + ccell_params_a.m_weights[1] = 1; + ccell_params_a.m_weights[2] = 1; + ccell_params_a.m_weights[3] = 1; + + color_cell_compressor_results ccell_results_a; + uint8_t ccell_result_selectors_a[16]; + memset(&ccell_results_a, 0, sizeof(ccell_results_a)); + ccell_results_a.m_pSelectors = &ccell_result_selectors_a[0]; + ccell_results_a.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err_a = color_cell_compression(255, &ccell_params_a, &ccell_results_a, &local_comp_params) / 3; + + uint64_t total_err = part_err_rgb + part_err_a; + + // ASTC + astc_block_desc blk; + memset(&blk, 0, sizeof(blk)); + + blk.m_dual_plane = true; + blk.m_weight_range = weight_range; + + blk.m_ccs = rot_comp; + blk.m_subsets = 1; + blk.m_partition_seed = 0; + blk.m_cem = 12; + + blk.m_endpoints[0] = (rot_comp == 0 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[1] = (rot_comp == 0 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[0]; + blk.m_endpoints[2] = (rot_comp == 1 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[1]; + blk.m_endpoints[3] = (rot_comp == 1 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[1]; + blk.m_endpoints[4] = (rot_comp == 2 ? ccell_results_a : ccell_results_rgb).m_astc_low_endpoint.m_c[2]; + blk.m_endpoints[5] = (rot_comp == 2 ? ccell_results_a : ccell_results_rgb).m_astc_high_endpoint.m_c[2]; + if (rot_comp == 3) + { + blk.m_endpoints[6] = ccell_results_a.m_astc_low_endpoint.m_c[0]; + blk.m_endpoints[7] = ccell_results_a.m_astc_high_endpoint.m_c[0]; + } + else + { + blk.m_endpoints[6] = ccell_results_rgb.m_astc_low_endpoint.m_c[rot_comp]; + blk.m_endpoints[7] = ccell_results_rgb.m_astc_high_endpoint.m_c[rot_comp]; + } + + bool invert = false; + + int s0 = g_astc_unquant[endpoint_range][blk.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][blk.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][blk.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(blk.m_endpoints[0], blk.m_endpoints[1]); + std::swap(blk.m_endpoints[2], blk.m_endpoints[3]); + std::swap(blk.m_endpoints[4], blk.m_endpoints[5]); + std::swap(blk.m_endpoints[6], blk.m_endpoints[7]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t rgb_index = ccell_result_selectors_rgb[x + y * 4]; + uint32_t a_index = ccell_result_selectors_a[x + y * 4]; + + if (invert) + { + rgb_index = 1 - rgb_index; + a_index = 1 - a_index; + } + + blk.m_weights[(x + y * 4) * 2 + 0] = (uint8_t)rgb_index; + blk.m_weights[(x + y * 4) * 2 + 1] = (uint8_t)a_index; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 13; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = blk; + pResults[total_results].m_astc_err = total_err; + total_results++; + } + } // rot_comp + } + + // MODE14 + // DualPlane: 0, WeightRange: 2 (4), Subsets: 1, CEM: 12 (RGBA Direct ), EndpointRange: 20 (256) MODE6 + static void astc_mode14(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + const uint32_t weight_range = 2; + const uint32_t endpoint_range = 20; + + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + ccell_params.m_num_pixels = 16; + ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_num_selector_weights = 4; + ccell_params.m_pSelector_weights = g_bc7_weights2; + ccell_params.m_pSelector_weightsx = (const bc7enc_vec4F*)g_bc7_weights2x; + ccell_params.m_astc_endpoint_range = endpoint_range; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + ccell_params.m_has_alpha = true; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + uint64_t part_err = color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = weight_range; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 1; + astc_results.m_partition_seed = 0; + astc_results.m_cem = 12; + + astc_results.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + astc_results.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[1]; + astc_results.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[1]; + astc_results.m_endpoints[4] = ccell_results.m_astc_low_endpoint.m_c[2]; + astc_results.m_endpoints[5] = ccell_results.m_astc_high_endpoint.m_c[2]; + astc_results.m_endpoints[6] = ccell_results.m_astc_low_endpoint.m_c[3]; + astc_results.m_endpoints[7] = ccell_results.m_astc_high_endpoint.m_c[3]; + + bool invert = false; + + int s0 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[0]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[2]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[4]].m_unquant; + int s1 = g_astc_unquant[endpoint_range][astc_results.m_endpoints[1]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[3]].m_unquant + g_astc_unquant[endpoint_range][astc_results.m_endpoints[5]].m_unquant; + if (s1 < s0) + { + std::swap(astc_results.m_endpoints[0], astc_results.m_endpoints[1]); + std::swap(astc_results.m_endpoints[2], astc_results.m_endpoints[3]); + std::swap(astc_results.m_endpoints[4], astc_results.m_endpoints[5]); + std::swap(astc_results.m_endpoints[6], astc_results.m_endpoints[7]); + invert = true; + } + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + astc_results.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + if (invert) + astc_results.m_weights[x + y * 4] = 3 - astc_results.m_weights[x + y * 4]; + } + } + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 14; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = part_err; + total_results++; + } + } + + // MODE 15 + // DualPlane: 0, WeightRange : 8 (16), Subsets : 1, CEM : 4 (LA Direct), EndpointRange : 20 (256) BC7 MODE6 + static void astc_mode15(const color_rgba block[4][4], uastc_encode_results* pResults, uint32_t& total_results, bc7enc_compress_block_params& comp_params) + { + const uint32_t weight_range = 8; + const uint32_t endpoint_range = 20; + + color_cell_compressor_params ccell_params; + memset(&ccell_params, 0, sizeof(ccell_params)); + + color_rgba temp_block[16]; + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t l = ((const color_rgba*)block)[i].r; + const uint32_t a = ((const color_rgba*)block)[i].a; + + // Use (l,0,0,a) not (l,l,l,a) so both components are treated equally. + temp_block[i].set_noclamp_rgba(l, 0, 0, a); + } + + ccell_params.m_num_pixels = 16; + //ccell_params.m_pPixels = (color_quad_u8*)&block[0][0]; + ccell_params.m_pPixels = (color_quad_u8*)temp_block; + ccell_params.m_num_selector_weights = 16; + ccell_params.m_pSelector_weights = g_astc_weights4; + ccell_params.m_pSelector_weightsx = (const bc7enc_vec4F*)g_astc_weights4x; + ccell_params.m_astc_endpoint_range = endpoint_range; + ccell_params.m_weights[0] = 1; + ccell_params.m_weights[1] = 1; + ccell_params.m_weights[2] = 1; + ccell_params.m_weights[3] = 1; + ccell_params.m_has_alpha = true; + + color_cell_compressor_results ccell_results; + uint8_t ccell_result_selectors[16]; + uint8_t ccell_result_selectors_temp[16]; + memset(&ccell_results, 0, sizeof(ccell_results)); + ccell_results.m_pSelectors = &ccell_result_selectors[0]; + ccell_results.m_pSelectors_temp = &ccell_result_selectors_temp[0]; + + color_cell_compression(255, &ccell_params, &ccell_results, &comp_params); + + // ASTC + astc_block_desc astc_results; + memset(&astc_results, 0, sizeof(astc_results)); + + astc_results.m_dual_plane = false; + astc_results.m_weight_range = weight_range; + + astc_results.m_ccs = 0; + astc_results.m_subsets = 1; + astc_results.m_partition_seed = 0; + astc_results.m_cem = 4; + + astc_results.m_endpoints[0] = ccell_results.m_astc_low_endpoint.m_c[0]; + astc_results.m_endpoints[1] = ccell_results.m_astc_high_endpoint.m_c[0]; + + astc_results.m_endpoints[2] = ccell_results.m_astc_low_endpoint.m_c[3]; + astc_results.m_endpoints[3] = ccell_results.m_astc_high_endpoint.m_c[3]; + + for (uint32_t y = 0; y < 4; y++) + for (uint32_t x = 0; x < 4; x++) + astc_results.m_weights[x + y * 4] = ccell_result_selectors[x + y * 4]; + + color_rgba colors[16]; + for (uint32_t c = 0; c < 4; c++) + { + colors[0].m_comps[c] = g_astc_unquant[endpoint_range][ccell_results.m_astc_low_endpoint.m_c[(c < 3) ? 0 : 3]].m_unquant; + colors[15].m_comps[c] = g_astc_unquant[endpoint_range][ccell_results.m_astc_high_endpoint.m_c[(c < 3) ? 0 : 3]].m_unquant; + } + + for (uint32_t i = 1; i < 16 - 1; i++) + for (uint32_t c = 0; c < 4; c++) + colors[i].m_comps[c] = (uint8_t)astc_interpolate(colors[0].m_comps[c], colors[15].m_comps[c], g_astc_weights4[i], false); + + uint64_t total_err = 0; + for (uint32_t p = 0; p < 16; p++) + total_err += color_distance_la(((const color_rgba*)block)[p], colors[ccell_result_selectors[p]]); + + assert(total_results < MAX_ENCODE_RESULTS); + if (total_results < MAX_ENCODE_RESULTS) + { + pResults[total_results].m_uastc_mode = 15; + pResults[total_results].m_common_pattern = 0; + pResults[total_results].m_astc = astc_results; + pResults[total_results].m_astc_err = total_err; + total_results++; + } + } + + static void compute_block_error(const color_rgba block[4][4], const color_rgba decoded_block[4][4], uint64_t &total_rgb_err, uint64_t &total_rgba_err, uint64_t &total_la_err) + { + uint64_t total_err_r = 0, total_err_g = 0, total_err_b = 0, total_err_a = 0; + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const int dr = (int)block[y][x].m_comps[0] - (int)decoded_block[y][x].m_comps[0]; + const int dg = (int)block[y][x].m_comps[1] - (int)decoded_block[y][x].m_comps[1]; + const int db = (int)block[y][x].m_comps[2] - (int)decoded_block[y][x].m_comps[2]; + const int da = (int)block[y][x].m_comps[3] - (int)decoded_block[y][x].m_comps[3]; + + total_err_r += dr * dr; + total_err_g += dg * dg; + total_err_b += db * db; + total_err_a += da * da; + } + } + + total_la_err = total_err_r + total_err_a; + total_rgb_err = total_err_r + total_err_g + total_err_b; + total_rgba_err = total_rgb_err + total_err_a; + } + + static void compute_bc1_hints(bool &bc1_hint0, bool &bc1_hint1, const uastc_encode_results &best_results, const color_rgba block[4][4], const color_rgba decoded_uastc_block[4][4]) + { + const uint32_t best_mode = best_results.m_uastc_mode; + const bool perceptual = false; + + bc1_hint0 = false; + bc1_hint1 = false; + + if (best_mode == UASTC_MODE_INDEX_SOLID_COLOR) + return; + + if (!g_uastc_mode_has_bc1_hint0[best_mode] && !g_uastc_mode_has_bc1_hint1[best_mode]) + return; + + color_rgba tblock_bc1[4][4]; + dxt1_block tbc1_block[8]; + basist::encode_bc1(tbc1_block, (const uint8_t*)&decoded_uastc_block[0][0], 0); + unpack_block(texture_format::cBC1, tbc1_block, &tblock_bc1[0][0]); + + color_rgba tblock_hint0_bc1[4][4]; + color_rgba tblock_hint1_bc1[4][4]; + + etc_block etc1_blk; + memset(&etc1_blk, 0, sizeof(etc1_blk)); + + eac_a8_block etc2_blk; + memset(&etc2_blk, 0, sizeof(etc2_blk)); + etc2_blk.m_multiplier = 1; + + // Pack to UASTC, then unpack, because the endpoints may be swapped. + + uastc_block temp_ublock; + pack_uastc(temp_ublock, best_results, etc1_blk, 0, etc2_blk, false, false); + + unpacked_uastc_block temp_ublock_unpacked; + unpack_uastc(temp_ublock, temp_ublock_unpacked, false); + + unpacked_uastc_block ublock; + memset(&ublock, 0, sizeof(ublock)); + ublock.m_mode = best_results.m_uastc_mode; + ublock.m_common_pattern = best_results.m_common_pattern; + ublock.m_astc = temp_ublock_unpacked.m_astc; + + dxt1_block b; + + // HINT1 + if (!g_uastc_mode_has_bc1_hint1[best_mode]) + { + memset(tblock_hint1_bc1, 0, sizeof(tblock_hint1_bc1)); + } + else + { + transcode_uastc_to_bc1_hint1(ublock, (color32 (*)[4]) decoded_uastc_block, &b, false); + + unpack_block(texture_format::cBC1, &b, &tblock_hint1_bc1[0][0]); + } + + // HINT0 + if (!g_uastc_mode_has_bc1_hint0[best_mode]) + { + memset(tblock_hint0_bc1, 0, sizeof(tblock_hint0_bc1)); + } + else + { + transcode_uastc_to_bc1_hint0(ublock, &b); + + unpack_block(texture_format::cBC1, &b, &tblock_hint0_bc1[0][0]); + } + + // Compute block errors + uint64_t total_t_err = 0, total_hint0_err = 0, total_hint1_err = 0; + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + total_t_err += color_distance(perceptual, block[y][x], tblock_bc1[y][x], false); + total_hint0_err += color_distance(perceptual, block[y][x], tblock_hint0_bc1[y][x], false); + total_hint1_err += color_distance(perceptual, block[y][x], tblock_hint1_bc1[y][x], false); + } + } + + const float t_err = sqrtf((float)total_t_err); + const float t_err_hint0 = sqrtf((float)total_hint0_err); + const float t_err_hint1 = sqrtf((float)total_hint1_err); + + const float err_thresh0 = 1.075f; + const float err_thresh1 = 1.075f; + + if ((g_uastc_mode_has_bc1_hint0[best_mode]) && (t_err_hint0 <= t_err * err_thresh0)) + bc1_hint0 = true; + + if ((g_uastc_mode_has_bc1_hint1[best_mode]) && (t_err_hint1 <= t_err * err_thresh1)) + bc1_hint1 = true; + } + + struct ycbcr + { + int32_t m_y; + int32_t m_cb; + int32_t m_cr; + }; + + static inline void rgb_to_y_cb_cr(const color_rgba& c, ycbcr& dst) + { + const int y = c.r * 54 + c.g * 183 + c.b * 19; + dst.m_y = y; + dst.m_cb = (c.b << 8) - y; + dst.m_cr = (c.r << 8) - y; + } + + static inline uint64_t color_diff(const ycbcr& a, const ycbcr& b) + { + const int y_delta = a.m_y - b.m_y; + const int cb_delta = a.m_cb - b.m_cb; + const int cr_delta = a.m_cr - b.m_cr; + return ((int64_t)y_delta * y_delta * 4) + ((int64_t)cr_delta * cr_delta) + ((int64_t)cb_delta * cb_delta); + } + + static inline int gray_distance2(const color_rgba& c, int r, int g, int b) + { + int gray_dist = (((int)c[0] - r) + ((int)c[1] - g) + ((int)c[2] - b) + 1) / 3; + + int gray_point_r = clamp255(r + gray_dist); + int gray_point_g = clamp255(g + gray_dist); + int gray_point_b = clamp255(b + gray_dist); + + int dist_to_gray_point_r = c[0] - gray_point_r; + int dist_to_gray_point_g = c[1] - gray_point_g; + int dist_to_gray_point_b = c[2] - gray_point_b; + + return (dist_to_gray_point_r * dist_to_gray_point_r) + (dist_to_gray_point_g * dist_to_gray_point_g) + (dist_to_gray_point_b * dist_to_gray_point_b); + } + + static bool pack_etc1_estimate_flipped(const color_rgba* pSrc_pixels) + { + int sums[3][2][2]; + +#define GET_XY(x, y, c) pSrc_pixels[(x) + ((y) * 4)][c] + + for (uint32_t c = 0; c < 3; c++) + { + sums[c][0][0] = GET_XY(0, 0, c) + GET_XY(0, 1, c) + GET_XY(1, 0, c) + GET_XY(1, 1, c); + sums[c][1][0] = GET_XY(2, 0, c) + GET_XY(2, 1, c) + GET_XY(3, 0, c) + GET_XY(3, 1, c); + sums[c][0][1] = GET_XY(0, 2, c) + GET_XY(0, 3, c) + GET_XY(1, 2, c) + GET_XY(1, 3, c); + sums[c][1][1] = GET_XY(2, 2, c) + GET_XY(2, 3, c) + GET_XY(3, 2, c) + GET_XY(3, 3, c); + } + + int upper_avg[3], lower_avg[3], left_avg[3], right_avg[3]; + for (uint32_t c = 0; c < 3; c++) + { + upper_avg[c] = (sums[c][0][0] + sums[c][1][0] + 4) / 8; + lower_avg[c] = (sums[c][0][1] + sums[c][1][1] + 4) / 8; + left_avg[c] = (sums[c][0][0] + sums[c][0][1] + 4) / 8; + right_avg[c] = (sums[c][1][0] + sums[c][1][1] + 4) / 8; + } + +#undef GET_XY +#define GET_XY(x, y, a) gray_distance2(pSrc_pixels[(x) + ((y) * 4)], a[0], a[1], a[2]) + + int upper_gray_dist = 0, lower_gray_dist = 0, left_gray_dist = 0, right_gray_dist = 0; + for (uint32_t i = 0; i < 4; i++) + { + for (uint32_t j = 0; j < 2; j++) + { + upper_gray_dist += GET_XY(i, j, upper_avg); + lower_gray_dist += GET_XY(i, 2 + j, lower_avg); + left_gray_dist += GET_XY(j, i, left_avg); + right_gray_dist += GET_XY(2 + j, i, right_avg); + } + } + +#undef GET_XY + + int upper_lower_sum = upper_gray_dist + lower_gray_dist; + int left_right_sum = left_gray_dist + right_gray_dist; + + return upper_lower_sum < left_right_sum; + } + + static void compute_etc1_hints(etc_block& best_etc1_blk, uint32_t& best_etc1_bias, const uastc_encode_results& best_results, const color_rgba block[4][4], const color_rgba decoded_uastc_block[4][4], int level, uint32_t flags) + { + best_etc1_bias = 0; + + if (best_results.m_uastc_mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + pack_etc1_block_solid_color(best_etc1_blk, &best_results.m_solid_color.m_comps[0]); + return; + } + + const bool faster_etc1 = (flags & cPackUASTCETC1FasterHints) != 0; + const bool fastest_etc1 = (flags & cPackUASTCETC1FastestHints) != 0; + + const bool has_bias = g_uastc_mode_has_etc1_bias[best_results.m_uastc_mode]; + + // 0 should be at the top, but we need 13 first because it represents bias (0,0,0). + const uint8_t s_sorted_bias_modes[32] = { 13, 0, 22, 29, 27, 12, 26, 9, 30, 31, 8, 10, 25, 2, 23, 5, 15, 7, 3, 11, 6, 17, 28, 18, 1, 19, 20, 21, 24, 4, 14, 16 }; + + uint32_t last_bias = 1; + bool use_faster_bias_mode_table = false; + const bool flip_estimate = (level <= cPackUASTCLevelFaster) || (faster_etc1) || (fastest_etc1); + if (has_bias) + { + switch (level) + { + case cPackUASTCLevelFastest: + { + last_bias = fastest_etc1 ? 1 : (faster_etc1 ? 1 : 2); + use_faster_bias_mode_table = true; + break; + } + case cPackUASTCLevelFaster: + { + last_bias = fastest_etc1 ? 1 : (faster_etc1 ? 3 : 5); + use_faster_bias_mode_table = true; + break; + } + case cPackUASTCLevelDefault: + { + last_bias = fastest_etc1 ? 1 : (faster_etc1 ? 10 : 20); + use_faster_bias_mode_table = true; + break; + } + case cPackUASTCLevelSlower: + { + last_bias = fastest_etc1 ? 1 : (faster_etc1 ? 16 : 32); + use_faster_bias_mode_table = true; + break; + } + default: + { + last_bias = 32; + break; + } + } + } + + memset(&best_etc1_blk, 0, sizeof(best_etc1_blk)); + uint64_t best_err = UINT64_MAX; + + etc_block trial_block; + memset(&trial_block, 0, sizeof(trial_block)); + + ycbcr block_ycbcr[4][4], decoded_uastc_block_ycbcr[4][4]; + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + rgb_to_y_cb_cr(block[y][x], block_ycbcr[y][x]); + rgb_to_y_cb_cr(decoded_uastc_block[y][x], decoded_uastc_block_ycbcr[y][x]); + } + } + + uint32_t first_flip = 0, last_flip = 2; + uint32_t first_individ = 0, last_individ = 2; + + if (flags & cPackUASTCETC1DisableFlipAndIndividual) + { + last_flip = 1; + last_individ = 1; + } + else if (flip_estimate) + { + if (pack_etc1_estimate_flipped(&decoded_uastc_block[0][0])) + first_flip = 1; + last_flip = first_flip + 1; + } + + for (uint32_t flip = first_flip; flip < last_flip; flip++) + { + trial_block.set_flip_bit(flip != 0); + + for (uint32_t individ = first_individ; individ < last_individ; individ++) + { + const uint32_t mul = individ ? 15 : 31; + + trial_block.set_diff_bit(individ == 0); + + color_rgba unbiased_block_colors[2]; + + int min_r[2] = { 255, 255 }, min_g[2] = { 255, 255 }, min_b[2] = { 255, 255 }, max_r[2] = { 0, 0 }, max_g[2] = { 0, 0 }, max_b[2] = { 0, 0 }; + + for (uint32_t subset = 0; subset < 2; subset++) + { + uint32_t avg_color[3]; + memset(avg_color, 0, sizeof(avg_color)); + + for (uint32_t j = 0; j < 8; j++) + { + const etc_coord2 &c = g_etc1_pixel_coords[flip][subset][j]; + const color_rgba& p = decoded_uastc_block[c.m_y][c.m_x]; + + avg_color[0] += p.r; + avg_color[1] += p.g; + avg_color[2] += p.b; + + min_r[subset] = basisu::minimum<uint32_t>(min_r[subset], p.r); + min_g[subset] = basisu::minimum<uint32_t>(min_g[subset], p.g); + min_b[subset] = basisu::minimum<uint32_t>(min_b[subset], p.b); + + max_r[subset] = basisu::maximum<uint32_t>(max_r[subset], p.r); + max_g[subset] = basisu::maximum<uint32_t>(max_g[subset], p.g); + max_b[subset] = basisu::maximum<uint32_t>(max_b[subset], p.b); + } // j + + unbiased_block_colors[subset][0] = (uint8_t)((avg_color[0] * mul + 1020) / (8 * 255)); + unbiased_block_colors[subset][1] = (uint8_t)((avg_color[1] * mul + 1020) / (8 * 255)); + unbiased_block_colors[subset][2] = (uint8_t)((avg_color[2] * mul + 1020) / (8 * 255)); + unbiased_block_colors[subset][3] = 0; + + } // subset + + for (uint32_t bias_iter = 0; bias_iter < last_bias; bias_iter++) + { + const uint32_t bias = use_faster_bias_mode_table ? s_sorted_bias_modes[bias_iter] : bias_iter; + + color_rgba block_colors[2]; + for (uint32_t subset = 0; subset < 2; subset++) + block_colors[subset] = has_bias ? apply_etc1_bias((color32&)unbiased_block_colors[subset], bias, mul, subset) : unbiased_block_colors[subset]; + + if (individ) + trial_block.set_block_color4(block_colors[0], block_colors[1]); + else + trial_block.set_block_color5_clamp(block_colors[0], block_colors[1]); + + uint32_t range[2]; + for (uint32_t subset = 0; subset < 2; subset++) + { + const color_rgba base_c(trial_block.get_block_color(subset, true)); + + const int pos_r = iabs(max_r[subset] - base_c.r); + const int neg_r = iabs(base_c.r - min_r[subset]); + + const int pos_g = iabs(max_g[subset] - base_c.g); + const int neg_g = iabs(base_c.g - min_g[subset]); + + const int pos_b = iabs(max_b[subset] - base_c.b); + const int neg_b = iabs(base_c.b - min_b[subset]); + + range[subset] = maximum(maximum(pos_r, neg_r, pos_g, neg_g), pos_b, neg_b); + } + + uint32_t best_inten_table[2] = { 0, 0 }; + + for (uint32_t subset = 0; subset < 2; subset++) + { + uint64_t best_subset_err = UINT64_MAX; + + const uint32_t inten_table_limit = (level == cPackUASTCLevelVerySlow) ? 8 : ((range[subset] > 51) ? 8 : (range[subset] >= 7 ? 4 : 2)); + + for (uint32_t inten_table = 0; inten_table < inten_table_limit; inten_table++) + { + trial_block.set_inten_table(subset, inten_table); + + color_rgba color_table[4]; + trial_block.get_block_colors(color_table, subset); + + ycbcr color_table_ycbcr[4]; + for (uint32_t i = 0; i < 4; i++) + rgb_to_y_cb_cr(color_table[i], color_table_ycbcr[i]); + + uint64_t total_error = 0; + if (flip) + { + for (uint32_t y = 0; y < 2; y++) + { + { + const ycbcr& c = decoded_uastc_block_ycbcr[subset * 2 + y][0]; + total_error += minimum(color_diff(color_table_ycbcr[0], c), color_diff(color_table_ycbcr[1], c), color_diff(color_table_ycbcr[2], c), color_diff(color_table_ycbcr[3], c)); + } + { + const ycbcr& c = decoded_uastc_block_ycbcr[subset * 2 + y][1]; + total_error += minimum(color_diff(color_table_ycbcr[0], c), color_diff(color_table_ycbcr[1], c), color_diff(color_table_ycbcr[2], c), color_diff(color_table_ycbcr[3], c)); + } + { + const ycbcr& c = decoded_uastc_block_ycbcr[subset * 2 + y][2]; + total_error += minimum(color_diff(color_table_ycbcr[0], c), color_diff(color_table_ycbcr[1], c), color_diff(color_table_ycbcr[2], c), color_diff(color_table_ycbcr[3], c)); + } + { + const ycbcr& c = decoded_uastc_block_ycbcr[subset * 2 + y][3]; + total_error += minimum(color_diff(color_table_ycbcr[0], c), color_diff(color_table_ycbcr[1], c), color_diff(color_table_ycbcr[2], c), color_diff(color_table_ycbcr[3], c)); + } + if (total_error >= best_subset_err) + break; + } + } + else + { + for (uint32_t y = 0; y < 4; y++) + { + { + const ycbcr& c = decoded_uastc_block_ycbcr[y][subset * 2 + 0]; + total_error += minimum(color_diff(color_table_ycbcr[0], c), color_diff(color_table_ycbcr[1], c), color_diff(color_table_ycbcr[2], c), color_diff(color_table_ycbcr[3], c)); + } + { + const ycbcr& c = decoded_uastc_block_ycbcr[y][subset * 2 + 1]; + total_error += minimum(color_diff(color_table_ycbcr[0], c), color_diff(color_table_ycbcr[1], c), color_diff(color_table_ycbcr[2], c), color_diff(color_table_ycbcr[3], c)); + } + } + if (total_error >= best_subset_err) + break; + } + + if (total_error < best_subset_err) + { + best_subset_err = total_error; + best_inten_table[subset] = inten_table; + } + + } // inten_table + + } // subset + + trial_block.set_inten_table(0, best_inten_table[0]); + trial_block.set_inten_table(1, best_inten_table[1]); + + // Compute error against the ORIGINAL block. + uint64_t err = 0; + + for (uint32_t subset = 0; subset < 2; subset++) + { + color_rgba color_table[4]; + trial_block.get_block_colors(color_table, subset); + + ycbcr color_table_ycbcr[4]; + for (uint32_t i = 0; i < 4; i++) + rgb_to_y_cb_cr(color_table[i], color_table_ycbcr[i]); + + if (flip) + { + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const ycbcr& c = decoded_uastc_block_ycbcr[subset * 2 + y][x]; + const uint64_t best_index_err = minimum(color_diff(color_table_ycbcr[0], c) << 2, (color_diff(color_table_ycbcr[1], c) << 2) + 1, (color_diff(color_table_ycbcr[2], c) << 2) + 2, (color_diff(color_table_ycbcr[3], c) << 2) + 3); + + const uint32_t best_index = (uint32_t)best_index_err & 3; + err += color_diff(block_ycbcr[subset * 2 + y][x], color_table_ycbcr[best_index]); + } + if (err >= best_err) + break; + } + } + else + { + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 2; x++) + { + const ycbcr& c = decoded_uastc_block_ycbcr[y][subset * 2 + x]; + const uint64_t best_index_err = minimum(color_diff(color_table_ycbcr[0], c) << 2, (color_diff(color_table_ycbcr[1], c) << 2) + 1, (color_diff(color_table_ycbcr[2], c) << 2) + 2, (color_diff(color_table_ycbcr[3], c) << 2) + 3); + + const uint32_t best_index = (uint32_t)best_index_err & 3; + err += color_diff(block_ycbcr[y][subset * 2 + x], color_table_ycbcr[best_index]); + } + if (err >= best_err) + break; + } + } + + } // subset + + if (err < best_err) + { + best_err = err; + + best_etc1_blk = trial_block; + best_etc1_bias = bias; + } + + } // bias_iter + + } // individ + + } // flip + } + + struct uastc_pack_eac_a8_results + { + uint32_t m_base; + uint32_t m_table; + uint32_t m_multiplier; + }; + + static uint64_t uastc_pack_eac_a8(uastc_pack_eac_a8_results& results, const uint8_t* pPixels, uint32_t num_pixels, uint32_t base_search_rad, uint32_t mul_search_rad, uint32_t table_mask) + { + assert(num_pixels <= 16); + + uint32_t min_alpha = 255, max_alpha = 0; + for (uint32_t i = 0; i < num_pixels; i++) + { + const uint32_t a = pPixels[i]; + if (a < min_alpha) min_alpha = a; + if (a > max_alpha) max_alpha = a; + } + + if (min_alpha == max_alpha) + { + results.m_base = min_alpha; + results.m_table = 13; + results.m_multiplier = 1; + return 0; + } + + const uint32_t alpha_range = max_alpha - min_alpha; + + uint64_t best_err = UINT64_MAX; + + for (uint32_t table = 0; table < 16; table++) + { + if ((table_mask & (1U << table)) == 0) + continue; + + const float range = (float)(g_etc2_eac_tables[table][ETC2_EAC_MAX_VALUE_SELECTOR] - g_etc2_eac_tables[table][ETC2_EAC_MIN_VALUE_SELECTOR]); + const int center = (int)roundf(lerp((float)min_alpha, (float)max_alpha, (float)(0 - g_etc2_eac_tables[table][ETC2_EAC_MIN_VALUE_SELECTOR]) / range)); + + const int base_min = clamp255(center - base_search_rad); + const int base_max = clamp255(center + base_search_rad); + + const int mul = (int)roundf(alpha_range / range); + const int mul_low = clamp<int>(mul - mul_search_rad, 1, 15); + const int mul_high = clamp<int>(mul + mul_search_rad, 1, 15); + + for (int base = base_min; base <= base_max; base++) + { + for (int multiplier = mul_low; multiplier <= mul_high; multiplier++) + { + uint64_t total_err = 0; + + for (uint32_t i = 0; i < num_pixels; i++) + { + const int a = pPixels[i]; + + uint32_t best_s_err = UINT32_MAX; + //uint32_t best_s = 0; + for (uint32_t s = 0; s < 8; s++) + { + const int v = clamp255((int)multiplier * g_etc2_eac_tables[table][s] + (int)base); + + uint32_t err = iabs(a - v); + if (err < best_s_err) + { + best_s_err = err; + //best_s = s; + } + } + + total_err += best_s_err * best_s_err; + if (total_err >= best_err) + break; + } + + if (total_err < best_err) + { + best_err = total_err; + results.m_base = base; + results.m_multiplier = multiplier; + results.m_table = table; + if (!best_err) + return best_err; + } + + } // table + + } // multiplier + + } // base + + return best_err; + } + + const int32_t DEFAULT_BC7_ERROR_WEIGHT = 50; + const float UASTC_ERROR_THRESH = 1.3f; + + // TODO: This is a quick hack to favor certain modes when we know we'll be followed up with an RDO postprocess. + static inline float get_uastc_mode_weight(uint32_t mode) + { + const float FAVORED_MODE_WEIGHT = .8f; + + switch (mode) + { + case 0: + case 10: + return FAVORED_MODE_WEIGHT; + default: + break; + } + + return 1.0f; + } + + void encode_uastc(const uint8_t* pRGBAPixels, uastc_block& output_block, uint32_t flags) + { +// printf("encode_uastc: \n"); +// for (int i = 0; i < 16; i++) +// printf("[%u %u %u %u] ", pRGBAPixels[i * 4 + 0], pRGBAPixels[i * 4 + 1], pRGBAPixels[i * 4 + 2], pRGBAPixels[i * 4 + 3]); +// printf("\n"); + + const color_rgba(*block)[4] = reinterpret_cast<const color_rgba(*)[4]>(pRGBAPixels); + + bool solid_color = true, has_alpha = false, is_la = true; + + const color_rgba first_color(block[0][0]); + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + if (block[y][x].a < 255) + has_alpha = true; + + if (block[y][x] != first_color) + solid_color = false; + + if ((block[y][x].r != block[y][x].g) || (block[y][x].r != block[y][x].b)) + is_la = false; + } + } + + if (solid_color) + { + // Solid color blocks are so common that we handle them specially and as quickly as we can. + uastc_encode_results solid_results; + solid_results.m_uastc_mode = UASTC_MODE_INDEX_SOLID_COLOR; + solid_results.m_astc_err = 0; + solid_results.m_common_pattern = 0; + solid_results.m_solid_color = first_color; + memset(&solid_results.m_astc, 0, sizeof(solid_results.m_astc)); + + etc_block etc1_blk; + uint32_t etc1_bias = 0; + + pack_etc1_block_solid_color(etc1_blk, &first_color.m_comps[0]); + + eac_a8_block eac_a8_blk; + eac_a8_blk.m_table = 0; + eac_a8_blk.m_multiplier = 1; + + pack_uastc(output_block, solid_results, etc1_blk, etc1_bias, eac_a8_blk, false, false); + +// printf(" Solid\n"); + + return; + } + + int level = flags & 7; + const bool favor_uastc_error = (flags & cPackUASTCFavorUASTCError) != 0; + const bool favor_bc7_error = !favor_uastc_error && ((flags & cPackUASTCFavorBC7Error) != 0); + //const bool etc1_perceptual = true; + + uastc_encode_results results[MAX_ENCODE_RESULTS]; + + level = clampi(level, cPackUASTCLevelFastest, cPackUASTCLevelVerySlow); + + // Set all options to slowest, then configure from there depending on the selected level. + uint32_t mode_mask = UINT32_MAX; + uint32_t uber_level = 6; + bool estimate_partition = false; + bool always_try_alpha_modes = true; + uint32_t eac_a8_mul_search_rad = 3; + uint32_t eac_a8_table_mask = UINT32_MAX; + uint32_t least_squares_passes = 2; + bool bc1_hints = true; + bool only_use_la_on_transparent_blocks = false; + + switch (level) + { + case cPackUASTCLevelFastest: + { + mode_mask = (1 << 0) | (1 << 8) | + (1 << 11) | (1 << 12) | + (1 << 15); + always_try_alpha_modes = false; + eac_a8_mul_search_rad = 0; + eac_a8_table_mask = (1 << 2) | (1 << 8) | (1 << 11) | (1 << 13); + uber_level = 0; + least_squares_passes = 1; + bc1_hints = false; + estimate_partition = true; + only_use_la_on_transparent_blocks = true; + break; + } + case cPackUASTCLevelFaster: + { + mode_mask = (1 << 0) | (1 << 4) | (1 << 6) | (1 << 8) | + (1 << 9) | (1 << 11) | (1 << 12) | + (1 << 15) | (1 << 17); + always_try_alpha_modes = false; + eac_a8_mul_search_rad = 0; + eac_a8_table_mask = (1 << 2) | (1 << 8) | (1 << 11) | (1 << 13); + uber_level = 0; + least_squares_passes = 1; + estimate_partition = true; + break; + } + case cPackUASTCLevelDefault: + { + mode_mask = (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 8) | + (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | + (1 << 15) | (1 << 16) | (1 << 17); + always_try_alpha_modes = false; + eac_a8_mul_search_rad = 1; + eac_a8_table_mask = (1 << 0) | (1 << 2) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 10) | (1 << 11) | (1 << 13); + uber_level = 1; + least_squares_passes = 1; + estimate_partition = true; + break; + } + case cPackUASTCLevelSlower: + { + always_try_alpha_modes = false; + eac_a8_mul_search_rad = 2; + uber_level = 3; + estimate_partition = true; + break; + } + case cPackUASTCLevelVerySlow: + { + break; + } + } + +#if BASISU_SUPPORT_FORCE_MODE + static int force_mode = -1; + force_mode = (force_mode + 1) % TOTAL_UASTC_MODES; + mode_mask = UINT32_MAX; + always_try_alpha_modes = true; + only_use_la_on_transparent_blocks = false; +#endif + + // HACK HACK + //mode_mask &= ~(1 << 18); + //mode_mask = (1 << 18)| (1 << 10); + + uint32_t total_results = 0; + + if (only_use_la_on_transparent_blocks) + { + if ((is_la) && (!has_alpha)) + is_la = false; + } + + const bool try_alpha_modes = has_alpha || always_try_alpha_modes; + + bc7enc_compress_block_params comp_params; + memset(&comp_params, 0, sizeof(comp_params)); + comp_params.m_max_partitions_mode1 = 64; + comp_params.m_least_squares_passes = least_squares_passes; + comp_params.m_weights[0] = 1; + comp_params.m_weights[1] = 1; + comp_params.m_weights[2] = 1; + comp_params.m_weights[3] = 1; + comp_params.m_uber_level = uber_level; + + if (is_la) + { + if (mode_mask & (1U << 15)) + astc_mode15(block, results, total_results, comp_params); + + if (mode_mask & (1U << 16)) + astc_mode9_or_16(16, block, results, total_results, comp_params, estimate_partition ? 4 : 0); + + if (mode_mask & (1U << 17)) + astc_mode11_or_17(17, block, results, total_results, comp_params); + } + + if (!has_alpha) + { + if (mode_mask & (1U << 0)) + astc_mode0_or_18(0, block, results, total_results, comp_params); + + if (mode_mask & (1U << 1)) + astc_mode1(block, results, total_results, comp_params); + + if (mode_mask & (1U << 2)) + astc_mode2(block, results, total_results, comp_params, estimate_partition); + + if (mode_mask & (1U << 3)) + astc_mode3(block, results, total_results, comp_params, estimate_partition); + + if (mode_mask & (1U << 4)) + astc_mode4(block, results, total_results, comp_params, estimate_partition); + + if (mode_mask & (1U << 5)) + astc_mode5(block, results, total_results, comp_params); + + if (mode_mask & (1U << 6)) + astc_mode6(block, results, total_results, comp_params); + + if (mode_mask & (1U << 7)) + astc_mode7(block, results, total_results, comp_params, estimate_partition); + + if (mode_mask & (1U << 18)) + astc_mode0_or_18(18, block, results, total_results, comp_params); + } + + if (try_alpha_modes) + { + if (mode_mask & (1U << 9)) + astc_mode9_or_16(9, block, results, total_results, comp_params, estimate_partition ? 4 : 0); + + if (mode_mask & (1U << 10)) + astc_mode10(block, results, total_results, comp_params); + + if (mode_mask & (1U << 11)) + astc_mode11_or_17(11, block, results, total_results, comp_params); + + if (mode_mask & (1U << 12)) + astc_mode12(block, results, total_results, comp_params); + + if (mode_mask & (1U << 13)) + astc_mode13(block, results, total_results, comp_params); + + if (mode_mask & (1U << 14)) + astc_mode14(block, results, total_results, comp_params); + } + + assert(total_results); + + // Fix up the errors so we consistently have LA, RGB, or RGBA error. + for (uint32_t i = 0; i < total_results; i++) + { + uastc_encode_results& r = results[i]; + if (!is_la) + { + if (g_uastc_mode_is_la[r.m_uastc_mode]) + { + color_rgba unpacked_block[16]; + unpack_uastc(r.m_uastc_mode, r.m_common_pattern, r.m_solid_color.get_color32(), r.m_astc, (basist::color32 *)unpacked_block, false); + + uint64_t total_err = 0; + for (uint32_t j = 0; j < 16; j++) + total_err += color_distance(unpacked_block[j], ((const color_rgba*)block)[j], true); + + r.m_astc_err = total_err; + } + } + else + { + if (!g_uastc_mode_is_la[r.m_uastc_mode]) + { + color_rgba unpacked_block[16]; + unpack_uastc(r.m_uastc_mode, r.m_common_pattern, r.m_solid_color.get_color32(), r.m_astc, (basist::color32 *)unpacked_block, false); + + uint64_t total_err = 0; + for (uint32_t j = 0; j < 16; j++) + total_err += color_distance_la(unpacked_block[j], ((const color_rgba*)block)[j]); + + r.m_astc_err = total_err; + } + } + } + + unpacked_uastc_block unpacked_ublock; + memset(&unpacked_ublock, 0, sizeof(unpacked_ublock)); + + uint64_t total_overall_err[MAX_ENCODE_RESULTS]; + float uastc_err_f[MAX_ENCODE_RESULTS]; + double best_uastc_err_f = 1e+20f; + + int best_index = -1; + + if (total_results == 1) + { + best_index = 0; + } + else + { + const uint32_t bc7_err_weight = favor_bc7_error ? 100 : ((favor_uastc_error ? 0 : DEFAULT_BC7_ERROR_WEIGHT)); + const uint32_t uastc_err_weight = favor_bc7_error ? 0 : 100; + + // Find best overall results, balancing UASTC and UASTC->BC7 error. + // We purposely allow UASTC error to increase a little, if doing so lowers the BC7 error. + for (uint32_t i = 0; i < total_results; i++) + { +#if BASISU_SUPPORT_FORCE_MODE + if (results[i].m_uastc_mode == force_mode) + { + best_index = i; + break; + } +#endif + + unpacked_ublock.m_mode = results[i].m_uastc_mode; + unpacked_ublock.m_astc = results[i].m_astc; + unpacked_ublock.m_common_pattern = results[i].m_common_pattern; + unpacked_ublock.m_solid_color = results[i].m_solid_color.get_color32(); + + color_rgba decoded_uastc_block[4][4]; + bool success = unpack_uastc(results[i].m_uastc_mode, results[i].m_common_pattern, results[i].m_solid_color.get_color32(), results[i].m_astc, (basist::color32 *)&decoded_uastc_block[0][0], false); + (void)success; + VALIDATE(success); + + uint64_t total_uastc_rgb_err, total_uastc_rgba_err, total_uastc_la_err; + compute_block_error(block, decoded_uastc_block, total_uastc_rgb_err, total_uastc_rgba_err, total_uastc_la_err); + + // Validate the computed error, or we're go mad if it's inaccurate. + if (results[i].m_uastc_mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + VALIDATE(total_uastc_rgba_err == 0); + } + else if (is_la) + { + VALIDATE(total_uastc_la_err == results[i].m_astc_err); + } + else if (g_uastc_mode_has_alpha[results[i].m_uastc_mode]) + { + VALIDATE(total_uastc_rgba_err == results[i].m_astc_err); + } + else + { + VALIDATE(total_uastc_rgb_err == results[i].m_astc_err); + } + + // Transcode to BC7 + bc7_optimization_results bc7_results; + transcode_uastc_to_bc7(unpacked_ublock, bc7_results); + + bc7_block bc7_data; + encode_bc7_block(&bc7_data, &bc7_results); + + color_rgba decoded_bc7_block[4][4]; + unpack_block(texture_format::cBC7, &bc7_data, &decoded_bc7_block[0][0]); + + // Compute BC7 error + uint64_t total_bc7_la_err, total_bc7_rgb_err, total_bc7_rgba_err; + compute_block_error(block, decoded_bc7_block, total_bc7_rgb_err, total_bc7_rgba_err, total_bc7_la_err); + + if (results[i].m_uastc_mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + VALIDATE(total_bc7_rgba_err == 0); + + best_index = i; + break; + } + + uint64_t total_uastc_err = 0, total_bc7_err = 0; + if (is_la) + { + total_bc7_err = total_bc7_la_err; + total_uastc_err = total_uastc_la_err; + } + else if (has_alpha) + { + total_bc7_err = total_bc7_rgba_err; + total_uastc_err = total_uastc_rgba_err; + } + else + { + total_bc7_err = total_bc7_rgb_err; + total_uastc_err = total_uastc_rgb_err; + } + + total_overall_err[i] = ((total_bc7_err * bc7_err_weight) / 100) + ((total_uastc_err * uastc_err_weight) / 100); + if (!total_overall_err[i]) + { + best_index = i; + break; + } + + uastc_err_f[i] = sqrtf((float)total_uastc_err); + + if (uastc_err_f[i] < best_uastc_err_f) + { + best_uastc_err_f = uastc_err_f[i]; + } + + } // total_results + + if (best_index < 0) + { + uint64_t best_err = UINT64_MAX; + + if ((best_uastc_err_f == 0.0f) || (favor_bc7_error)) + { + for (uint32_t i = 0; i < total_results; i++) + { + // TODO: This is a quick hack to favor modes 0 or 10 for better RDO compression. + const float err_weight = (flags & cPackUASTCFavorSimplerModes) ? get_uastc_mode_weight(results[i].m_uastc_mode) : 1.0f; + + const uint64_t w = (uint64_t)(total_overall_err[i] * err_weight); + if (w < best_err) + { + best_err = w; + best_index = i; + if (!best_err) + break; + } + } // i + } + else + { + // Scan the UASTC results, and consider all results within a window that has the best UASTC+BC7 error. + for (uint32_t i = 0; i < total_results; i++) + { + double err_delta = uastc_err_f[i] / best_uastc_err_f; + + if (err_delta <= UASTC_ERROR_THRESH) + { + // TODO: This is a quick hack to favor modes 0 or 10 for better RDO compression. + const float err_weight = (flags & cPackUASTCFavorSimplerModes) ? get_uastc_mode_weight(results[i].m_uastc_mode) : 1.0f; + + const uint64_t w = (uint64_t)(total_overall_err[i] * err_weight); + if (w < best_err) + { + best_err = w; + best_index = i; + if (!best_err) + break; + } + } + } // i + } + } + } + + const uastc_encode_results& best_results = results[best_index]; + const uint32_t best_mode = best_results.m_uastc_mode; + const astc_block_desc& best_astc_results = best_results.m_astc; + + color_rgba decoded_uastc_block[4][4]; + bool success = unpack_uastc(best_mode, best_results.m_common_pattern, best_results.m_solid_color.get_color32(), best_astc_results, (basist::color32 *)&decoded_uastc_block[0][0], false); + (void)success; + VALIDATE(success); + +#if BASISU_VALIDATE_UASTC_ENC + // Make sure that the UASTC block unpacks to the same exact pixels as the ASTC block does, using two different decoders. + { + // Round trip to packed UASTC and back, then decode to pixels. + etc_block etc1_blk; + memset(&etc1_blk, 0, sizeof(etc1_blk)); + eac_a8_block etc_eac_a8_blk; + memset(&etc_eac_a8_blk, 0, sizeof(etc_eac_a8_blk)); + etc_eac_a8_blk.m_multiplier = 1; + + basist::uastc_block temp_block; + pack_uastc(temp_block, best_results, etc1_blk, 0, etc_eac_a8_blk, false, false); + + basist::color32 temp_block_unpacked[4][4]; + success = basist::unpack_uastc(temp_block, (basist::color32 *)temp_block_unpacked, false); + VALIDATE(success); + + // Now round trip to packed ASTC and back, then decode to pixels. + uint32_t astc_data[4]; + + if (best_results.m_uastc_mode == UASTC_MODE_INDEX_SOLID_COLOR) + pack_astc_solid_block(astc_data, (color32 &)best_results.m_solid_color); + else + { + success = pack_astc_block(astc_data, &best_astc_results, best_results.m_uastc_mode); + VALIDATE(success); + } + + color_rgba decoded_astc_block[4][4]; + success = basisu_astc::astc::decompress((uint8_t*)decoded_astc_block, (uint8_t*)&astc_data, false, 4, 4); + VALIDATE(success); + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + VALIDATE(decoded_astc_block[y][x] == decoded_uastc_block[y][x]); + + VALIDATE(temp_block_unpacked[y][x].c[0] == decoded_uastc_block[y][x].r); + VALIDATE(temp_block_unpacked[y][x].c[1] == decoded_uastc_block[y][x].g); + VALIDATE(temp_block_unpacked[y][x].c[2] == decoded_uastc_block[y][x].b); + VALIDATE(temp_block_unpacked[y][x].c[3] == decoded_uastc_block[y][x].a); + } + } + } +#endif + + // Compute BC1 hints + bool bc1_hint0 = false, bc1_hint1 = false; + if (bc1_hints) + compute_bc1_hints(bc1_hint0, bc1_hint1, best_results, block, decoded_uastc_block); + + eac_a8_block eac_a8_blk; + if ((g_uastc_mode_has_alpha[best_mode]) && (best_mode != UASTC_MODE_INDEX_SOLID_COLOR)) + { + // Compute ETC2 hints + uint8_t decoded_uastc_block_alpha[16]; + for (uint32_t i = 0; i < 16; i++) + decoded_uastc_block_alpha[i] = decoded_uastc_block[i >> 2][i & 3].a; + + uastc_pack_eac_a8_results eac8_a8_results; + memset(&eac8_a8_results, 0, sizeof(eac8_a8_results)); + uastc_pack_eac_a8(eac8_a8_results, decoded_uastc_block_alpha, 16, 0, eac_a8_mul_search_rad, eac_a8_table_mask); + + // All we care about for hinting is the table and multiplier. + eac_a8_blk.m_table = eac8_a8_results.m_table; + eac_a8_blk.m_multiplier = eac8_a8_results.m_multiplier; + } + else + { + memset(&eac_a8_blk, 0, sizeof(eac_a8_blk)); + } + + // Compute ETC1 hints + etc_block etc1_blk; + uint32_t etc1_bias = 0; + compute_etc1_hints(etc1_blk, etc1_bias, best_results, block, decoded_uastc_block, level, flags); + + // Finally, pack the UASTC block with its hints and we're done. + pack_uastc(output_block, best_results, etc1_blk, etc1_bias, eac_a8_blk, bc1_hint0, bc1_hint1); + +// printf(" Packed: "); +// for (int i = 0; i < 16; i++) +// printf("%X ", output_block.m_bytes[i]); +// printf("\n"); + } + + static bool uastc_recompute_hints(basist::uastc_block* pBlock, const color_rgba* pBlock_pixels, uint32_t flags, const unpacked_uastc_block *pUnpacked_blk) + { + unpacked_uastc_block unpacked_blk; + + if (pUnpacked_blk) + unpacked_blk = *pUnpacked_blk; + else + { + if (!unpack_uastc(*pBlock, unpacked_blk, false, true)) + return false; + } + color_rgba decoded_uastc_block[4][4]; + if (!unpack_uastc(unpacked_blk, (basist::color32 *)decoded_uastc_block, false)) + return false; + uastc_encode_results results; + results.m_uastc_mode = unpacked_blk.m_mode; + results.m_common_pattern = unpacked_blk.m_common_pattern; + results.m_astc = unpacked_blk.m_astc; + results.m_solid_color = unpacked_blk.m_solid_color; + results.m_astc_err = 0; + bool bc1_hints = true; + uint32_t eac_a8_mul_search_rad = 3; + uint32_t eac_a8_table_mask = UINT32_MAX; + const uint32_t level = flags & cPackUASTCLevelMask; + switch (level) + { + case cPackUASTCLevelFastest: + { + eac_a8_mul_search_rad = 0; + eac_a8_table_mask = (1 << 2) | (1 << 8) | (1 << 11) | (1 << 13); + bc1_hints = false; + break; + } + case cPackUASTCLevelFaster: + { + eac_a8_mul_search_rad = 0; + eac_a8_table_mask = (1 << 2) | (1 << 8) | (1 << 11) | (1 << 13); + break; + } + case cPackUASTCLevelDefault: + { + eac_a8_mul_search_rad = 1; + eac_a8_table_mask = (1 << 0) | (1 << 2) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 10) | (1 << 11) | (1 << 13); + break; + } + case cPackUASTCLevelSlower: + { + eac_a8_mul_search_rad = 2; + break; + } + case cPackUASTCLevelVerySlow: + { + break; + } + } + bool bc1_hint0 = false, bc1_hint1 = false; + if (bc1_hints) + compute_bc1_hints(bc1_hint0, bc1_hint1, results, (color_rgba (*)[4])pBlock_pixels, decoded_uastc_block); + const uint32_t best_mode = unpacked_blk.m_mode; + eac_a8_block eac_a8_blk; + if ((g_uastc_mode_has_alpha[best_mode]) && (best_mode != UASTC_MODE_INDEX_SOLID_COLOR)) + { + uint8_t decoded_uastc_block_alpha[16]; + for (uint32_t i = 0; i < 16; i++) + decoded_uastc_block_alpha[i] = decoded_uastc_block[i >> 2][i & 3].a; + uastc_pack_eac_a8_results eac8_a8_results; + memset(&eac8_a8_results, 0, sizeof(eac8_a8_results)); + uastc_pack_eac_a8(eac8_a8_results, decoded_uastc_block_alpha, 16, 0, eac_a8_mul_search_rad, eac_a8_table_mask); + eac_a8_blk.m_table = eac8_a8_results.m_table; + eac_a8_blk.m_multiplier = eac8_a8_results.m_multiplier; + } + else + { + memset(&eac_a8_blk, 0, sizeof(eac_a8_blk)); + } + etc_block etc1_blk; + uint32_t etc1_bias = 0; + compute_etc1_hints(etc1_blk, etc1_bias, results, (color_rgba (*)[4])pBlock_pixels, decoded_uastc_block, level, flags); + pack_uastc(*pBlock, results, etc1_blk, etc1_bias, eac_a8_blk, bc1_hint0, bc1_hint1); + return true; + } + + static const uint8_t g_uastc_mode_selector_bits[TOTAL_UASTC_MODES][2] = + { + { 65, 63 }, { 69, 31 }, { 73, 46 }, { 89, 29 }, + { 89, 30 }, { 68, 47 }, { 66, 62 }, { 89, 30 }, + { 0, 0 }, { 97, 30 }, { 65, 63 }, { 66, 62 }, + { 81, 47 }, { 94, 30 }, { 92, 31 }, { 62, 63 }, + { 98, 30 }, { 61, 62 }, { 49, 79 } + }; + + static inline uint32_t set_block_bits(uint8_t* pBytes, uint64_t val, uint32_t num_bits, uint32_t cur_ofs) + { + assert(num_bits <= 64); + assert((num_bits == 64) || (val < (1ULL << num_bits))); + uint64_t mask = (num_bits == 64) ? UINT64_MAX : ((1ULL << num_bits) - 1); + while (num_bits) + { + const uint32_t n = basisu::minimum<uint32_t>(8U - (cur_ofs & 7U), num_bits); + pBytes[cur_ofs >> 3] &= ~static_cast<uint8_t>(mask << (cur_ofs & 7U)); + pBytes[cur_ofs >> 3] |= static_cast<uint8_t>(val << (cur_ofs & 7U)); + val >>= n; + mask >>= n; + num_bits -= n; + cur_ofs += n; + } + return cur_ofs; + } + + static const uint8_t g_tdefl_small_dist_extra[512] = + { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7 + }; + + static const uint8_t g_tdefl_large_dist_extra[128] = + { + 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 + }; + + static inline uint32_t compute_match_cost_estimate(uint32_t dist) + { + uint32_t len_cost = 7; + uint32_t dist_cost = 5; + if (dist < 512) + dist_cost += g_tdefl_small_dist_extra[dist & 511]; + else + { + dist_cost += g_tdefl_large_dist_extra[basisu::minimum<uint32_t>(dist, 32767) >> 8]; + while (dist >= 32768) + { + dist_cost++; + dist >>= 1; + } + } + return len_cost + dist_cost; + } + + struct selector_bitsequence + { + uint64_t m_sel; + uint32_t m_ofs; + selector_bitsequence() { } + selector_bitsequence(uint32_t bit_ofs, uint64_t sel) : m_sel(sel), m_ofs(bit_ofs) { } + bool operator== (const selector_bitsequence& other) const + { + return (m_ofs == other.m_ofs) && (m_sel == other.m_sel); + } + + bool operator< (const selector_bitsequence& other) const + { + if (m_ofs < other.m_ofs) + return true; + else if (m_ofs == other.m_ofs) + return m_sel < other.m_sel; + + return false; + } + }; + + struct selector_bitsequence_hash + { + std::size_t operator()(selector_bitsequence const& s) const noexcept + { + return static_cast<std::size_t>(hash_hsieh((uint8_t *)&s, sizeof(s)) ^ s.m_sel); + } + }; + + class tracked_stat + { + public: + tracked_stat() { clear(); } + + void clear() { m_num = 0; m_total = 0; m_total2 = 0; } + + void update(uint32_t val) { m_num++; m_total += val; m_total2 += val * val; } + + tracked_stat& operator += (uint32_t val) { update(val); return *this; } + + uint32_t get_number_of_values() { return m_num; } + uint64_t get_total() const { return m_total; } + uint64_t get_total2() const { return m_total2; } + + float get_average() const { return m_num ? (float)m_total / m_num : 0.0f; }; + float get_std_dev() const { return m_num ? sqrtf((float)(m_num * m_total2 - m_total * m_total)) / m_num : 0.0f; } + float get_variance() const { float s = get_std_dev(); return s * s; } + + private: + uint32_t m_num; + uint64_t m_total; + uint64_t m_total2; + }; + + static bool uastc_rdo_blocks(uint32_t first_index, uint32_t last_index, basist::uastc_block* pBlocks, const color_rgba* pBlock_pixels, const uastc_rdo_params& params, uint32_t flags, + uint32_t &total_skipped, uint32_t &total_refined, uint32_t &total_modified, uint32_t &total_smooth) + { + debug_printf("uastc_rdo_blocks: Processing blocks %u to %u\n", first_index, last_index); + + const int total_blocks_to_check = basisu::maximum<uint32_t>(1U, params.m_lz_dict_size / sizeof(basist::uastc_block)); + const bool perceptual = false; + + std::unordered_map<selector_bitsequence, uint32_t, selector_bitsequence_hash> selector_history; + + for (uint32_t block_index = first_index; block_index < last_index; block_index++) + { + const basist::uastc_block& blk = pBlocks[block_index]; + const color_rgba* pPixels = &pBlock_pixels[16 * block_index]; + + unpacked_uastc_block unpacked_blk; + if (!unpack_uastc(blk, unpacked_blk, false, true)) + return false; + + const uint32_t block_mode = unpacked_blk.m_mode; + if (block_mode == UASTC_MODE_INDEX_SOLID_COLOR) + continue; + + tracked_stat r_stats, g_stats, b_stats, a_stats; + + for (uint32_t i = 0; i < 16; i++) + { + r_stats.update(pPixels[i].r); + g_stats.update(pPixels[i].g); + b_stats.update(pPixels[i].b); + a_stats.update(pPixels[i].a); + } + + const float max_std_dev = basisu::maximum<float>(basisu::maximum<float>(basisu::maximum(r_stats.get_std_dev(), g_stats.get_std_dev()), b_stats.get_std_dev()), a_stats.get_std_dev()); + + float yl = clamp<float>(max_std_dev / params.m_max_smooth_block_std_dev, 0.0f, 1.0f); + yl = yl * yl; + const float smooth_block_error_scale = lerp<float>(params.m_smooth_block_max_error_scale, 1.0f, yl); + if (smooth_block_error_scale > 1.0f) + total_smooth++; + + color_rgba decoded_uastc_block[4][4]; + if (!unpack_uastc(unpacked_blk, (basist::color32*)decoded_uastc_block, false)) + return false; + + uint64_t uastc_err = 0; + for (uint32_t i = 0; i < 16; i++) + uastc_err += color_distance(perceptual, pPixels[i], ((color_rgba*)decoded_uastc_block)[i], true); + + // Transcode to BC7 + bc7_optimization_results b7_results; + if (!transcode_uastc_to_bc7(unpacked_blk, b7_results)) + return false; + + basist::bc7_block b7_block; + basist::encode_bc7_block(&b7_block, &b7_results); + + color_rgba decoded_b7_blk[4][4]; + unpack_block(texture_format::cBC7, &b7_block, &decoded_b7_blk[0][0]); + + uint64_t bc7_err = 0; + for (uint32_t i = 0; i < 16; i++) + bc7_err += color_distance(perceptual, pPixels[i], ((color_rgba*)decoded_b7_blk)[i], true); + + uint64_t cur_err = (uastc_err + bc7_err) / 2; + + // Divide by 16*4 to compute RMS error + const float cur_ms_err = (float)cur_err * (1.0f / 64.0f); + const float cur_rms_err = sqrt(cur_ms_err); + + const uint32_t first_sel_bit = g_uastc_mode_selector_bits[block_mode][0]; + const uint32_t total_sel_bits = g_uastc_mode_selector_bits[block_mode][1]; + assert(first_sel_bit + total_sel_bits <= 128); + assert(total_sel_bits > 0); + + uint32_t cur_bit_offset = first_sel_bit; + uint64_t cur_sel_bits = read_bits((const uint8_t*)&blk, cur_bit_offset, basisu::minimum(64U, total_sel_bits)); + + if (cur_rms_err >= params.m_skip_block_rms_thresh) + { + auto cur_search_res = selector_history.insert(std::make_pair(selector_bitsequence(first_sel_bit, cur_sel_bits), block_index)); + + // Block already has too much error, so don't mess with it. + if (!cur_search_res.second) + (*cur_search_res.first).second = block_index; + + total_skipped++; + continue; + } + + int cur_bits; + auto cur_find_res = selector_history.find(selector_bitsequence(first_sel_bit, cur_sel_bits)); + if (cur_find_res == selector_history.end()) + { + // Wasn't found - wildly estimate literal cost + //cur_bits = (total_sel_bits * 5) / 4; + cur_bits = (total_sel_bits * params.m_lz_literal_cost) / 100; + } + else + { + // Was found - wildly estimate match cost + uint32_t match_block_index = cur_find_res->second; + const int block_dist_in_bytes = (block_index - match_block_index) * 16; + cur_bits = compute_match_cost_estimate(block_dist_in_bytes); + } + + int first_block_to_check = basisu::maximum<int>(first_index, block_index - total_blocks_to_check); + int last_block_to_check = block_index - 1; + + basist::uastc_block best_block(blk); + uint32_t best_block_index = block_index; + + float best_t = cur_ms_err * smooth_block_error_scale + cur_bits * params.m_lambda; + + // Now scan through previous blocks, insert their selector bit patterns into the current block, and find + // selector bit patterns which don't increase the overall block error too much. + for (int prev_block_index = last_block_to_check; prev_block_index >= first_block_to_check; --prev_block_index) + { + const basist::uastc_block& prev_blk = pBlocks[prev_block_index]; + + uint32_t bit_offset = first_sel_bit; + uint64_t sel_bits = read_bits((const uint8_t*)&prev_blk, bit_offset, basisu::minimum(64U, total_sel_bits)); + + int match_block_index = prev_block_index; + auto res = selector_history.find(selector_bitsequence(first_sel_bit, sel_bits)); + if (res != selector_history.end()) + match_block_index = res->second; + // Have we already checked this bit pattern? If so then skip this block. + if (match_block_index > prev_block_index) + continue; + + unpacked_uastc_block unpacked_prev_blk; + if (!unpack_uastc(prev_blk, unpacked_prev_blk, false, true)) + return false; + + basist::uastc_block trial_blk(blk); + + set_block_bits((uint8_t*)&trial_blk, sel_bits, basisu::minimum(64U, total_sel_bits), first_sel_bit); + + if (total_sel_bits > 64) + { + sel_bits = read_bits((const uint8_t*)&prev_blk, bit_offset, total_sel_bits - 64U); + + set_block_bits((uint8_t*)&trial_blk, sel_bits, total_sel_bits - 64U, first_sel_bit + basisu::minimum(64U, total_sel_bits)); + } + + unpacked_uastc_block unpacked_trial_blk; + if (!unpack_uastc(trial_blk, unpacked_trial_blk, false, true)) + continue; + + color_rgba decoded_trial_uastc_block[4][4]; + if (!unpack_uastc(unpacked_trial_blk, (basist::color32*)decoded_trial_uastc_block, false)) + continue; + + uint64_t trial_uastc_err = 0; + for (uint32_t i = 0; i < 16; i++) + trial_uastc_err += color_distance(perceptual, pPixels[i], ((color_rgba*)decoded_trial_uastc_block)[i], true); + + // Transcode trial to BC7, compute error + bc7_optimization_results trial_b7_results; + if (!transcode_uastc_to_bc7(unpacked_trial_blk, trial_b7_results)) + return false; + + basist::bc7_block trial_b7_block; + basist::encode_bc7_block(&trial_b7_block, &trial_b7_results); + + color_rgba decoded_trial_b7_blk[4][4]; + unpack_block(texture_format::cBC7, &trial_b7_block, &decoded_trial_b7_blk[0][0]); + + uint64_t trial_bc7_err = 0; + for (uint32_t i = 0; i < 16; i++) + trial_bc7_err += color_distance(perceptual, pPixels[i], ((color_rgba*)decoded_trial_b7_blk)[i], true); + + uint64_t trial_err = (trial_uastc_err + trial_bc7_err) / 2; + + const float trial_ms_err = (float)trial_err * (1.0f / 64.0f); + const float trial_rms_err = sqrtf(trial_ms_err); + + if (trial_rms_err > cur_rms_err * params.m_max_allowed_rms_increase_ratio) + continue; + + const int block_dist_in_bytes = (block_index - match_block_index) * 16; + const int match_bits = compute_match_cost_estimate(block_dist_in_bytes); + + float t = trial_ms_err * smooth_block_error_scale + match_bits * params.m_lambda; + if (t < best_t) + { + best_t = t; + best_block_index = prev_block_index; + + best_block = trial_blk; + } + + } // prev_block_index + + if (best_block_index != block_index) + { + total_modified++; + + unpacked_uastc_block unpacked_best_blk; + if (!unpack_uastc(best_block, unpacked_best_blk, false, false)) + return false; + + if ((params.m_endpoint_refinement) && (block_mode == 0)) + { + // Attempt to refine mode 0 block's endpoints, using the new selectors. This doesn't help much, but it does help. + // TODO: We could do this with the other modes too. + color_rgba decoded_best_uastc_block[4][4]; + if (!unpack_uastc(unpacked_best_blk, (basist::color32*)decoded_best_uastc_block, false)) + return false; + + // Compute the block's current error (with the modified selectors). + uint64_t best_uastc_err = 0; + for (uint32_t i = 0; i < 16; i++) + best_uastc_err += color_distance(perceptual, pPixels[i], ((color_rgba*)decoded_best_uastc_block)[i], true); + + bc7enc_compress_block_params comp_params; + memset(&comp_params, 0, sizeof(comp_params)); + comp_params.m_max_partitions_mode1 = 64; + comp_params.m_least_squares_passes = 1; + comp_params.m_weights[0] = 1; + comp_params.m_weights[1] = 1; + comp_params.m_weights[2] = 1; + comp_params.m_weights[3] = 1; + comp_params.m_uber_level = 0; + + uastc_encode_results results; + uint32_t total_results = 0; + astc_mode0_or_18(0, (color_rgba(*)[4])pPixels, &results, total_results, comp_params, unpacked_best_blk.m_astc.m_weights); + assert(total_results == 1); + + // See if the overall error has actually gone done. + + color_rgba decoded_trial_uastc_block[4][4]; + bool success = unpack_uastc(results.m_uastc_mode, results.m_common_pattern, results.m_solid_color.get_color32(), results.m_astc, (basist::color32*) & decoded_trial_uastc_block[0][0], false); + assert(success); + + BASISU_NOTE_UNUSED(success); + + uint64_t trial_uastc_err = 0; + for (uint32_t i = 0; i < 16; i++) + trial_uastc_err += color_distance(perceptual, pPixels[i], ((color_rgba*)decoded_trial_uastc_block)[i], true); + + if (trial_uastc_err < best_uastc_err) + { + // The error went down, so accept the new endpoints. + + // Ensure the selectors haven't changed, otherwise we'll invalidate the LZ matches. + for (uint32_t i = 0; i < 16; i++) + assert(unpacked_best_blk.m_astc.m_weights[i] == results.m_astc.m_weights[i]); + + unpacked_best_blk.m_astc = results.m_astc; + + total_refined++; + } + } // if ((params.m_endpoint_refinement) && (block_mode == 0)) + + // The selectors have changed, so go recompute the block hints. + if (!uastc_recompute_hints(&best_block, pPixels, flags, &unpacked_best_blk)) + return false; + + // Write the modified block + pBlocks[block_index] = best_block; + + } // if (best_block_index != block_index) + + { + uint32_t bit_offset = first_sel_bit; + uint64_t sel_bits = read_bits((const uint8_t*)&best_block, bit_offset, basisu::minimum(64U, total_sel_bits)); + + auto res = selector_history.insert(std::make_pair(selector_bitsequence(first_sel_bit, sel_bits), block_index)); + if (!res.second) + (*res.first).second = block_index; + } + + } // block_index + + return true; + } + + // This function implements a basic form of rate distortion optimization (RDO) for UASTC. + // It only changes selectors and then updates the hints. It uses very approximate LZ bitprice estimation. + // There's A LOT that can be done better in here, but it's a start. + // One nice advantage of the method used here is that it works for any input, no matter which or how many modes it uses. + bool uastc_rdo(uint32_t num_blocks, basist::uastc_block* pBlocks, const color_rgba* pBlock_pixels, const uastc_rdo_params& params, uint32_t flags, job_pool* pJob_pool, uint32_t total_jobs) + { + assert(params.m_max_allowed_rms_increase_ratio > 1.0f); + assert(params.m_lz_dict_size > 0); + assert(params.m_lambda > 0.0f); + + uint32_t total_skipped = 0, total_modified = 0, total_refined = 0, total_smooth = 0; + + uint32_t blocks_per_job = total_jobs ? (num_blocks / total_jobs) : 0; + + std::mutex stat_mutex; + + bool status = false; + + if ((!pJob_pool) || (total_jobs <= 1) || (blocks_per_job <= 8)) + { + status = uastc_rdo_blocks(0, num_blocks, pBlocks, pBlock_pixels, params, flags, total_skipped, total_refined, total_modified, total_smooth); + } + else + { + bool all_succeeded = true; + + for (uint32_t block_index_iter = 0; block_index_iter < num_blocks; block_index_iter += blocks_per_job) + { + const uint32_t first_index = block_index_iter; + const uint32_t last_index = minimum<uint32_t>(num_blocks, block_index_iter + blocks_per_job); + +#ifndef __EMSCRIPTEN__ + pJob_pool->add_job([first_index, last_index, pBlocks, pBlock_pixels, ¶ms, flags, &total_skipped, &total_modified, &total_refined, &total_smooth, &all_succeeded, &stat_mutex] { +#endif + + uint32_t job_skipped = 0, job_modified = 0, job_refined = 0, job_smooth = 0; + + bool status = uastc_rdo_blocks(first_index, last_index, pBlocks, pBlock_pixels, params, flags, job_skipped, job_refined, job_modified, job_smooth); + + { + std::lock_guard<std::mutex> lck(stat_mutex); + + all_succeeded = all_succeeded && status; + total_skipped += job_skipped; + total_modified += job_modified; + total_refined += job_refined; + total_smooth += job_smooth; + } + +#ifndef __EMSCRIPTEN__ + } + ); +#endif + + } // block_index_iter + +#ifndef __EMSCRIPTEN__ + pJob_pool->wait_for_all(); +#endif + + status = all_succeeded; + } + + debug_printf("uastc_rdo: Total modified: %3.2f%%, total skipped: %3.2f%%, total refined: %3.2f%%, total smooth: %3.2f%%\n", total_modified * 100.0f / num_blocks, total_skipped * 100.0f / num_blocks, total_refined * 100.0f / num_blocks, total_smooth * 100.0f / num_blocks); + + return status; + } +} // namespace basisu + + + + + diff --git a/thirdparty/basis_universal/encoder/basisu_uastc_enc.h b/thirdparty/basis_universal/encoder/basisu_uastc_enc.h new file mode 100644 index 0000000000..ba39a558b3 --- /dev/null +++ b/thirdparty/basis_universal/encoder/basisu_uastc_enc.h @@ -0,0 +1,140 @@ +// basisu_uastc_enc.h +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once +#include "basisu_etc.h" + +#include "../transcoder/basisu_transcoder_uastc.h" + +namespace basisu +{ + const uint32_t TOTAL_PACK_UASTC_LEVELS = 5; + + enum + { + // Fastest is the lowest quality, although it's stil substantially higher quality vs. BC1/ETC1. It supports 5 modes. + // The output may be somewhat blocky because this setting doesn't support 2/3-subset UASTC modes, but it should be less blocky vs. BC1/ETC1. + // This setting doesn't write BC1 hints, so BC1 transcoding will be slower. + // Transcoded ETC1 quality will be lower because it only considers 2 hints out of 32. + // Avg. 43.45 dB + cPackUASTCLevelFastest = 0, + + // Faster is ~3x slower than fastest. It supports 9 modes. + // Avg. 46.49 dB + cPackUASTCLevelFaster = 1, + + // Default is ~5.5x slower than fastest. It supports 14 modes. + // Avg. 47.47 dB + cPackUASTCLevelDefault = 2, + + // Slower is ~14.5x slower than fastest. It supports all 18 modes. + // Avg. 48.01 dB + cPackUASTCLevelSlower = 3, + + // VerySlow is ~200x slower than fastest. + // The best quality the codec is capable of, but you'll need to be patient or have a lot of cores. + // Avg. 48.24 dB + cPackUASTCLevelVerySlow = 4, + + cPackUASTCLevelMask = 0xF, + + // By default the encoder tries to strike a balance between UASTC and transcoded BC7 quality. + // These flags allow you to favor only optimizing for lowest UASTC error, or lowest BC7 error. + cPackUASTCFavorUASTCError = 8, + cPackUASTCFavorBC7Error = 16, + + cPackUASTCETC1FasterHints = 64, + cPackUASTCETC1FastestHints = 128, + cPackUASTCETC1DisableFlipAndIndividual = 256, + + // Favor UASTC modes 0 and 10 more than the others (this is experimental, it's useful for RDO compression) + cPackUASTCFavorSimplerModes = 512, + }; + + // pRGBAPixels: Pointer to source 4x4 block of RGBA pixels (R first in memory). + // block: Reference to destination UASTC block. + // level: Controls compression speed vs. performance tradeoff. + void encode_uastc(const uint8_t* pRGBAPixels, basist::uastc_block& output_block, uint32_t flags = cPackUASTCLevelDefault); + + struct uastc_encode_results + { + uint32_t m_uastc_mode; + uint32_t m_common_pattern; + basist::astc_block_desc m_astc; + color_rgba m_solid_color; + uint64_t m_astc_err; + }; + + void pack_uastc(basist::uastc_block& blk, const uastc_encode_results& result, const etc_block& etc1_blk, uint32_t etc1_bias, const eac_a8_block& etc_eac_a8_blk, bool bc1_hint0, bool bc1_hint1); + + const uint32_t UASCT_RDO_DEFAULT_LZ_DICT_SIZE = 4096; + + const float UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO = 10.0f; + const float UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH = 8.0f; + + // The RDO encoder computes a smoothness factor, from [0,1], for each block. To do this it computes each block's maximum component variance, then it divides this by this factor and clamps the result. + // Larger values will result in more blocks being protected from too much distortion. + const float UASTC_RDO_DEFAULT_MAX_SMOOTH_BLOCK_STD_DEV = 18.0f; + + // The RDO encoder can artifically boost the error of smooth blocks, in order to suppress distortions on smooth areas of the texture. + // The encoder will use this value as the maximum error scale to use on smooth blocks. The larger this value, the better smooth bocks will look. Set to 1.0 to disable this completely. + const float UASTC_RDO_DEFAULT_SMOOTH_BLOCK_MAX_ERROR_SCALE = 10.0f; + + struct uastc_rdo_params + { + uastc_rdo_params() + { + clear(); + } + + void clear() + { + m_lz_dict_size = UASCT_RDO_DEFAULT_LZ_DICT_SIZE; + m_lambda = 0.5f; + m_max_allowed_rms_increase_ratio = UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO; + m_skip_block_rms_thresh = UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH; + m_endpoint_refinement = true; + m_lz_literal_cost = 100; + + m_max_smooth_block_std_dev = UASTC_RDO_DEFAULT_MAX_SMOOTH_BLOCK_STD_DEV; + m_smooth_block_max_error_scale = UASTC_RDO_DEFAULT_SMOOTH_BLOCK_MAX_ERROR_SCALE; + } + + // m_lz_dict_size: Size of LZ dictionary to simulate in bytes. The larger this value, the slower the encoder but the higher the quality per LZ compressed bit. + uint32_t m_lz_dict_size; + + // m_lambda: The post-processor tries to reduce distortion+rate*lambda (rate is approximate LZ bits and distortion is scaled MS error). + // Larger values push the postprocessor towards optimizing more for lower rate, and smaller values more for distortion. 0=minimal distortion. + float m_lambda; + + // m_max_allowed_rms_increase_ratio: How much the RMS error of a block is allowed to increase before a trial is rejected. 1.0=no increase allowed, 1.05=5% increase allowed, etc. + float m_max_allowed_rms_increase_ratio; + + // m_skip_block_rms_thresh: Blocks with this much RMS error or more are completely skipped by the RDO encoder. + float m_skip_block_rms_thresh; + + // m_endpoint_refinement: If true, the post-process will attempt to refine the endpoints of blocks with modified selectors. + bool m_endpoint_refinement; + + float m_max_smooth_block_std_dev; + float m_smooth_block_max_error_scale; + + uint32_t m_lz_literal_cost; + }; + + // num_blocks, pBlocks: Number of blocks and pointer to UASTC blocks to process. + // pBlock_pixels: Pointer to an array of 4x4 blocks containing the original texture pixels. This is NOT a raster image, but a pointer to individual 4x4 blocks. + // flags: Pass in the same flags used to encode the UASTC blocks. The flags are used to reencode the transcode hints in the same way. + bool uastc_rdo(uint32_t num_blocks, basist::uastc_block* pBlocks, const color_rgba* pBlock_pixels, const uastc_rdo_params ¶ms, uint32_t flags = cPackUASTCLevelDefault, job_pool* pJob_pool = nullptr, uint32_t total_jobs = 0); +} // namespace basisu diff --git a/thirdparty/basis_universal/encoder/cppspmd_flow.h b/thirdparty/basis_universal/encoder/cppspmd_flow.h new file mode 100644 index 0000000000..f6930476aa --- /dev/null +++ b/thirdparty/basis_universal/encoder/cppspmd_flow.h @@ -0,0 +1,590 @@ +// Do not include this header directly. +// Control flow functionality in common between all the headers. +// +// Copyright 2020-2021 Binomial LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifdef _DEBUG +CPPSPMD_FORCE_INLINE void spmd_kernel::check_masks() +{ + assert(!any(andnot(m_kernel_exec, m_exec))); +} +#endif + +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_break() +{ +#ifdef _DEBUG + assert(m_in_loop); +#endif + + m_exec = exec_mask::all_off(); +} + +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_continue() +{ +#ifdef _DEBUG + assert(m_in_loop); +#endif + + // Kill any active lanes, and remember which lanes were active so we can re-enable them at the end of the loop body. + m_continue_mask = m_continue_mask | m_exec; + m_exec = exec_mask::all_off(); +} + +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_return() +{ + // Permenantly kill all active lanes + m_kernel_exec = andnot(m_exec, m_kernel_exec); + m_exec = exec_mask::all_off(); +} + +template<typename UnmaskedBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_unmasked(const UnmaskedBody& unmaskedBody) +{ + exec_mask orig_exec = m_exec, orig_kernel_exec = m_kernel_exec; + + m_kernel_exec = exec_mask::all_on(); + m_exec = exec_mask::all_on(); + + unmaskedBody(); + + m_kernel_exec = m_kernel_exec & orig_kernel_exec; + m_exec = m_exec & orig_exec; + + check_masks(); +} + +struct scoped_unmasked_restorer +{ + spmd_kernel *m_pKernel; + exec_mask m_orig_exec, m_orig_kernel_exec; + + CPPSPMD_FORCE_INLINE scoped_unmasked_restorer(spmd_kernel *pKernel) : + m_pKernel(pKernel), + m_orig_exec(pKernel->m_exec), + m_orig_kernel_exec(pKernel->m_kernel_exec) + { + pKernel->m_kernel_exec = exec_mask::all_on(); + pKernel->m_exec = exec_mask::all_on(); + } + + CPPSPMD_FORCE_INLINE ~scoped_unmasked_restorer() + { + m_pKernel->m_kernel_exec = m_pKernel->m_kernel_exec & m_orig_kernel_exec; + m_pKernel->m_exec = m_pKernel->m_exec & m_orig_exec; + m_pKernel->check_masks(); + } +}; + +#define SPMD_UNMASKED_BEGIN { scoped_unmasked_restorer _unmasked_restorer(this); +#define SPMD_UNMASKED_END } + +#if 0 +template<typename SPMDKernel, typename... Args> +CPPSPMD_FORCE_INLINE decltype(auto) spmd_kernel::spmd_call(Args&&... args) +{ + SPMDKernel kernel; + kernel.init(m_exec); + return kernel._call(std::forward<Args>(args)...); +} +#else +template<typename SPMDKernel, typename... Args> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_call(Args&&... args) +{ + SPMDKernel kernel; + kernel.init(m_exec); + kernel._call(std::forward<Args>(args)...); +} +#endif + +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_if_break(const vbool& cond) +{ +#ifdef _DEBUG + assert(m_in_loop); +#endif + + exec_mask cond_exec(cond); + + m_exec = andnot(m_exec & cond_exec, m_exec); + + check_masks(); +} + +// No SPMD breaks, continues, etc. allowed +template<typename IfBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_sif(const vbool& cond, const IfBody& ifBody) +{ + exec_mask im = m_exec & exec_mask(cond); + + if (any(im)) + { + const exec_mask orig_exec = m_exec; + m_exec = im; + ifBody(); + m_exec = orig_exec; + } +} + +// No SPMD breaks, continues, etc. allowed +template<typename IfBody, typename ElseBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_sifelse(const vbool& cond, const IfBody& ifBody, const ElseBody &elseBody) +{ + const exec_mask orig_exec = m_exec; + + exec_mask im = m_exec & exec_mask(cond); + + if (any(im)) + { + m_exec = im; + ifBody(); + } + + exec_mask em = orig_exec & exec_mask(!cond); + + if (any(em)) + { + m_exec = em; + elseBody(); + } + + m_exec = orig_exec; +} + +template<typename IfBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_if(const vbool& cond, const IfBody& ifBody) +{ + exec_mask cond_exec(cond); + + exec_mask pre_if_exec = cond_exec & m_exec; + + if (any(pre_if_exec)) + { + exec_mask unexecuted_lanes = andnot(cond_exec, m_exec); + m_exec = pre_if_exec; + + ifBody(); + + // Propagate any lanes that got disabled inside the if body into the exec mask outside the if body, but turn on any lanes that didn't execute inside the if body. + m_exec = m_exec | unexecuted_lanes; + + check_masks(); + } +} + +template<typename IfBody, typename ElseBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_ifelse(const vbool& cond, const IfBody& ifBody, const ElseBody& elseBody) +{ + bool all_flag = false; + + exec_mask cond_exec(cond); + + { + exec_mask pre_if_exec = cond_exec & m_exec; + + int mask = pre_if_exec.get_movemask(); + if (mask != 0) + { + all_flag = ((uint32_t)mask == m_exec.get_movemask()); + + exec_mask unexecuted_lanes = andnot(cond_exec, m_exec); + m_exec = pre_if_exec; + + ifBody(); + + // Propagate any lanes that got disabled inside the if body into the exec mask outside the if body, but turn on any lanes that didn't execute inside the if body. + m_exec = m_exec | unexecuted_lanes; + + check_masks(); + } + } + + if (!all_flag) + { + exec_mask pre_if_exec = andnot(cond_exec, m_exec); + + if (any(pre_if_exec)) + { + exec_mask unexecuted_lanes = cond_exec & m_exec; + m_exec = pre_if_exec; + + ifBody(); + + // Propagate any lanes that got disabled inside the if body into the exec mask outside the if body, but turn on any lanes that didn't execute inside the if body. + m_exec = m_exec | unexecuted_lanes; + + check_masks(); + } + } +} + +struct scoped_exec_restorer +{ + exec_mask *m_pMask; + exec_mask m_prev_mask; + CPPSPMD_FORCE_INLINE scoped_exec_restorer(exec_mask *pExec_mask) : m_pMask(pExec_mask), m_prev_mask(*pExec_mask) { } + CPPSPMD_FORCE_INLINE ~scoped_exec_restorer() { *m_pMask = m_prev_mask; } +}; + +// Cannot use SPMD break, continue, or return inside "simple" if/else +#define SPMD_SIF(cond) exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(m_exec & exec_mask(vbool(cond))); if (any(CPPSPMD_GLUER2(_exec_temp, __LINE__))) \ + { CPPSPMD::scoped_exec_restorer CPPSPMD_GLUER2(_exec_restore_, __LINE__)(&m_exec); m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); + +#define SPMD_SELSE(cond) } exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(m_exec & exec_mask(!vbool(cond))); if (any(CPPSPMD_GLUER2(_exec_temp, __LINE__))) \ + { CPPSPMD::scoped_exec_restorer CPPSPMD_GLUER2(_exec_restore_, __LINE__)(&m_exec); m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); + +#define SPMD_SENDIF } + +// Same as SPMD_SIF, except doesn't use a scoped object +#define SPMD_SIF2(cond) exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(m_exec & exec_mask(vbool(cond))); if (any(CPPSPMD_GLUER2(_exec_temp, __LINE__))) \ + { exec_mask _orig_exec = m_exec; m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); + +#define SPMD_SELSE2(cond) m_exec = _orig_exec; } exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(m_exec & exec_mask(!vbool(cond))); if (any(CPPSPMD_GLUER2(_exec_temp, __LINE__))) \ + { exec_mask _orig_exec = m_exec; m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); + +#define SPMD_SEND_IF2 m_exec = _orig_exec; } + +// Same as SPMD_SIF(), except the if/else blocks are always executed +#define SPMD_SAIF(cond) exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(m_exec & exec_mask(vbool(cond))); { CPPSPMD::scoped_exec_restorer CPPSPMD_GLUER2(_exec_restore_, __LINE__)(&m_exec); \ + m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); + +#define SPMD_SAELSE(cond) } exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(m_exec & exec_mask(!vbool(cond))); { CPPSPMD::scoped_exec_restorer CPPSPMD_GLUER2(_exec_restore_, __LINE__)(&m_exec); \ + m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); + +#define SPMD_SAENDIF } + +// Cannot use SPMD break, continue, or return inside sselect +#define SPMD_SSELECT(var) do { vint_t _select_var = var; scoped_exec_restorer _orig_exec(&m_exec); exec_mask _select_executed(exec_mask::all_off()); +#define SPMD_SCASE(value) exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(_orig_exec.m_prev_mask & exec_mask(vbool(_select_var == (value)))); if (any(CPPSPMD_GLUER2(_exec_temp, __LINE__))) \ + { m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); _select_executed = _select_executed | m_exec; + +//#define SPMD_SCASE_END if (_select_executed.get_movemask() == _orig_exec.m_prev_mask.get_movemask()) break; } +#define SPMD_SCASE_END if (!any(_select_executed ^ _orig_exec.m_prev_mask)) break; } +#define SPMD_SDEFAULT exec_mask _all_other_lanes(andnot(_select_executed, _orig_exec.m_prev_mask)); if (any(_all_other_lanes)) { m_exec = _all_other_lanes; +#define SPMD_SDEFAULT_END } +#define SPMD_SSELECT_END } while(0); + +// Same as SPMD_SSELECT, except all cases are executed. +// Cannot use SPMD break, continue, or return inside sselect +#define SPMD_SASELECT(var) do { vint_t _select_var = var; scoped_exec_restorer _orig_exec(&m_exec); exec_mask _select_executed(exec_mask::all_off()); + +#define SPMD_SACASE(value) exec_mask CPPSPMD_GLUER2(_exec_temp, __LINE__)(_orig_exec.m_prev_mask & exec_mask(vbool(_select_var == (value)))); { m_exec = CPPSPMD_GLUER2(_exec_temp, __LINE__); \ + _select_executed = _select_executed | m_exec; + +#define SPMD_SACASE_END } +#define SPMD_SADEFAULT exec_mask _all_other_lanes(andnot(_select_executed, _orig_exec.m_prev_mask)); { m_exec = _all_other_lanes; +#define SPMD_SADEFAULT_END } +#define SPMD_SASELECT_END } while(0); + +struct scoped_exec_restorer2 +{ + spmd_kernel *m_pKernel; + exec_mask m_unexecuted_lanes; + + CPPSPMD_FORCE_INLINE scoped_exec_restorer2(spmd_kernel *pKernel, const vbool &cond) : + m_pKernel(pKernel) + { + exec_mask cond_exec(cond); + m_unexecuted_lanes = andnot(cond_exec, pKernel->m_exec); + pKernel->m_exec = cond_exec & pKernel->m_exec; + } + + CPPSPMD_FORCE_INLINE ~scoped_exec_restorer2() + { + m_pKernel->m_exec = m_pKernel->m_exec | m_unexecuted_lanes; + m_pKernel->check_masks(); + } +}; + +#define SPMD_IF(cond) { CPPSPMD::scoped_exec_restorer2 CPPSPMD_GLUER2(_exec_restore2_, __LINE__)(this, vbool(cond)); if (any(m_exec)) { +#define SPMD_ELSE(cond) } } { CPPSPMD::scoped_exec_restorer2 CPPSPMD_GLUER2(_exec_restore2_, __LINE__)(this, !vbool(cond)); if (any(m_exec)) { +#define SPMD_END_IF } } + +// Same as SPMD_IF, except the conditional block is always executed. +#define SPMD_AIF(cond) { CPPSPMD::scoped_exec_restorer2 CPPSPMD_GLUER2(_exec_restore2_, __LINE__)(this, vbool(cond)); { +#define SPMD_AELSE(cond) } } { CPPSPMD::scoped_exec_restorer2 CPPSPMD_GLUER2(_exec_restore2_, __LINE__)(this, !vbool(cond)); { +#define SPMD_AEND_IF } } + +class scoped_exec_saver +{ + exec_mask m_exec, m_kernel_exec, m_continue_mask; + spmd_kernel *m_pKernel; +#ifdef _DEBUG + bool m_in_loop; +#endif + +public: + inline scoped_exec_saver(spmd_kernel *pKernel) : + m_exec(pKernel->m_exec), m_kernel_exec(pKernel->m_kernel_exec), m_continue_mask(pKernel->m_continue_mask), + m_pKernel(pKernel) + { +#ifdef _DEBUG + m_in_loop = pKernel->m_in_loop; +#endif + } + + inline ~scoped_exec_saver() + { + m_pKernel->m_exec = m_exec; + m_pKernel->m_continue_mask = m_continue_mask; + m_pKernel->m_kernel_exec = m_kernel_exec; +#ifdef _DEBUG + m_pKernel->m_in_loop = m_in_loop; + m_pKernel->check_masks(); +#endif + } +}; + +#define SPMD_BEGIN_CALL scoped_exec_saver CPPSPMD_GLUER2(_begin_call_scoped_exec_saver, __LINE__)(this); m_continue_mask = exec_mask::all_off(); +#define SPMD_BEGIN_CALL_ALL_LANES scoped_exec_saver CPPSPMD_GLUER2(_begin_call_scoped_exec_saver, __LINE__)(this); m_exec = exec_mask::all_on(); m_continue_mask = exec_mask::all_off(); + +template<typename ForeachBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_foreach(int begin, int end, const ForeachBody& foreachBody) +{ + if (begin == end) + return; + + if (!any(m_exec)) + return; + + // We don't support iterating backwards. + if (begin > end) + std::swap(begin, end); + + exec_mask prev_continue_mask = m_continue_mask, prev_exec = m_exec; + + int total_full = (end - begin) / PROGRAM_COUNT; + int total_partial = (end - begin) % PROGRAM_COUNT; + + lint_t loop_index = begin + program_index; + + const int total_loops = total_full + (total_partial ? 1 : 0); + + m_continue_mask = exec_mask::all_off(); + + for (int i = 0; i < total_loops; i++) + { + int n = PROGRAM_COUNT; + if ((i == (total_loops - 1)) && (total_partial)) + { + exec_mask partial_mask = exec_mask(vint_t(total_partial) > vint_t(program_index)); + m_exec = m_exec & partial_mask; + n = total_partial; + } + + foreachBody(loop_index, n); + + m_exec = m_exec | m_continue_mask; + if (!any(m_exec)) + break; + + m_continue_mask = exec_mask::all_off(); + check_masks(); + + store_all(loop_index, loop_index + PROGRAM_COUNT); + } + + m_exec = prev_exec & m_kernel_exec; + m_continue_mask = prev_continue_mask; + check_masks(); +} + +template<typename WhileCondBody, typename WhileBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_while(const WhileCondBody& whileCondBody, const WhileBody& whileBody) +{ + exec_mask orig_exec = m_exec; + + exec_mask orig_continue_mask = m_continue_mask; + m_continue_mask = exec_mask::all_off(); + +#ifdef _DEBUG + const bool prev_in_loop = m_in_loop; + m_in_loop = true; +#endif + + while(true) + { + exec_mask cond_exec = exec_mask(whileCondBody()); + m_exec = m_exec & cond_exec; + + if (!any(m_exec)) + break; + + whileBody(); + + m_exec = m_exec | m_continue_mask; + m_continue_mask = exec_mask::all_off(); + check_masks(); + } + +#ifdef _DEBUG + m_in_loop = prev_in_loop; +#endif + + m_exec = orig_exec & m_kernel_exec; + m_continue_mask = orig_continue_mask; + check_masks(); +} + +struct scoped_while_restorer +{ + spmd_kernel *m_pKernel; + exec_mask m_orig_exec, m_orig_continue_mask; +#ifdef _DEBUG + bool m_prev_in_loop; +#endif + + CPPSPMD_FORCE_INLINE scoped_while_restorer(spmd_kernel *pKernel) : + m_pKernel(pKernel), + m_orig_exec(pKernel->m_exec), + m_orig_continue_mask(pKernel->m_continue_mask) + { + pKernel->m_continue_mask.all_off(); + +#ifdef _DEBUG + m_prev_in_loop = pKernel->m_in_loop; + pKernel->m_in_loop = true; +#endif + } + + CPPSPMD_FORCE_INLINE ~scoped_while_restorer() + { + m_pKernel->m_exec = m_orig_exec & m_pKernel->m_kernel_exec; + m_pKernel->m_continue_mask = m_orig_continue_mask; +#ifdef _DEBUG + m_pKernel->m_in_loop = m_prev_in_loop; + m_pKernel->check_masks(); +#endif + } +}; + +#undef SPMD_WHILE +#undef SPMD_WEND +#define SPMD_WHILE(cond) { scoped_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); while(true) { exec_mask CPPSPMD_GLUER2(cond_exec, __LINE__) = exec_mask(vbool(cond)); \ + m_exec = m_exec & CPPSPMD_GLUER2(cond_exec, __LINE__); if (!any(m_exec)) break; + +#define SPMD_WEND m_exec = m_exec | m_continue_mask; m_continue_mask = exec_mask::all_off(); check_masks(); } } + +// Nesting is not supported (although it will compile, but the results won't make much sense). +#define SPMD_FOREACH(loop_var, bi, ei) if (((bi) != (ei)) && (any(m_exec))) { \ + scoped_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); \ + uint32_t b = (uint32_t)(bi), e = (uint32_t)(ei); if ((b) > (e)) { std::swap(b, e); } const uint32_t total_full = ((e) - (b)) >> PROGRAM_COUNT_SHIFT, total_partial = ((e) - (b)) & (PROGRAM_COUNT - 1); \ + lint_t loop_var = program_index + (int)b; const uint32_t total_loops = total_full + (total_partial ? 1U : 0U); \ + for (uint32_t CPPSPMD_GLUER2(_foreach_counter, __LINE__) = 0; CPPSPMD_GLUER2(_foreach_counter, __LINE__) < total_loops; ++CPPSPMD_GLUER2(_foreach_counter, __LINE__)) { \ + if ((CPPSPMD_GLUER2(_foreach_counter, __LINE__) == (total_loops - 1)) && (total_partial)) { exec_mask partial_mask = exec_mask(vint_t((int)total_partial) > vint_t(program_index)); m_exec = m_exec & partial_mask; } + +#define SPMD_FOREACH_END(loop_var) m_exec = m_exec | m_continue_mask; if (!any(m_exec)) break; m_continue_mask = exec_mask::all_off(); check_masks(); store_all(loop_var, loop_var + PROGRAM_COUNT); } } + +// Okay to use spmd_continue or spmd_return, but not spmd_break +#define SPMD_FOREACH_ACTIVE(index_var) int64_t index_var; { uint64_t _movemask = m_exec.get_movemask(); if (_movemask) { scoped_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); \ + for (uint32_t _i = 0; _i < PROGRAM_COUNT; ++_i) { \ + if (_movemask & (1U << _i)) { \ + m_exec.enable_lane(_i); m_exec = m_exec & m_kernel_exec; \ + (index_var) = _i; \ + +#define SPMD_FOREACH_ACTIVE_END } } } } + +// Okay to use spmd_continue, but not spmd_break/spmd_continue +#define SPMD_FOREACH_UNIQUE_INT(index_var, var) { scoped_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); \ + CPPSPMD_DECL(int_t, _vals[PROGRAM_COUNT]); store_linear_all(_vals, var); std::sort(_vals, _vals + PROGRAM_COUNT); \ + const int _n = (int)(std::unique(_vals, _vals + PROGRAM_COUNT) - _vals); \ + for (int _i = 0; _i < _n; ++_i) { int index_var = _vals[_i]; vbool cond = (vint_t(var) == vint_t(index_var)); m_exec = exec_mask(cond); + +#define SPMD_FOREACH_UNIQUE_INT_END } } + +struct scoped_simple_while_restorer +{ + spmd_kernel* m_pKernel; + exec_mask m_orig_exec; +#ifdef _DEBUG + bool m_prev_in_loop; +#endif + + CPPSPMD_FORCE_INLINE scoped_simple_while_restorer(spmd_kernel* pKernel) : + m_pKernel(pKernel), + m_orig_exec(pKernel->m_exec) + { + +#ifdef _DEBUG + m_prev_in_loop = pKernel->m_in_loop; + pKernel->m_in_loop = true; +#endif + } + + CPPSPMD_FORCE_INLINE ~scoped_simple_while_restorer() + { + m_pKernel->m_exec = m_orig_exec; +#ifdef _DEBUG + m_pKernel->m_in_loop = m_prev_in_loop; + m_pKernel->check_masks(); +#endif + } +}; + +// Cannot use SPMD break, continue, or return inside simple while + +#define SPMD_SWHILE(cond) { scoped_simple_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); \ + while(true) { \ + exec_mask CPPSPMD_GLUER2(cond_exec, __LINE__) = exec_mask(vbool(cond)); m_exec = m_exec & CPPSPMD_GLUER2(cond_exec, __LINE__); if (!any(m_exec)) break; +#define SPMD_SWEND } } + +// Cannot use SPMD break, continue, or return inside simple do +#define SPMD_SDO { scoped_simple_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); while(true) { +#define SPMD_SEND_DO(cond) exec_mask CPPSPMD_GLUER2(cond_exec, __LINE__) = exec_mask(vbool(cond)); m_exec = m_exec & CPPSPMD_GLUER2(cond_exec, __LINE__); if (!any(m_exec)) break; } } + +#undef SPMD_FOR +#undef SPMD_END_FOR +#define SPMD_FOR(for_init, for_cond) { for_init; scoped_while_restorer CPPSPMD_GLUER2(_while_restore_, __LINE__)(this); while(true) { exec_mask CPPSPMD_GLUER2(cond_exec, __LINE__) = exec_mask(vbool(for_cond)); \ + m_exec = m_exec & CPPSPMD_GLUER2(cond_exec, __LINE__); if (!any(m_exec)) break; +#define SPMD_END_FOR(for_inc) m_exec = m_exec | m_continue_mask; m_continue_mask = exec_mask::all_off(); check_masks(); for_inc; } } + +template<typename ForInitBody, typename ForCondBody, typename ForIncrBody, typename ForBody> +CPPSPMD_FORCE_INLINE void spmd_kernel::spmd_for(const ForInitBody& forInitBody, const ForCondBody& forCondBody, const ForIncrBody& forIncrBody, const ForBody& forBody) +{ + exec_mask orig_exec = m_exec; + + forInitBody(); + + exec_mask orig_continue_mask = m_continue_mask; + m_continue_mask = exec_mask::all_off(); + +#ifdef _DEBUG + const bool prev_in_loop = m_in_loop; + m_in_loop = true; +#endif + + while(true) + { + exec_mask cond_exec = exec_mask(forCondBody()); + m_exec = m_exec & cond_exec; + + if (!any(m_exec)) + break; + + forBody(); + + m_exec = m_exec | m_continue_mask; + m_continue_mask = exec_mask::all_off(); + check_masks(); + + forIncrBody(); + } + + m_exec = orig_exec & m_kernel_exec; + m_continue_mask = orig_continue_mask; + +#ifdef _DEBUG + m_in_loop = prev_in_loop; + check_masks(); +#endif +} diff --git a/thirdparty/basis_universal/encoder/cppspmd_math.h b/thirdparty/basis_universal/encoder/cppspmd_math.h new file mode 100644 index 0000000000..e7b3202b8e --- /dev/null +++ b/thirdparty/basis_universal/encoder/cppspmd_math.h @@ -0,0 +1,725 @@ +// Do not include this header directly. +// +// Copyright 2020-2021 Binomial LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The general goal of these vectorized estimated math functions is scalability/performance. +// There are explictly no checks NaN's/Inf's on the input arguments. There are no assertions either. +// These are fast estimate functions - if you need more than that, use stdlib. Please do a proper +// engineering analysis before relying on them. +// I have chosen functions written by others, ported them to CppSPMD, then measured their abs/rel errors. +// I compared each to the ones in DirectXMath and stdlib's for accuracy/performance. + +CPPSPMD_FORCE_INLINE vfloat fmod_inv(const vfloat& a, const vfloat& b, const vfloat& b_inv) +{ + vfloat c = frac(abs(a * b_inv)) * abs(b); + return spmd_ternaryf(a < 0, -c, c); +} + +CPPSPMD_FORCE_INLINE vfloat fmod_inv_p(const vfloat& a, const vfloat& b, const vfloat& b_inv) +{ + return frac(a * b_inv) * b; +} + +// Avoids dividing by zero or very small values. +CPPSPMD_FORCE_INLINE vfloat safe_div(vfloat a, vfloat b, float fDivThresh = 1e-7f) +{ + return a / spmd_ternaryf( abs(b) > fDivThresh, b, spmd_ternaryf(b < 0.0f, -fDivThresh, fDivThresh) ); +} + +/* + clang 9.0.0 for win /fp:precise release + f range: 0.0000000000001250 10000000000.0000000000000000, vals: 1073741824 + + log2_est(): + max abs err: 0.0000023076808731 + max rel err: 0.0000000756678881 + avg abs err: 0.0000007535452724 + avg rel err: 0.0000000235117843 + + XMVectorLog2(): + max abs err: 0.0000023329709933 + max rel err: 0.0000000826961046 + avg abs err: 0.0000007564889684 + avg rel err: 0.0000000236051899 + + std::log2f(): + max abs err: 0.0000020265979401 + max rel err: 0.0000000626647654 + avg abs err: 0.0000007494445227 + avg rel err: 0.0000000233800985 +*/ + +// See https://tech.ebayinc.com/engineering/fast-approximate-logarithms-part-iii-the-formulas/ +inline vfloat spmd_kernel::log2_est(vfloat v) +{ + vfloat signif, fexp; + + // Just clamp to a very small value, instead of checking for invalid inputs. + vfloat x = max(v, 2.2e-38f); + + /* + * Assume IEEE representation, which is sgn(1):exp(8):frac(23) + * representing (1+frac)*2^(exp-127). Call 1+frac the significand + */ + + // get exponent + vint ux1_i = cast_vfloat_to_vint(x); + + vint exp = VUINT_SHIFT_RIGHT(ux1_i & 0x7F800000, 23); + + // actual exponent is exp-127, will subtract 127 later + + vint ux2_i; + vfloat ux2_f; + + vint greater = ux1_i & 0x00400000; // true if signif > 1.5 + SPMD_SIF(greater != 0) + { + // signif >= 1.5 so need to divide by 2. Accomplish this by stuffing exp = 126 which corresponds to an exponent of -1 + store_all(ux2_i, (ux1_i & 0x007FFFFF) | 0x3f000000); + + store_all(ux2_f, cast_vint_to_vfloat(ux2_i)); + + // 126 instead of 127 compensates for division by 2 + store_all(fexp, vfloat(exp - 126)); + } + SPMD_SELSE(greater != 0) + { + // get signif by stuffing exp = 127 which corresponds to an exponent of 0 + store(ux2_i, (ux1_i & 0x007FFFFF) | 0x3f800000); + + store(ux2_f, cast_vint_to_vfloat(ux2_i)); + + store(fexp, vfloat(exp - 127)); + } + SPMD_SENDIF + + store_all(signif, ux2_f); + store_all(signif, signif - 1.0f); + + const float a = 0.1501692f, b = 3.4226132f, c = 5.0225057f, d = 4.1130283f, e = 3.4813372f; + + vfloat xm1 = signif; + vfloat xm1sqr = xm1 * xm1; + + return fexp + ((a * (xm1sqr * xm1) + b * xm1sqr + c * xm1) / (xm1sqr + d * xm1 + e)); + + // fma lowers accuracy for SSE4.1 - no idea why (compiler reordering?) + //return fexp + ((vfma(a, (xm1sqr * xm1), vfma(b, xm1sqr, c * xm1))) / (xm1sqr + vfma(d, xm1, e))); +} + +// Uses log2_est(), so this function must be <= the precision of that. +inline vfloat spmd_kernel::log_est(vfloat v) +{ + return log2_est(v) * 0.693147181f; +} + +CPPSPMD_FORCE_INLINE void spmd_kernel::reduce_expb(vfloat& arg, vfloat& two_int_a, vint& adjustment) +{ + // Assume we're using equation (2) + store_all(adjustment, 0); + + // integer part of the input argument + vint int_arg = (vint)arg; + + // if frac(arg) is in [0.5, 1.0]... + SPMD_SIF((arg - int_arg) > 0.5f) + { + store(adjustment, 1); + + // then change it to [0.0, 0.5] + store(arg, arg - 0.5f); + } + SPMD_SENDIF + + // arg == just the fractional part + store_all(arg, arg - (vfloat)int_arg); + + // Now compute 2** (int) arg. + store_all(int_arg, min(int_arg + 127, 254)); + + store_all(two_int_a, cast_vint_to_vfloat(VINT_SHIFT_LEFT(int_arg, 23))); +} + +/* + clang 9.0.0 for win /fp:precise release + f range : -50.0000000000000000 49.9999940395355225, vals : 16777216 + + exp2_est(): + Total passed near - zero check : 16777216 + Total sign diffs : 0 + max abs err: 1668910609.7500000000000000 + max rel err: 0.0000015642030031 + avg abs err: 10793794.4007573910057545 + avg rel err: 0.0000003890893282 + + XMVectorExp2(): + Total passed near-zero check: 16777216 + Total sign diffs: 0 + max abs err: 1665552836.8750000000000000 + max rel err: 0.0000114674862370 + avg abs err: 10771868.2627860084176064 + avg rel err: 0.0000011218880770 + + std::exp2f(): + Total passed near-zero check: 16777216 + Total sign diffs: 0 + max abs err: 1591636585.6250000000000000 + max rel err: 0.0000014849731018 + avg abs err: 10775800.3204844966530800 + avg rel err: 0.0000003851496422 +*/ + +// http://www.ganssle.com/item/approximations-c-code-exponentiation-log.htm +inline vfloat spmd_kernel::exp2_est(vfloat arg) +{ + SPMD_BEGIN_CALL + + const vfloat P00 = +7.2152891521493f; + const vfloat P01 = +0.0576900723731f; + const vfloat Q00 = +20.8189237930062f; + const vfloat Q01 = +1.0f; + const vfloat sqrt2 = 1.4142135623730950488f; // sqrt(2) for scaling + + vfloat result = 0.0f; + + // Return 0 if arg is too large. + // We're not introducing inf/nan's into calculations, or risk doing so by returning huge default values. + SPMD_IF(abs(arg) > 126.0f) + { + spmd_return(); + } + SPMD_END_IF + + // 2**(int(a)) + vfloat two_int_a; + + // set to 1 by reduce_expb + vint adjustment; + + // 0 if arg is +; 1 if negative + vint negative = 0; + + // If the input is negative, invert it. At the end we'll take the reciprocal, since n**(-1) = 1/(n**x). + SPMD_SIF(arg < 0.0f) + { + store(arg, -arg); + store(negative, 1); + } + SPMD_SENDIF + + store_all(arg, min(arg, 126.0f)); + + // reduce to [0.0, 0.5] + reduce_expb(arg, two_int_a, adjustment); + + // The format of the polynomial is: + // answer=(Q(x**2) + x*P(x**2))/(Q(x**2) - x*P(x**2)) + // + // The following computes the polynomial in several steps: + + // Q(x**2) + vfloat Q = vfma(Q01, (arg * arg), Q00); + + // x*P(x**2) + vfloat x_P = arg * (vfma(P01, arg * arg, P00)); + + vfloat answer = (Q + x_P) / (Q - x_P); + + // Now correct for the scaling factor of 2**(int(a)) + store_all(answer, answer * two_int_a); + + // If the result had a fractional part > 0.5, correct for that + store_all(answer, spmd_ternaryf(adjustment != 0, answer * sqrt2, answer)); + + // Correct for a negative input + SPMD_SIF(negative != 0) + { + store(answer, 1.0f / answer); + } + SPMD_SENDIF + + store(result, answer); + + return result; +} + +inline vfloat spmd_kernel::exp_est(vfloat arg) +{ + // e^x = exp2(x / log_base_e(2)) + // constant is 1.0/(log(2)/log(e)) or 1/log(2) + return exp2_est(arg * 1.44269504f); +} + +inline vfloat spmd_kernel::pow_est(vfloat arg1, vfloat arg2) +{ + return exp_est(log_est(arg1) * arg2); +} + +/* + clang 9.0.0 for win /fp:precise release + Total near-zero: 144, output above near-zero tresh: 30 + Total near-zero avg: 0.0000067941016621 max: 0.0000134706497192 + Total near-zero sign diffs: 5 + Total passed near-zero check: 16777072 + Total sign diffs: 5 + max abs err: 0.0000031375306036 + max rel err: 0.1140846017075028 + avg abs err: 0.0000003026226621 + avg rel err: 0.0000033564977623 +*/ + +// Math from this web page: http://developer.download.nvidia.com/cg/sin.html +// This is ~2x slower than sin_est() or cos_est(), and less accurate, but I'm keeping it here for comparison purposes to help validate/sanity check sin_est() and cos_est(). +inline vfloat spmd_kernel::sincos_est_a(vfloat a, bool sin_flag) +{ + const float c0_x = 0.0f, c0_y = 0.5f, c0_z = 1.0f; + const float c1_x = 0.25f, c1_y = -9.0f, c1_z = 0.75f, c1_w = 0.159154943091f; + const float c2_x = 24.9808039603f, c2_y = -24.9808039603f, c2_z = -60.1458091736f, c2_w = 60.1458091736f; + const float c3_x = 85.4537887573f, c3_y = -85.4537887573f, c3_z = -64.9393539429f, c3_w = 64.9393539429f; + const float c4_x = 19.7392082214f, c4_y = -19.7392082214f, c4_z = -1.0f, c4_w = 1.0f; + + vfloat r0_x, r0_y, r0_z, r1_x, r1_y, r1_z, r2_x, r2_y, r2_z; + + store_all(r1_x, sin_flag ? vfms(c1_w, a, c1_x) : c1_w * a); + + store_all(r1_y, frac(r1_x)); + + store_all(r2_x, (vfloat)(r1_y < c1_x)); + + store_all(r2_y, (vfloat)(r1_y >= c1_y)); + store_all(r2_z, (vfloat)(r1_y >= c1_z)); + + store_all(r2_y, vfma(r2_x, c4_z, vfma(r2_y, c4_w, r2_z * c4_z))); + + store_all(r0_x, c0_x - r1_y); + store_all(r0_y, c0_y - r1_y); + store_all(r0_z, c0_z - r1_y); + + store_all(r0_x, r0_x * r0_x); + store_all(r0_y, r0_y * r0_y); + store_all(r0_z, r0_z * r0_z); + + store_all(r1_x, vfma(c2_x, r0_x, c2_z)); + store_all(r1_y, vfma(c2_y, r0_y, c2_w)); + store_all(r1_z, vfma(c2_x, r0_z, c2_z)); + + store_all(r1_x, vfma(r1_x, r0_x, c3_x)); + store_all(r1_y, vfma(r1_y, r0_y, c3_y)); + store_all(r1_z, vfma(r1_z, r0_z, c3_x)); + + store_all(r1_x, vfma(r1_x, r0_x, c3_z)); + store_all(r1_y, vfma(r1_y, r0_y, c3_w)); + store_all(r1_z, vfma(r1_z, r0_z, c3_z)); + + store_all(r1_x, vfma(r1_x, r0_x, c4_x)); + store_all(r1_y, vfma(r1_y, r0_y, c4_y)); + store_all(r1_z, vfma(r1_z, r0_z, c4_x)); + + store_all(r1_x, vfma(r1_x, r0_x, c4_z)); + store_all(r1_y, vfma(r1_y, r0_y, c4_w)); + store_all(r1_z, vfma(r1_z, r0_z, c4_z)); + + store_all(r0_x, vfnma(r1_x, r2_x, vfnma(r1_y, r2_y, r1_z * -r2_z))); + + return r0_x; +} + +// positive values only +CPPSPMD_FORCE_INLINE vfloat spmd_kernel::recip_est1(const vfloat& q) +{ + //const int mag = 0x7EF312AC; // 2 NR iters, 3 is 0x7EEEEBB3 + const int mag = 0x7EF311C3; + const float fMinThresh = .0000125f; + + vfloat l = spmd_ternaryf(q >= fMinThresh, q, cast_vint_to_vfloat(vint(mag))); + + vint x_l = vint(mag) - cast_vfloat_to_vint(l); + + vfloat rcp_l = cast_vint_to_vfloat(x_l); + + return rcp_l * vfnma(rcp_l, q, 2.0f); +} + +CPPSPMD_FORCE_INLINE vfloat spmd_kernel::recip_est1_pn(const vfloat& t) +{ + //const int mag = 0x7EF312AC; // 2 NR iters, 3 is 0x7EEEEBB3 + const int mag = 0x7EF311C3; + const float fMinThresh = .0000125f; + + vfloat s = sign(t); + vfloat q = abs(t); + + vfloat l = spmd_ternaryf(q >= fMinThresh, q, cast_vint_to_vfloat(vint(mag))); + + vint x_l = vint(mag) - cast_vfloat_to_vint(l); + + vfloat rcp_l = cast_vint_to_vfloat(x_l); + + return rcp_l * vfnma(rcp_l, q, 2.0f) * s; +} + +// https://basesandframes.files.wordpress.com/2020/04/even_faster_math_functions_green_2020.pdf +// https://github.com/hcs0/Hackers-Delight/blob/master/rsqrt.c.txt +CPPSPMD_FORCE_INLINE vfloat spmd_kernel::rsqrt_est1(vfloat x0) +{ + vfloat xhalf = 0.5f * x0; + vfloat x = cast_vint_to_vfloat(vint(0x5F375A82) - (VINT_SHIFT_RIGHT(cast_vfloat_to_vint(x0), 1))); + return x * vfnma(xhalf * x, x, 1.5008909f); +} + +CPPSPMD_FORCE_INLINE vfloat spmd_kernel::rsqrt_est2(vfloat x0) +{ + vfloat xhalf = 0.5f * x0; + vfloat x = cast_vint_to_vfloat(vint(0x5F37599E) - (VINT_SHIFT_RIGHT(cast_vfloat_to_vint(x0), 1))); + vfloat x1 = x * vfnma(xhalf * x, x, 1.5); + vfloat x2 = x1 * vfnma(xhalf * x1, x1, 1.5); + return x2; +} + +// Math from: http://developer.download.nvidia.com/cg/atan2.html +// TODO: Needs more validation, parameter checking. +CPPSPMD_FORCE_INLINE vfloat spmd_kernel::atan2_est(vfloat y, vfloat x) +{ + vfloat t1 = abs(y); + vfloat t3 = abs(x); + + vfloat t0 = max(t3, t1); + store_all(t1, min(t3, t1)); + + store_all(t3, t1 / t0); + + vfloat t4 = t3 * t3; + store_all(t0, vfma(-0.013480470f, t4, 0.057477314f)); + store_all(t0, vfms(t0, t4, 0.121239071f)); + store_all(t0, vfma(t0, t4, 0.195635925f)); + store_all(t0, vfms(t0, t4, 0.332994597f)); + store_all(t0, vfma(t0, t4, 0.999995630f)); + store_all(t3, t0 * t3); + + store_all(t3, spmd_ternaryf(abs(y) > abs(x), vfloat(1.570796327f) - t3, t3)); + + store_all(t3, spmd_ternaryf(x < 0.0f, vfloat(3.141592654f) - t3, t3)); + store_all(t3, spmd_ternaryf(y < 0.0f, -t3, t3)); + + return t3; +} + +/* + clang 9.0.0 for win /fp:precise release + Tested range: -25.1327412287183449 25.1327382326621169, vals : 16777216 + Skipped angles near 90/270 within +- .001 radians. + Near-zero threshold: .0000125f + Near-zero output above check threshold: 1e-6f + + Total near-zero: 144, output above near-zero tresh: 20 + Total near-zero avg: 0.0000067510751968 max: 0.0000133514404297 + Total near-zero sign diffs: 5 + Total passed near-zero check: 16766400 + Total sign diffs: 5 + max abs err: 1.4982600811139264 + max rel err: 0.1459155900188041 + avg rel err: 0.0000054659502568 + + XMVectorTan() precise: + Total near-zero: 144, output above near-zero tresh: 18 + Total near-zero avg: 0.0000067641216186 max: 0.0000133524126795 + Total near-zero sign diffs: 0 + Total passed near-zero check: 16766400 + Total sign diffs: 0 + max abs err: 1.9883573246424930 + max rel err: 0.1459724171926864 + avg rel err: 0.0000054965766843 + + std::tanf(): + Total near-zero: 144, output above near-zero tresh: 0 + Total near-zero avg: 0.0000067116930779 max: 0.0000127713074107 + Total near-zero sign diffs: 11 + Total passed near-zero check: 16766400 + Total sign diffs: 11 + max abs err: 0.8989131818294709 + max rel err: 0.0573181403173166 + avg rel err: 0.0000030791301203 + + Originally from: + http://www.ganssle.com/approx.htm +*/ + +CPPSPMD_FORCE_INLINE vfloat spmd_kernel::tan82(vfloat x) +{ + // Original double version was 8.2 digits + //double c1 = 211.849369664121f, c2 = -12.5288887278448f, c3 = 269.7350131214121f, c4 = -71.4145309347748f; + // Tuned float constants for lower avg rel error (without using FMA3): + const float c1 = 211.849350f, c2 = -12.5288887f, c3 = 269.734985f, c4 = -71.4145203f; + vfloat x2 = x * x; + return (x * (vfma(c2, x2, c1)) / (vfma(x2, (c4 + x2), c3))); +} + +// Don't call this for angles close to 90/270!. +inline vfloat spmd_kernel::tan_est(vfloat x) +{ + const float fPi = 3.141592653589793f, fOneOverPi = 0.3183098861837907f; + CPPSPMD_DECL(const uint8_t, s_table0[16]) = { 128 + 0, 128 + 2, 128 + -2, 128 + 4, 128 + 0, 128 + 2, 128 + -2, 128 + 4, 128 + 0, 128 + 2, 128 + -2, 128 + 4, 128 + 0, 128 + 2, 128 + -2, 128 + 4 }; + + vint table = init_lookup4(s_table0); // a load + vint sgn = cast_vfloat_to_vint(x) & 0x80000000; + + store_all(x, abs(x)); + vfloat orig_x = x; + + vfloat q = x * fOneOverPi; + store_all(x, q - floor(q)); + + vfloat x4 = x * 4.0f; + vint octant = (vint)(x4); + + vfloat x0 = spmd_ternaryf((octant & 1) != 0, -x4, x4); + + vint k = table_lookup4_8(octant, table) & 0xFF; // a shuffle + + vfloat bias = (vfloat)k + -128.0f; + vfloat y = x0 + bias; + + vfloat z = tan82(y); + + vfloat r; + + vbool octant_one_or_two = (octant == 1) || (octant == 2); + + // SPMD optimization - skip costly divide if we can + if (spmd_any(octant_one_or_two)) + { + const float fDivThresh = .4371e-7f; + vfloat one_over_z = 1.0f / spmd_ternaryf(abs(z) > fDivThresh, z, spmd_ternaryf(z < 0.0f, -fDivThresh, fDivThresh)); + + vfloat b = spmd_ternaryf(octant_one_or_two, one_over_z, z); + store_all(r, spmd_ternaryf((octant & 2) != 0, -b, b)); + } + else + { + store_all(r, spmd_ternaryf(octant == 0, z, -z)); + } + + // Small angle approximation, to decrease the max rel error near Pi. + SPMD_SIF(x >= (1.0f - .0003125f*4.0f)) + { + store(r, vfnma(floor(q) + 1.0f, fPi, orig_x)); + } + SPMD_SENDIF + + return cast_vint_to_vfloat(cast_vfloat_to_vint(r) ^ sgn); +} + +inline void spmd_kernel::seed_rand(rand_context& x, vint seed) +{ + store(x.a, 0xf1ea5eed); + store(x.b, seed ^ 0xd8487b1f); + store(x.c, seed ^ 0xdbadef9a); + store(x.d, seed); + for (int i = 0; i < 20; ++i) + (void)get_randu(x); +} + +// https://burtleburtle.net/bob/rand/smallprng.html +// Returns 32-bit unsigned random numbers. +inline vint spmd_kernel::get_randu(rand_context& x) +{ + vint e = x.a - VINT_ROT(x.b, 27); + store(x.a, x.b ^ VINT_ROT(x.c, 17)); + store(x.b, x.c + x.d); + store(x.c, x.d + e); + store(x.d, e + x.a); + return x.d; +} + +// Returns random numbers between [low, high), or low if low >= high +inline vint spmd_kernel::get_randi(rand_context& x, vint low, vint high) +{ + vint rnd = get_randu(x); + + vint range = high - low; + + vint rnd_range = mulhiu(rnd, range); + + return spmd_ternaryi(low < high, low + rnd_range, low); +} + +// Returns random numbers between [low, high), or low if low >= high +inline vfloat spmd_kernel::get_randf(rand_context& x, vfloat low, vfloat high) +{ + vint rndi = get_randu(x) & 0x7fffff; + + vfloat rnd = (vfloat)(rndi) * (1.0f / 8388608.0f); + + return spmd_ternaryf(low < high, vfma(high - low, rnd, low), low); +} + +CPPSPMD_FORCE_INLINE void spmd_kernel::init_reverse_bits(vint& tab1, vint& tab2) +{ + const uint8_t tab1_bytes[16] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; + const uint8_t tab2_bytes[16] = { 0, 8 << 4, 4 << 4, 12 << 4, 2 << 4, 10 << 4, 6 << 4, 14 << 4, 1 << 4, 9 << 4, 5 << 4, 13 << 4, 3 << 4, 11 << 4, 7 << 4, 15 << 4 }; + store_all(tab1, init_lookup4(tab1_bytes)); + store_all(tab2, init_lookup4(tab2_bytes)); +} + +CPPSPMD_FORCE_INLINE vint spmd_kernel::reverse_bits(vint k, vint tab1, vint tab2) +{ + vint r0 = table_lookup4_8(k & 0x7F7F7F7F, tab2); + vint r1 = table_lookup4_8(VUINT_SHIFT_RIGHT(k, 4) & 0x7F7F7F7F, tab1); + vint r3 = r0 | r1; + return byteswap(r3); +} + +CPPSPMD_FORCE_INLINE vint spmd_kernel::count_leading_zeros(vint x) +{ + CPPSPMD_DECL(const uint8_t, s_tab[16]) = { 0, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + + vint tab = init_lookup4(s_tab); + + //x <= 0x0000ffff + vbool c0 = (x & 0xFFFF0000) == 0; + vint n0 = spmd_ternaryi(c0, 16, 0); + vint x0 = spmd_ternaryi(c0, VINT_SHIFT_LEFT(x, 16), x); + + //x <= 0x00ffffff + vbool c1 = (x0 & 0xFF000000) == 0; + vint n1 = spmd_ternaryi(c1, n0 + 8, n0); + vint x1 = spmd_ternaryi(c1, VINT_SHIFT_LEFT(x0, 8), x0); + + //x <= 0x0fffffff + vbool c2 = (x1 & 0xF0000000) == 0; + vint n2 = spmd_ternaryi(c2, n1 + 4, n1); + vint x2 = spmd_ternaryi(c2, VINT_SHIFT_LEFT(x1, 4), x1); + + return table_lookup4_8(VUINT_SHIFT_RIGHT(x2, 28), tab) + n2; +} + +CPPSPMD_FORCE_INLINE vint spmd_kernel::count_leading_zeros_alt(vint x) +{ + //x <= 0x0000ffff + vbool c0 = (x & 0xFFFF0000) == 0; + vint n0 = spmd_ternaryi(c0, 16, 0); + vint x0 = spmd_ternaryi(c0, VINT_SHIFT_LEFT(x, 16), x); + + //x <= 0x00ffffff + vbool c1 = (x0 & 0xFF000000) == 0; + vint n1 = spmd_ternaryi(c1, n0 + 8, n0); + vint x1 = spmd_ternaryi(c1, VINT_SHIFT_LEFT(x0, 8), x0); + + //x <= 0x0fffffff + vbool c2 = (x1 & 0xF0000000) == 0; + vint n2 = spmd_ternaryi(c2, n1 + 4, n1); + vint x2 = spmd_ternaryi(c2, VINT_SHIFT_LEFT(x1, 4), x1); + + // x <= 0x3fffffff + vbool c3 = (x2 & 0xC0000000) == 0; + vint n3 = spmd_ternaryi(c3, n2 + 2, n2); + vint x3 = spmd_ternaryi(c3, VINT_SHIFT_LEFT(x2, 2), x2); + + // x <= 0x7fffffff + vbool c4 = (x3 & 0x80000000) == 0; + return spmd_ternaryi(c4, n3 + 1, n3); +} + +CPPSPMD_FORCE_INLINE vint spmd_kernel::count_trailing_zeros(vint x) +{ + // cast the least significant bit in v to a float + vfloat f = (vfloat)(x & -x); + + // extract exponent and adjust + return VUINT_SHIFT_RIGHT(cast_vfloat_to_vint(f), 23) - 0x7F; +} + +CPPSPMD_FORCE_INLINE vint spmd_kernel::count_set_bits(vint x) +{ + vint v = x - (VUINT_SHIFT_RIGHT(x, 1) & 0x55555555); + vint v1 = (v & 0x33333333) + (VUINT_SHIFT_RIGHT(v, 2) & 0x33333333); + return VUINT_SHIFT_RIGHT(((v1 + VUINT_SHIFT_RIGHT(v1, 4) & 0xF0F0F0F) * 0x1010101), 24); +} + +CPPSPMD_FORCE_INLINE vint cmple_epu16(const vint &a, const vint &b) +{ + return cmpeq_epi16(subs_epu16(a, b), vint(0)); +} + +CPPSPMD_FORCE_INLINE vint cmpge_epu16(const vint &a, const vint &b) +{ + return cmple_epu16(b, a); +} + +CPPSPMD_FORCE_INLINE vint cmpgt_epu16(const vint &a, const vint &b) +{ + return andnot(cmpeq_epi16(a, b), cmple_epu16(b, a)); +} + +CPPSPMD_FORCE_INLINE vint cmplt_epu16(const vint &a, const vint &b) +{ + return cmpgt_epu16(b, a); +} + +CPPSPMD_FORCE_INLINE vint cmpge_epi16(const vint &a, const vint &b) +{ + return cmpeq_epi16(a, b) | cmpgt_epi16(a, b); +} + +CPPSPMD_FORCE_INLINE vint cmple_epi16(const vint &a, const vint &b) +{ + return cmpge_epi16(b, a); +} + +void spmd_kernel::print_vint(vint v) +{ + for (uint32_t i = 0; i < PROGRAM_COUNT; i++) + printf("%i ", extract(v, i)); + printf("\n"); +} + +void spmd_kernel::print_vbool(vbool v) +{ + for (uint32_t i = 0; i < PROGRAM_COUNT; i++) + printf("%i ", extract(v, i) ? 1 : 0); + printf("\n"); +} + +void spmd_kernel::print_vint_hex(vint v) +{ + for (uint32_t i = 0; i < PROGRAM_COUNT; i++) + printf("0x%X ", extract(v, i)); + printf("\n"); +} + +void spmd_kernel::print_active_lanes(const char *pPrefix) +{ + CPPSPMD_DECL(int, flags[PROGRAM_COUNT]); + memset(flags, 0, sizeof(flags)); + storeu_linear(flags, vint(1)); + + if (pPrefix) + printf("%s", pPrefix); + + for (uint32_t i = 0; i < PROGRAM_COUNT; i++) + { + if (flags[i]) + printf("%u ", i); + } + printf("\n"); +} + +void spmd_kernel::print_vfloat(vfloat v) +{ + for (uint32_t i = 0; i < PROGRAM_COUNT; i++) + printf("%f ", extract(v, i)); + printf("\n"); +} diff --git a/thirdparty/basis_universal/encoder/cppspmd_math_declares.h b/thirdparty/basis_universal/encoder/cppspmd_math_declares.h new file mode 100644 index 0000000000..cdb6447b62 --- /dev/null +++ b/thirdparty/basis_universal/encoder/cppspmd_math_declares.h @@ -0,0 +1,89 @@ +// Do not include this header directly. +// This header defines shared struct spmd_kernel helpers. +// +// Copyright 2020-2021 Binomial LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// See cppspmd_math.h for detailed error statistics. + +CPPSPMD_FORCE_INLINE void reduce_expb(vfloat& arg, vfloat& two_int_a, vint& adjustment); +CPPSPMD_FORCE_INLINE vfloat tan56(vfloat x); +CPPSPMD_FORCE_INLINE vfloat tan82(vfloat x); + +inline vfloat log2_est(vfloat v); + +inline vfloat log_est(vfloat v); + +inline vfloat exp2_est(vfloat arg); + +inline vfloat exp_est(vfloat arg); + +inline vfloat pow_est(vfloat arg1, vfloat arg2); + +CPPSPMD_FORCE_INLINE vfloat recip_est1(const vfloat& q); +CPPSPMD_FORCE_INLINE vfloat recip_est1_pn(const vfloat& q); + +inline vfloat mod_angles(vfloat a); + +inline vfloat sincos_est_a(vfloat a, bool sin_flag); +CPPSPMD_FORCE_INLINE vfloat sin_est_a(vfloat a) { return sincos_est_a(a, true); } +CPPSPMD_FORCE_INLINE vfloat cos_est_a(vfloat a) { return sincos_est_a(a, false); } + +inline vfloat sin_est(vfloat a); + +inline vfloat cos_est(vfloat a); + +// Don't call with values <= 0. +CPPSPMD_FORCE_INLINE vfloat rsqrt_est1(vfloat x0); + +// Don't call with values <= 0. +CPPSPMD_FORCE_INLINE vfloat rsqrt_est2(vfloat x0); + +CPPSPMD_FORCE_INLINE vfloat atan2_est(vfloat y, vfloat x); + +CPPSPMD_FORCE_INLINE vfloat atan_est(vfloat x) { return atan2_est(x, vfloat(1.0f)); } + +// Don't call this for angles close to 90/270! +inline vfloat tan_est(vfloat x); + +// https://burtleburtle.net/bob/rand/smallprng.html +struct rand_context { vint a, b, c, d; }; + +inline void seed_rand(rand_context& x, vint seed); + +// Returns 32-bit unsigned random numbers. +inline vint get_randu(rand_context& x); + +// Returns random numbers between [low, high), or low if low >= high +inline vint get_randi(rand_context& x, vint low, vint high); + +// Returns random numbers between [low, high), or low if low >= high +inline vfloat get_randf(rand_context& x, vfloat low, vfloat high); + +CPPSPMD_FORCE_INLINE void init_reverse_bits(vint& tab1, vint& tab2); +CPPSPMD_FORCE_INLINE vint reverse_bits(vint k, vint tab1, vint tab2); + +CPPSPMD_FORCE_INLINE vint count_leading_zeros(vint x); +CPPSPMD_FORCE_INLINE vint count_leading_zeros_alt(vint x); + +CPPSPMD_FORCE_INLINE vint count_trailing_zeros(vint x); + +CPPSPMD_FORCE_INLINE vint count_set_bits(vint x); + +void print_vint(vint v); +void print_vbool(vbool v); +void print_vint_hex(vint v); +void print_active_lanes(const char *pPrefix); +void print_vfloat(vfloat v); + diff --git a/thirdparty/basis_universal/encoder/cppspmd_sse.h b/thirdparty/basis_universal/encoder/cppspmd_sse.h new file mode 100644 index 0000000000..b39cb82a5f --- /dev/null +++ b/thirdparty/basis_universal/encoder/cppspmd_sse.h @@ -0,0 +1,2118 @@ +// cppspmd_sse.h +// Note for Basis Universal: All of the "cppspmd" code and headers are OPTIONAL to Basis Universal. if BASISU_SUPPORT_SSE is 0, it will never be included and does not impact compilation. +// SSE 2 or 4.1 +// Originally written by Nicolas Guillemot, Jefferson Amstutz in the "CppSPMD" project. +// 4/20: Richard Geldreich: Macro control flow, more SIMD instruction sets, optimizations, supports using multiple SIMD instruction sets in same executable. Still a work in progress! +// +// Originally Copyright 2016 Nicolas Guillemot +// Changed from the MIT license to Apache 2.0 with permission from the author. +// +// Modifications/enhancements Copyright 2020-2021 Binomial LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <stdlib.h> +#include <stdint.h> +#include <assert.h> +#include <math.h> +#include <utility> +#include <algorithm> + +#if CPPSPMD_SSE2 +#include <xmmintrin.h> // SSE +#include <emmintrin.h> // SSE2 +#else +#include <xmmintrin.h> // SSE +#include <emmintrin.h> // SSE2 +#include <pmmintrin.h> // SSE3 +#include <tmmintrin.h> // SSSE3 +#include <smmintrin.h> // SSE4.1 +//#include <nmmintrin.h> // SSE4.2 +#endif + +#undef CPPSPMD_SSE +#undef CPPSPMD_AVX1 +#undef CPPSPMD_AVX2 +#undef CPPSPMD_AVX +#undef CPPSPMD_FLOAT4 +#undef CPPSPMD_INT16 + +#define CPPSPMD_SSE 1 +#define CPPSPMD_AVX 0 +#define CPPSPMD_AVX1 0 +#define CPPSPMD_AVX2 0 +#define CPPSPMD_FLOAT4 0 +#define CPPSPMD_INT16 0 + +#ifdef _MSC_VER + #ifndef CPPSPMD_DECL + #define CPPSPMD_DECL(type, name) __declspec(align(16)) type name + #endif + + #ifndef CPPSPMD_ALIGN + #define CPPSPMD_ALIGN(v) __declspec(align(v)) + #endif + + #define _mm_undefined_si128 _mm_setzero_si128 + #define _mm_undefined_ps _mm_setzero_ps +#else + #ifndef CPPSPMD_DECL + #define CPPSPMD_DECL(type, name) type name __attribute__((aligned(32))) + #endif + + #ifndef CPPSPMD_ALIGN + #define CPPSPMD_ALIGN(v) __attribute__((aligned(v))) + #endif +#endif + +#ifndef CPPSPMD_FORCE_INLINE +#ifdef _DEBUG +#define CPPSPMD_FORCE_INLINE inline +#else + #ifdef _MSC_VER + #define CPPSPMD_FORCE_INLINE __forceinline + #else + #define CPPSPMD_FORCE_INLINE inline + #endif +#endif +#endif + +#undef CPPSPMD +#undef CPPSPMD_ARCH + +#if CPPSPMD_SSE2 + #define CPPSPMD_SSE41 0 + #define CPPSPMD cppspmd_sse2 + #define CPPSPMD_ARCH _sse2 +#else + #define CPPSPMD_SSE41 1 + #define CPPSPMD cppspmd_sse41 + #define CPPSPMD_ARCH _sse41 +#endif + +#ifndef CPPSPMD_GLUER + #define CPPSPMD_GLUER(a, b) a##b +#endif + +#ifndef CPPSPMD_GLUER2 + #define CPPSPMD_GLUER2(a, b) CPPSPMD_GLUER(a, b) +#endif + +#ifndef CPPSPMD_NAME +#define CPPSPMD_NAME(a) CPPSPMD_GLUER2(a, CPPSPMD_ARCH) +#endif + +#undef VASSERT +#define VCOND(cond) ((exec_mask(vbool(cond)) & m_exec).get_movemask() == m_exec.get_movemask()) +#define VASSERT(cond) assert( VCOND(cond) ) + +#define CPPSPMD_ALIGNMENT (16) + +#define storeu_si32(p, a) (void)(*(int*)(p) = _mm_cvtsi128_si32((a))) + +namespace CPPSPMD +{ + +const int PROGRAM_COUNT_SHIFT = 2; +const int PROGRAM_COUNT = 1 << PROGRAM_COUNT_SHIFT; + +template <typename N> inline N* aligned_new() { void* p = _mm_malloc(sizeof(N), 64); new (p) N; return static_cast<N*>(p); } +template <typename N> void aligned_delete(N* p) { if (p) { p->~N(); _mm_free(p); } } + +CPPSPMD_DECL(const uint32_t, g_allones_128[4]) = { UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX }; +CPPSPMD_DECL(const uint32_t, g_x_128[4]) = { UINT32_MAX, 0, 0, 0 }; +CPPSPMD_DECL(const float, g_onef_128[4]) = { 1.0f, 1.0f, 1.0f, 1.0f }; +CPPSPMD_DECL(const uint32_t, g_oneu_128[4]) = { 1, 1, 1, 1 }; + +CPPSPMD_DECL(const uint32_t, g_lane_masks_128[4][4]) = +{ + { UINT32_MAX, 0, 0, 0 }, + { 0, UINT32_MAX, 0, 0 }, + { 0, 0, UINT32_MAX, 0 }, + { 0, 0, 0, UINT32_MAX }, +}; + +#if CPPSPMD_SSE41 +CPPSPMD_FORCE_INLINE __m128i _mm_blendv_epi32(__m128i a, __m128i b, __m128i c) { return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _mm_castsi128_ps(c))); } +#endif + +CPPSPMD_FORCE_INLINE __m128i blendv_epi8(__m128i a, __m128i b, __m128i mask) +{ +#if CPPSPMD_SSE2 + return _mm_castps_si128(_mm_or_ps(_mm_and_ps(_mm_castsi128_ps(mask), _mm_castsi128_ps(b)), _mm_andnot_ps(_mm_castsi128_ps(mask), _mm_castsi128_ps(a)))); +#else + return _mm_blendv_epi8(a, b, mask); +#endif +} + +CPPSPMD_FORCE_INLINE __m128 blendv_mask_ps(__m128 a, __m128 b, __m128 mask) +{ +#if CPPSPMD_SSE2 + // We know it's a mask, so we can just emulate the blend. + return _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a)); +#else + return _mm_blendv_ps(a, b, mask); +#endif +} + +CPPSPMD_FORCE_INLINE __m128 blendv_ps(__m128 a, __m128 b, __m128 mask) +{ +#if CPPSPMD_SSE2 + // Input is not a mask, but MSB bits - so emulate _mm_blendv_ps() by replicating bit 31. + mask = _mm_castsi128_ps(_mm_srai_epi32(_mm_castps_si128(mask), 31)); + return _mm_or_ps(_mm_and_ps(mask, b), _mm_andnot_ps(mask, a)); +#else + return _mm_blendv_ps(a, b, mask); +#endif +} + +CPPSPMD_FORCE_INLINE __m128i blendv_mask_epi32(__m128i a, __m128i b, __m128i mask) +{ + return _mm_castps_si128(blendv_mask_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _mm_castsi128_ps(mask))); +} + +CPPSPMD_FORCE_INLINE __m128i blendv_epi32(__m128i a, __m128i b, __m128i mask) +{ + return _mm_castps_si128(blendv_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _mm_castsi128_ps(mask))); +} + +#if CPPSPMD_SSE2 +CPPSPMD_FORCE_INLINE int extract_x(const __m128i& vec) { return _mm_cvtsi128_si32(vec); } +CPPSPMD_FORCE_INLINE int extract_y(const __m128i& vec) { return _mm_cvtsi128_si32(_mm_shuffle_epi32(vec, 0x55)); } +CPPSPMD_FORCE_INLINE int extract_z(const __m128i& vec) { return _mm_cvtsi128_si32(_mm_shuffle_epi32(vec, 0xAA)); } +CPPSPMD_FORCE_INLINE int extract_w(const __m128i& vec) { return _mm_cvtsi128_si32(_mm_shuffle_epi32(vec, 0xFF)); } + +// Returns float bits as int, to emulate _mm_extract_ps() +CPPSPMD_FORCE_INLINE int extract_ps_x(const __m128& vec) { float f = _mm_cvtss_f32(vec); return *(const int*)&f; } +CPPSPMD_FORCE_INLINE int extract_ps_y(const __m128& vec) { float f = _mm_cvtss_f32(_mm_shuffle_ps(vec, vec, 0x55)); return *(const int*)&f; } +CPPSPMD_FORCE_INLINE int extract_ps_z(const __m128& vec) { float f = _mm_cvtss_f32(_mm_shuffle_ps(vec, vec, 0xAA)); return *(const int*)&f; } +CPPSPMD_FORCE_INLINE int extract_ps_w(const __m128& vec) { float f = _mm_cvtss_f32(_mm_shuffle_ps(vec, vec, 0xFF)); return *(const int*)&f; } + +// Returns floats +CPPSPMD_FORCE_INLINE float extractf_ps_x(const __m128& vec) { return _mm_cvtss_f32(vec); } +CPPSPMD_FORCE_INLINE float extractf_ps_y(const __m128& vec) { return _mm_cvtss_f32(_mm_shuffle_ps(vec, vec, 0x55)); } +CPPSPMD_FORCE_INLINE float extractf_ps_z(const __m128& vec) { return _mm_cvtss_f32(_mm_shuffle_ps(vec, vec, 0xAA)); } +CPPSPMD_FORCE_INLINE float extractf_ps_w(const __m128& vec) { return _mm_cvtss_f32(_mm_shuffle_ps(vec, vec, 0xFF)); } +#else +CPPSPMD_FORCE_INLINE int extract_x(const __m128i& vec) { return _mm_extract_epi32(vec, 0); } +CPPSPMD_FORCE_INLINE int extract_y(const __m128i& vec) { return _mm_extract_epi32(vec, 1); } +CPPSPMD_FORCE_INLINE int extract_z(const __m128i& vec) { return _mm_extract_epi32(vec, 2); } +CPPSPMD_FORCE_INLINE int extract_w(const __m128i& vec) { return _mm_extract_epi32(vec, 3); } + +// Returns float bits as int +CPPSPMD_FORCE_INLINE int extract_ps_x(const __m128& vec) { return _mm_extract_ps(vec, 0); } +CPPSPMD_FORCE_INLINE int extract_ps_y(const __m128& vec) { return _mm_extract_ps(vec, 1); } +CPPSPMD_FORCE_INLINE int extract_ps_z(const __m128& vec) { return _mm_extract_ps(vec, 2); } +CPPSPMD_FORCE_INLINE int extract_ps_w(const __m128& vec) { return _mm_extract_ps(vec, 3); } + +// Returns floats +CPPSPMD_FORCE_INLINE float extractf_ps_x(const __m128& vec) { int v = extract_ps_x(vec); return *(const float*)&v; } +CPPSPMD_FORCE_INLINE float extractf_ps_y(const __m128& vec) { int v = extract_ps_y(vec); return *(const float*)&v; } +CPPSPMD_FORCE_INLINE float extractf_ps_z(const __m128& vec) { int v = extract_ps_z(vec); return *(const float*)&v; } +CPPSPMD_FORCE_INLINE float extractf_ps_w(const __m128& vec) { int v = extract_ps_w(vec); return *(const float*)&v; } +#endif + +#if CPPSPMD_SSE2 +CPPSPMD_FORCE_INLINE __m128i insert_x(const __m128i& vec, int v) { return _mm_insert_epi16(_mm_insert_epi16(vec, v, 0), (uint32_t)v >> 16U, 1); } +CPPSPMD_FORCE_INLINE __m128i insert_y(const __m128i& vec, int v) { return _mm_insert_epi16(_mm_insert_epi16(vec, v, 2), (uint32_t)v >> 16U, 3); } +CPPSPMD_FORCE_INLINE __m128i insert_z(const __m128i& vec, int v) { return _mm_insert_epi16(_mm_insert_epi16(vec, v, 4), (uint32_t)v >> 16U, 5); } +CPPSPMD_FORCE_INLINE __m128i insert_w(const __m128i& vec, int v) { return _mm_insert_epi16(_mm_insert_epi16(vec, v, 6), (uint32_t)v >> 16U, 7); } +#else +CPPSPMD_FORCE_INLINE __m128i insert_x(const __m128i& vec, int v) { return _mm_insert_epi32(vec, v, 0); } +CPPSPMD_FORCE_INLINE __m128i insert_y(const __m128i& vec, int v) { return _mm_insert_epi32(vec, v, 1); } +CPPSPMD_FORCE_INLINE __m128i insert_z(const __m128i& vec, int v) { return _mm_insert_epi32(vec, v, 2); } +CPPSPMD_FORCE_INLINE __m128i insert_w(const __m128i& vec, int v) { return _mm_insert_epi32(vec, v, 3); } +#endif + +#if CPPSPMD_SSE2 +inline __m128i shuffle_epi8(const __m128i& a, const __m128i& b) +{ + // Just emulate _mm_shuffle_epi8. This is very slow, but what else can we do? + CPPSPMD_ALIGN(16) uint8_t av[16]; + _mm_store_si128((__m128i*)av, a); + + CPPSPMD_ALIGN(16) uint8_t bvi[16]; + _mm_store_ps((float*)bvi, _mm_and_ps(_mm_castsi128_ps(b), _mm_castsi128_ps(_mm_set1_epi32(0x0F0F0F0F)))); + + CPPSPMD_ALIGN(16) uint8_t result[16]; + + result[0] = av[bvi[0]]; + result[1] = av[bvi[1]]; + result[2] = av[bvi[2]]; + result[3] = av[bvi[3]]; + + result[4] = av[bvi[4]]; + result[5] = av[bvi[5]]; + result[6] = av[bvi[6]]; + result[7] = av[bvi[7]]; + + result[8] = av[bvi[8]]; + result[9] = av[bvi[9]]; + result[10] = av[bvi[10]]; + result[11] = av[bvi[11]]; + + result[12] = av[bvi[12]]; + result[13] = av[bvi[13]]; + result[14] = av[bvi[14]]; + result[15] = av[bvi[15]]; + + return _mm_andnot_si128(_mm_cmplt_epi8(b, _mm_setzero_si128()), _mm_load_si128((__m128i*)result)); +} +#else +CPPSPMD_FORCE_INLINE __m128i shuffle_epi8(const __m128i& a, const __m128i& b) +{ + return _mm_shuffle_epi8(a, b); +} +#endif + +#if CPPSPMD_SSE2 +CPPSPMD_FORCE_INLINE __m128i min_epi32(__m128i a, __m128i b) +{ + return blendv_mask_epi32(b, a, _mm_cmplt_epi32(a, b)); +} +CPPSPMD_FORCE_INLINE __m128i max_epi32(__m128i a, __m128i b) +{ + return blendv_mask_epi32(b, a, _mm_cmpgt_epi32(a, b)); +} +CPPSPMD_FORCE_INLINE __m128i min_epu32(__m128i a, __m128i b) +{ + __m128i n = _mm_set1_epi32(0x80000000); + __m128i ac = _mm_add_epi32(a, n); + __m128i bc = _mm_add_epi32(b, n); + return blendv_mask_epi32(b, a, _mm_cmplt_epi32(ac, bc)); +} +CPPSPMD_FORCE_INLINE __m128i max_epu32(__m128i a, __m128i b) +{ + __m128i n = _mm_set1_epi32(0x80000000); + __m128i ac = _mm_add_epi32(a, n); + __m128i bc = _mm_add_epi32(b, n); + return blendv_mask_epi32(b, a, _mm_cmpgt_epi32(ac, bc)); +} +#else +CPPSPMD_FORCE_INLINE __m128i min_epi32(__m128i a, __m128i b) +{ + return _mm_min_epi32(a, b); +} +CPPSPMD_FORCE_INLINE __m128i max_epi32(__m128i a, __m128i b) +{ + return _mm_max_epi32(a, b); +} +CPPSPMD_FORCE_INLINE __m128i min_epu32(__m128i a, __m128i b) +{ + return _mm_min_epu32(a, b); +} +CPPSPMD_FORCE_INLINE __m128i max_epu32(__m128i a, __m128i b) +{ + return _mm_max_epu32(a, b); +} +#endif + +#if CPPSPMD_SSE2 +CPPSPMD_FORCE_INLINE __m128i abs_epi32(__m128i a) +{ + __m128i sign_mask = _mm_srai_epi32(a, 31); + return _mm_sub_epi32(_mm_castps_si128(_mm_xor_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(sign_mask))), sign_mask); +} +#else +CPPSPMD_FORCE_INLINE __m128i abs_epi32(__m128i a) +{ + return _mm_abs_epi32(a); +} +#endif + +#if CPPSPMD_SSE2 +CPPSPMD_FORCE_INLINE __m128i mullo_epi32(__m128i a, __m128i b) +{ + __m128i tmp1 = _mm_mul_epu32(a, b); + __m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(a, 4), _mm_srli_si128(b, 4)); + return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0))); +} +#else +CPPSPMD_FORCE_INLINE __m128i mullo_epi32(__m128i a, __m128i b) +{ + return _mm_mullo_epi32(a, b); +} +#endif + +CPPSPMD_FORCE_INLINE __m128i mulhi_epu32(__m128i a, __m128i b) +{ + __m128i tmp1 = _mm_mul_epu32(a, b); + __m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(a, 4), _mm_srli_si128(b, 4)); + return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 3, 1)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 3, 1))); +} + +#if CPPSPMD_SSE2 +inline __m128i load_rgba32(const void* p) +{ + __m128i xmm = _mm_cvtsi32_si128(*(const int*)p); + xmm = _mm_unpacklo_epi8(xmm, _mm_setzero_si128()); + xmm = _mm_unpacklo_epi16(xmm, _mm_setzero_si128()); + return xmm; +} +#else +inline __m128i load_rgba32(const void* p) +{ + return _mm_cvtepu8_epi32(_mm_castps_si128(_mm_load_ss((const float*)p))); +} +#endif + +inline void transpose4x4(__m128i& x, __m128i& y, __m128i& z, __m128i& w, const __m128i& r0, const __m128i& r1, const __m128i& r2, const __m128i& r3) +{ + __m128i t0 = _mm_unpacklo_epi32(r0, r1); + __m128i t1 = _mm_unpacklo_epi32(r2, r3); + __m128i t2 = _mm_unpackhi_epi32(r0, r1); + __m128i t3 = _mm_unpackhi_epi32(r2, r3); + x = _mm_unpacklo_epi64(t0, t1); + y = _mm_unpackhi_epi64(t0, t1); + z = _mm_unpacklo_epi64(t2, t3); + w = _mm_unpackhi_epi64(t2, t3); +} + +const uint32_t ALL_ON_MOVEMASK = 0xF; + +struct spmd_kernel +{ + struct vint; + struct lint; + struct vbool; + struct vfloat; + + typedef int int_t; + typedef vint vint_t; + typedef lint lint_t; + + // Exec mask + struct exec_mask + { + __m128i m_mask; + + exec_mask() = default; + + CPPSPMD_FORCE_INLINE explicit exec_mask(const vbool& b); + CPPSPMD_FORCE_INLINE explicit exec_mask(const __m128i& mask) : m_mask(mask) { } + + CPPSPMD_FORCE_INLINE void enable_lane(uint32_t lane) { m_mask = _mm_load_si128((const __m128i *)&g_lane_masks_128[lane][0]); } + + static CPPSPMD_FORCE_INLINE exec_mask all_on() { return exec_mask{ _mm_load_si128((const __m128i*)g_allones_128) }; } + static CPPSPMD_FORCE_INLINE exec_mask all_off() { return exec_mask{ _mm_setzero_si128() }; } + + CPPSPMD_FORCE_INLINE uint32_t get_movemask() const { return _mm_movemask_ps(_mm_castsi128_ps(m_mask)); } + }; + + friend CPPSPMD_FORCE_INLINE bool all(const exec_mask& e); + friend CPPSPMD_FORCE_INLINE bool any(const exec_mask& e); + + CPPSPMD_FORCE_INLINE bool spmd_all() const { return all(m_exec); } + CPPSPMD_FORCE_INLINE bool spmd_any() const { return any(m_exec); } + CPPSPMD_FORCE_INLINE bool spmd_none() { return !any(m_exec); } + + // true if cond is true for all active lanes - false if no active lanes + CPPSPMD_FORCE_INLINE bool spmd_all(const vbool& e) { uint32_t m = m_exec.get_movemask(); return (m != 0) && ((exec_mask(e) & m_exec).get_movemask() == m); } + // true if cond is true for any active lanes + CPPSPMD_FORCE_INLINE bool spmd_any(const vbool& e) { return (exec_mask(e) & m_exec).get_movemask() != 0; } + CPPSPMD_FORCE_INLINE bool spmd_none(const vbool& e) { return !spmd_any(e); } + + friend CPPSPMD_FORCE_INLINE exec_mask operator^ (const exec_mask& a, const exec_mask& b); + friend CPPSPMD_FORCE_INLINE exec_mask operator& (const exec_mask& a, const exec_mask& b); + friend CPPSPMD_FORCE_INLINE exec_mask operator| (const exec_mask& a, const exec_mask& b); + + exec_mask m_exec; + exec_mask m_kernel_exec; + exec_mask m_continue_mask; +#ifdef _DEBUG + bool m_in_loop; +#endif + + CPPSPMD_FORCE_INLINE uint32_t get_movemask() const { return m_exec.get_movemask(); } + + void init(const exec_mask& kernel_exec); + + // Varying bool + + struct vbool + { + __m128i m_value; + + vbool() = default; + + CPPSPMD_FORCE_INLINE vbool(bool value) : m_value(_mm_set1_epi32(value ? UINT32_MAX : 0)) { } + + CPPSPMD_FORCE_INLINE explicit vbool(const __m128i& value) : m_value(value) { } + + CPPSPMD_FORCE_INLINE explicit operator vfloat() const; + CPPSPMD_FORCE_INLINE explicit operator vint() const; + + private: + vbool& operator=(const vbool&); + }; + + friend vbool operator!(const vbool& v); + + CPPSPMD_FORCE_INLINE vbool& store(vbool& dst, const vbool& src) + { + dst.m_value = blendv_mask_epi32(dst.m_value, src.m_value, m_exec.m_mask); + return dst; + } + + CPPSPMD_FORCE_INLINE vbool& store_all(vbool& dst, const vbool& src) + { + dst.m_value = src.m_value; + return dst; + } + + // Varying float + struct vfloat + { + __m128 m_value; + + vfloat() = default; + + CPPSPMD_FORCE_INLINE explicit vfloat(const __m128& v) : m_value(v) { } + + CPPSPMD_FORCE_INLINE vfloat(float value) : m_value(_mm_set1_ps(value)) { } + + CPPSPMD_FORCE_INLINE explicit vfloat(int value) : m_value(_mm_set1_ps((float)value)) { } + + private: + vfloat& operator=(const vfloat&); + }; + + CPPSPMD_FORCE_INLINE vfloat& store(vfloat& dst, const vfloat& src) + { + dst.m_value = blendv_mask_ps(dst.m_value, src.m_value, _mm_castsi128_ps(m_exec.m_mask)); + return dst; + } + + CPPSPMD_FORCE_INLINE vfloat& store(vfloat&& dst, const vfloat& src) + { + dst.m_value = blendv_mask_ps(dst.m_value, src.m_value, _mm_castsi128_ps(m_exec.m_mask)); + return dst; + } + + CPPSPMD_FORCE_INLINE vfloat& store_all(vfloat& dst, const vfloat& src) + { + dst.m_value = src.m_value; + return dst; + } + + CPPSPMD_FORCE_INLINE vfloat& store_all(vfloat&& dst, const vfloat& src) + { + dst.m_value = src.m_value; + return dst; + } + + // Linear ref to floats + struct float_lref + { + float* m_pValue; + + private: + float_lref& operator=(const float_lref&); + }; + + CPPSPMD_FORCE_INLINE const float_lref& store(const float_lref& dst, const vfloat& src) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + if (mask == ALL_ON_MOVEMASK) + _mm_storeu_ps(dst.m_pValue, src.m_value); + else + _mm_storeu_ps(dst.m_pValue, blendv_mask_ps(_mm_loadu_ps(dst.m_pValue), src.m_value, _mm_castsi128_ps(m_exec.m_mask))); + return dst; + } + + CPPSPMD_FORCE_INLINE const float_lref& store(const float_lref&& dst, const vfloat& src) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + if (mask == ALL_ON_MOVEMASK) + _mm_storeu_ps(dst.m_pValue, src.m_value); + else + _mm_storeu_ps(dst.m_pValue, blendv_mask_ps(_mm_loadu_ps(dst.m_pValue), src.m_value, _mm_castsi128_ps(m_exec.m_mask))); + return dst; + } + + CPPSPMD_FORCE_INLINE const float_lref& store_all(const float_lref& dst, const vfloat& src) + { + _mm_storeu_ps(dst.m_pValue, src.m_value); + return dst; + } + + CPPSPMD_FORCE_INLINE const float_lref& store_all(const float_lref&& dst, const vfloat& src) + { + _mm_storeu_ps(dst.m_pValue, src.m_value); + return dst; + } + + CPPSPMD_FORCE_INLINE vfloat load(const float_lref& src) + { + return vfloat{ _mm_and_ps(_mm_loadu_ps(src.m_pValue), _mm_castsi128_ps(m_exec.m_mask)) }; + } + + // Varying ref to floats + struct float_vref + { + __m128i m_vindex; + float* m_pValue; + + private: + float_vref& operator=(const float_vref&); + }; + + // Varying ref to varying float + struct vfloat_vref + { + __m128i m_vindex; + vfloat* m_pValue; + + private: + vfloat_vref& operator=(const vfloat_vref&); + }; + + // Varying ref to varying int + struct vint_vref + { + __m128i m_vindex; + vint* m_pValue; + + private: + vint_vref& operator=(const vint_vref&); + }; + + CPPSPMD_FORCE_INLINE const float_vref& store(const float_vref& dst, const vfloat& src); + CPPSPMD_FORCE_INLINE const float_vref& store(const float_vref&& dst, const vfloat& src); + + CPPSPMD_FORCE_INLINE const float_vref& store_all(const float_vref& dst, const vfloat& src); + CPPSPMD_FORCE_INLINE const float_vref& store_all(const float_vref&& dst, const vfloat& src); + + CPPSPMD_FORCE_INLINE vfloat load(const float_vref& src) + { + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i *)vindex, src.m_vindex); + + CPPSPMD_ALIGN(16) float loaded[4]; + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + loaded[i] = src.m_pValue[vindex[i]]; + } + return vfloat{ _mm_and_ps(_mm_castsi128_ps(m_exec.m_mask), _mm_load_ps((const float*)loaded)) }; + } + + CPPSPMD_FORCE_INLINE vfloat load_all(const float_vref& src) + { + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i *)vindex, src.m_vindex); + + CPPSPMD_ALIGN(16) float loaded[4]; + + for (int i = 0; i < 4; i++) + loaded[i] = src.m_pValue[vindex[i]]; + return vfloat{ _mm_load_ps((const float*)loaded) }; + } + + // Linear ref to ints + struct int_lref + { + int* m_pValue; + + private: + int_lref& operator=(const int_lref&); + }; + + CPPSPMD_FORCE_INLINE const int_lref& store(const int_lref& dst, const vint& src) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + if (mask == ALL_ON_MOVEMASK) + { + _mm_storeu_si128((__m128i *)dst.m_pValue, src.m_value); + } + else + { + CPPSPMD_ALIGN(16) int stored[4]; + _mm_store_si128((__m128i *)stored, src.m_value); + + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + dst.m_pValue[i] = stored[i]; + } + } + return dst; + } + + CPPSPMD_FORCE_INLINE vint load(const int_lref& src) + { + __m128i v = _mm_loadu_si128((const __m128i*)src.m_pValue); + + v = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(v), _mm_castsi128_ps(m_exec.m_mask))); + + return vint{ v }; + } + + // Linear ref to int16's + struct int16_lref + { + int16_t* m_pValue; + + private: + int16_lref& operator=(const int16_lref&); + }; + + CPPSPMD_FORCE_INLINE const int16_lref& store(const int16_lref& dst, const vint& src) + { + CPPSPMD_ALIGN(16) int stored[4]; + _mm_store_si128((__m128i *)stored, src.m_value); + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + dst.m_pValue[i] = static_cast<int16_t>(stored[i]); + } + return dst; + } + + CPPSPMD_FORCE_INLINE const int16_lref& store_all(const int16_lref& dst, const vint& src) + { + CPPSPMD_ALIGN(16) int stored[4]; + _mm_store_si128((__m128i *)stored, src.m_value); + + for (int i = 0; i < 4; i++) + dst.m_pValue[i] = static_cast<int16_t>(stored[i]); + return dst; + } + + CPPSPMD_FORCE_INLINE vint load(const int16_lref& src) + { + CPPSPMD_ALIGN(16) int values[4]; + + for (int i = 0; i < 4; i++) + values[i] = static_cast<int16_t>(src.m_pValue[i]); + + __m128i t = _mm_load_si128( (const __m128i *)values ); + + return vint{ _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps( t ), _mm_castsi128_ps(m_exec.m_mask))) }; + } + + CPPSPMD_FORCE_INLINE vint load_all(const int16_lref& src) + { + CPPSPMD_ALIGN(16) int values[4]; + + for (int i = 0; i < 4; i++) + values[i] = static_cast<int16_t>(src.m_pValue[i]); + + __m128i t = _mm_load_si128( (const __m128i *)values ); + + return vint{ t }; + } + + // Linear ref to constant ints + struct cint_lref + { + const int* m_pValue; + + private: + cint_lref& operator=(const cint_lref&); + }; + + CPPSPMD_FORCE_INLINE vint load(const cint_lref& src) + { + __m128i v = _mm_loadu_si128((const __m128i *)src.m_pValue); + v = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(v), _mm_castsi128_ps(m_exec.m_mask))); + return vint{ v }; + } + + CPPSPMD_FORCE_INLINE vint load_all(const cint_lref& src) + { + return vint{ _mm_loadu_si128((const __m128i *)src.m_pValue) }; + } + + // Varying ref to ints + struct int_vref + { + __m128i m_vindex; + int* m_pValue; + + private: + int_vref& operator=(const int_vref&); + }; + + // Varying ref to constant ints + struct cint_vref + { + __m128i m_vindex; + const int* m_pValue; + + private: + cint_vref& operator=(const cint_vref&); + }; + + // Varying int + struct vint + { + __m128i m_value; + + vint() = default; + + CPPSPMD_FORCE_INLINE explicit vint(const __m128i& value) : m_value(value) { } + + CPPSPMD_FORCE_INLINE explicit vint(const lint &other) : m_value(other.m_value) { } + + CPPSPMD_FORCE_INLINE vint& operator=(const lint& other) { m_value = other.m_value; return *this; } + + CPPSPMD_FORCE_INLINE vint(int value) : m_value(_mm_set1_epi32(value)) { } + + CPPSPMD_FORCE_INLINE explicit vint(float value) : m_value(_mm_set1_epi32((int)value)) { } + + CPPSPMD_FORCE_INLINE explicit vint(const vfloat& other) : m_value(_mm_cvttps_epi32(other.m_value)) { } + + CPPSPMD_FORCE_INLINE explicit operator vbool() const + { + return vbool{ _mm_xor_si128( _mm_load_si128((const __m128i*)g_allones_128), _mm_cmpeq_epi32(m_value, _mm_setzero_si128())) }; + } + + CPPSPMD_FORCE_INLINE explicit operator vfloat() const + { + return vfloat{ _mm_cvtepi32_ps(m_value) }; + } + + CPPSPMD_FORCE_INLINE int_vref operator[](int* ptr) const + { + return int_vref{ m_value, ptr }; + } + + CPPSPMD_FORCE_INLINE cint_vref operator[](const int* ptr) const + { + return cint_vref{ m_value, ptr }; + } + + CPPSPMD_FORCE_INLINE float_vref operator[](float* ptr) const + { + return float_vref{ m_value, ptr }; + } + + CPPSPMD_FORCE_INLINE vfloat_vref operator[](vfloat* ptr) const + { + return vfloat_vref{ m_value, ptr }; + } + + CPPSPMD_FORCE_INLINE vint_vref operator[](vint* ptr) const + { + return vint_vref{ m_value, ptr }; + } + + private: + vint& operator=(const vint&); + }; + + // Load/store linear int + CPPSPMD_FORCE_INLINE void storeu_linear(int *pDst, const vint& src) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + if (mask == ALL_ON_MOVEMASK) + _mm_storeu_si128((__m128i *)pDst, src.m_value); + else + { + if (mask & 1) pDst[0] = extract_x(src.m_value); + if (mask & 2) pDst[1] = extract_y(src.m_value); + if (mask & 4) pDst[2] = extract_z(src.m_value); + if (mask & 8) pDst[3] = extract_w(src.m_value); + } + } + + CPPSPMD_FORCE_INLINE void storeu_linear_all(int *pDst, const vint& src) + { + _mm_storeu_si128((__m128i*)pDst, src.m_value); + } + + CPPSPMD_FORCE_INLINE void store_linear_all(int *pDst, const vint& src) + { + _mm_store_si128((__m128i*)pDst, src.m_value); + } + + CPPSPMD_FORCE_INLINE vint loadu_linear(const int *pSrc) + { + __m128i v = _mm_loadu_si128((const __m128i*)pSrc); + + v = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(v), _mm_castsi128_ps(m_exec.m_mask))); + + return vint{ v }; + } + + CPPSPMD_FORCE_INLINE vint loadu_linear_all(const int *pSrc) + { + return vint{ _mm_loadu_si128((__m128i*)pSrc) }; + } + + CPPSPMD_FORCE_INLINE vint load_linear_all(const int *pSrc) + { + return vint{ _mm_load_si128((__m128i*)pSrc) }; + } + + // Load/store linear float + CPPSPMD_FORCE_INLINE void storeu_linear(float *pDst, const vfloat& src) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + if (mask == ALL_ON_MOVEMASK) + _mm_storeu_ps((float*)pDst, src.m_value); + else + { + int *pDstI = (int *)pDst; + if (mask & 1) pDstI[0] = extract_ps_x(src.m_value); + if (mask & 2) pDstI[1] = extract_ps_y(src.m_value); + if (mask & 4) pDstI[2] = extract_ps_z(src.m_value); + if (mask & 8) pDstI[3] = extract_ps_w(src.m_value); + } + } + + CPPSPMD_FORCE_INLINE void storeu_linear_all(float *pDst, const vfloat& src) + { + _mm_storeu_ps((float*)pDst, src.m_value); + } + + CPPSPMD_FORCE_INLINE void store_linear_all(float *pDst, const vfloat& src) + { + _mm_store_ps((float*)pDst, src.m_value); + } + + CPPSPMD_FORCE_INLINE vfloat loadu_linear(const float *pSrc) + { + __m128 v = _mm_loadu_ps((const float*)pSrc); + + v = _mm_and_ps(v, _mm_castsi128_ps(m_exec.m_mask)); + + return vfloat{ v }; + } + + CPPSPMD_FORCE_INLINE vfloat loadu_linear_all(const float *pSrc) + { + return vfloat{ _mm_loadu_ps((float*)pSrc) }; + } + + CPPSPMD_FORCE_INLINE vfloat load_linear_all(const float *pSrc) + { + return vfloat{ _mm_load_ps((float*)pSrc) }; + } + + CPPSPMD_FORCE_INLINE vint& store(vint& dst, const vint& src) + { + dst.m_value = blendv_mask_epi32(dst.m_value, src.m_value, m_exec.m_mask); + return dst; + } + + CPPSPMD_FORCE_INLINE const int_vref& store(const int_vref& dst, const vint& src) + { + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i*)vindex, dst.m_vindex); + + CPPSPMD_ALIGN(16) int stored[4]; + _mm_store_si128((__m128i*)stored, src.m_value); + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + dst.m_pValue[vindex[i]] = stored[i]; + } + return dst; + } + + CPPSPMD_FORCE_INLINE vint& store_all(vint& dst, const vint& src) + { + dst.m_value = src.m_value; + return dst; + } + + CPPSPMD_FORCE_INLINE const int_vref& store_all(const int_vref& dst, const vint& src) + { + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i*)vindex, dst.m_vindex); + + CPPSPMD_ALIGN(16) int stored[4]; + _mm_store_si128((__m128i*)stored, src.m_value); + + for (int i = 0; i < 4; i++) + dst.m_pValue[vindex[i]] = stored[i]; + + return dst; + } + + CPPSPMD_FORCE_INLINE vint load(const int_vref& src) + { + CPPSPMD_ALIGN(16) int values[4]; + + CPPSPMD_ALIGN(16) int indices[4]; + _mm_store_si128((__m128i *)indices, src.m_vindex); + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + values[i] = src.m_pValue[indices[i]]; + } + + return vint{ _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(m_exec.m_mask), _mm_load_ps((const float*)values))) }; + } + + CPPSPMD_FORCE_INLINE vint load_all(const int_vref& src) + { + CPPSPMD_ALIGN(16) int values[4]; + + CPPSPMD_ALIGN(16) int indices[4]; + _mm_store_si128((__m128i *)indices, src.m_vindex); + + for (int i = 0; i < 4; i++) + values[i] = src.m_pValue[indices[i]]; + + return vint{ _mm_castps_si128( _mm_load_ps((const float*)values)) }; + } + + CPPSPMD_FORCE_INLINE vint load(const cint_vref& src) + { + CPPSPMD_ALIGN(16) int values[4]; + + CPPSPMD_ALIGN(16) int indices[4]; + _mm_store_si128((__m128i *)indices, src.m_vindex); + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + values[i] = src.m_pValue[indices[i]]; + } + + return vint{ _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(m_exec.m_mask), _mm_load_ps((const float*)values))) }; + } + + CPPSPMD_FORCE_INLINE vint load_all(const cint_vref& src) + { + CPPSPMD_ALIGN(16) int values[4]; + + CPPSPMD_ALIGN(16) int indices[4]; + _mm_store_si128((__m128i *)indices, src.m_vindex); + + for (int i = 0; i < 4; i++) + values[i] = src.m_pValue[indices[i]]; + + return vint{ _mm_castps_si128( _mm_load_ps((const float*)values)) }; + } + + CPPSPMD_FORCE_INLINE vint load_bytes_all(const cint_vref& src) + { + __m128i v0_l; + + const uint8_t* pSrc = (const uint8_t*)src.m_pValue; + v0_l = insert_x(_mm_undefined_si128(), ((int*)(pSrc + extract_x(src.m_vindex)))[0]); + v0_l = insert_y(v0_l, ((int*)(pSrc + extract_y(src.m_vindex)))[0]); + v0_l = insert_z(v0_l, ((int*)(pSrc + extract_z(src.m_vindex)))[0]); + v0_l = insert_w(v0_l, ((int*)(pSrc + extract_w(src.m_vindex)))[0]); + + return vint{ v0_l }; + } + + CPPSPMD_FORCE_INLINE vint load_words_all(const cint_vref& src) + { + __m128i v0_l; + + const uint8_t* pSrc = (const uint8_t*)src.m_pValue; + v0_l = insert_x(_mm_undefined_si128(), ((int16_t*)(pSrc + 2 * extract_x(src.m_vindex)))[0]); + v0_l = insert_y(v0_l, ((int16_t*)(pSrc + 2 * extract_y(src.m_vindex)))[0]); + v0_l = insert_z(v0_l, ((int16_t*)(pSrc + 2 * extract_z(src.m_vindex)))[0]); + v0_l = insert_w(v0_l, ((int16_t*)(pSrc + 2 * extract_w(src.m_vindex)))[0]); + + return vint{ v0_l }; + } + + CPPSPMD_FORCE_INLINE void store_strided(int *pDst, uint32_t stride, const vint &v) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + + if (mask & 1) pDst[0] = extract_x(v.m_value); + if (mask & 2) pDst[stride] = extract_y(v.m_value); + if (mask & 4) pDst[stride*2] = extract_z(v.m_value); + if (mask & 8) pDst[stride*3] = extract_w(v.m_value); + } + + CPPSPMD_FORCE_INLINE void store_strided(float *pDstF, uint32_t stride, const vfloat &v) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + + if (mask & 1) ((int *)pDstF)[0] = extract_ps_x(v.m_value); + if (mask & 2) ((int *)pDstF)[stride] = extract_ps_y(v.m_value); + if (mask & 4) ((int *)pDstF)[stride*2] = extract_ps_z(v.m_value); + if (mask & 8) ((int *)pDstF)[stride*3] = extract_ps_w(v.m_value); + } + + CPPSPMD_FORCE_INLINE void store_all_strided(int *pDst, uint32_t stride, const vint &v) + { + pDst[0] = extract_x(v.m_value); + pDst[stride] = extract_y(v.m_value); + pDst[stride*2] = extract_z(v.m_value); + pDst[stride*3] = extract_w(v.m_value); + } + + CPPSPMD_FORCE_INLINE void store_all_strided(float *pDstF, uint32_t stride, const vfloat &v) + { + ((int *)pDstF)[0] = extract_ps_x(v.m_value); + ((int *)pDstF)[stride] = extract_ps_y(v.m_value); + ((int *)pDstF)[stride*2] = extract_ps_z(v.m_value); + ((int *)pDstF)[stride*3] = extract_ps_w(v.m_value); + } + + CPPSPMD_FORCE_INLINE vint load_strided(const int *pSrc, uint32_t stride) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + +#if CPPSPMD_SSE2 + CPPSPMD_ALIGN(16) int vals[4] = { 0, 0, 0, 0 }; + if (mask & 1) vals[0] = pSrc[0]; + if (mask & 2) vals[1] = pSrc[stride]; + if (mask & 4) vals[2] = pSrc[stride * 2]; + if (mask & 8) vals[3] = pSrc[stride * 3]; + return vint{ _mm_load_si128((__m128i*)vals) }; +#else + const float* pSrcF = (const float*)pSrc; + __m128 v = _mm_setzero_ps(); + if (mask & 1) v = _mm_load_ss(pSrcF); + if (mask & 2) v = _mm_insert_ps(v, _mm_load_ss(pSrcF + stride), 0x10); + if (mask & 4) v = _mm_insert_ps(v, _mm_load_ss(pSrcF + 2 * stride), 0x20); + if (mask & 8) v = _mm_insert_ps(v, _mm_load_ss(pSrcF + 3 * stride), 0x30); + return vint{ _mm_castps_si128(v) }; +#endif + } + + CPPSPMD_FORCE_INLINE vfloat load_strided(const float *pSrc, uint32_t stride) + { + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + +#if CPPSPMD_SSE2 + CPPSPMD_ALIGN(16) float vals[4] = { 0, 0, 0, 0 }; + if (mask & 1) vals[0] = pSrc[0]; + if (mask & 2) vals[1] = pSrc[stride]; + if (mask & 4) vals[2] = pSrc[stride * 2]; + if (mask & 8) vals[3] = pSrc[stride * 3]; + return vfloat{ _mm_load_ps(vals) }; +#else + __m128 v = _mm_setzero_ps(); + if (mask & 1) v = _mm_load_ss(pSrc); + if (mask & 2) v = _mm_insert_ps(v, _mm_load_ss(pSrc + stride), 0x10); + if (mask & 4) v = _mm_insert_ps(v, _mm_load_ss(pSrc + 2 * stride), 0x20); + if (mask & 8) v = _mm_insert_ps(v, _mm_load_ss(pSrc + 3 * stride), 0x30); + return vfloat{ v }; +#endif + } + + CPPSPMD_FORCE_INLINE vint load_all_strided(const int *pSrc, uint32_t stride) + { +#if CPPSPMD_SSE2 + CPPSPMD_ALIGN(16) int vals[4]; + vals[0] = pSrc[0]; + vals[1] = pSrc[stride]; + vals[2] = pSrc[stride * 2]; + vals[3] = pSrc[stride * 3]; + return vint{ _mm_load_si128((__m128i*)vals) }; +#else + const float* pSrcF = (const float*)pSrc; + __m128 v = _mm_load_ss(pSrcF); + v = _mm_insert_ps(v, _mm_load_ss(pSrcF + stride), 0x10); + v = _mm_insert_ps(v, _mm_load_ss(pSrcF + 2 * stride), 0x20); + v = _mm_insert_ps(v, _mm_load_ss(pSrcF + 3 * stride), 0x30); + return vint{ _mm_castps_si128(v) }; +#endif + } + + CPPSPMD_FORCE_INLINE vfloat load_all_strided(const float *pSrc, uint32_t stride) + { +#if CPPSPMD_SSE2 + CPPSPMD_ALIGN(16) float vals[4]; + vals[0] = pSrc[0]; + vals[1] = pSrc[stride]; + vals[2] = pSrc[stride * 2]; + vals[3] = pSrc[stride * 3]; + return vfloat{ _mm_load_ps(vals) }; +#else + __m128 v = _mm_load_ss(pSrc); + v = _mm_insert_ps(v, _mm_load_ss(pSrc + stride), 0x10); + v = _mm_insert_ps(v, _mm_load_ss(pSrc + 2 * stride), 0x20); + v = _mm_insert_ps(v, _mm_load_ss(pSrc + 3 * stride), 0x30); + return vfloat{ v }; +#endif + } + + CPPSPMD_FORCE_INLINE const vfloat_vref& store(const vfloat_vref& dst, const vfloat& src) + { + // TODO: There's surely a better way + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + + if (mask & 1) ((int *)(&dst.m_pValue[extract_x(dst.m_vindex)]))[0] = extract_x(_mm_castps_si128(src.m_value)); + if (mask & 2) ((int *)(&dst.m_pValue[extract_y(dst.m_vindex)]))[1] = extract_y(_mm_castps_si128(src.m_value)); + if (mask & 4) ((int *)(&dst.m_pValue[extract_z(dst.m_vindex)]))[2] = extract_z(_mm_castps_si128(src.m_value)); + if (mask & 8) ((int *)(&dst.m_pValue[extract_w(dst.m_vindex)]))[3] = extract_w(_mm_castps_si128(src.m_value)); + + return dst; + } + + CPPSPMD_FORCE_INLINE vfloat load(const vfloat_vref& src) + { + // TODO: There's surely a better way + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + + __m128i k = _mm_setzero_si128(); + + if (mask & 1) k = insert_x(k, ((int *)(&src.m_pValue[extract_x(src.m_vindex)]))[0]); + if (mask & 2) k = insert_y(k, ((int *)(&src.m_pValue[extract_y(src.m_vindex)]))[1]); + if (mask & 4) k = insert_z(k, ((int *)(&src.m_pValue[extract_z(src.m_vindex)]))[2]); + if (mask & 8) k = insert_w(k, ((int *)(&src.m_pValue[extract_w(src.m_vindex)]))[3]); + + return vfloat{ _mm_castsi128_ps(k) }; + } + + CPPSPMD_FORCE_INLINE const vint_vref& store(const vint_vref& dst, const vint& src) + { + // TODO: There's surely a better way + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + + if (mask & 1) ((int *)(&dst.m_pValue[extract_x(dst.m_vindex)]))[0] = extract_x(src.m_value); + if (mask & 2) ((int *)(&dst.m_pValue[extract_y(dst.m_vindex)]))[1] = extract_y(src.m_value); + if (mask & 4) ((int *)(&dst.m_pValue[extract_z(dst.m_vindex)]))[2] = extract_z(src.m_value); + if (mask & 8) ((int *)(&dst.m_pValue[extract_w(dst.m_vindex)]))[3] = extract_w(src.m_value); + + return dst; + } + + CPPSPMD_FORCE_INLINE vint load(const vint_vref& src) + { + // TODO: There's surely a better way + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + + __m128i k = _mm_setzero_si128(); + + if (mask & 1) k = insert_x(k, ((int *)(&src.m_pValue[extract_x(src.m_vindex)]))[0]); + if (mask & 2) k = insert_y(k, ((int *)(&src.m_pValue[extract_y(src.m_vindex)]))[1]); + if (mask & 4) k = insert_z(k, ((int *)(&src.m_pValue[extract_z(src.m_vindex)]))[2]); + if (mask & 8) k = insert_w(k, ((int *)(&src.m_pValue[extract_w(src.m_vindex)]))[3]); + + return vint{ k }; + } + + CPPSPMD_FORCE_INLINE vint load_all(const vint_vref& src) + { + // TODO: There's surely a better way + __m128i k; + + k = insert_x(k, ((int*)(&src.m_pValue[extract_x(src.m_vindex)]))[0]); + k = insert_y(k, ((int*)(&src.m_pValue[extract_y(src.m_vindex)]))[1]); + k = insert_z(k, ((int*)(&src.m_pValue[extract_z(src.m_vindex)]))[2]); + k = insert_w(k, ((int*)(&src.m_pValue[extract_w(src.m_vindex)]))[3]); + + return vint{ k }; + } + + // Linear integer + struct lint + { + __m128i m_value; + + CPPSPMD_FORCE_INLINE explicit lint(__m128i value) + : m_value(value) + { } + + CPPSPMD_FORCE_INLINE explicit operator vfloat() const + { + return vfloat{ _mm_cvtepi32_ps(m_value) }; + } + + CPPSPMD_FORCE_INLINE explicit operator vint() const + { + return vint{ m_value }; + } + + CPPSPMD_FORCE_INLINE int get_first_value() const + { + return _mm_cvtsi128_si32(m_value); + } + + CPPSPMD_FORCE_INLINE float_lref operator[](float* ptr) const + { + return float_lref{ ptr + get_first_value() }; + } + + CPPSPMD_FORCE_INLINE int_lref operator[](int* ptr) const + { + return int_lref{ ptr + get_first_value() }; + } + + CPPSPMD_FORCE_INLINE int16_lref operator[](int16_t* ptr) const + { + return int16_lref{ ptr + get_first_value() }; + } + + CPPSPMD_FORCE_INLINE cint_lref operator[](const int* ptr) const + { + return cint_lref{ ptr + get_first_value() }; + } + + private: + lint& operator=(const lint&); + }; + + CPPSPMD_FORCE_INLINE lint& store_all(lint& dst, const lint& src) + { + dst.m_value = src.m_value; + return dst; + } + + const lint program_index = lint{ _mm_set_epi32( 3, 2, 1, 0 ) }; + + // SPMD condition helpers + + template<typename IfBody> + CPPSPMD_FORCE_INLINE void spmd_if(const vbool& cond, const IfBody& ifBody); + + CPPSPMD_FORCE_INLINE void spmd_if_break(const vbool& cond); + + // No breaks, continues, etc. allowed + template<typename IfBody> + CPPSPMD_FORCE_INLINE void spmd_sif(const vbool& cond, const IfBody& ifBody); + + // No breaks, continues, etc. allowed + template<typename IfBody, typename ElseBody> + CPPSPMD_FORCE_INLINE void spmd_sifelse(const vbool& cond, const IfBody& ifBody, const ElseBody &elseBody); + + template<typename IfBody, typename ElseBody> + CPPSPMD_FORCE_INLINE void spmd_ifelse(const vbool& cond, const IfBody& ifBody, const ElseBody& elseBody); + + template<typename WhileCondBody, typename WhileBody> + CPPSPMD_FORCE_INLINE void spmd_while(const WhileCondBody& whileCondBody, const WhileBody& whileBody); + + template<typename ForInitBody, typename ForCondBody, typename ForIncrBody, typename ForBody> + CPPSPMD_FORCE_INLINE void spmd_for(const ForInitBody& forInitBody, const ForCondBody& forCondBody, const ForIncrBody& forIncrBody, const ForBody& forBody); + + template<typename ForeachBody> + CPPSPMD_FORCE_INLINE void spmd_foreach(int begin, int end, const ForeachBody& foreachBody); + +#ifdef _DEBUG + CPPSPMD_FORCE_INLINE void check_masks(); +#else + CPPSPMD_FORCE_INLINE void check_masks() { } +#endif + + CPPSPMD_FORCE_INLINE void spmd_break(); + CPPSPMD_FORCE_INLINE void spmd_continue(); + + CPPSPMD_FORCE_INLINE void spmd_return(); + + template<typename UnmaskedBody> + CPPSPMD_FORCE_INLINE void spmd_unmasked(const UnmaskedBody& unmaskedBody); + + template<typename SPMDKernel, typename... Args> + //CPPSPMD_FORCE_INLINE decltype(auto) spmd_call(Args&&... args); + CPPSPMD_FORCE_INLINE void spmd_call(Args&&... args); + + CPPSPMD_FORCE_INLINE void swap(vint &a, vint &b) { vint temp = a; store(a, b); store(b, temp); } + CPPSPMD_FORCE_INLINE void swap(vfloat &a, vfloat &b) { vfloat temp = a; store(a, b); store(b, temp); } + CPPSPMD_FORCE_INLINE void swap(vbool &a, vbool &b) { vbool temp = a; store(a, b); store(b, temp); } + + CPPSPMD_FORCE_INLINE float reduce_add(vfloat v) + { + __m128 k3210 = _mm_castsi128_ps(blendv_mask_epi32(_mm_setzero_si128(), _mm_castps_si128(v.m_value), m_exec.m_mask)); + +//#if CPPSPMD_SSE2 +#if 1 + // See https://stackoverflow.com/questions/6996764/fastest-way-to-do-horizontal-sse-vector-sum-or-other-reduction/35270026#35270026 + __m128 shuf = _mm_shuffle_ps(k3210, k3210, _MM_SHUFFLE(2, 3, 0, 1)); + __m128 sums = _mm_add_ps(k3210, shuf); + shuf = _mm_movehl_ps(shuf, sums); + sums = _mm_add_ss(sums, shuf); + return _mm_cvtss_f32(sums); +#else + // This is pretty slow. + __m128 a = _mm_hadd_ps(k3210, k3210); + __m128 b = _mm_hadd_ps(a, a); + return extractf_ps_x(b); +#endif + } + + CPPSPMD_FORCE_INLINE int reduce_add(vint v) + { + __m128i k3210 = blendv_mask_epi32(_mm_setzero_si128(), v.m_value, m_exec.m_mask); + + // See https://stackoverflow.com/questions/6996764/fastest-way-to-do-horizontal-sse-vector-sum-or-other-reduction/35270026#35270026 + __m128i shuf = _mm_shuffle_epi32(k3210, _MM_SHUFFLE(2, 3, 0, 1)); + __m128i sums = _mm_add_epi32(k3210, shuf); + shuf = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(shuf), _mm_castsi128_ps(sums))); + sums = _mm_add_epi32(sums, shuf); + return extract_x(sums); + } + + #include "cppspmd_math_declares.h" + +}; // struct spmd_kernel + +using exec_mask = spmd_kernel::exec_mask; +using vint = spmd_kernel::vint; +using int_lref = spmd_kernel::int_lref; +using cint_vref = spmd_kernel::cint_vref; +using cint_lref = spmd_kernel::cint_lref; +using int_vref = spmd_kernel::int_vref; +using lint = spmd_kernel::lint; +using vbool = spmd_kernel::vbool; +using vfloat = spmd_kernel::vfloat; +using float_lref = spmd_kernel::float_lref; +using float_vref = spmd_kernel::float_vref; +using vfloat_vref = spmd_kernel::vfloat_vref; +using vint_vref = spmd_kernel::vint_vref; + +CPPSPMD_FORCE_INLINE spmd_kernel::vbool::operator vfloat() const +{ + return vfloat { _mm_and_ps( _mm_castsi128_ps(m_value), *(const __m128 *)g_onef_128 ) }; +} + +// Returns UINT32_MAX's for true, 0 for false. (Should it return 1's?) +CPPSPMD_FORCE_INLINE spmd_kernel::vbool::operator vint() const +{ + return vint { m_value }; +} + +CPPSPMD_FORCE_INLINE vbool operator!(const vbool& v) +{ + return vbool{ _mm_castps_si128(_mm_xor_ps(_mm_load_ps((const float*)g_allones_128), _mm_castsi128_ps(v.m_value))) }; +} + +CPPSPMD_FORCE_INLINE exec_mask::exec_mask(const vbool& b) { m_mask = b.m_value; } + +CPPSPMD_FORCE_INLINE exec_mask operator^(const exec_mask& a, const exec_mask& b) { return exec_mask{ _mm_xor_si128(a.m_mask, b.m_mask) }; } +CPPSPMD_FORCE_INLINE exec_mask operator&(const exec_mask& a, const exec_mask& b) { return exec_mask{ _mm_and_si128(a.m_mask, b.m_mask) }; } +CPPSPMD_FORCE_INLINE exec_mask operator|(const exec_mask& a, const exec_mask& b) { return exec_mask{ _mm_or_si128(a.m_mask, b.m_mask) }; } + +CPPSPMD_FORCE_INLINE bool all(const exec_mask& e) { return _mm_movemask_ps(_mm_castsi128_ps(e.m_mask)) == ALL_ON_MOVEMASK; } +CPPSPMD_FORCE_INLINE bool any(const exec_mask& e) { return _mm_movemask_ps(_mm_castsi128_ps(e.m_mask)) != 0; } + +// Bad pattern - doesn't factor in the current exec mask. Prefer spmd_any() instead. +CPPSPMD_FORCE_INLINE bool all(const vbool& e) { return _mm_movemask_ps(_mm_castsi128_ps(e.m_value)) == ALL_ON_MOVEMASK; } +CPPSPMD_FORCE_INLINE bool any(const vbool& e) { return _mm_movemask_ps(_mm_castsi128_ps(e.m_value)) != 0; } + +CPPSPMD_FORCE_INLINE exec_mask andnot(const exec_mask& a, const exec_mask& b) { return exec_mask{ _mm_andnot_si128(a.m_mask, b.m_mask) }; } +CPPSPMD_FORCE_INLINE vbool operator||(const vbool& a, const vbool& b) { return vbool{ _mm_or_si128(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator&&(const vbool& a, const vbool& b) { return vbool{ _mm_and_si128(a.m_value, b.m_value) }; } + +CPPSPMD_FORCE_INLINE vfloat operator+(const vfloat& a, const vfloat& b) { return vfloat{ _mm_add_ps(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat operator-(const vfloat& a, const vfloat& b) { return vfloat{ _mm_sub_ps(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat operator+(float a, const vfloat& b) { return vfloat(a) + b; } +CPPSPMD_FORCE_INLINE vfloat operator+(const vfloat& a, float b) { return a + vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator-(const vfloat& a, const vint& b) { return a - vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator-(const vint& a, const vfloat& b) { return vfloat(a) - b; } +CPPSPMD_FORCE_INLINE vfloat operator-(const vfloat& a, int b) { return a - vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator-(int a, const vfloat& b) { return vfloat(a) - b; } +CPPSPMD_FORCE_INLINE vfloat operator-(const vfloat& a, float b) { return a - vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator-(float a, const vfloat& b) { return vfloat(a) - b; } + +CPPSPMD_FORCE_INLINE vfloat operator*(const vfloat& a, const vfloat& b) { return vfloat{ _mm_mul_ps(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat operator*(const vfloat& a, float b) { return a * vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator*(float a, const vfloat& b) { return vfloat(a) * b; } +CPPSPMD_FORCE_INLINE vfloat operator*(const vfloat& a, int b) { return a * vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator*(int a, const vfloat& b) { return vfloat(a) * b; } + +CPPSPMD_FORCE_INLINE vfloat operator/(const vfloat& a, const vfloat& b) { return vfloat{ _mm_div_ps(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat operator/(const vfloat& a, int b) { return a / vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator/(int a, const vfloat& b) { return vfloat(a) / b; } +CPPSPMD_FORCE_INLINE vfloat operator/(const vfloat& a, float b) { return a / vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator/(float a, const vfloat& b) { return vfloat(a) / b; } +CPPSPMD_FORCE_INLINE vfloat operator-(const vfloat& v) { return vfloat{ _mm_sub_ps(_mm_xor_ps(v.m_value, v.m_value), v.m_value) }; } + +CPPSPMD_FORCE_INLINE vbool operator==(const vfloat& a, const vfloat& b) { return vbool{ _mm_castps_si128(_mm_cmpeq_ps(a.m_value, b.m_value)) }; } +CPPSPMD_FORCE_INLINE vbool operator==(const vfloat& a, float b) { return a == vfloat(b); } + +CPPSPMD_FORCE_INLINE vbool operator!=(const vfloat& a, const vfloat& b) { return !vbool{ _mm_castps_si128(_mm_cmpeq_ps(a.m_value, b.m_value)) }; } +CPPSPMD_FORCE_INLINE vbool operator!=(const vfloat& a, float b) { return a != vfloat(b); } + +CPPSPMD_FORCE_INLINE vbool operator<(const vfloat& a, const vfloat& b) { return vbool{ _mm_castps_si128(_mm_cmplt_ps(a.m_value, b.m_value)) }; } +CPPSPMD_FORCE_INLINE vbool operator<(const vfloat& a, float b) { return a < vfloat(b); } + +CPPSPMD_FORCE_INLINE vbool operator>(const vfloat& a, const vfloat& b) { return vbool{ _mm_castps_si128(_mm_cmpgt_ps(a.m_value, b.m_value)) }; } +CPPSPMD_FORCE_INLINE vbool operator>(const vfloat& a, float b) { return a > vfloat(b); } + +CPPSPMD_FORCE_INLINE vbool operator<=(const vfloat& a, const vfloat& b) { return vbool{ _mm_castps_si128(_mm_cmple_ps(a.m_value, b.m_value)) }; } +CPPSPMD_FORCE_INLINE vbool operator<=(const vfloat& a, float b) { return a <= vfloat(b); } + +CPPSPMD_FORCE_INLINE vbool operator>=(const vfloat& a, const vfloat& b) { return vbool{ _mm_castps_si128(_mm_cmpge_ps(a.m_value, b.m_value)) }; } +CPPSPMD_FORCE_INLINE vbool operator>=(const vfloat& a, float b) { return a >= vfloat(b); } + +CPPSPMD_FORCE_INLINE vfloat spmd_ternaryf(const vbool& cond, const vfloat& a, const vfloat& b) { return vfloat{ blendv_mask_ps(b.m_value, a.m_value, _mm_castsi128_ps(cond.m_value)) }; } +CPPSPMD_FORCE_INLINE vint spmd_ternaryi(const vbool& cond, const vint& a, const vint& b) { return vint{ blendv_mask_epi32(b.m_value, a.m_value, cond.m_value) }; } + +CPPSPMD_FORCE_INLINE vfloat sqrt(const vfloat& v) { return vfloat{ _mm_sqrt_ps(v.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat abs(const vfloat& v) { return vfloat{ _mm_andnot_ps(_mm_set1_ps(-0.0f), v.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat max(const vfloat& a, const vfloat& b) { return vfloat{ _mm_max_ps(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat min(const vfloat& a, const vfloat& b) { return vfloat{ _mm_min_ps(a.m_value, b.m_value) }; } + +#if CPPSPMD_SSE2 +CPPSPMD_FORCE_INLINE vfloat round_truncate(const vfloat& a) +{ + __m128i abs_a = _mm_and_si128(_mm_castps_si128(a.m_value), _mm_set1_epi32(0x7FFFFFFFU) ); + __m128i has_fractional = _mm_cmplt_epi32(abs_a, _mm_castps_si128(_mm_set1_ps(8388608.0f))); + + __m128i ai = _mm_cvttps_epi32(a.m_value); + + __m128 af = _mm_cvtepi32_ps(ai); + return vfloat{ blendv_mask_ps(a.m_value, af, _mm_castsi128_ps(has_fractional)) }; +} + +CPPSPMD_FORCE_INLINE vfloat floor(const vfloat& a) +{ + __m128i abs_a = _mm_and_si128(_mm_castps_si128(a.m_value), _mm_set1_epi32(0x7FFFFFFFU)); + __m128i has_fractional = _mm_cmplt_epi32(abs_a, _mm_castps_si128(_mm_set1_ps(8388608.0f))); + + __m128i ai = _mm_cvtps_epi32(a.m_value); + __m128 af = _mm_cvtepi32_ps(ai); + __m128 changed = _mm_cvtepi32_ps(_mm_castps_si128(_mm_cmpgt_ps(af, a.m_value))); + + af = _mm_add_ps(af, changed); + + return vfloat{ blendv_mask_ps(a.m_value, af, _mm_castsi128_ps(has_fractional)) }; +} + +CPPSPMD_FORCE_INLINE vfloat ceil(const vfloat& a) +{ + __m128i abs_a = _mm_and_si128(_mm_castps_si128(a.m_value), _mm_set1_epi32(0x7FFFFFFFU)); + __m128i has_fractional = _mm_cmplt_epi32(abs_a, _mm_castps_si128(_mm_set1_ps(8388608.0f))); + + __m128i ai = _mm_cvtps_epi32(a.m_value); + __m128 af = _mm_cvtepi32_ps(ai); + __m128 changed = _mm_cvtepi32_ps(_mm_castps_si128(_mm_cmplt_ps(af, a.m_value))); + + af = _mm_sub_ps(af, changed); + + return vfloat{ blendv_mask_ps(a.m_value, af, _mm_castsi128_ps(has_fractional)) }; +} + +// We need to disable unsafe math optimizations for the key operations used for rounding to nearest. +// I wish there was a better way. +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) +inline __m128 add_sub(__m128 a, __m128 b) __attribute__((optimize("-fno-unsafe-math-optimizations"))) +#elif defined(__clang__) +inline __m128 add_sub(__m128 a, __m128 b) __attribute__((optnone)) +#elif defined (_MSC_VER) +#pragma float_control(push) +#pragma float_control(precise, on) +inline __m128 add_sub(__m128 a, __m128 b) +#else +inline __m128 add_sub(__m128 a, __m128 b) +#endif +{ + return _mm_sub_ps(_mm_add_ps(a, b), b); +} + +#if defined (_MSC_VER) +#pragma float_control(pop) +#endif + +CPPSPMD_FORCE_INLINE vfloat round_nearest(const vfloat& a) +{ + __m128i no_fract_fp_bits = _mm_castps_si128(_mm_set1_ps(8388608.0f)); + + __m128i sign_a = _mm_and_si128(_mm_castps_si128(a.m_value), _mm_set1_epi32(0x80000000U)); + __m128 force_int = _mm_castsi128_ps(_mm_or_si128(no_fract_fp_bits, sign_a)); + + // Can't use individual _mm_add_ps/_mm_sub_ps - this will be optimized out with /fp:fast by clang and probably other compilers. + //__m128 temp1 = _mm_add_ps(a.m_value, force_int); + //__m128 temp2 = _mm_sub_ps(temp1, force_int); + __m128 temp2 = add_sub(a.m_value, force_int); + + __m128i abs_a = _mm_and_si128(_mm_castps_si128(a.m_value), _mm_set1_epi32(0x7FFFFFFFU)); + __m128i has_fractional = _mm_cmplt_epi32(abs_a, no_fract_fp_bits); + return vfloat{ blendv_mask_ps(a.m_value, temp2, _mm_castsi128_ps(has_fractional)) }; +} + +#else +CPPSPMD_FORCE_INLINE vfloat floor(const vfloat& v) { return vfloat{ _mm_floor_ps(v.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat ceil(const vfloat& a) { return vfloat{ _mm_ceil_ps(a.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat round_nearest(const vfloat &a) { return vfloat{ _mm_round_ps(a.m_value, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC ) }; } +CPPSPMD_FORCE_INLINE vfloat round_truncate(const vfloat &a) { return vfloat{ _mm_round_ps(a.m_value, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC ) }; } +#endif + +CPPSPMD_FORCE_INLINE vfloat frac(const vfloat& a) { return a - floor(a); } +CPPSPMD_FORCE_INLINE vfloat fmod(vfloat a, vfloat b) { vfloat c = frac(abs(a / b)) * abs(b); return spmd_ternaryf(a < 0, -c, c); } +CPPSPMD_FORCE_INLINE vfloat sign(const vfloat& a) { return spmd_ternaryf(a < 0.0f, 1.0f, 1.0f); } + +CPPSPMD_FORCE_INLINE vint max(const vint& a, const vint& b) { return vint{ max_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint min(const vint& a, const vint& b) { return vint{ min_epi32(a.m_value, b.m_value) }; } + +CPPSPMD_FORCE_INLINE vint maxu(const vint& a, const vint& b) { return vint{ max_epu32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint minu(const vint& a, const vint& b) { return vint{ min_epu32(a.m_value, b.m_value) }; } + +CPPSPMD_FORCE_INLINE vint abs(const vint& v) { return vint{ abs_epi32(v.m_value) }; } + +CPPSPMD_FORCE_INLINE vint byteswap(const vint& v) { return vint{ shuffle_epi8(v.m_value, _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3)) }; } + +CPPSPMD_FORCE_INLINE vint cast_vfloat_to_vint(const vfloat& v) { return vint{ _mm_castps_si128(v.m_value) }; } +CPPSPMD_FORCE_INLINE vfloat cast_vint_to_vfloat(const vint& v) { return vfloat{ _mm_castsi128_ps(v.m_value) }; } + +CPPSPMD_FORCE_INLINE vfloat clamp(const vfloat& v, const vfloat& a, const vfloat& b) +{ + return vfloat{ _mm_min_ps(b.m_value, _mm_max_ps(v.m_value, a.m_value) ) }; +} + +CPPSPMD_FORCE_INLINE vint clamp(const vint& v, const vint& a, const vint& b) +{ + return vint{ min_epi32(b.m_value, max_epi32(v.m_value, a.m_value) ) }; +} + +CPPSPMD_FORCE_INLINE vfloat vfma(const vfloat& a, const vfloat& b, const vfloat& c) +{ + return vfloat{ _mm_add_ps(_mm_mul_ps(a.m_value, b.m_value), c.m_value) }; +} + +CPPSPMD_FORCE_INLINE vfloat vfms(const vfloat& a, const vfloat& b, const vfloat& c) +{ + return vfloat{ _mm_sub_ps(_mm_mul_ps(a.m_value, b.m_value), c.m_value) }; +} + +CPPSPMD_FORCE_INLINE vfloat vfnma(const vfloat& a, const vfloat& b, const vfloat& c) +{ + return vfloat{ _mm_sub_ps(c.m_value, _mm_mul_ps(a.m_value, b.m_value)) }; +} + +CPPSPMD_FORCE_INLINE vfloat vfnms(const vfloat& a, const vfloat& b, const vfloat& c) +{ + return vfloat{ _mm_sub_ps(_mm_sub_ps(_mm_xor_ps(a.m_value, a.m_value), _mm_mul_ps(a.m_value, b.m_value)), c.m_value) }; +} + +CPPSPMD_FORCE_INLINE vfloat lerp(const vfloat &x, const vfloat &y, const vfloat &s) { return vfma(y - x, s, x); } + +CPPSPMD_FORCE_INLINE lint operator+(int a, const lint& b) { return lint{ _mm_add_epi32(_mm_set1_epi32(a), b.m_value) }; } +CPPSPMD_FORCE_INLINE lint operator+(const lint& a, int b) { return lint{ _mm_add_epi32(a.m_value, _mm_set1_epi32(b)) }; } +CPPSPMD_FORCE_INLINE vfloat operator+(float a, const lint& b) { return vfloat(a) + vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator+(const lint& a, float b) { return vfloat(a) + vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator*(const lint& a, float b) { return vfloat(a) * vfloat(b); } +CPPSPMD_FORCE_INLINE vfloat operator*(float b, const lint& a) { return vfloat(a) * vfloat(b); } + +CPPSPMD_FORCE_INLINE vint operator&(const vint& a, const vint& b) { return vint{ _mm_and_si128(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator&(const vint& a, int b) { return a & vint(b); } +CPPSPMD_FORCE_INLINE vint andnot(const vint& a, const vint& b) { return vint{ _mm_andnot_si128(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator|(const vint& a, const vint& b) { return vint{ _mm_or_si128(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator|(const vint& a, int b) { return a | vint(b); } +CPPSPMD_FORCE_INLINE vint operator^(const vint& a, const vint& b) { return vint{ _mm_xor_si128(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator^(const vint& a, int b) { return a ^ vint(b); } +CPPSPMD_FORCE_INLINE vbool operator==(const vint& a, const vint& b) { return vbool{ _mm_cmpeq_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator!=(const vint& a, const vint& b) { return !vbool{ _mm_cmpeq_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator<(const vint& a, const vint& b) { return vbool{ _mm_cmpgt_epi32(b.m_value, a.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator<=(const vint& a, const vint& b) { return !vbool{ _mm_cmpgt_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator>=(const vint& a, const vint& b) { return !vbool{ _mm_cmpgt_epi32(b.m_value, a.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator>(const vint& a, const vint& b) { return vbool{ _mm_cmpgt_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator+(const vint& a, const vint& b) { return vint{ _mm_add_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator-(const vint& a, const vint& b) { return vint{ _mm_sub_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator+(const vint& a, int b) { return a + vint(b); } +CPPSPMD_FORCE_INLINE vint operator-(const vint& a, int b) { return a - vint(b); } +CPPSPMD_FORCE_INLINE vint operator+(int a, const vint& b) { return vint(a) + b; } +CPPSPMD_FORCE_INLINE vint operator-(int a, const vint& b) { return vint(a) - b; } +CPPSPMD_FORCE_INLINE vint operator*(const vint& a, const vint& b) { return vint{ mullo_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint operator*(const vint& a, int b) { return a * vint(b); } +CPPSPMD_FORCE_INLINE vint operator*(int a, const vint& b) { return vint(a) * b; } + +CPPSPMD_FORCE_INLINE vint mulhiu(const vint& a, const vint& b) { return vint{ mulhi_epu32(a.m_value, b.m_value) }; } + +CPPSPMD_FORCE_INLINE vint operator-(const vint& v) { return vint{ _mm_sub_epi32(_mm_setzero_si128(), v.m_value) }; } + +CPPSPMD_FORCE_INLINE vint operator~(const vint& a) { return vint{ -a - 1 }; } + +// A few of these break the lane-based abstraction model. They are supported in SSE2, so it makes sense to support them and let the user figure it out. +CPPSPMD_FORCE_INLINE vint adds_epu8(const vint& a, const vint& b) { return vint{ _mm_adds_epu8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint subs_epu8(const vint& a, const vint& b) { return vint{ _mm_subs_epu8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint avg_epu8(const vint & a, const vint & b) { return vint{ _mm_avg_epu8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint max_epu8(const vint& a, const vint& b) { return vint{ _mm_max_epu8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint min_epu8(const vint& a, const vint& b) { return vint{ _mm_min_epu8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint sad_epu8(const vint& a, const vint& b) { return vint{ _mm_sad_epu8(a.m_value, b.m_value) }; } + +CPPSPMD_FORCE_INLINE vint add_epi8(const vint& a, const vint& b) { return vint{ _mm_add_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint adds_epi8(const vint& a, const vint& b) { return vint{ _mm_adds_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint sub_epi8(const vint& a, const vint& b) { return vint{ _mm_sub_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint subs_epi8(const vint& a, const vint& b) { return vint{ _mm_subs_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmpeq_epi8(const vint& a, const vint& b) { return vint{ _mm_cmpeq_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmpgt_epi8(const vint& a, const vint& b) { return vint{ _mm_cmpgt_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmplt_epi8(const vint& a, const vint& b) { return vint{ _mm_cmplt_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint unpacklo_epi8(const vint& a, const vint& b) { return vint{ _mm_unpacklo_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint unpackhi_epi8(const vint& a, const vint& b) { return vint{ _mm_unpackhi_epi8(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE int movemask_epi8(const vint& a) { return _mm_movemask_epi8(a.m_value); } +CPPSPMD_FORCE_INLINE int movemask_epi32(const vint& a) { return _mm_movemask_ps(_mm_castsi128_ps(a.m_value)); } + +CPPSPMD_FORCE_INLINE vint cmple_epu8(const vint& a, const vint& b) { return vint{ _mm_cmpeq_epi8(_mm_min_epu8(a.m_value, b.m_value), a.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmpge_epu8(const vint& a, const vint& b) { return vint{ cmple_epu8(b, a) }; } +CPPSPMD_FORCE_INLINE vint cmpgt_epu8(const vint& a, const vint& b) { return vint{ _mm_andnot_si128(_mm_cmpeq_epi8(a.m_value, b.m_value), _mm_cmpeq_epi8(_mm_max_epu8(a.m_value, b.m_value), a.m_value)) }; } +CPPSPMD_FORCE_INLINE vint cmplt_epu8(const vint& a, const vint& b) { return vint{ cmpgt_epu8(b, a) }; } +CPPSPMD_FORCE_INLINE vint absdiff_epu8(const vint& a, const vint& b) { return vint{ _mm_or_si128(_mm_subs_epu8(a.m_value, b.m_value), _mm_subs_epu8(b.m_value, a.m_value)) }; } + +CPPSPMD_FORCE_INLINE vint blendv_epi8(const vint& a, const vint& b, const vint &mask) { return vint{ blendv_epi8(a.m_value, b.m_value, _mm_cmplt_epi8(mask.m_value, _mm_setzero_si128())) }; } +CPPSPMD_FORCE_INLINE vint blendv_epi32(const vint& a, const vint& b, const vint &mask) { return vint{ blendv_epi32(a.m_value, b.m_value, mask.m_value) }; } + +CPPSPMD_FORCE_INLINE vint add_epi16(const vint& a, const vint& b) { return vint{ _mm_add_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint adds_epi16(const vint& a, const vint& b) { return vint{ _mm_adds_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint adds_epu16(const vint& a, const vint& b) { return vint{ _mm_adds_epu16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint avg_epu16(const vint& a, const vint& b) { return vint{ _mm_avg_epu16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint sub_epi16(const vint& a, const vint& b) { return vint{ _mm_sub_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint subs_epi16(const vint& a, const vint& b) { return vint{ _mm_subs_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint subs_epu16(const vint& a, const vint& b) { return vint{ _mm_subs_epu16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint mullo_epi16(const vint& a, const vint& b) { return vint{ _mm_mullo_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint mulhi_epi16(const vint& a, const vint& b) { return vint{ _mm_mulhi_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint mulhi_epu16(const vint& a, const vint& b) { return vint{ _mm_mulhi_epu16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint min_epi16(const vint& a, const vint& b) { return vint{ _mm_min_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint max_epi16(const vint& a, const vint& b) { return vint{ _mm_max_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint madd_epi16(const vint& a, const vint& b) { return vint{ _mm_madd_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmpeq_epi16(const vint& a, const vint& b) { return vint{ _mm_cmpeq_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmpgt_epi16(const vint& a, const vint& b) { return vint{ _mm_cmpgt_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint cmplt_epi16(const vint& a, const vint& b) { return vint{ _mm_cmplt_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint packs_epi16(const vint& a, const vint& b) { return vint{ _mm_packs_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint packus_epi16(const vint& a, const vint& b) { return vint{ _mm_packus_epi16(a.m_value, b.m_value) }; } + +CPPSPMD_FORCE_INLINE vint uniform_shift_left_epi16(const vint& a, const vint& b) { return vint{ _mm_sll_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint uniform_arith_shift_right_epi16(const vint& a, const vint& b) { return vint{ _mm_sra_epi16(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vint uniform_shift_right_epi16(const vint& a, const vint& b) { return vint{ _mm_srl_epi16(a.m_value, b.m_value) }; } + +#define VINT_SHIFT_LEFT_EPI16(a, b) vint(_mm_slli_epi16((a).m_value, b)) +#define VINT_SHIFT_RIGHT_EPI16(a, b) vint(_mm_srai_epi16((a).m_value, b)) +#define VUINT_SHIFT_RIGHT_EPI16(a, b) vint(_mm_srli_epi16((a).m_value, b)) + +CPPSPMD_FORCE_INLINE vint undefined_vint() { return vint{ _mm_undefined_si128() }; } +CPPSPMD_FORCE_INLINE vfloat undefined_vfloat() { return vfloat{ _mm_undefined_ps() }; } + +// control is an 8-bit immediate value containing 4 2-bit indices which shuffles the int32's in each 128-bit lane. +#define VINT_LANE_SHUFFLE_EPI32(a, control) vint(_mm_shuffle_epi32((a).m_value, control)) + +// control is an 8-bit immediate value containing 4 2-bit indices which shuffles the int16's in either the high or low 64-bit lane. +#define VINT_LANE_SHUFFLELO_EPI16(a, control) vint(_mm_shufflelo_epi16((a).m_value, control)) +#define VINT_LANE_SHUFFLEHI_EPI16(a, control) vint(_mm_shufflehi_epi16((a).m_value, control)) + +#define VINT_LANE_SHUFFLE_MASK(a, b, c, d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6)) +#define VINT_LANE_SHUFFLE_MASK_R(d, c, b, a) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6)) + +#define VINT_LANE_SHIFT_LEFT_BYTES(a, l) vint(_mm_slli_si128((a).m_value, l)) +#define VINT_LANE_SHIFT_RIGHT_BYTES(a, l) vint(_mm_srli_si128((a).m_value, l)) + +// Unpack and interleave 8-bit integers from the low or high half of a and b +CPPSPMD_FORCE_INLINE vint vint_lane_unpacklo_epi8(const vint& a, const vint& b) { return vint(_mm_unpacklo_epi8(a.m_value, b.m_value)); } +CPPSPMD_FORCE_INLINE vint vint_lane_unpackhi_epi8(const vint& a, const vint& b) { return vint(_mm_unpackhi_epi8(a.m_value, b.m_value)); } + +// Unpack and interleave 16-bit integers from the low or high half of a and b +CPPSPMD_FORCE_INLINE vint vint_lane_unpacklo_epi16(const vint& a, const vint& b) { return vint(_mm_unpacklo_epi16(a.m_value, b.m_value)); } +CPPSPMD_FORCE_INLINE vint vint_lane_unpackhi_epi16(const vint& a, const vint& b) { return vint(_mm_unpackhi_epi16(a.m_value, b.m_value)); } + +// Unpack and interleave 32-bit integers from the low or high half of a and b +CPPSPMD_FORCE_INLINE vint vint_lane_unpacklo_epi32(const vint& a, const vint& b) { return vint(_mm_unpacklo_epi32(a.m_value, b.m_value)); } +CPPSPMD_FORCE_INLINE vint vint_lane_unpackhi_epi32(const vint& a, const vint& b) { return vint(_mm_unpackhi_epi32(a.m_value, b.m_value)); } + +// Unpack and interleave 64-bit integers from the low or high half of a and b +CPPSPMD_FORCE_INLINE vint vint_lane_unpacklo_epi64(const vint& a, const vint& b) { return vint(_mm_unpacklo_epi64(a.m_value, b.m_value)); } +CPPSPMD_FORCE_INLINE vint vint_lane_unpackhi_epi64(const vint& a, const vint& b) { return vint(_mm_unpackhi_epi64(a.m_value, b.m_value)); } + +CPPSPMD_FORCE_INLINE vint vint_set1_epi8(int8_t a) { return vint(_mm_set1_epi8(a)); } +CPPSPMD_FORCE_INLINE vint vint_set1_epi16(int16_t a) { return vint(_mm_set1_epi16(a)); } +CPPSPMD_FORCE_INLINE vint vint_set1_epi32(int32_t a) { return vint(_mm_set1_epi32(a)); } +CPPSPMD_FORCE_INLINE vint vint_set1_epi64(int64_t a) { return vint(_mm_set1_epi64x(a)); } + +CPPSPMD_FORCE_INLINE vint mul_epu32(const vint &a, const vint& b) { return vint(_mm_mul_epu32(a.m_value, b.m_value)); } + +CPPSPMD_FORCE_INLINE vint div_epi32(const vint &a, const vint& b) +{ + __m128d al = _mm_cvtepi32_pd(a.m_value); + __m128d ah = _mm_cvtepi32_pd(_mm_unpackhi_epi64(a.m_value, a.m_value)); + + __m128d bl = _mm_cvtepi32_pd(b.m_value); + __m128d bh = _mm_cvtepi32_pd(_mm_unpackhi_epi64(b.m_value, b.m_value)); + + __m128d rl = _mm_div_pd(al, bl); + __m128d rh = _mm_div_pd(ah, bh); + + __m128i rli = _mm_cvttpd_epi32(rl); + __m128i rhi = _mm_cvttpd_epi32(rh); + + return vint(_mm_unpacklo_epi64(rli, rhi)); +} + +CPPSPMD_FORCE_INLINE vint mod_epi32(const vint &a, const vint& b) +{ + vint aa = abs(a), ab = abs(b); + vint q = div_epi32(aa, ab); + vint r = aa - q * ab; + return spmd_ternaryi(a < 0, -r, r); +} + +CPPSPMD_FORCE_INLINE vint operator/ (const vint& a, const vint& b) +{ + return div_epi32(a, b); +} + +CPPSPMD_FORCE_INLINE vint operator/ (const vint& a, int b) +{ + return div_epi32(a, vint(b)); +} + +CPPSPMD_FORCE_INLINE vint operator% (const vint& a, const vint& b) +{ + return mod_epi32(a, b); +} + +CPPSPMD_FORCE_INLINE vint operator% (const vint& a, int b) +{ + return mod_epi32(a, vint(b)); +} + +CPPSPMD_FORCE_INLINE vint operator<< (const vint& a, const vint& b) +{ +#if 0 + CPPSPMD_ALIGN(32) int result[4]; + result[0] = extract_x(a.m_value) << extract_x(b.m_value); + result[1] = extract_y(a.m_value) << extract_y(b.m_value); + result[2] = extract_z(a.m_value) << extract_z(b.m_value); + result[3] = extract_w(a.m_value) << extract_w(b.m_value); + + return vint{ _mm_load_si128((__m128i*)result) }; +#elif 0 + int x = extract_x(a.m_value) << extract_x(b.m_value); + int y = extract_y(a.m_value) << extract_y(b.m_value); + int z = extract_z(a.m_value) << extract_z(b.m_value); + int w = extract_w(a.m_value) << extract_w(b.m_value); + + __m128i v = insert_x(_mm_undefined_si128(), x); + v = insert_y(v, y); + v = insert_z(v, z); + return vint{ insert_w(v, w) }; +#else + // What this does: shift left each b lane by 23 bits (to move the shift amount into the FP exponent position), then epi32 add to the integer rep of 1.0f, then cast that to float, then convert that to int to get fast 2^x. + return a * vint(cast_vint_to_vfloat(vint(_mm_slli_epi32(b.m_value, 23)) + cast_vfloat_to_vint(vfloat(1.0f)))); +#endif +} + +// uniform shift left +CPPSPMD_FORCE_INLINE vint operator<< (const vint& a, int b) +{ + __m128i bv = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(_mm_set1_epi32(b)), _mm_castsi128_ps(_mm_load_si128((const __m128i *)g_x_128)))); + return vint{ _mm_sll_epi32(a.m_value, bv) }; +} + +// uniform arithmetic shift right +CPPSPMD_FORCE_INLINE vint operator>> (const vint& a, int b) +{ + __m128i bv = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(_mm_set1_epi32(b)), _mm_castsi128_ps(_mm_load_si128((const __m128i *)g_x_128)))); + return vint{ _mm_sra_epi32(a.m_value, bv) }; +} + +// uniform shift right +CPPSPMD_FORCE_INLINE vint vuint_shift_right(const vint& a, int b) +{ + __m128i bv = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(_mm_set1_epi32(b)), _mm_castsi128_ps(_mm_load_si128((const __m128i *)g_x_128)))); + return vint{ _mm_srl_epi32(a.m_value, bv) }; +} + +CPPSPMD_FORCE_INLINE vint vuint_shift_right(const vint& a, const vint& b) +{ +#if 0 + CPPSPMD_ALIGN(32) int result[4]; + result[0] = ((uint32_t)extract_x(a.m_value)) >> extract_x(b.m_value); + result[1] = ((uint32_t)extract_y(a.m_value)) >> extract_y(b.m_value); + result[2] = ((uint32_t)extract_z(a.m_value)) >> extract_z(b.m_value); + result[3] = ((uint32_t)extract_w(a.m_value)) >> extract_w(b.m_value); + + return vint{ _mm_load_si128((__m128i*)result) }; +#elif 0 + uint32_t x = ((uint32_t)extract_x(a.m_value)) >> ((uint32_t)extract_x(b.m_value)); + uint32_t y = ((uint32_t)extract_y(a.m_value)) >> ((uint32_t)extract_y(b.m_value)); + uint32_t z = ((uint32_t)extract_z(a.m_value)) >> ((uint32_t)extract_z(b.m_value)); + uint32_t w = ((uint32_t)extract_w(a.m_value)) >> ((uint32_t)extract_w(b.m_value)); + + __m128i v = insert_x(_mm_undefined_si128(), x); + v = insert_y(v, y); + v = insert_z(v, z); + return vint{ insert_w(v, w) }; +#else + //vint inv_shift = 32 - b; + //vfloat f = cast_vint_to_vfloat(vint(_mm_slli_epi32(inv_shift.m_value, 23)) + cast_vfloat_to_vint(vfloat(1.0f))); + + // Take float rep of 1.0f (0x3f800000), subtract (32<<23), subtract (shift<<23), cast to float. + vfloat f = cast_vint_to_vfloat(vint(_mm_sub_epi32(_mm_set1_epi32(0x4f800000), _mm_slli_epi32(b.m_value, 23)))); + + // Now convert scale factor to integer. + vint r = vint(f); + + // mulhi_epu32 (using two _mm_mul_epu32), to emulate varying shift left. + vint q(mulhi_epu32(a.m_value, r.m_value)); + + // Handle shift amounts of 0. + return spmd_ternaryi(b > 0, q, a); +#endif +} + +CPPSPMD_FORCE_INLINE vint vuint_shift_right_not_zero(const vint& a, const vint& b) +{ + //vint inv_shift = 32 - b; + //vfloat f = cast_vint_to_vfloat(vint(_mm_slli_epi32(inv_shift.m_value, 23)) + cast_vfloat_to_vint(vfloat(1.0f))); + + // Take float rep of 1.0f (0x3f800000), subtract (32<<23), subtract (shift<<23), cast to float. + vfloat f = cast_vint_to_vfloat(vint(_mm_sub_epi32(_mm_set1_epi32(0x4f800000), _mm_slli_epi32(b.m_value, 23)))); + + // Now convert scale factor to integer. + vint r = vint(f); + + // mulhi_epu32 (using two _mm_mul_epu32), to emulate varying shift left. + return vint(mulhi_epu32(a.m_value, r.m_value)); +} + +CPPSPMD_FORCE_INLINE vint operator>> (const vint& a, const vint& b) +{ +#if 0 + CPPSPMD_ALIGN(32) int result[4]; + result[0] = extract_x(a.m_value) >> extract_x(b.m_value); + result[1] = extract_y(a.m_value) >> extract_y(b.m_value); + result[2] = extract_z(a.m_value) >> extract_z(b.m_value); + result[3] = extract_w(a.m_value) >> extract_w(b.m_value); + + return vint{ _mm_load_si128((__m128i*)result) }; +#elif 0 + int x = extract_x(a.m_value) >> extract_x(b.m_value); + int y = extract_y(a.m_value) >> extract_y(b.m_value); + int z = extract_z(a.m_value) >> extract_z(b.m_value); + int w = extract_w(a.m_value) >> extract_w(b.m_value); + + __m128i v = insert_x(_mm_undefined_si128(), x); + v = insert_y(v, y); + v = insert_z(v, z); + return vint{ insert_w(v, w) }; +#else + vint sign_mask(_mm_cmplt_epi32(a.m_value, _mm_setzero_si128())); + vint a_shifted = vuint_shift_right(a ^ sign_mask, b) ^ sign_mask; + return a_shifted; +#endif +} + +#undef VINT_SHIFT_LEFT +#undef VINT_SHIFT_RIGHT +#undef VUINT_SHIFT_RIGHT + +// Shift left/right by a uniform immediate constant +#define VINT_SHIFT_LEFT(a, b) vint(_mm_slli_epi32( (a).m_value, (b) ) ) +#define VINT_SHIFT_RIGHT(a, b) vint( _mm_srai_epi32( (a).m_value, (b) ) ) +#define VUINT_SHIFT_RIGHT(a, b) vint( _mm_srli_epi32( (a).m_value, (b) ) ) +#define VINT_ROT(x, k) (VINT_SHIFT_LEFT((x), (k)) | VUINT_SHIFT_RIGHT((x), 32 - (k))) + +CPPSPMD_FORCE_INLINE vbool operator==(const lint& a, const lint& b) { return vbool{ _mm_cmpeq_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator==(const lint& a, int b) { return vint(a) == vint(b); } +CPPSPMD_FORCE_INLINE vbool operator==(int a, const lint& b) { return vint(a) == vint(b); } +CPPSPMD_FORCE_INLINE vbool operator<(const lint& a, const lint& b) { return vbool{ _mm_cmpgt_epi32(b.m_value, a.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator>(const lint& a, const lint& b) { return vbool{ _mm_cmpgt_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator<=(const lint& a, const lint& b) { return !vbool{ _mm_cmpgt_epi32(a.m_value, b.m_value) }; } +CPPSPMD_FORCE_INLINE vbool operator>=(const lint& a, const lint& b) { return !vbool{ _mm_cmpgt_epi32(b.m_value, a.m_value) }; } + +CPPSPMD_FORCE_INLINE float extract(const vfloat& v, int instance) { assert(instance < 4); CPPSPMD_ALIGN(16) float values[4]; _mm_store_ps(values, v.m_value); return values[instance]; } +CPPSPMD_FORCE_INLINE int extract(const vint& v, int instance) { assert(instance < 4); CPPSPMD_ALIGN(16) int values[4]; _mm_store_si128((__m128i*)values, v.m_value); return values[instance]; } +CPPSPMD_FORCE_INLINE int extract(const lint& v, int instance) { assert(instance < 4); CPPSPMD_ALIGN(16) int values[4]; _mm_store_si128((__m128i*)values, v.m_value); return values[instance]; } +CPPSPMD_FORCE_INLINE bool extract(const vbool& v, int instance) { assert(instance < 4); CPPSPMD_ALIGN(16) int values[4]; _mm_store_si128((__m128i*)values, v.m_value); return values[instance] != 0; } + +#undef VINT_EXTRACT +#undef VBOOL_EXTRACT +#undef VFLOAT_EXTRACT + +#if CPPSPMD_SSE2 +// Pass in an immediate constant and the compiler will optimize these expressions. +#define VINT_EXTRACT(v, instance) ( ((instance) == 0) ? extract_x((v).m_value) : (((instance) == 1) ? extract_y((v).m_value) : (((instance) == 2) ? extract_z((v).m_value) : extract_w((v).m_value))) ) +#define VBOOL_EXTRACT(v, instance) ( ((instance) == 0) ? extract_x((v).m_value) : (((instance) == 1) ? extract_y((v).m_value) : (((instance) == 2) ? extract_z((v).m_value) : extract_w((v).m_value))) ) +#define VFLOAT_EXTRACT(v, instance) ( ((instance) == 0) ? extractf_ps_x((v).m_value) : (((instance) == 1) ? extractf_ps_y((v).m_value) : (((instance) == 2) ? extractf_ps_z((v).m_value) : extractf_ps_w((v).m_value))) ) +#else +CPPSPMD_FORCE_INLINE float cast_int_bits_as_float(int v) { return *(const float*)&v; } + +#define VINT_EXTRACT(v, instance) _mm_extract_epi32((v).m_value, instance) +#define VBOOL_EXTRACT(v, instance) _mm_extract_epi32((v).m_value, instance) +#define VFLOAT_EXTRACT(v, instance) cast_int_bits_as_float(_mm_extract_ps((v).m_value, instance)) +#endif + +CPPSPMD_FORCE_INLINE vfloat &insert(vfloat& v, int instance, float f) +{ + assert(instance < 4); + CPPSPMD_ALIGN(16) float values[4]; + _mm_store_ps(values, v.m_value); + values[instance] = f; + v.m_value = _mm_load_ps(values); + return v; +} + +CPPSPMD_FORCE_INLINE vint &insert(vint& v, int instance, int i) +{ + assert(instance < 4); + CPPSPMD_ALIGN(16) int values[4]; + _mm_store_si128((__m128i *)values, v.m_value); + values[instance] = i; + v.m_value = _mm_load_si128((__m128i *)values); + return v; +} + +CPPSPMD_FORCE_INLINE vint init_lookup4(const uint8_t pTab[16]) +{ + __m128i l = _mm_loadu_si128((const __m128i*)pTab); + return vint{ l }; +} + +CPPSPMD_FORCE_INLINE vint table_lookup4_8(const vint& a, const vint& table) +{ + return vint{ shuffle_epi8(table.m_value, a.m_value) }; +} + +CPPSPMD_FORCE_INLINE void init_lookup5(const uint8_t pTab[32], vint& table_0, vint& table_1) +{ + __m128i l = _mm_loadu_si128((const __m128i*)pTab); + __m128i h = _mm_loadu_si128((const __m128i*)(pTab + 16)); + table_0.m_value = l; + table_1.m_value = h; +} + +CPPSPMD_FORCE_INLINE vint table_lookup5_8(const vint& a, const vint& table_0, const vint& table_1) +{ + __m128i l_0 = shuffle_epi8(table_0.m_value, a.m_value); + __m128i h_0 = shuffle_epi8(table_1.m_value, a.m_value); + + __m128i m_0 = _mm_slli_epi32(a.m_value, 31 - 4); + + __m128 v_0 = blendv_ps(_mm_castsi128_ps(l_0), _mm_castsi128_ps(h_0), _mm_castsi128_ps(m_0)); + + return vint{ _mm_castps_si128(v_0) }; +} + +CPPSPMD_FORCE_INLINE void init_lookup6(const uint8_t pTab[64], vint& table_0, vint& table_1, vint& table_2, vint& table_3) +{ + __m128i a = _mm_loadu_si128((const __m128i*)pTab); + __m128i b = _mm_loadu_si128((const __m128i*)(pTab + 16)); + __m128i c = _mm_loadu_si128((const __m128i*)(pTab + 32)); + __m128i d = _mm_loadu_si128((const __m128i*)(pTab + 48)); + + table_0.m_value = a; + table_1.m_value = b; + table_2.m_value = c; + table_3.m_value = d; +} + +CPPSPMD_FORCE_INLINE vint table_lookup6_8(const vint& a, const vint& table_0, const vint& table_1, const vint& table_2, const vint& table_3) +{ + __m128i m_0 = _mm_slli_epi32(a.m_value, 31 - 4); + + __m128 av_0; + { + __m128i al_0 = shuffle_epi8(table_0.m_value, a.m_value); + __m128i ah_0 = shuffle_epi8(table_1.m_value, a.m_value); + av_0 = blendv_ps(_mm_castsi128_ps(al_0), _mm_castsi128_ps(ah_0), _mm_castsi128_ps(m_0)); + } + + __m128 bv_0; + { + __m128i bl_0 = shuffle_epi8(table_2.m_value, a.m_value); + __m128i bh_0 = shuffle_epi8(table_3.m_value, a.m_value); + bv_0 = blendv_ps(_mm_castsi128_ps(bl_0), _mm_castsi128_ps(bh_0), _mm_castsi128_ps(m_0)); + } + + __m128i m2_0 = _mm_slli_epi32(a.m_value, 31 - 5); + __m128 v2_0 = blendv_ps(av_0, bv_0, _mm_castsi128_ps(m2_0)); + + return vint{ _mm_castps_si128(v2_0) }; +} + +#if 0 +template<typename SPMDKernel, typename... Args> +CPPSPMD_FORCE_INLINE decltype(auto) spmd_call(Args&&... args) +{ + SPMDKernel kernel; + kernel.init(exec_mask::all_on()); + return kernel._call(std::forward<Args>(args)...); +} +#else +template<typename SPMDKernel, typename... Args> +CPPSPMD_FORCE_INLINE void spmd_call(Args&&... args) +{ + SPMDKernel kernel; + kernel.init(exec_mask::all_on()); + kernel._call(std::forward<Args>(args)...); +} +#endif + +CPPSPMD_FORCE_INLINE void spmd_kernel::init(const spmd_kernel::exec_mask& kernel_exec) +{ + m_exec = kernel_exec; + m_kernel_exec = kernel_exec; + m_continue_mask = exec_mask::all_off(); + +#ifdef _DEBUG + m_in_loop = false; +#endif +} + +CPPSPMD_FORCE_INLINE const float_vref& spmd_kernel::store(const float_vref& dst, const vfloat& src) +{ + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i*)vindex, dst.m_vindex); + + CPPSPMD_ALIGN(16) float stored[4]; + _mm_store_ps(stored, src.m_value); + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + dst.m_pValue[vindex[i]] = stored[i]; + } + return dst; +} + +CPPSPMD_FORCE_INLINE const float_vref& spmd_kernel::store_all(const float_vref& dst, const vfloat& src) +{ + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i*)vindex, dst.m_vindex); + + CPPSPMD_ALIGN(16) float stored[4]; + _mm_store_ps(stored, src.m_value); + + for (int i = 0; i < 4; i++) + dst.m_pValue[vindex[i]] = stored[i]; + return dst; +} + +CPPSPMD_FORCE_INLINE const float_vref& spmd_kernel::store(const float_vref&& dst, const vfloat& src) +{ + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i*)vindex, dst.m_vindex); + + CPPSPMD_ALIGN(16) float stored[4]; + _mm_store_ps(stored, src.m_value); + + int mask = _mm_movemask_ps(_mm_castsi128_ps(m_exec.m_mask)); + for (int i = 0; i < 4; i++) + { + if (mask & (1 << i)) + dst.m_pValue[vindex[i]] = stored[i]; + } + return dst; +} + +CPPSPMD_FORCE_INLINE const float_vref& spmd_kernel::store_all(const float_vref&& dst, const vfloat& src) +{ + CPPSPMD_ALIGN(16) int vindex[4]; + _mm_store_si128((__m128i*)vindex, dst.m_vindex); + + CPPSPMD_ALIGN(16) float stored[4]; + _mm_store_ps(stored, src.m_value); + + for (int i = 0; i < 4; i++) + dst.m_pValue[vindex[i]] = stored[i]; + return dst; +} + +#include "cppspmd_flow.h" +#include "cppspmd_math.h" + +} // namespace cppspmd_sse41 + diff --git a/thirdparty/basis_universal/encoder/cppspmd_type_aliases.h b/thirdparty/basis_universal/encoder/cppspmd_type_aliases.h new file mode 100644 index 0000000000..0dfb28b88f --- /dev/null +++ b/thirdparty/basis_universal/encoder/cppspmd_type_aliases.h @@ -0,0 +1,47 @@ +// cppspmd_type_aliases.h +// Do not include this file directly +// +// Copyright 2020-2021 Binomial LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifndef CPPSPMD_TYPES +#define CPPSPMD_TYPES + +using exec_mask = CPPSPMD::exec_mask; + +#if CPPSPMD_INT16 +using vint16 = CPPSPMD::vint16; +using int16_lref = CPPSPMD::int16_lref; +using cint16_vref = CPPSPMD::cint16_vref; +using int16_vref = CPPSPMD::int16_vref; +using lint16 = CPPSPMD::lint16; +using vint16_vref = CPPSPMD::vint16_vref; +#else +using vint = CPPSPMD::vint; +using int_lref = CPPSPMD::int_lref; +using cint_vref = CPPSPMD::cint_vref; +using int_vref = CPPSPMD::int_vref; +using lint = CPPSPMD::lint; +using vint_vref = CPPSPMD::vint_vref; +#endif + +using vbool = CPPSPMD::vbool; +using vfloat = CPPSPMD::vfloat; +using float_lref = CPPSPMD::float_lref; +using float_vref = CPPSPMD::float_vref; +using vfloat_vref = CPPSPMD::vfloat_vref; + +#endif // CPPSPMD_TYPES diff --git a/thirdparty/basis_universal/encoder/jpgd.cpp b/thirdparty/basis_universal/encoder/jpgd.cpp new file mode 100644 index 0000000000..460834409d --- /dev/null +++ b/thirdparty/basis_universal/encoder/jpgd.cpp @@ -0,0 +1,3241 @@ +// jpgd.cpp - C++ class for JPEG decompression. Written by Richard Geldreich <richgel99@gmail.com> between 1994-2020. +// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// Supports box and linear chroma upsampling. +// +// Released under two licenses. You are free to choose which license you want: +// License 1: +// Public Domain +// +// License 2: +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Alex Evans: Linear memory allocator (taken from jpge.h). +// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings +// v2.00, March 20, 2020: Fuzzed with zzuf and afl. Fixed several issues, converted most assert()'s to run-time checks. Added chroma upsampling. Removed freq. domain upsampling. gcc/clang warnings. +// +#ifdef _MSC_VER +#ifndef BASISU_NO_ITERATOR_DEBUG_LEVEL +#if defined(_DEBUG) || defined(DEBUG) +#define _ITERATOR_DEBUG_LEVEL 1 +#define _SECURE_SCL 1 +#else +#define _SECURE_SCL 0 +#define _ITERATOR_DEBUG_LEVEL 0 +#endif +#endif +#endif + +#include "jpgd.h" +#include <string.h> +#include <algorithm> +#include <assert.h> + +#ifdef _MSC_VER +#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable +#endif + +#define JPGD_TRUE (1) +#define JPGD_FALSE (0) + +#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b)) +#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b)) + +namespace jpgd { + + static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); } + static inline void jpgd_free(void* p) { free(p); } + + // DCT coefficients are stored in this sequence. + static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; + + enum JPEG_MARKER + { + M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, + M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, + M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, + M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, + M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 + }; + + enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + +#define CONST_BITS 13 +#define PASS1_BITS 2 +#define SCALEDONE ((int32)1) + +#define FIX_0_298631336 ((int32)2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((int32)3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((int32)4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((int32)6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((int32)7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((int32)9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((int32)12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((int32)15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((int32)16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((int32)16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((int32)20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((int32)25172) /* FIX(3.072711026) */ + +#define DESCALE(x,n) (((x) + (SCALEDONE << ((n)-1))) >> (n)) +#define DESCALE_ZEROSHIFT(x,n) (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n)) + +#define MULTIPLY(var, cnst) ((var) * (cnst)) + +#define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i)) + + static inline int left_shifti(int val, uint32_t bits) + { + return static_cast<int>(static_cast<uint32_t>(val) << bits); + } + + // Compiler creates a fast path 1D IDCT for X non-zero columns + template <int NONZERO_COLS> + struct Row + { + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + // ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0. +#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) + + const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS); + const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS); + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, -FIX_0_899976223); + const int az2 = MULTIPLY(bz2, -FIX_2_562915447); + const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS); + pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS); + pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS); + pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS); + pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS); + pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS); + pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS); + pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS); + } + }; + + template <> + struct Row<0> + { + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + (void)pTemp; + (void)pSrc; + } + }; + + template <> + struct Row<1> + { + static void idct(int* pTemp, const jpgd_block_t* pSrc) + { + const int dcval = left_shifti(pSrc[0], PASS1_BITS); + + pTemp[0] = dcval; + pTemp[1] = dcval; + pTemp[2] = dcval; + pTemp[3] = dcval; + pTemp[4] = dcval; + pTemp[5] = dcval; + pTemp[6] = dcval; + pTemp[7] = dcval; + } + }; + + // Compiler creates a fast path 1D IDCT for X non-zero rows + template <int NONZERO_ROWS> + struct Col + { + static void idct(uint8* pDst_ptr, const int* pTemp) + { + // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. +#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) + + const int z2 = ACCESS_ROW(2); + const int z3 = ACCESS_ROW(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS); + const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS); + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, -FIX_0_899976223); + const int az2 = MULTIPLY(bz2, -FIX_2_562915447); + const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 0] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 7] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 1] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 6] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 2] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 5] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 3] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 4] = (uint8)CLAMP(i); + } + }; + + template <> + struct Col<1> + { + static void idct(uint8* pDst_ptr, const int* pTemp) + { + int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3); + const uint8 dcval_clamped = (uint8)CLAMP(dcval); + pDst_ptr[0 * 8] = dcval_clamped; + pDst_ptr[1 * 8] = dcval_clamped; + pDst_ptr[2 * 8] = dcval_clamped; + pDst_ptr[3 * 8] = dcval_clamped; + pDst_ptr[4 * 8] = dcval_clamped; + pDst_ptr[5 * 8] = dcval_clamped; + pDst_ptr[6 * 8] = dcval_clamped; + pDst_ptr[7 * 8] = dcval_clamped; + } + }; + + static const uint8 s_idct_row_table[] = + { + 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, + 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, + 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, + 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, + 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, + 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, + 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, + 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, + }; + + static const uint8 s_idct_col_table[] = + { + 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // Scalar "fast pathing" IDCT. + static void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag) + { + assert(block_max_zag >= 1); + assert(block_max_zag <= 64); + + if (block_max_zag <= 1) + { + int k = ((pSrc_ptr[0] + 4) >> 3) + 128; + k = CLAMP(k); + k = k | (k << 8); + k = k | (k << 16); + + for (int i = 8; i > 0; i--) + { + *(int*)&pDst_ptr[0] = k; + *(int*)&pDst_ptr[4] = k; + pDst_ptr += 8; + } + return; + } + + int temp[64]; + + const jpgd_block_t* pSrc = pSrc_ptr; + int* pTemp = temp; + + const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; + int i; + for (i = 8; i > 0; i--, pRow_tab++) + { + switch (*pRow_tab) + { + case 0: Row<0>::idct(pTemp, pSrc); break; + case 1: Row<1>::idct(pTemp, pSrc); break; + case 2: Row<2>::idct(pTemp, pSrc); break; + case 3: Row<3>::idct(pTemp, pSrc); break; + case 4: Row<4>::idct(pTemp, pSrc); break; + case 5: Row<5>::idct(pTemp, pSrc); break; + case 6: Row<6>::idct(pTemp, pSrc); break; + case 7: Row<7>::idct(pTemp, pSrc); break; + case 8: Row<8>::idct(pTemp, pSrc); break; + } + + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + + const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; + for (i = 8; i > 0; i--) + { + switch (nonzero_rows) + { + case 1: Col<1>::idct(pDst_ptr, pTemp); break; + case 2: Col<2>::idct(pDst_ptr, pTemp); break; + case 3: Col<3>::idct(pDst_ptr, pTemp); break; + case 4: Col<4>::idct(pDst_ptr, pTemp); break; + case 5: Col<5>::idct(pDst_ptr, pTemp); break; + case 6: Col<6>::idct(pDst_ptr, pTemp); break; + case 7: Col<7>::idct(pDst_ptr, pTemp); break; + case 8: Col<8>::idct(pDst_ptr, pTemp); break; + } + + pTemp++; + pDst_ptr++; + } + } + + // Retrieve one character from the input stream. + inline uint jpeg_decoder::get_char() + { + // Any bytes remaining in buffer? + if (!m_in_buf_left) + { + // Try to get more bytes. + prep_in_buffer(); + // Still nothing to get? + if (!m_in_buf_left) + { + // Pad the end of the stream with 0xFF 0xD9 (EOI marker) + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; + } + + // Same as previous method, except can indicate if the character is a pad character or not. + inline uint jpeg_decoder::get_char(bool* pPadding_flag) + { + if (!m_in_buf_left) + { + prep_in_buffer(); + if (!m_in_buf_left) + { + *pPadding_flag = true; + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + *pPadding_flag = false; + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; + } + + // Inserts a previously retrieved character back into the input buffer. + inline void jpeg_decoder::stuff_char(uint8 q) + { + // This could write before the input buffer, but we've placed another array there. + *(--m_pIn_buf_ofs) = q; + m_in_buf_left++; + } + + // Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. + inline uint8 jpeg_decoder::get_octet() + { + bool padding_flag; + int c = get_char(&padding_flag); + + if (c == 0xFF) + { + if (padding_flag) + return 0xFF; + + c = get_char(&padding_flag); + if (padding_flag) + { + stuff_char(0xFF); + return 0xFF; + } + + if (c == 0x00) + return 0xFF; + else + { + stuff_char(static_cast<uint8>(c)); + stuff_char(0xFF); + return 0xFF; + } + } + + return static_cast<uint8>(c); + } + + // Retrieves a variable number of bits from the input stream. Does not recognize markers. + inline uint jpeg_decoder::get_bits(int num_bits) + { + if (!num_bits) + return 0; + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + uint c1 = get_char(); + uint c2 = get_char(); + m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + assert(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; + } + + // Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. + inline uint jpeg_decoder::get_bits_no_markers(int num_bits) + { + if (!num_bits) + return 0; + + assert(num_bits <= 16); + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) + { + uint c1 = get_octet(); + uint c2 = get_octet(); + m_bit_buf |= (c1 << 8) | c2; + } + else + { + m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; + m_in_buf_left -= 2; + m_pIn_buf_ofs += 2; + } + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + assert(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; + } + + // Decodes a Huffman encoded symbol. + inline int jpeg_decoder::huff_decode(huff_tables* pH) + { + if (!pH) + stop_decoding(JPGD_DECODE_ERROR); + + int symbol; + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) + { + // Decode more bits, use a tree traversal to find symbol. + int ofs = 23; + do + { + unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); + + // This should never happen, but to be safe I'm turning these asserts into a run-time check. + if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0)) + stop_decoding(JPGD_DECODE_ERROR); + + symbol = pH->tree[idx]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + } + else + { + assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); + get_bits_no_markers(pH->code_size[symbol]); + } + + return symbol; + } + + // Decodes a Huffman encoded symbol. + inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits) + { + int symbol; + + if (!pH) + stop_decoding(JPGD_DECODE_ERROR); + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) + { + // Use a tree traversal to find symbol. + int ofs = 23; + do + { + unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); + + // This should never happen, but to be safe I'm turning these asserts into a run-time check. + if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0)) + stop_decoding(JPGD_DECODE_ERROR); + + symbol = pH->tree[idx]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + + extra_bits = get_bits_no_markers(symbol & 0xF); + } + else + { + if (symbol & 0x8000) + { + //get_bits_no_markers((symbol >> 8) & 31); + assert(((symbol >> 8) & 31) <= 15); + get_bits_no_markers((symbol >> 8) & 15); + extra_bits = symbol >> 16; + } + else + { + int code_size = (symbol >> 8) & 31; + int num_extra_bits = symbol & 0xF; + int bits = code_size + num_extra_bits; + + if (bits <= 16) + extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); + else + { + get_bits_no_markers(code_size); + extra_bits = get_bits_no_markers(num_extra_bits); + } + } + + symbol &= 0xFF; + } + + return symbol; + } + + // Tables and macro used to fully decode the DPCM differences. + static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 }; + //static const int s_extend_mask[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16) }; + +#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x)) + + // Unconditionally frees all allocated m_blocks. + void jpeg_decoder::free_all_blocks() + { + m_pStream = nullptr; + for (mem_block* b = m_pMem_blocks; b; ) + { + mem_block* n = b->m_pNext; + jpgd_free(b); + b = n; + } + m_pMem_blocks = nullptr; + } + + // This method handles all errors. It will never return. + // It could easily be changed to use C++ exceptions. + JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) + { + m_error_code = status; + free_all_blocks(); + longjmp(m_jmp_state, status); + } + + void* jpeg_decoder::alloc(size_t nSize, bool zero) + { + nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; + char* rv = nullptr; + for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext) + { + if ((b->m_used_count + nSize) <= b->m_size) + { + rv = b->m_data + b->m_used_count; + b->m_used_count += nSize; + break; + } + } + if (!rv) + { + int capacity = JPGD_MAX(32768 - 256, ((int)nSize + 2047) & ~2047); + mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity); + if (!b) + { + stop_decoding(JPGD_NOTENOUGHMEM); + } + + b->m_pNext = m_pMem_blocks; + m_pMem_blocks = b; + b->m_used_count = nSize; + b->m_size = capacity; + rv = b->m_data; + } + if (zero) memset(rv, 0, nSize); + return rv; + } + + void jpeg_decoder::word_clear(void* p, uint16 c, uint n) + { + uint8* pD = (uint8*)p; + const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF; + while (n) + { + pD[0] = l; + pD[1] = h; + pD += 2; + n--; + } + } + + // Refill the input buffer. + // This method will sit in a loop until (A) the buffer is full or (B) + // the stream's read() method reports and end of file condition. + void jpeg_decoder::prep_in_buffer() + { + m_in_buf_left = 0; + m_pIn_buf_ofs = m_in_buf; + + if (m_eof_flag) + return; + + do + { + int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); + if (bytes_read == -1) + stop_decoding(JPGD_STREAM_READ); + + m_in_buf_left += bytes_read; + } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); + + m_total_bytes_read += m_in_buf_left; + + // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). + // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) + word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); + } + + // Read a Huffman code table. + void jpeg_decoder::read_dht_marker() + { + int i, index, count; + uint8 huff_num[17]; + uint8 huff_val[256]; + + uint num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_DHT_MARKER); + + num_left -= 2; + + while (num_left) + { + index = get_bits(8); + + huff_num[0] = 0; + + count = 0; + + for (i = 1; i <= 16; i++) + { + huff_num[i] = static_cast<uint8>(get_bits(8)); + count += huff_num[i]; + } + + if (count > 255) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + bool symbol_present[256]; + memset(symbol_present, 0, sizeof(symbol_present)); + + for (i = 0; i < count; i++) + { + const int s = get_bits(8); + + // Check for obviously bogus tables. + if (symbol_present[s]) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + huff_val[i] = static_cast<uint8_t>(s); + symbol_present[s] = true; + } + + i = 1 + 16 + count; + + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DHT_MARKER); + + num_left -= i; + + if ((index & 0x10) > 0x10) + stop_decoding(JPGD_BAD_DHT_INDEX); + + index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); + + if (index >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_BAD_DHT_INDEX); + + if (!m_huff_num[index]) + m_huff_num[index] = (uint8*)alloc(17); + + if (!m_huff_val[index]) + m_huff_val[index] = (uint8*)alloc(256); + + m_huff_ac[index] = (index & 0x10) != 0; + memcpy(m_huff_num[index], huff_num, 17); + memcpy(m_huff_val[index], huff_val, 256); + } + } + + // Read a quantization table. + void jpeg_decoder::read_dqt_marker() + { + int n, i, prec; + uint num_left; + uint temp; + + num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_DQT_MARKER); + + num_left -= 2; + + while (num_left) + { + n = get_bits(8); + prec = n >> 4; + n &= 0x0F; + + if (n >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_BAD_DQT_TABLE); + + if (!m_quant[n]) + m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t)); + + // read quantization entries, in zag order + for (i = 0; i < 64; i++) + { + temp = get_bits(8); + + if (prec) + temp = (temp << 8) + get_bits(8); + + m_quant[n][i] = static_cast<jpgd_quant_t>(temp); + } + + i = 64 + 1; + + if (prec) + i += 64; + + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DQT_LENGTH); + + num_left -= i; + } + } + + // Read the start of frame (SOF) marker. + void jpeg_decoder::read_sof_marker() + { + int i; + uint num_left; + + num_left = get_bits(16); + + /* precision: sorry, only 8-bit precision is supported */ + if (get_bits(8) != 8) + stop_decoding(JPGD_BAD_PRECISION); + + m_image_y_size = get_bits(16); + + if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) + stop_decoding(JPGD_BAD_HEIGHT); + + m_image_x_size = get_bits(16); + + if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) + stop_decoding(JPGD_BAD_WIDTH); + + m_comps_in_frame = get_bits(8); + + if (m_comps_in_frame > JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_TOO_MANY_COMPONENTS); + + if (num_left != (uint)(m_comps_in_frame * 3 + 8)) + stop_decoding(JPGD_BAD_SOF_LENGTH); + + for (i = 0; i < m_comps_in_frame; i++) + { + m_comp_ident[i] = get_bits(8); + m_comp_h_samp[i] = get_bits(4); + m_comp_v_samp[i] = get_bits(4); + + if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + m_comp_quant[i] = get_bits(8); + if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + } + } + + // Used to skip unrecognized markers. + void jpeg_decoder::skip_variable_marker() + { + uint num_left; + + num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_VARIABLE_MARKER); + + num_left -= 2; + + while (num_left) + { + get_bits(8); + num_left--; + } + } + + // Read a define restart interval (DRI) marker. + void jpeg_decoder::read_dri_marker() + { + if (get_bits(16) != 4) + stop_decoding(JPGD_BAD_DRI_LENGTH); + + m_restart_interval = get_bits(16); + } + + // Read a start of scan (SOS) marker. + void jpeg_decoder::read_sos_marker() + { + uint num_left; + int i, ci, n, c, cc; + + num_left = get_bits(16); + + n = get_bits(8); + + m_comps_in_scan = n; + + num_left -= 3; + + if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN)) + stop_decoding(JPGD_BAD_SOS_LENGTH); + + for (i = 0; i < n; i++) + { + cc = get_bits(8); + c = get_bits(8); + num_left -= 2; + + for (ci = 0; ci < m_comps_in_frame; ci++) + if (cc == m_comp_ident[ci]) + break; + + if (ci >= m_comps_in_frame) + stop_decoding(JPGD_BAD_SOS_COMP_ID); + + if (ci >= JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_DECODE_ERROR); + + m_comp_list[i] = ci; + + m_comp_dc_tab[ci] = (c >> 4) & 15; + m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); + + if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + } + + m_spectral_start = get_bits(8); + m_spectral_end = get_bits(8); + m_successive_high = get_bits(4); + m_successive_low = get_bits(4); + + if (!m_progressive_flag) + { + m_spectral_start = 0; + m_spectral_end = 63; + } + + num_left -= 3; + + /* read past whatever is num_left */ + while (num_left) + { + get_bits(8); + num_left--; + } + } + + // Finds the next marker. + int jpeg_decoder::next_marker() + { + uint c, bytes; + + bytes = 0; + + do + { + do + { + bytes++; + c = get_bits(8); + } while (c != 0xFF); + + do + { + c = get_bits(8); + } while (c == 0xFF); + + } while (c == 0); + + // If bytes > 0 here, there where extra bytes before the marker (not good). + + return c; + } + + // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is + // encountered. + int jpeg_decoder::process_markers() + { + int c; + + for (; ; ) + { + c = next_marker(); + + switch (c) + { + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + // case M_JPG: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + case M_SOI: + case M_EOI: + case M_SOS: + { + return c; + } + case M_DHT: + { + read_dht_marker(); + break; + } + // No arithmitic support - dumb patents! + case M_DAC: + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + case M_DQT: + { + read_dqt_marker(); + break; + } + case M_DRI: + { + read_dri_marker(); + break; + } + //case M_APP0: /* no need to read the JFIF marker */ + case M_JPG: + case M_RST0: /* no parameters */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + { + stop_decoding(JPGD_UNEXPECTED_MARKER); + break; + } + default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ + { + skip_variable_marker(); + break; + } + } + } + } + + // Finds the start of image (SOI) marker. + void jpeg_decoder::locate_soi_marker() + { + uint lastchar, thischar; + uint bytesleft; + + lastchar = get_bits(8); + + thischar = get_bits(8); + + /* ok if it's a normal JPEG file without a special header */ + + if ((lastchar == 0xFF) && (thischar == M_SOI)) + return; + + bytesleft = 4096; + + for (; ; ) + { + if (--bytesleft == 0) + stop_decoding(JPGD_NOT_JPEG); + + lastchar = thischar; + + thischar = get_bits(8); + + if (lastchar == 0xFF) + { + if (thischar == M_SOI) + break; + else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end + stop_decoding(JPGD_NOT_JPEG); + } + } + + // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. + thischar = (m_bit_buf >> 24) & 0xFF; + + if (thischar != 0xFF) + stop_decoding(JPGD_NOT_JPEG); + } + + // Find a start of frame (SOF) marker. + void jpeg_decoder::locate_sof_marker() + { + locate_soi_marker(); + + int c = process_markers(); + + switch (c) + { + case M_SOF2: + { + m_progressive_flag = JPGD_TRUE; + read_sof_marker(); + break; + } + case M_SOF0: /* baseline DCT */ + case M_SOF1: /* extended sequential DCT */ + { + read_sof_marker(); + break; + } + case M_SOF9: /* Arithmitic coding */ + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + default: + { + stop_decoding(JPGD_UNSUPPORTED_MARKER); + break; + } + } + } + + // Find a start of scan (SOS) marker. + int jpeg_decoder::locate_sos_marker() + { + int c; + + c = process_markers(); + + if (c == M_EOI) + return JPGD_FALSE; + else if (c != M_SOS) + stop_decoding(JPGD_UNEXPECTED_MARKER); + + read_sos_marker(); + + return JPGD_TRUE; + } + + // Reset everything to default/uninitialized state. + void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags) + { + m_flags = flags; + m_pMem_blocks = nullptr; + m_error_code = JPGD_SUCCESS; + m_ready_flag = false; + m_image_x_size = m_image_y_size = 0; + m_pStream = pStream; + m_progressive_flag = JPGD_FALSE; + + memset(m_huff_ac, 0, sizeof(m_huff_ac)); + memset(m_huff_num, 0, sizeof(m_huff_num)); + memset(m_huff_val, 0, sizeof(m_huff_val)); + memset(m_quant, 0, sizeof(m_quant)); + + m_scan_type = 0; + m_comps_in_frame = 0; + + memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); + memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); + memset(m_comp_quant, 0, sizeof(m_comp_quant)); + memset(m_comp_ident, 0, sizeof(m_comp_ident)); + memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); + memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); + + m_comps_in_scan = 0; + memset(m_comp_list, 0, sizeof(m_comp_list)); + memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); + memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); + + m_spectral_start = 0; + m_spectral_end = 0; + m_successive_low = 0; + m_successive_high = 0; + m_max_mcu_x_size = 0; + m_max_mcu_y_size = 0; + m_blocks_per_mcu = 0; + m_max_blocks_per_row = 0; + m_mcus_per_row = 0; + m_mcus_per_col = 0; + + memset(m_mcu_org, 0, sizeof(m_mcu_org)); + + m_total_lines_left = 0; + m_mcu_lines_left = 0; + m_num_buffered_scanlines = 0; + m_real_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_pixel = 0; + + memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); + + memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); + memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_eob_run = 0; + + m_pIn_buf_ofs = m_in_buf; + m_in_buf_left = 0; + m_eof_flag = false; + m_tem_flag = 0; + + memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); + memset(m_in_buf, 0, sizeof(m_in_buf)); + memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); + + m_restart_interval = 0; + m_restarts_left = 0; + m_next_restart_num = 0; + + m_max_mcus_per_row = 0; + m_max_blocks_per_mcu = 0; + m_max_mcus_per_col = 0; + + memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); + m_pMCU_coefficients = nullptr; + m_pSample_buf = nullptr; + m_pSample_buf_prev = nullptr; + m_sample_buf_prev_valid = false; + + m_total_bytes_read = 0; + + m_pScan_line_0 = nullptr; + m_pScan_line_1 = nullptr; + + // Ready the input buffer. + prep_in_buffer(); + + // Prime the bit buffer. + m_bits_left = 16; + m_bit_buf = 0; + + get_bits(16); + get_bits(16); + + for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) + m_mcu_block_max_zag[i] = 64; + } + +#define SCALEBITS 16 +#define ONE_HALF ((int) 1 << (SCALEBITS-1)) +#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f)) + + // Create a few tables that allow us to quickly convert YCbCr to RGB. + void jpeg_decoder::create_look_ups() + { + for (int i = 0; i <= 255; i++) + { + int k = i - 128; + m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS; + m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; + m_crg[i] = (-FIX(0.71414f)) * k; + m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; + } + } + + // This method throws back into the stream any bytes that where read + // into the bit buffer during initial marker scanning. + void jpeg_decoder::fix_in_buffer() + { + // In case any 0xFF's where pulled into the buffer during marker scanning. + assert((m_bits_left & 7) == 0); + + if (m_bits_left == 16) + stuff_char((uint8)(m_bit_buf & 0xFF)); + + if (m_bits_left >= 8) + stuff_char((uint8)((m_bit_buf >> 8) & 0xFF)); + + stuff_char((uint8)((m_bit_buf >> 16) & 0xFF)); + stuff_char((uint8)((m_bit_buf >> 24) & 0xFF)); + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); + } + + void jpeg_decoder::transform_mcu(int mcu_row) + { + jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; + if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row) + stop_decoding(JPGD_DECODE_ERROR); + + uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); + pSrc_ptr += 64; + pDst_ptr += 64; + } + } + + // Loads and dequantizes the next row of (already decoded) coefficients. + // Progressive images only. + void jpeg_decoder::load_next_row() + { + int i; + jpgd_block_t* p; + jpgd_quant_t* q; + int mcu_row, mcu_block, row_block = 0; + int component_num, component_id; + int block_x_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + q = m_quant[m_comp_quant[component_id]]; + + p = m_pMCU_coefficients + 64 * mcu_block; + + jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + p[0] = pDC[0]; + memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t)); + + for (i = 63; i > 0; i--) + if (p[g_ZAG[i]]) + break; + + m_mcu_block_max_zag[mcu_block] = i + 1; + + for (; i >= 0; i--) + if (p[g_ZAG[i]]) + p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]); + + row_block++; + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + transform_mcu(mcu_row); + } + + if (m_comps_in_scan == 1) + m_block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } + + // Restart interval processing. + void jpeg_decoder::process_restart() + { + int i; + int c = 0; + + // Align to a byte boundry + // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! + //get_bits_no_markers(m_bits_left & 7); + + // Let's scan a little bit to find the marker, but not _too_ far. + // 1536 is a "fudge factor" that determines how much to scan. + for (i = 1536; i > 0; i--) + if (get_char() == 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + for (; i > 0; i--) + if ((c = get_char()) != 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Is it the expected marker? If not, something bad happened. + if (c != (m_next_restart_num + M_RST0)) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Reset each component's DC prediction values. + memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + m_restarts_left = m_restart_interval; + + m_next_restart_num = (m_next_restart_num + 1) & 7; + + // Get the bit buffer going again... + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); + } + + static inline int dequantize_ac(int c, int q) { c *= q; return c; } + + // Decodes and dequantizes the next row of coefficients. + void jpeg_decoder::decode_next_row() + { + int row_block = 0; + + for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + jpgd_block_t* p = m_pMCU_coefficients; + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) + { + int component_id = m_mcu_org[mcu_block]; + if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; + + int r, s; + s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); + if (s >= 16) + stop_decoding(JPGD_DECODE_ERROR); + + s = JPGD_HUFF_EXTEND(r, s); + + m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_t>(s * q[0]); + + int prev_num_set = m_mcu_block_max_zag[mcu_block]; + + huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; + + int k; + for (k = 1; k < 64; k++) + { + int extra_bits; + s = huff_decode(pH, extra_bits); + + r = s >> 4; + s &= 15; + + if (s) + { + if (r) + { + if ((k + r) > 63) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(r, prev_num_set - k); + int kt = k; + while (n--) + p[g_ZAG[kt++]] = 0; + } + + k += r; + } + + s = JPGD_HUFF_EXTEND(extra_bits, s); + + if (k >= 64) + stop_decoding(JPGD_DECODE_ERROR); + + p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k]; + } + else + { + if (r == 15) + { + if ((k + 16) > 64) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(16, prev_num_set - k); + int kt = k; + while (n--) + { + if (kt > 63) + stop_decoding(JPGD_DECODE_ERROR); + p[g_ZAG[kt++]] = 0; + } + } + + k += 16 - 1; // - 1 because the loop counter is k + + if (p[g_ZAG[k & 63]] != 0) + stop_decoding(JPGD_DECODE_ERROR); + } + else + break; + } + } + + if (k < prev_num_set) + { + int kt = k; + while (kt < prev_num_set) + p[g_ZAG[kt++]] = 0; + } + + m_mcu_block_max_zag[mcu_block] = k; + + row_block++; + } + + transform_mcu(mcu_row); + + m_restarts_left--; + } + } + + // YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB + void jpeg_decoder::H1V1Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d = m_pScan_line_0; + uint8* s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int y = s[j]; + int cb = s[64 + j]; + int cr = s[128 + j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + + d += 4; + } + + s += 64 * 3; + } + } + + // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H2V1Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* y = m_pSample_buf + row * 8; + uint8* c = m_pSample_buf + 2 * 64 + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 4; j++) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j << 1]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[(j << 1) + 1]; + d0[4] = clamp(yy + rc); + d0[5] = clamp(yy + gc); + d0[6] = clamp(yy + bc); + d0[7] = 255; + + d0 += 8; + + c++; + } + y += 64; + } + + y += 64 * 4 - 64 * 2; + c += 64 * 4 - 8; + } + } + + // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H2V1ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 4; + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + + const int half_image_x_size = (m_image_x_size >> 1) - 1; + const int row_x8 = row * 8; + + for (int x = 0; x < m_image_x_size; x++) + { + int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128; + int cb0 = m_pSample_buf[check_sample_buf_ofs(a)]; + int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128; + int cb1 = m_pSample_buf[check_sample_buf_ofs(b)]; + int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)]; + + int w0 = (x & 1) ? 3 : 1; + int w1 = (x & 1) ? 1 : 3; + + int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2; + int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y + rc); + d0[1] = clamp(y + gc); + d0[2] = clamp(y + bc); + d0[3] = 255; + + d0 += 4; + } + } + + // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H1V2Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* d1 = m_pScan_line_1; + uint8* y; + uint8* c; + + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64 * 1 + (row & 7) * 8; + + c = m_pSample_buf + 64 * 2 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int cb = c[0 + j]; + int cr = c[64 + j]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[8 + j]; + d1[0] = clamp(yy + rc); + d1[1] = clamp(yy + gc); + d1[2] = clamp(yy + bc); + d1[3] = 255; + + d0 += 4; + d1 += 4; + } + + y += 64 * 4; + c += 64 * 4; + } + } + + // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H1V2ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 4; + int y = m_image_y_size - m_total_lines_left; + int row = y & 15; + + const int half_image_y_size = (m_image_y_size >> 1) - 1; + + uint8* d0 = m_pScan_line_0; + + const int w0 = (row & 1) ? 3 : 1; + const int w1 = (row & 1) ? 1 : 3; + + int c_y0 = (y - 1) >> 1; + int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size); + + const uint8_t* p_YSamples = m_pSample_buf; + const uint8_t* p_C0Samples = m_pSample_buf; + if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1)) + { + assert(y > 0); + assert(m_sample_buf_prev_valid); + + if ((row & 15) == 15) + p_YSamples = m_pSample_buf_prev; + + p_C0Samples = m_pSample_buf_prev; + } + + const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8; + const int y0_base = (c_y0 & 7) * 8 + 128; + const int y1_base = (c_y1 & 7) * 8 + 128; + + for (int x = 0; x < m_image_x_size; x++) + { + const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7); + + int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)]; + + int a = base_ofs + y0_base; + int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)]; + int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)]; + + int b = base_ofs + y1_base; + int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)]; + int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)]; + + int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2; + int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample + rc); + d0[1] = clamp(y_sample + gc); + d0[2] = clamp(y_sample + bc); + d0[3] = 255; + + d0 += 4; + } + } + + // YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB + void jpeg_decoder::H2V2Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* d1 = m_pScan_line_1; + uint8* y; + uint8* c; + + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64 * 2 + (row & 7) * 8; + + c = m_pSample_buf + 64 * 4 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 8; j += 2) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[j + 1]; + d0[4] = clamp(yy + rc); + d0[5] = clamp(yy + gc); + d0[6] = clamp(yy + bc); + d0[7] = 255; + + yy = y[j + 8]; + d1[0] = clamp(yy + rc); + d1[1] = clamp(yy + gc); + d1[2] = clamp(yy + bc); + d1[3] = 255; + + yy = y[j + 8 + 1]; + d1[4] = clamp(yy + rc); + d1[5] = clamp(yy + gc); + d1[6] = clamp(yy + bc); + d1[7] = 255; + + d0 += 8; + d1 += 8; + + c++; + } + y += 64; + } + + y += 64 * 6 - 64 * 2; + c += 64 * 6 - 8; + } + } + + uint32_t jpeg_decoder::H2V2ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 6; + int y = m_image_y_size - m_total_lines_left; + int row = y & 15; + + const int half_image_y_size = (m_image_y_size >> 1) - 1; + + uint8* d0 = m_pScan_line_0; + + int c_y0 = (y - 1) >> 1; + int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size); + + const uint8_t* p_YSamples = m_pSample_buf; + const uint8_t* p_C0Samples = m_pSample_buf; + if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1)) + { + assert(y > 0); + assert(m_sample_buf_prev_valid); + + if ((row & 15) == 15) + p_YSamples = m_pSample_buf_prev; + + p_C0Samples = m_pSample_buf_prev; + } + + const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8; + const int y0_base = (c_y0 & 7) * 8 + 256; + const int y1_base = (c_y1 & 7) * 8 + 256; + + const int half_image_x_size = (m_image_x_size >> 1) - 1; + + static const uint8_t s_muls[2][2][4] = + { + { { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, }, + { { 3, 1, 9, 3 }, { 9, 3, 3, 1 } } + }; + + if (((row & 15) >= 1) && ((row & 15) <= 14)) + { + assert((row & 1) == 1); + assert(((y + 1 - 1) >> 1) == c_y0); + + assert(p_YSamples == m_pSample_buf); + assert(p_C0Samples == m_pSample_buf); + + uint8* d1 = m_pScan_line_1; + const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8; + + for (int x = 0; x < m_image_x_size; x++) + { + int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7); + int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)]; + int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7); + int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)]; + int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)]; + + int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)]; + int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7); + int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)]; + int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)]; + + int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)]; + int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)]; + + { + const uint8_t* pMuls = &s_muls[row & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample0 + rc); + d0[1] = clamp(y_sample0 + gc); + d0[2] = clamp(y_sample0 + bc); + d0[3] = 255; + + d0 += 4; + } + + { + const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d1[0] = clamp(y_sample1 + rc); + d1[1] = clamp(y_sample1 + gc); + d1[2] = clamp(y_sample1 + bc); + d1[3] = 255; + + d1 += 4; + } + + if (((x & 1) == 1) && (x < m_image_x_size - 1)) + { + const int nx = x + 1; + assert(c_x0 == (nx - 1) >> 1); + + k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7); + y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)]; + y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)]; + + { + const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample0 + rc); + d0[1] = clamp(y_sample0 + gc); + d0[2] = clamp(y_sample0 + bc); + d0[3] = 255; + + d0 += 4; + } + + { + const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d1[0] = clamp(y_sample1 + rc); + d1[1] = clamp(y_sample1 + gc); + d1[2] = clamp(y_sample1 + bc); + d1[3] = 255; + + d1 += 4; + } + + ++x; + } + } + + return 2; + } + else + { + for (int x = 0; x < m_image_x_size; x++) + { + int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7); + int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)]; + int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)]; + + int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)]; + int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7); + int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)]; + int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)]; + + int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)]; + int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)]; + + const uint8_t* pMuls = &s_muls[row & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample + rc); + d0[1] = clamp(y_sample + gc); + d0[2] = clamp(y_sample + bc); + d0[3] = 255; + + d0 += 4; + } + + return 1; + } + } + + // Y (1 block per MCU) to 8-bit grayscale + void jpeg_decoder::gray_convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d = m_pScan_line_0; + uint8* s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + *(uint*)d = *(uint*)s; + *(uint*)(&d[4]) = *(uint*)(&s[4]); + + s += 64; + d += 8; + } + } + + // Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. + void jpeg_decoder::find_eoi() + { + if (!m_progressive_flag) + { + // Attempt to read the EOI marker. + //get_bits_no_markers(m_bits_left & 7); + + // Prime the bit buffer + m_bits_left = 16; + get_bits(16); + get_bits(16); + + // The next marker _should_ be EOI + process_markers(); + } + + m_total_bytes_read -= m_in_buf_left; + } + + int jpeg_decoder::decode_next_mcu_row() + { + if (setjmp(m_jmp_state)) + return JPGD_FAILED; + + const bool chroma_y_filtering = (m_flags & cFlagLinearChromaFiltering) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); + if (chroma_y_filtering) + { + std::swap(m_pSample_buf, m_pSample_buf_prev); + + m_sample_buf_prev_valid = true; + } + + if (m_progressive_flag) + load_next_row(); + else + decode_next_row(); + + // Find the EOI marker if that was the last row. + if (m_total_lines_left <= m_max_mcu_y_size) + find_eoi(); + + m_mcu_lines_left = m_max_mcu_y_size; + return 0; + } + + int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len) + { + if ((m_error_code) || (!m_ready_flag)) + return JPGD_FAILED; + + if (m_total_lines_left == 0) + return JPGD_DONE; + + const bool chroma_y_filtering = (m_flags & cFlagLinearChromaFiltering) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); + + bool get_another_mcu_row = false; + bool got_mcu_early = false; + if (chroma_y_filtering) + { + if (m_total_lines_left == m_image_y_size) + get_another_mcu_row = true; + else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1)) + { + get_another_mcu_row = true; + got_mcu_early = true; + } + } + else + { + get_another_mcu_row = (m_mcu_lines_left == 0); + } + + if (get_another_mcu_row) + { + int status = decode_next_mcu_row(); + if (status != 0) + return status; + } + + switch (m_scan_type) + { + case JPGD_YH2V2: + { + if (m_flags & cFlagLinearChromaFiltering) + { + if (m_num_buffered_scanlines == 1) + { + *pScan_line = m_pScan_line_1; + } + else if (m_num_buffered_scanlines == 0) + { + m_num_buffered_scanlines = H2V2ConvertFiltered(); + *pScan_line = m_pScan_line_0; + } + + m_num_buffered_scanlines--; + } + else + { + if ((m_mcu_lines_left & 1) == 0) + { + H2V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + } + + break; + } + case JPGD_YH2V1: + { + if (m_flags & cFlagLinearChromaFiltering) + H2V1ConvertFiltered(); + else + H2V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_YH1V2: + { + if (chroma_y_filtering) + { + H1V2ConvertFiltered(); + *pScan_line = m_pScan_line_0; + } + else + { + if ((m_mcu_lines_left & 1) == 0) + { + H1V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + } + + break; + } + case JPGD_YH1V1: + { + H1V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_GRAYSCALE: + { + gray_convert(); + *pScan_line = m_pScan_line_0; + + break; + } + } + + *pScan_line_len = m_real_dest_bytes_per_scan_line; + + if (!got_mcu_early) + { + m_mcu_lines_left--; + } + + m_total_lines_left--; + + return JPGD_SUCCESS; + } + + // Creates the tables needed for efficient Huffman decoding. + void jpeg_decoder::make_huff_table(int index, huff_tables* pH) + { + int p, i, l, si; + uint8 huffsize[258]; + uint huffcode[258]; + uint code; + uint subtree; + int code_size; + int lastp; + int nextfreeentry; + int currententry; + + pH->ac_table = m_huff_ac[index] != 0; + + p = 0; + + for (l = 1; l <= 16; l++) + { + for (i = 1; i <= m_huff_num[index][l]; i++) + { + if (p >= 257) + stop_decoding(JPGD_DECODE_ERROR); + huffsize[p++] = static_cast<uint8>(l); + } + } + + assert(p < 258); + huffsize[p] = 0; + + lastp = p; + + code = 0; + si = huffsize[0]; + p = 0; + + while (huffsize[p]) + { + while (huffsize[p] == si) + { + if (p >= 257) + stop_decoding(JPGD_DECODE_ERROR); + huffcode[p++] = code; + code++; + } + + code <<= 1; + si++; + } + + memset(pH->look_up, 0, sizeof(pH->look_up)); + memset(pH->look_up2, 0, sizeof(pH->look_up2)); + memset(pH->tree, 0, sizeof(pH->tree)); + memset(pH->code_size, 0, sizeof(pH->code_size)); + + nextfreeentry = -1; + + p = 0; + + while (p < lastp) + { + i = m_huff_val[index][p]; + + code = huffcode[p]; + code_size = huffsize[p]; + + assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); + pH->code_size[i] = static_cast<uint8>(code_size); + + if (code_size <= 8) + { + code <<= (8 - code_size); + + for (l = 1 << (8 - code_size); l > 0; l--) + { + if (code >= 256) + stop_decoding(JPGD_DECODE_ERROR); + + pH->look_up[code] = i; + + bool has_extrabits = false; + int extra_bits = 0; + int num_extra_bits = i & 15; + + int bits_to_fetch = code_size; + if (num_extra_bits) + { + int total_codesize = code_size + num_extra_bits; + if (total_codesize <= 8) + { + has_extrabits = true; + extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); + + if (extra_bits > 0x7FFF) + stop_decoding(JPGD_DECODE_ERROR); + + bits_to_fetch += num_extra_bits; + } + } + + if (!has_extrabits) + pH->look_up2[code] = i | (bits_to_fetch << 8); + else + pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); + + code++; + } + } + else + { + subtree = (code >> (code_size - 8)) & 0xFF; + + currententry = pH->look_up[subtree]; + + if (currententry == 0) + { + pH->look_up[subtree] = currententry = nextfreeentry; + pH->look_up2[subtree] = currententry = nextfreeentry; + + nextfreeentry -= 2; + } + + code <<= (16 - (code_size - 8)); + + for (l = code_size; l > 9; l--) + { + if ((code & 0x8000) == 0) + currententry--; + + unsigned int idx = -currententry - 1; + + if (idx >= JPGD_HUFF_TREE_MAX_LENGTH) + stop_decoding(JPGD_DECODE_ERROR); + + if (pH->tree[idx] == 0) + { + pH->tree[idx] = nextfreeentry; + + currententry = nextfreeentry; + + nextfreeentry -= 2; + } + else + { + currententry = pH->tree[idx]; + } + + code <<= 1; + } + + if ((code & 0x8000) == 0) + currententry--; + + if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH) + stop_decoding(JPGD_DECODE_ERROR); + + pH->tree[-currententry - 1] = i; + } + + p++; + } + } + + // Verifies the quantization tables needed for this scan are available. + void jpeg_decoder::check_quant_tables() + { + for (int i = 0; i < m_comps_in_scan; i++) + if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr) + stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); + } + + // Verifies that all the Huffman tables needed for this scan are available. + void jpeg_decoder::check_huff_tables() + { + for (int i = 0; i < m_comps_in_scan; i++) + { + if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + + if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + } + + for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) + if (m_huff_num[i]) + { + if (!m_pHuff_tabs[i]) + m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables)); + + make_huff_table(i, m_pHuff_tabs[i]); + } + } + + // Determines the component order inside each MCU. + // Also calcs how many MCU's are on each row, etc. + bool jpeg_decoder::calc_mcu_block_order() + { + int component_num, component_id; + int max_h_samp = 0, max_v_samp = 0; + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + if (m_comp_h_samp[component_id] > max_h_samp) + max_h_samp = m_comp_h_samp[component_id]; + + if (m_comp_v_samp[component_id] > max_v_samp) + max_v_samp = m_comp_v_samp[component_id]; + } + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; + m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; + } + + if (m_comps_in_scan == 1) + { + m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; + m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; + } + else + { + m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; + m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; + } + + if (m_comps_in_scan == 1) + { + m_mcu_org[0] = m_comp_list[0]; + + m_blocks_per_mcu = 1; + } + else + { + m_blocks_per_mcu = 0; + + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + int num_blocks; + + component_id = m_comp_list[component_num]; + + num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; + + while (num_blocks--) + m_mcu_org[m_blocks_per_mcu++] = component_id; + } + } + + if (m_blocks_per_mcu > m_max_blocks_per_mcu) + return false; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + int comp_id = m_mcu_org[mcu_block]; + if (comp_id >= JPGD_MAX_QUANT_TABLES) + return false; + } + + return true; + } + + // Starts a new scan. + int jpeg_decoder::init_scan() + { + if (!locate_sos_marker()) + return JPGD_FALSE; + + if (!calc_mcu_block_order()) + return JPGD_FALSE; + + check_huff_tables(); + + check_quant_tables(); + + memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + if (m_restart_interval) + { + m_restarts_left = m_restart_interval; + m_next_restart_num = 0; + } + + fix_in_buffer(); + + return JPGD_TRUE; + } + + // Starts a frame. Determines if the number of components or sampling factors + // are supported. + void jpeg_decoder::init_frame() + { + int i; + + if (m_comps_in_frame == 1) + { + if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + m_scan_type = JPGD_GRAYSCALE; + m_max_blocks_per_mcu = 1; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if (m_comps_in_frame == 3) + { + if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || + ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1))) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH1V1; + + m_max_blocks_per_mcu = 3; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH2V1; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH1V2; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 16; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH2V2; + m_max_blocks_per_mcu = 6; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 16; + } + else + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + } + else + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; + m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; + + // These values are for the *destination* pixels: after conversion. + if (m_scan_type == JPGD_GRAYSCALE) + m_dest_bytes_per_pixel = 1; + else + m_dest_bytes_per_pixel = 4; + + m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; + + m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); + + // Initialize two scan line buffers. + m_pScan_line_0 = (uint8*)alloc(m_dest_bytes_per_scan_line, true); + if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) + m_pScan_line_1 = (uint8*)alloc(m_dest_bytes_per_scan_line, true); + + m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; + + // Should never happen + if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) + stop_decoding(JPGD_DECODE_ERROR); + + // Allocate the coefficient buffer, enough for one MCU + m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t)); + + for (i = 0; i < m_max_blocks_per_mcu; i++) + m_mcu_block_max_zag[i] = 64; + + m_pSample_buf = (uint8*)alloc(m_max_blocks_per_row * 64); + m_pSample_buf_prev = (uint8*)alloc(m_max_blocks_per_row * 64); + + m_total_lines_left = m_image_y_size; + + m_mcu_lines_left = 0; + + create_look_ups(); + } + + // The coeff_buf series of methods originally stored the coefficients + // into a "virtual" file which was located in EMS, XMS, or a disk file. A cache + // was used to make this process more efficient. Now, we can store the entire + // thing in RAM. + jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) + { + coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); + + cb->block_num_x = block_num_x; + cb->block_num_y = block_num_y; + cb->block_len_x = block_len_x; + cb->block_len_y = block_len_y; + cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t); + cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true); + return cb; + } + + inline jpgd_block_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y) + { + if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y)) + stop_decoding(JPGD_DECODE_ERROR); + + return (jpgd_block_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); + } + + // The following methods decode the various types of m_blocks encountered + // in progressively encoded images. + void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int s, r; + jpgd_block_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) + { + if (s >= 16) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + } + + pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low); + } + + void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + if (pD->get_bits_no_markers(1)) + { + jpgd_block_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + p[0] |= (1 << pD->m_successive_low); + } + } + + void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int k, s, r; + + if (pD->m_eob_run) + { + pD->m_eob_run--; + return; + } + + jpgd_block_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) + { + unsigned int idx = pD->m_comp_ac_tab[component_id]; + if (idx >= JPGD_MAX_HUFF_TABLES) + pD->stop_decoding(JPGD_DECODE_ERROR); + + s = pD->huff_decode(pD->m_pHuff_tabs[idx]); + + r = s >> 4; + s &= 15; + + if (s) + { + if ((k += r) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + + p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low); + } + else + { + if (r == 15) + { + if ((k += 15) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + } + else + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + pD->m_eob_run--; + + break; + } + } + } + } + + void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int s, k, r; + + int p1 = 1 << pD->m_successive_low; + + //int m1 = (-1) << pD->m_successive_low; + int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low)); + + jpgd_block_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + if (pD->m_spectral_end > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + k = pD->m_spectral_start; + + if (pD->m_eob_run == 0) + { + for (; k <= pD->m_spectral_end; k++) + { + unsigned int idx = pD->m_comp_ac_tab[component_id]; + if (idx >= JPGD_MAX_HUFF_TABLES) + pD->stop_decoding(JPGD_DECODE_ERROR); + + s = pD->huff_decode(pD->m_pHuff_tabs[idx]); + + r = s >> 4; + s &= 15; + + if (s) + { + if (s != 1) + pD->stop_decoding(JPGD_DECODE_ERROR); + + if (pD->get_bits_no_markers(1)) + s = p1; + else + s = m1; + } + else + { + if (r != 15) + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + break; + } + } + + do + { + jpgd_block_t* this_coef = p + g_ZAG[k & 63]; + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); + else + *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); + } + } + } + else + { + if (--r < 0) + break; + } + + k++; + + } while (k <= pD->m_spectral_end); + + if ((s) && (k < 64)) + { + p[g_ZAG[k]] = static_cast<jpgd_block_t>(s); + } + } + } + + if (pD->m_eob_run > 0) + { + for (; k <= pD->m_spectral_end; k++) + { + jpgd_block_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); + else + *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); + } + } + } + } + + pD->m_eob_run--; + } + } + + // Decode a scan in a progressively encoded image. + void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) + { + int mcu_row, mcu_col, mcu_block; + int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_y_mcu, 0, sizeof(block_y_mcu)); + + for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) + { + int component_num, component_id; + + memset(block_x_mcu, 0, sizeof(block_x_mcu)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + + decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs); + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + m_restarts_left--; + } + + if (m_comps_in_scan == 1) + block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } + } + + // Decode a progressively encoded image. + void jpeg_decoder::init_progressive() + { + int i; + + if (m_comps_in_frame == 4) + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + // Allocate the coefficient buffers. + for (i = 0; i < m_comps_in_frame; i++) + { + m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); + m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); + } + + // See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + uint32_t total_scans = 0; + const uint32_t MAX_SCANS_TO_PROCESS = 1000; + + for (; ; ) + { + int dc_only_scan, refinement_scan; + pDecode_block_func decode_block_func; + + if (!init_scan()) + break; + + dc_only_scan = (m_spectral_start == 0); + refinement_scan = (m_successive_high != 0); + + if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if (dc_only_scan) + { + if (m_spectral_end) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + } + else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) + stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); + + if (dc_only_scan) + { + if (refinement_scan) + decode_block_func = decode_block_dc_refine; + else + decode_block_func = decode_block_dc_first; + } + else + { + if (refinement_scan) + decode_block_func = decode_block_ac_refine; + else + decode_block_func = decode_block_ac_first; + } + + decode_scan(decode_block_func); + + m_bits_left = 16; + get_bits(16); + get_bits(16); + + total_scans++; + if (total_scans > MAX_SCANS_TO_PROCESS) + stop_decoding(JPGD_TOO_MANY_SCANS); + } + + m_comps_in_scan = m_comps_in_frame; + + for (i = 0; i < m_comps_in_frame; i++) + m_comp_list[i] = i; + + if (!calc_mcu_block_order()) + stop_decoding(JPGD_DECODE_ERROR); + } + + void jpeg_decoder::init_sequential() + { + if (!init_scan()) + stop_decoding(JPGD_UNEXPECTED_MARKER); + } + + void jpeg_decoder::decode_start() + { + init_frame(); + + if (m_progressive_flag) + init_progressive(); + else + init_sequential(); + } + + void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags) + { + init(pStream, flags); + locate_sof_marker(); + } + + jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags) + { + if (setjmp(m_jmp_state)) + return; + decode_init(pStream, flags); + } + + int jpeg_decoder::begin_decoding() + { + if (m_ready_flag) + return JPGD_SUCCESS; + + if (m_error_code) + return JPGD_FAILED; + + if (setjmp(m_jmp_state)) + return JPGD_FAILED; + + decode_start(); + + m_ready_flag = true; + + return JPGD_SUCCESS; + } + + jpeg_decoder::~jpeg_decoder() + { + free_all_blocks(); + } + + jpeg_decoder_file_stream::jpeg_decoder_file_stream() + { + m_pFile = nullptr; + m_eof_flag = false; + m_error_flag = false; + } + + void jpeg_decoder_file_stream::close() + { + if (m_pFile) + { + fclose(m_pFile); + m_pFile = nullptr; + } + + m_eof_flag = false; + m_error_flag = false; + } + + jpeg_decoder_file_stream::~jpeg_decoder_file_stream() + { + close(); + } + + bool jpeg_decoder_file_stream::open(const char* Pfilename) + { + close(); + + m_eof_flag = false; + m_error_flag = false; + +#if defined(_MSC_VER) + m_pFile = nullptr; + fopen_s(&m_pFile, Pfilename, "rb"); +#else + m_pFile = fopen(Pfilename, "rb"); +#endif + return m_pFile != nullptr; + } + + int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) + { + if (!m_pFile) + return -1; + + if (m_eof_flag) + { + *pEOF_flag = true; + return 0; + } + + if (m_error_flag) + return -1; + + int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile)); + if (bytes_read < max_bytes_to_read) + { + if (ferror(m_pFile)) + { + m_error_flag = true; + return -1; + } + + m_eof_flag = true; + *pEOF_flag = true; + } + + return bytes_read; + } + + bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size) + { + close(); + m_pSrc_data = pSrc_data; + m_ofs = 0; + m_size = size; + return true; + } + + int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) + { + *pEOF_flag = false; + + if (!m_pSrc_data) + return -1; + + uint bytes_remaining = m_size - m_ofs; + if ((uint)max_bytes_to_read > bytes_remaining) + { + max_bytes_to_read = bytes_remaining; + *pEOF_flag = true; + } + + memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); + m_ofs += max_bytes_to_read; + + return max_bytes_to_read; + } + + unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + if (!actual_comps) + return nullptr; + *actual_comps = 0; + + if ((!pStream) || (!width) || (!height) || (!req_comps)) + return nullptr; + + if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) + return nullptr; + + jpeg_decoder decoder(pStream, flags); + if (decoder.get_error_code() != JPGD_SUCCESS) + return nullptr; + + const int image_width = decoder.get_width(), image_height = decoder.get_height(); + *width = image_width; + *height = image_height; + *actual_comps = decoder.get_num_components(); + + if (decoder.begin_decoding() != JPGD_SUCCESS) + return nullptr; + + const int dst_bpl = image_width * req_comps; + + uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height); + if (!pImage_data) + return nullptr; + + for (int y = 0; y < image_height; y++) + { + const uint8* pScan_line; + uint scan_line_len; + if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) + { + jpgd_free(pImage_data); + return nullptr; + } + + uint8* pDst = pImage_data + y * dst_bpl; + + if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3))) + memcpy(pDst, pScan_line, dst_bpl); + else if (decoder.get_num_components() == 1) + { + if (req_comps == 3) + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst += 3; + } + } + else + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst[3] = 255; + pDst += 4; + } + } + } + else if (decoder.get_num_components() == 3) + { + if (req_comps == 1) + { + const int YR = 19595, YG = 38470, YB = 7471; + for (int x = 0; x < image_width; x++) + { + int r = pScan_line[x * 4 + 0]; + int g = pScan_line[x * 4 + 1]; + int b = pScan_line[x * 4 + 2]; + *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16); + } + } + else + { + for (int x = 0; x < image_width; x++) + { + pDst[0] = pScan_line[x * 4 + 0]; + pDst[1] = pScan_line[x * 4 + 1]; + pDst[2] = pScan_line[x * 4 + 2]; + pDst += 3; + } + } + } + } + + return pImage_data; + } + + unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size); + return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags); + } + + unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + jpgd::jpeg_decoder_file_stream file_stream; + if (!file_stream.open(pSrc_filename)) + return nullptr; + return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags); + } + +} // namespace jpgd diff --git a/thirdparty/basis_universal/encoder/jpgd.h b/thirdparty/basis_universal/encoder/jpgd.h new file mode 100644 index 0000000000..86a7814cae --- /dev/null +++ b/thirdparty/basis_universal/encoder/jpgd.h @@ -0,0 +1,347 @@ +// jpgd.h - C++ class for JPEG decompression. +// Public domain, Rich Geldreich <richgel99@gmail.com> +#ifndef JPEG_DECODER_H +#define JPEG_DECODER_H + +#include <stdlib.h> +#include <stdio.h> +#include <setjmp.h> +#include <assert.h> +#include <stdint.h> + +#ifdef _MSC_VER +#define JPGD_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) +#define JPGD_NORETURN __attribute__ ((noreturn)) +#else +#define JPGD_NORETURN +#endif + +#define JPGD_HUFF_TREE_MAX_LENGTH 512 +#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256 + +namespace jpgd +{ + typedef unsigned char uint8; + typedef signed short int16; + typedef unsigned short uint16; + typedef unsigned int uint; + typedef signed int int32; + + // Loads a JPEG image from a memory buffer or a file. + // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). + // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). + // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly. + // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. + unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + + // Success/failure error codes. + enum jpgd_status + { + JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, + JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, + JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, + JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, + JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, + JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, + JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, + JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, + JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, JPGD_TOO_MANY_SCANS + }; + + // Input stream interface. + // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. + // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. + // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. + // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. + class jpeg_decoder_stream + { + public: + jpeg_decoder_stream() { } + virtual ~jpeg_decoder_stream() { } + + // The read() method is called when the internal input buffer is empty. + // Parameters: + // pBuf - input buffer + // max_bytes_to_read - maximum bytes that can be written to pBuf + // pEOF_flag - set this to true if at end of stream (no more bytes remaining) + // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). + // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) = 0; + }; + + // stdio FILE stream class. + class jpeg_decoder_file_stream : public jpeg_decoder_stream + { + jpeg_decoder_file_stream(const jpeg_decoder_file_stream&); + jpeg_decoder_file_stream& operator =(const jpeg_decoder_file_stream&); + + FILE* m_pFile; + bool m_eof_flag, m_error_flag; + + public: + jpeg_decoder_file_stream(); + virtual ~jpeg_decoder_file_stream(); + + bool open(const char* Pfilename); + void close(); + + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag); + }; + + // Memory stream class. + class jpeg_decoder_mem_stream : public jpeg_decoder_stream + { + const uint8* m_pSrc_data; + uint m_ofs, m_size; + + public: + jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { } + jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { } + + virtual ~jpeg_decoder_mem_stream() { } + + bool open(const uint8* pSrc_data, uint size); + void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; } + + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag); + }; + + // Loads JPEG file from a jpeg_decoder_stream. + unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + + enum + { + JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, + JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 16384, JPGD_MAX_HEIGHT = 32768, JPGD_MAX_WIDTH = 32768 + }; + + typedef int16 jpgd_quant_t; + typedef int16 jpgd_block_t; + + class jpeg_decoder + { + public: + enum + { + cFlagLinearChromaFiltering = 1 + }; + + // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. + // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. + jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags = cFlagLinearChromaFiltering); + + ~jpeg_decoder(); + + // Call this method after constructing the object to begin decompression. + // If JPGD_SUCCESS is returned you may then call decode() on each scanline. + + int begin_decoding(); + + // Returns the next scan line. + // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). + // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). + // Returns JPGD_SUCCESS if a scan line has been returned. + // Returns JPGD_DONE if all scan lines have been returned. + // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. + int decode(const void** pScan_line, uint* pScan_line_len); + + inline jpgd_status get_error_code() const { return m_error_code; } + + inline int get_width() const { return m_image_x_size; } + inline int get_height() const { return m_image_y_size; } + + inline int get_num_components() const { return m_comps_in_frame; } + + inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } + inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } + + // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). + inline int get_total_bytes_read() const { return m_total_bytes_read; } + + private: + jpeg_decoder(const jpeg_decoder&); + jpeg_decoder& operator =(const jpeg_decoder&); + + typedef void (*pDecode_block_func)(jpeg_decoder*, int, int, int); + + struct huff_tables + { + bool ac_table; + uint look_up[256]; + uint look_up2[256]; + uint8 code_size[JPGD_HUFF_CODE_SIZE_MAX_LENGTH]; + uint tree[JPGD_HUFF_TREE_MAX_LENGTH]; + }; + + struct coeff_buf + { + uint8* pData; + int block_num_x, block_num_y; + int block_len_x, block_len_y; + int block_size; + }; + + struct mem_block + { + mem_block* m_pNext; + size_t m_used_count; + size_t m_size; + char m_data[1]; + }; + + jmp_buf m_jmp_state; + uint32_t m_flags; + mem_block* m_pMem_blocks; + int m_image_x_size; + int m_image_y_size; + jpeg_decoder_stream* m_pStream; + + int m_progressive_flag; + + uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES]; + uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size + uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size + jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables + int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) + int m_comps_in_frame; // # of components in frame + int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor + int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor + int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector + int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID + int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; + int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; + int m_comps_in_scan; // # of components in scan + int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan + int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector + int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector + int m_spectral_start; // spectral selection start + int m_spectral_end; // spectral selection end + int m_successive_low; // successive approximation low + int m_successive_high; // successive approximation high + int m_max_mcu_x_size; // MCU's max. X size in pixels + int m_max_mcu_y_size; // MCU's max. Y size in pixels + int m_blocks_per_mcu; + int m_max_blocks_per_row; + int m_mcus_per_row, m_mcus_per_col; + int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; + int m_total_lines_left; // total # lines left in image + int m_mcu_lines_left; // total # lines left in this MCU + int m_num_buffered_scanlines; + int m_real_dest_bytes_per_scan_line; + int m_dest_bytes_per_scan_line; // rounded up + int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) + huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; + coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; + coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; + int m_eob_run; + int m_block_y_mcu[JPGD_MAX_COMPONENTS]; + uint8* m_pIn_buf_ofs; + int m_in_buf_left; + int m_tem_flag; + + uint8 m_in_buf_pad_start[64]; + uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128]; + uint8 m_in_buf_pad_end[64]; + + int m_bits_left; + uint m_bit_buf; + int m_restart_interval; + int m_restarts_left; + int m_next_restart_num; + int m_max_mcus_per_row; + int m_max_blocks_per_mcu; + + int m_max_mcus_per_col; + uint m_last_dc_val[JPGD_MAX_COMPONENTS]; + jpgd_block_t* m_pMCU_coefficients; + int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; + uint8* m_pSample_buf; + uint8* m_pSample_buf_prev; + int m_crr[256]; + int m_cbb[256]; + int m_crg[256]; + int m_cbg[256]; + uint8* m_pScan_line_0; + uint8* m_pScan_line_1; + jpgd_status m_error_code; + int m_total_bytes_read; + + bool m_ready_flag; + bool m_eof_flag; + bool m_sample_buf_prev_valid; + + inline int check_sample_buf_ofs(int ofs) const { assert(ofs >= 0); assert(ofs < m_max_blocks_per_row * 64); return ofs; } + void free_all_blocks(); + JPGD_NORETURN void stop_decoding(jpgd_status status); + void* alloc(size_t n, bool zero = false); + void word_clear(void* p, uint16 c, uint n); + void prep_in_buffer(); + void read_dht_marker(); + void read_dqt_marker(); + void read_sof_marker(); + void skip_variable_marker(); + void read_dri_marker(); + void read_sos_marker(); + int next_marker(); + int process_markers(); + void locate_soi_marker(); + void locate_sof_marker(); + int locate_sos_marker(); + void init(jpeg_decoder_stream* pStream, uint32_t flags); + void create_look_ups(); + void fix_in_buffer(); + void transform_mcu(int mcu_row); + coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); + inline jpgd_block_t* coeff_buf_getp(coeff_buf* cb, int block_x, int block_y); + void load_next_row(); + void decode_next_row(); + void make_huff_table(int index, huff_tables* pH); + void check_quant_tables(); + void check_huff_tables(); + bool calc_mcu_block_order(); + int init_scan(); + void init_frame(); + void process_restart(); + void decode_scan(pDecode_block_func decode_block_func); + void init_progressive(); + void init_sequential(); + void decode_start(); + void decode_init(jpeg_decoder_stream* pStream, uint32_t flags); + void H2V2Convert(); + uint32_t H2V2ConvertFiltered(); + void H2V1Convert(); + void H2V1ConvertFiltered(); + void H1V2Convert(); + void H1V2ConvertFiltered(); + void H1V1Convert(); + void gray_convert(); + void find_eoi(); + inline uint get_char(); + inline uint get_char(bool* pPadding_flag); + inline void stuff_char(uint8 q); + inline uint8 get_octet(); + inline uint get_bits(int num_bits); + inline uint get_bits_no_markers(int numbits); + inline int huff_decode(huff_tables* pH); + inline int huff_decode(huff_tables* pH, int& extrabits); + + // Clamps a value between 0-255. + static inline uint8 clamp(int i) + { + if (static_cast<uint>(i) > 255) + i = (((~i) >> 31) & 0xFF); + return static_cast<uint8>(i); + } + int decode_next_mcu_row(); + + static void decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y); + }; + +} // namespace jpgd + +#endif // JPEG_DECODER_H diff --git a/thirdparty/basis_universal/lodepng.cpp b/thirdparty/basis_universal/encoder/lodepng.cpp index cf964d0555..63adcf49b6 100644 --- a/thirdparty/basis_universal/lodepng.cpp +++ b/thirdparty/basis_universal/encoder/lodepng.cpp @@ -29,6 +29,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for */ #ifdef _MSC_VER +#define _CRT_SECURE_NO_DEPRECATE #pragma warning (disable : 4201) #ifndef BASISU_NO_ITERATOR_DEBUG_LEVEL @@ -200,6 +201,7 @@ static void uivector_init(uivector* p) { /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_push_back(uivector* p, unsigned c) { if(!uivector_resize(p, p->size + 1)) return 0; + if (!p->data) return 0; p->data[p->size - 1] = c; return 1; } diff --git a/thirdparty/basis_universal/lodepng.h b/thirdparty/basis_universal/encoder/lodepng.h index 476a2061e2..476a2061e2 100644 --- a/thirdparty/basis_universal/lodepng.h +++ b/thirdparty/basis_universal/encoder/lodepng.h diff --git a/thirdparty/basis_universal/transcoder/basisu.h b/thirdparty/basis_universal/transcoder/basisu.h index 25600a69bf..f33baf67c8 100644 --- a/thirdparty/basis_universal/transcoder/basisu.h +++ b/thirdparty/basis_universal/transcoder/basisu.h @@ -1,5 +1,5 @@ // basisu.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // Important: If compiling with gcc, be sure strict aliasing is disabled: -fno-strict-aliasing // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,10 +41,6 @@ #endif #endif // defined(_DEBUG) || defined(DEBUG) - #ifndef NOMINMAX - #define NOMINMAX - #endif - #endif // BASISU_NO_ITERATOR_DEBUG_LEVEL #endif // _MSC_VER @@ -63,10 +59,11 @@ #include <functional> #include <iterator> #include <type_traits> -#include <vector> #include <assert.h> #include <random> +#include "basisu_containers.h" + #ifdef max #undef max #endif @@ -79,20 +76,20 @@ #define strcasecmp _stricmp #endif -// Set to one to enable debug printf()'s when any errors occur, for development/debugging. -#ifndef BASISU_DEVEL_MESSAGES -#define BASISU_DEVEL_MESSAGES 0 +// Set to one to enable debug printf()'s when any errors occur, for development/debugging. Especially useful for WebGL development. +#ifndef BASISU_FORCE_DEVEL_MESSAGES +#define BASISU_FORCE_DEVEL_MESSAGES 0 #endif #define BASISU_NOTE_UNUSED(x) (void)(x) #define BASISU_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define BASISU_NO_EQUALS_OR_COPY_CONSTRUCT(x) x(const x &) = delete; x& operator= (const x &) = delete; #define BASISU_ASSUME(x) static_assert(x, #x); -#define BASISU_OFFSETOF(s, m) (uint32_t)(intptr_t)(&((s *)(0))->m) +#define BASISU_OFFSETOF(s, m) offsetof(s, m) #define BASISU_STRINGIZE(x) #x #define BASISU_STRINGIZE2(x) BASISU_STRINGIZE(x) -#if BASISU_DEVEL_MESSAGES +#if BASISU_FORCE_DEVEL_MESSAGES #define BASISU_DEVEL_ERROR(...) do { basisu::debug_printf(__VA_ARGS__); } while(0) #else #define BASISU_DEVEL_ERROR(...) @@ -108,26 +105,43 @@ namespace basisu const char BASISU_PATH_SEPERATOR_CHAR = '/'; #endif - typedef std::vector<uint8_t> uint8_vec; - typedef std::vector<int16_t> int16_vec; - typedef std::vector<uint16_t> uint16_vec; - typedef std::vector<uint32_t> uint_vec; - typedef std::vector<uint64_t> uint64_vec; - typedef std::vector<int> int_vec; - typedef std::vector<bool> bool_vec; + typedef basisu::vector<uint8_t> uint8_vec; + typedef basisu::vector<int16_t> int16_vec; + typedef basisu::vector<uint16_t> uint16_vec; + typedef basisu::vector<uint32_t> uint_vec; + typedef basisu::vector<uint64_t> uint64_vec; + typedef basisu::vector<int> int_vec; + typedef basisu::vector<bool> bool_vec; void enable_debug_printf(bool enabled); void debug_printf(const char *pFmt, ...); + template <typename T> inline void clear_obj(T& obj) { memset(&obj, 0, sizeof(obj)); } template <typename T0, typename T1> inline T0 lerp(T0 a, T0 b, T1 c) { return a + (b - a) * c; } template <typename S> inline S maximum(S a, S b) { return (a > b) ? a : b; } template <typename S> inline S maximum(S a, S b, S c) { return maximum(maximum(a, b), c); } + template <typename S> inline S maximum(S a, S b, S c, S d) { return maximum(maximum(maximum(a, b), c), d); } template <typename S> inline S minimum(S a, S b) { return (a < b) ? a : b; } template <typename S> inline S minimum(S a, S b, S c) { return minimum(minimum(a, b), c); } + template <typename S> inline S minimum(S a, S b, S c, S d) { return minimum(minimum(minimum(a, b), c), d); } + + inline float clampf(float value, float low, float high) { if (value < low) value = low; else if (value > high) value = high; return value; } + inline float saturate(float value) { return clampf(value, 0, 1.0f); } + inline uint8_t minimumub(uint8_t a, uint8_t b) { return (a < b) ? a : b; } + inline uint32_t minimumu(uint32_t a, uint32_t b) { return (a < b) ? a : b; } + inline int32_t minimumi(int32_t a, int32_t b) { return (a < b) ? a : b; } + inline float minimumf(float a, float b) { return (a < b) ? a : b; } + inline uint8_t maximumub(uint8_t a, uint8_t b) { return (a > b) ? a : b; } + inline uint32_t maximumu(uint32_t a, uint32_t b) { return (a > b) ? a : b; } + inline int32_t maximumi(int32_t a, int32_t b) { return (a > b) ? a : b; } + inline float maximumf(float a, float b) { return (a > b) ? a : b; } + inline int squarei(int i) { return i * i; } + inline float squaref(float i) { return i * i; } + template<typename T> inline T square(T a) { return a * a; } template <typename S> inline S clamp(S value, S low, S high) { return (value < low) ? low : ((value > high) ? high : value); } @@ -137,12 +151,10 @@ namespace basisu template<typename T> inline void clear_vector(T &vec) { vec.erase(vec.begin(), vec.end()); } template<typename T> inline typename T::value_type *enlarge_vector(T &vec, size_t n) { size_t cs = vec.size(); vec.resize(cs + n); return &vec[cs]; } - template<typename S> inline S square(S val) { return val * val; } - inline bool is_pow2(uint32_t x) { return x && ((x & (x - 1U)) == 0U); } inline bool is_pow2(uint64_t x) { return x && ((x & (x - 1U)) == 0U); } - template<typename T> inline T open_range_check(T v, T minv, T maxv) { assert(v >= minv && v < maxv); return v; } + template<typename T> inline T open_range_check(T v, T minv, T maxv) { assert(v >= minv && v < maxv); BASISU_NOTE_UNUSED(minv); BASISU_NOTE_UNUSED(maxv); return v; } template<typename T> inline T open_range_check(T v, T maxv) { assert(v < maxv); BASISU_NOTE_UNUSED(maxv); return v; } inline uint32_t total_bits(uint32_t v) { uint32_t l = 0; for ( ; v > 0U; ++l) v >>= 1; return l; } @@ -244,27 +256,92 @@ namespace basisu if ((ha <= lb) || (la >= hb)) return false; return true; } + + static inline uint32_t read_le_dword(const uint8_t *pBytes) + { + return (pBytes[3] << 24U) | (pBytes[2] << 16U) | (pBytes[1] << 8U) | (pBytes[0]); + } + + static inline void write_le_dword(uint8_t* pBytes, uint32_t val) + { + pBytes[0] = (uint8_t)val; + pBytes[1] = (uint8_t)(val >> 8U); + pBytes[2] = (uint8_t)(val >> 16U); + pBytes[3] = (uint8_t)(val >> 24U); + } - // Always little endian 2-4 byte unsigned int + // Always little endian 1-8 byte unsigned int template<uint32_t NumBytes> struct packed_uint { uint8_t m_bytes[NumBytes]; - inline packed_uint() { static_assert(NumBytes <= 4, "NumBytes <= 4"); } - inline packed_uint(uint32_t v) { *this = v; } + inline packed_uint() { static_assert(NumBytes <= sizeof(uint64_t), "Invalid NumBytes"); } + inline packed_uint(uint64_t v) { *this = v; } inline packed_uint(const packed_uint& other) { *this = other; } + + inline packed_uint& operator= (uint64_t v) + { + for (uint32_t i = 0; i < NumBytes; i++) + m_bytes[i] = static_cast<uint8_t>(v >> (i * 8)); + return *this; + } - inline packed_uint& operator= (uint32_t v) { for (uint32_t i = 0; i < NumBytes; i++) m_bytes[i] = static_cast<uint8_t>(v >> (i * 8)); return *this; } + inline packed_uint& operator= (const packed_uint& rhs) + { + memcpy(m_bytes, rhs.m_bytes, sizeof(m_bytes)); + return *this; + } inline operator uint32_t() const { switch (NumBytes) { - case 1: return m_bytes[0]; - case 2: return (m_bytes[1] << 8U) | m_bytes[0]; - case 3: return (m_bytes[2] << 16U) | (m_bytes[1] << 8U) | (m_bytes[0]); - default: return (m_bytes[3] << 24U) | (m_bytes[2] << 16U) | (m_bytes[1] << 8U) | (m_bytes[0]); + case 1: + { + return m_bytes[0]; + } + case 2: + { + return (m_bytes[1] << 8U) | m_bytes[0]; + } + case 3: + { + return (m_bytes[2] << 16U) | (m_bytes[1] << 8U) | m_bytes[0]; + } + case 4: + { + return read_le_dword(m_bytes); + } + case 5: + { + uint32_t l = read_le_dword(m_bytes); + uint32_t h = m_bytes[4]; + return static_cast<uint64_t>(l) | (static_cast<uint64_t>(h) << 32U); + } + case 6: + { + uint32_t l = read_le_dword(m_bytes); + uint32_t h = (m_bytes[5] << 8U) | m_bytes[4]; + return static_cast<uint64_t>(l) | (static_cast<uint64_t>(h) << 32U); + } + case 7: + { + uint32_t l = read_le_dword(m_bytes); + uint32_t h = (m_bytes[6] << 16U) | (m_bytes[5] << 8U) | m_bytes[4]; + return static_cast<uint64_t>(l) | (static_cast<uint64_t>(h) << 32U); + } + case 8: + { + uint32_t l = read_le_dword(m_bytes); + uint32_t h = read_le_dword(m_bytes + 4); + return static_cast<uint64_t>(l) | (static_cast<uint64_t>(h) << 32U); + } + default: + { + assert(0); + return 0; + } } } }; @@ -278,7 +355,7 @@ namespace basisu enum { cHuffmanMaxSupportedCodeSize = 16, cHuffmanMaxSupportedInternalCodeSize = 31, - cHuffmanFastLookupBits = 10, cHuffmanFastLookupSize = 1 << cHuffmanFastLookupBits, + cHuffmanFastLookupBits = 10, cHuffmanMaxSymsLog2 = 14, cHuffmanMaxSyms = 1 << cHuffmanMaxSymsLog2, // Small zero runs @@ -308,15 +385,15 @@ namespace basisu // Block-based formats cETC1, // ETC1 cETC1S, // ETC1 (subset: diff colors only, no subblocks) - cETC2_RGB, // ETC2 color block - cETC2_RGBA, // ETC2 alpha block followed by ETC2 color block + cETC2_RGB, // ETC2 color block (basisu doesn't support ETC2 planar/T/H modes - just basic ETC1) + cETC2_RGBA, // ETC2 EAC alpha block followed by ETC2 color block cETC2_ALPHA, // ETC2 EAC alpha block cBC1, // DXT1 - cBC3, // DXT5 (DXT5A block followed by a DXT1 block) + cBC3, // DXT5 (BC4/DXT5A block followed by a BC1/DXT1 block) cBC4, // DXT5A - cBC5, // 3DC/DXN (two DXT5A blocks) + cBC5, // 3DC/DXN (two BC4/DXT5A blocks) cBC7, - cASTC4x4, + cASTC4x4, // LDR only cPVRTC1_4_RGB, cPVRTC1_4_RGBA, cATC_RGB, @@ -325,6 +402,9 @@ namespace basisu cPVRTC2_4_RGBA, cETC2_R11_EAC, cETC2_RG11_EAC, + cUASTC4x4, + cBC1_NV, + cBC1_AMD, // Uncompressed/raw pixels cRGBA32, @@ -343,6 +423,8 @@ namespace basisu case texture_format::cETC2_RGB: case texture_format::cETC2_ALPHA: case texture_format::cBC1: + case texture_format::cBC1_NV: + case texture_format::cBC1_AMD: case texture_format::cBC4: case texture_format::cPVRTC1_4_RGB: case texture_format::cPVRTC1_4_RGBA: diff --git a/thirdparty/basis_universal/transcoder/basisu_containers.h b/thirdparty/basis_universal/transcoder/basisu_containers.h new file mode 100644 index 0000000000..1ca4bab307 --- /dev/null +++ b/thirdparty/basis_universal/transcoder/basisu_containers.h @@ -0,0 +1,1908 @@ +// basisu_containers.h +#pragma once +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <assert.h> +#include <algorithm> + +#if defined(__linux__) && !defined(ANDROID) +// Only for malloc_usable_size() in basisu_containers_impl.h +#include <malloc.h> +#define HAS_MALLOC_USABLE_SIZE 1 +#endif + +#ifdef _MSC_VER +#define BASISU_FORCE_INLINE __forceinline +#else +#define BASISU_FORCE_INLINE inline +#endif + +namespace basisu +{ + enum { cInvalidIndex = -1 }; + + namespace helpers + { + inline bool is_power_of_2(uint32_t x) { return x && ((x & (x - 1U)) == 0U); } + inline bool is_power_of_2(uint64_t x) { return x && ((x & (x - 1U)) == 0U); } + template<class T> const T& minimum(const T& a, const T& b) { return (b < a) ? b : a; } + template<class T> const T& maximum(const T& a, const T& b) { return (a < b) ? b : a; } + + inline uint32_t floor_log2i(uint32_t v) + { + uint32_t l = 0; + while (v > 1U) + { + v >>= 1; + l++; + } + return l; + } + + inline uint32_t next_pow2(uint32_t val) + { + val--; + val |= val >> 16; + val |= val >> 8; + val |= val >> 4; + val |= val >> 2; + val |= val >> 1; + return val + 1; + } + + inline uint64_t next_pow2(uint64_t val) + { + val--; + val |= val >> 32; + val |= val >> 16; + val |= val >> 8; + val |= val >> 4; + val |= val >> 2; + val |= val >> 1; + return val + 1; + } + } // namespace helpers + + template <typename T> + inline T* construct(T* p) + { + return new (static_cast<void*>(p)) T; + } + + template <typename T, typename U> + inline T* construct(T* p, const U& init) + { + return new (static_cast<void*>(p)) T(init); + } + + template <typename T> + inline void construct_array(T* p, size_t n) + { + T* q = p + n; + for (; p != q; ++p) + new (static_cast<void*>(p)) T; + } + + template <typename T, typename U> + inline void construct_array(T* p, size_t n, const U& init) + { + T* q = p + n; + for (; p != q; ++p) + new (static_cast<void*>(p)) T(init); + } + + template <typename T> + inline void destruct(T* p) + { + (void)p; + p->~T(); + } + + template <typename T> inline void destruct_array(T* p, size_t n) + { + T* q = p + n; + for (; p != q; ++p) + p->~T(); + } + + template<typename T> struct int_traits { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; }; + + template<> struct int_traits<int8_t> { enum { cMin = INT8_MIN, cMax = INT8_MAX, cSigned = true }; }; + template<> struct int_traits<int16_t> { enum { cMin = INT16_MIN, cMax = INT16_MAX, cSigned = true }; }; + template<> struct int_traits<int32_t> { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; }; + + template<> struct int_traits<uint8_t> { enum { cMin = 0, cMax = UINT8_MAX, cSigned = false }; }; + template<> struct int_traits<uint16_t> { enum { cMin = 0, cMax = UINT16_MAX, cSigned = false }; }; + template<> struct int_traits<uint32_t> { enum { cMin = 0, cMax = UINT32_MAX, cSigned = false }; }; + + template<typename T> + struct scalar_type + { + enum { cFlag = false }; + static inline void construct(T* p) { basisu::construct(p); } + static inline void construct(T* p, const T& init) { basisu::construct(p, init); } + static inline void construct_array(T* p, size_t n) { basisu::construct_array(p, n); } + static inline void destruct(T* p) { basisu::destruct(p); } + static inline void destruct_array(T* p, size_t n) { basisu::destruct_array(p, n); } + }; + + template<typename T> struct scalar_type<T*> + { + enum { cFlag = true }; + static inline void construct(T** p) { memset(p, 0, sizeof(T*)); } + static inline void construct(T** p, T* init) { *p = init; } + static inline void construct_array(T** p, size_t n) { memset(p, 0, sizeof(T*) * n); } + static inline void destruct(T** p) { p; } + static inline void destruct_array(T** p, size_t n) { p, n; } + }; + +#define BASISU_DEFINE_BUILT_IN_TYPE(X) \ + template<> struct scalar_type<X> { \ + enum { cFlag = true }; \ + static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \ + static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \ + static inline void construct_array(X* p, size_t n) { memset(p, 0, sizeof(X) * n); } \ + static inline void destruct(X* p) { p; } \ + static inline void destruct_array(X* p, size_t n) { p, n; } }; + + BASISU_DEFINE_BUILT_IN_TYPE(bool) + BASISU_DEFINE_BUILT_IN_TYPE(char) + BASISU_DEFINE_BUILT_IN_TYPE(unsigned char) + BASISU_DEFINE_BUILT_IN_TYPE(short) + BASISU_DEFINE_BUILT_IN_TYPE(unsigned short) + BASISU_DEFINE_BUILT_IN_TYPE(int) + BASISU_DEFINE_BUILT_IN_TYPE(unsigned int) + BASISU_DEFINE_BUILT_IN_TYPE(long) + BASISU_DEFINE_BUILT_IN_TYPE(unsigned long) +#ifdef __GNUC__ + BASISU_DEFINE_BUILT_IN_TYPE(long long) + BASISU_DEFINE_BUILT_IN_TYPE(unsigned long long) +#else + BASISU_DEFINE_BUILT_IN_TYPE(__int64) + BASISU_DEFINE_BUILT_IN_TYPE(unsigned __int64) +#endif + BASISU_DEFINE_BUILT_IN_TYPE(float) + BASISU_DEFINE_BUILT_IN_TYPE(double) + BASISU_DEFINE_BUILT_IN_TYPE(long double) + +#undef BASISU_DEFINE_BUILT_IN_TYPE + + template<typename T> + struct bitwise_movable { enum { cFlag = false }; }; + +#define BASISU_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable<Q> { enum { cFlag = true }; }; + + template<typename T> + struct bitwise_copyable { enum { cFlag = false }; }; + +#define BASISU_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable<Q> { enum { cFlag = true }; }; + +#define BASISU_IS_POD(T) __is_pod(T) + +#define BASISU_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag) + +#if defined(__GNUC__) && __GNUC__<5 + #define BASISU_IS_TRIVIALLY_COPYABLE(...) __has_trivial_copy(__VA_ARGS__) +#else + #define BASISU_IS_TRIVIALLY_COPYABLE(...) std::is_trivially_copyable<__VA_ARGS__>::value +#endif + +// TODO: clean this up +#define BASISU_IS_BITWISE_COPYABLE(T) (BASISU_IS_SCALAR_TYPE(T) || BASISU_IS_POD(T) || BASISU_IS_TRIVIALLY_COPYABLE(T) || (bitwise_copyable<T>::cFlag)) + +#define BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T) (BASISU_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag)) + +#define BASISU_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!__is_pod(T))) + + typedef char(&yes_t)[1]; + typedef char(&no_t)[2]; + + template <class U> yes_t class_test(int U::*); + template <class U> no_t class_test(...); + + template <class T> struct is_class + { + enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) }; + }; + + template <typename T> struct is_pointer + { + enum { value = false }; + }; + + template <typename T> struct is_pointer<T*> + { + enum { value = true }; + }; + + struct empty_type { }; + + BASISU_DEFINE_BITWISE_COPYABLE(empty_type); + BASISU_DEFINE_BITWISE_MOVABLE(empty_type); + + template<typename T> struct rel_ops + { + friend bool operator!=(const T& x, const T& y) { return (!(x == y)); } + friend bool operator> (const T& x, const T& y) { return (y < x); } + friend bool operator<=(const T& x, const T& y) { return (!(y < x)); } + friend bool operator>=(const T& x, const T& y) { return (!(x < y)); } + }; + + struct elemental_vector + { + void* m_p; + uint32_t m_size; + uint32_t m_capacity; + + typedef void (*object_mover)(void* pDst, void* pSrc, uint32_t num); + + bool increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pRelocate, bool nofail); + }; + + template<typename T> + class vector : public rel_ops< vector<T> > + { + public: + typedef T* iterator; + typedef const T* const_iterator; + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + + inline vector() : + m_p(NULL), + m_size(0), + m_capacity(0) + { + } + + inline vector(uint32_t n, const T& init) : + m_p(NULL), + m_size(0), + m_capacity(0) + { + increase_capacity(n, false); + construct_array(m_p, n, init); + m_size = n; + } + + inline vector(const vector& other) : + m_p(NULL), + m_size(0), + m_capacity(0) + { + increase_capacity(other.m_size, false); + + m_size = other.m_size; + + if (BASISU_IS_BITWISE_COPYABLE(T)) + memcpy(m_p, other.m_p, m_size * sizeof(T)); + else + { + T* pDst = m_p; + const T* pSrc = other.m_p; + for (uint32_t i = m_size; i > 0; i--) + construct(pDst++, *pSrc++); + } + } + + inline explicit vector(size_t size) : + m_p(NULL), + m_size(0), + m_capacity(0) + { + resize(size); + } + + inline ~vector() + { + if (m_p) + { + scalar_type<T>::destruct_array(m_p, m_size); + free(m_p); + } + } + + inline vector& operator= (const vector& other) + { + if (this == &other) + return *this; + + if (m_capacity >= other.m_size) + resize(0); + else + { + clear(); + increase_capacity(other.m_size, false); + } + + if (BASISU_IS_BITWISE_COPYABLE(T)) + memcpy(m_p, other.m_p, other.m_size * sizeof(T)); + else + { + T* pDst = m_p; + const T* pSrc = other.m_p; + for (uint32_t i = other.m_size; i > 0; i--) + construct(pDst++, *pSrc++); + } + + m_size = other.m_size; + + return *this; + } + + BASISU_FORCE_INLINE const T* begin() const { return m_p; } + BASISU_FORCE_INLINE T* begin() { return m_p; } + + BASISU_FORCE_INLINE const T* end() const { return m_p + m_size; } + BASISU_FORCE_INLINE T* end() { return m_p + m_size; } + + BASISU_FORCE_INLINE bool empty() const { return !m_size; } + BASISU_FORCE_INLINE uint32_t size() const { return m_size; } + BASISU_FORCE_INLINE uint32_t size_in_bytes() const { return m_size * sizeof(T); } + BASISU_FORCE_INLINE uint32_t capacity() const { return m_capacity; } + + // operator[] will assert on out of range indices, but in final builds there is (and will never be) any range checking on this method. + //BASISU_FORCE_INLINE const T& operator[] (uint32_t i) const { assert(i < m_size); return m_p[i]; } + //BASISU_FORCE_INLINE T& operator[] (uint32_t i) { assert(i < m_size); return m_p[i]; } + + BASISU_FORCE_INLINE const T& operator[] (size_t i) const { assert(i < m_size); return m_p[i]; } + BASISU_FORCE_INLINE T& operator[] (size_t i) { assert(i < m_size); return m_p[i]; } + + // at() always includes range checking, even in final builds, unlike operator []. + // The first element is returned if the index is out of range. + BASISU_FORCE_INLINE const T& at(size_t i) const { assert(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; } + BASISU_FORCE_INLINE T& at(size_t i) { assert(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; } + + BASISU_FORCE_INLINE const T& front() const { assert(m_size); return m_p[0]; } + BASISU_FORCE_INLINE T& front() { assert(m_size); return m_p[0]; } + + BASISU_FORCE_INLINE const T& back() const { assert(m_size); return m_p[m_size - 1]; } + BASISU_FORCE_INLINE T& back() { assert(m_size); return m_p[m_size - 1]; } + + BASISU_FORCE_INLINE const T* get_ptr() const { return m_p; } + BASISU_FORCE_INLINE T* get_ptr() { return m_p; } + + BASISU_FORCE_INLINE const T* data() const { return m_p; } + BASISU_FORCE_INLINE T* data() { return m_p; } + + // clear() sets the container to empty, then frees the allocated block. + inline void clear() + { + if (m_p) + { + scalar_type<T>::destruct_array(m_p, m_size); + free(m_p); + m_p = NULL; + m_size = 0; + m_capacity = 0; + } + } + + inline void clear_no_destruction() + { + if (m_p) + { + free(m_p); + m_p = NULL; + m_size = 0; + m_capacity = 0; + } + } + + inline void reserve(size_t new_capacity_size_t) + { + if (new_capacity_size_t > UINT32_MAX) + { + assert(0); + return; + } + + uint32_t new_capacity = (uint32_t)new_capacity_size_t; + + if (new_capacity > m_capacity) + increase_capacity(new_capacity, false); + else if (new_capacity < m_capacity) + { + // Must work around the lack of a "decrease_capacity()" method. + // This case is rare enough in practice that it's probably not worth implementing an optimized in-place resize. + vector tmp; + tmp.increase_capacity(helpers::maximum(m_size, new_capacity), false); + tmp = *this; + swap(tmp); + } + } + + inline bool try_reserve(size_t new_capacity_size_t) + { + if (new_capacity_size_t > UINT32_MAX) + { + assert(0); + return false; + } + + uint32_t new_capacity = (uint32_t)new_capacity_size_t; + + if (new_capacity > m_capacity) + { + if (!increase_capacity(new_capacity, false)) + return false; + } + else if (new_capacity < m_capacity) + { + // Must work around the lack of a "decrease_capacity()" method. + // This case is rare enough in practice that it's probably not worth implementing an optimized in-place resize. + vector tmp; + tmp.increase_capacity(helpers::maximum(m_size, new_capacity), false); + tmp = *this; + swap(tmp); + } + + return true; + } + + // resize(0) sets the container to empty, but does not free the allocated block. + inline void resize(size_t new_size_size_t, bool grow_hint = false) + { + if (new_size_size_t > UINT32_MAX) + { + assert(0); + return; + } + + uint32_t new_size = (uint32_t)new_size_size_t; + + if (m_size != new_size) + { + if (new_size < m_size) + scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size); + else + { + if (new_size > m_capacity) + increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint); + + scalar_type<T>::construct_array(m_p + m_size, new_size - m_size); + } + + m_size = new_size; + } + } + + inline bool try_resize(size_t new_size_size_t, bool grow_hint = false) + { + if (new_size_size_t > UINT32_MAX) + { + assert(0); + return false; + } + + uint32_t new_size = (uint32_t)new_size_size_t; + + if (m_size != new_size) + { + if (new_size < m_size) + scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size); + else + { + if (new_size > m_capacity) + { + if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true)) + return false; + } + + scalar_type<T>::construct_array(m_p + m_size, new_size - m_size); + } + + m_size = new_size; + } + + return true; + } + + // If size >= capacity/2, reset() sets the container's size to 0 but doesn't free the allocated block (because the container may be similarly loaded in the future). + // Otherwise it blows away the allocated block. See http://www.codercorner.com/blog/?p=494 + inline void reset() + { + if (m_size >= (m_capacity >> 1)) + resize(0); + else + clear(); + } + + inline T* enlarge(uint32_t i) + { + uint32_t cur_size = m_size; + resize(cur_size + i, true); + return get_ptr() + cur_size; + } + + inline T* try_enlarge(uint32_t i) + { + uint32_t cur_size = m_size; + if (!try_resize(cur_size + i, true)) + return NULL; + return get_ptr() + cur_size; + } + + BASISU_FORCE_INLINE void push_back(const T& obj) + { + assert(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size))); + + if (m_size >= m_capacity) + increase_capacity(m_size + 1, true); + + scalar_type<T>::construct(m_p + m_size, obj); + m_size++; + } + + inline bool try_push_back(const T& obj) + { + assert(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size))); + + if (m_size >= m_capacity) + { + if (!increase_capacity(m_size + 1, true, true)) + return false; + } + + scalar_type<T>::construct(m_p + m_size, obj); + m_size++; + + return true; + } + + inline void push_back_value(T obj) + { + if (m_size >= m_capacity) + increase_capacity(m_size + 1, true); + + scalar_type<T>::construct(m_p + m_size, obj); + m_size++; + } + + inline void pop_back() + { + assert(m_size); + + if (m_size) + { + m_size--; + scalar_type<T>::destruct(&m_p[m_size]); + } + } + + inline void insert(uint32_t index, const T* p, uint32_t n) + { + assert(index <= m_size); + if (!n) + return; + + const uint32_t orig_size = m_size; + resize(m_size + n, true); + + const uint32_t num_to_move = orig_size - index; + + if (BASISU_IS_BITWISE_COPYABLE(T)) + { + // This overwrites the destination object bits, but bitwise copyable means we don't need to worry about destruction. + memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move); + } + else + { + const T* pSrc = m_p + orig_size - 1; + T* pDst = const_cast<T*>(pSrc) + n; + + for (uint32_t i = 0; i < num_to_move; i++) + { + assert((pDst - m_p) < (int)m_size); + *pDst-- = *pSrc--; + } + } + + T* pDst = m_p + index; + + if (BASISU_IS_BITWISE_COPYABLE(T)) + { + // This copies in the new bits, overwriting the existing objects, which is OK for copyable types that don't need destruction. + memcpy(pDst, p, sizeof(T) * n); + } + else + { + for (uint32_t i = 0; i < n; i++) + { + assert((pDst - m_p) < (int)m_size); + *pDst++ = *p++; + } + } + } + + inline void insert(T* p, const T& obj) + { + int64_t ofs = p - begin(); + if ((ofs < 0) || (ofs > UINT32_MAX)) + { + assert(0); + return; + } + + insert((uint32_t)ofs, &obj, 1); + } + + // push_front() isn't going to be very fast - it's only here for usability. + inline void push_front(const T& obj) + { + insert(0, &obj, 1); + } + + vector& append(const vector& other) + { + if (other.m_size) + insert(m_size, &other[0], other.m_size); + return *this; + } + + vector& append(const T* p, uint32_t n) + { + if (n) + insert(m_size, p, n); + return *this; + } + + inline void erase(uint32_t start, uint32_t n) + { + assert((start + n) <= m_size); + if ((start + n) > m_size) + return; + + if (!n) + return; + + const uint32_t num_to_move = m_size - (start + n); + + T* pDst = m_p + start; + + const T* pSrc = m_p + start + n; + + if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T)) + { + // This test is overly cautious. + if ((!BASISU_IS_BITWISE_COPYABLE(T)) || (BASISU_HAS_DESTRUCTOR(T))) + { + // Type has been marked explictly as bitwise movable, which means we can move them around but they may need to be destructed. + // First destroy the erased objects. + scalar_type<T>::destruct_array(pDst, n); + } + + // Copy "down" the objects to preserve, filling in the empty slots. + memmove(pDst, pSrc, num_to_move * sizeof(T)); + } + else + { + // Type is not bitwise copyable or movable. + // Move them down one at a time by using the equals operator, and destroying anything that's left over at the end. + T* pDst_end = pDst + num_to_move; + while (pDst != pDst_end) + *pDst++ = *pSrc++; + + scalar_type<T>::destruct_array(pDst_end, n); + } + + m_size -= n; + } + + inline void erase(uint32_t index) + { + erase(index, 1); + } + + inline void erase(T* p) + { + assert((p >= m_p) && (p < (m_p + m_size))); + erase(static_cast<uint32_t>(p - m_p)); + } + + inline void erase(T *pFirst, T *pEnd) + { + assert(pFirst <= pEnd); + assert(pFirst >= begin() && pFirst <= end()); + assert(pEnd >= begin() && pEnd <= end()); + + int64_t ofs = pFirst - begin(); + if ((ofs < 0) || (ofs > UINT32_MAX)) + { + assert(0); + return; + } + + int64_t n = pEnd - pFirst; + if ((n < 0) || (n > UINT32_MAX)) + { + assert(0); + return; + } + + erase((uint32_t)ofs, (uint32_t)n); + } + + void erase_unordered(uint32_t index) + { + assert(index < m_size); + + if ((index + 1) < m_size) + (*this)[index] = back(); + + pop_back(); + } + + inline bool operator== (const vector& rhs) const + { + if (m_size != rhs.m_size) + return false; + else if (m_size) + { + if (scalar_type<T>::cFlag) + return memcmp(m_p, rhs.m_p, sizeof(T) * m_size) == 0; + else + { + const T* pSrc = m_p; + const T* pDst = rhs.m_p; + for (uint32_t i = m_size; i; i--) + if (!(*pSrc++ == *pDst++)) + return false; + } + } + + return true; + } + + inline bool operator< (const vector& rhs) const + { + const uint32_t min_size = helpers::minimum(m_size, rhs.m_size); + + const T* pSrc = m_p; + const T* pSrc_end = m_p + min_size; + const T* pDst = rhs.m_p; + + while ((pSrc < pSrc_end) && (*pSrc == *pDst)) + { + pSrc++; + pDst++; + } + + if (pSrc < pSrc_end) + return *pSrc < *pDst; + + return m_size < rhs.m_size; + } + + inline void swap(vector& other) + { + std::swap(m_p, other.m_p); + std::swap(m_size, other.m_size); + std::swap(m_capacity, other.m_capacity); + } + + inline void sort() + { + std::sort(begin(), end()); + } + + inline void unique() + { + if (!empty()) + { + sort(); + + resize(std::unique(begin(), end()) - begin()); + } + } + + inline void reverse() + { + uint32_t j = m_size >> 1; + for (uint32_t i = 0; i < j; i++) + std::swap(m_p[i], m_p[m_size - 1 - i]); + } + + inline int find(const T& key) const + { + const T* p = m_p; + const T* p_end = m_p + m_size; + + uint32_t index = 0; + + while (p != p_end) + { + if (key == *p) + return index; + + p++; + index++; + } + + return cInvalidIndex; + } + + inline int find_sorted(const T& key) const + { + if (m_size) + { + // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice. + int i = ((m_size + 1) >> 1) - 1; + int m = m_size; + + for (; ; ) + { + assert(i >= 0 && i < (int)m_size); + const T* pKey_i = m_p + i; + int cmp = key < *pKey_i; +#if defined(_DEBUG) || defined(DEBUG) + int cmp2 = *pKey_i < key; + assert((cmp != cmp2) || (key == *pKey_i)); +#endif + if ((!cmp) && (key == *pKey_i)) return i; + m >>= 1; + if (!m) break; + cmp = -cmp; + i += (((m + 1) >> 1) ^ cmp) - cmp; + if (i < 0) + break; + + assert(i >= 0 && i < (int)m_size); + pKey_i = m_p + i; + cmp = key < *pKey_i; +#if defined(_DEBUG) || defined(DEBUG) + cmp2 = *pKey_i < key; + assert((cmp != cmp2) || (key == *pKey_i)); +#endif + if ((!cmp) && (key == *pKey_i)) return i; + m >>= 1; + if (!m) break; + cmp = -cmp; + i += (((m + 1) >> 1) ^ cmp) - cmp; + if (i < 0) + break; + } + } + + return cInvalidIndex; + } + + template<typename Q> + inline int find_sorted(const T& key, Q less_than) const + { + if (m_size) + { + // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice. + int i = ((m_size + 1) >> 1) - 1; + int m = m_size; + + for (; ; ) + { + assert(i >= 0 && i < (int)m_size); + const T* pKey_i = m_p + i; + int cmp = less_than(key, *pKey_i); + if ((!cmp) && (!less_than(*pKey_i, key))) return i; + m >>= 1; + if (!m) break; + cmp = -cmp; + i += (((m + 1) >> 1) ^ cmp) - cmp; + if (i < 0) + break; + + assert(i >= 0 && i < (int)m_size); + pKey_i = m_p + i; + cmp = less_than(key, *pKey_i); + if ((!cmp) && (!less_than(*pKey_i, key))) return i; + m >>= 1; + if (!m) break; + cmp = -cmp; + i += (((m + 1) >> 1) ^ cmp) - cmp; + if (i < 0) + break; + } + } + + return cInvalidIndex; + } + + inline uint32_t count_occurences(const T& key) const + { + uint32_t c = 0; + + const T* p = m_p; + const T* p_end = m_p + m_size; + + while (p != p_end) + { + if (key == *p) + c++; + + p++; + } + + return c; + } + + inline void set_all(const T& o) + { + if ((sizeof(T) == 1) && (scalar_type<T>::cFlag)) + memset(m_p, *reinterpret_cast<const uint8_t*>(&o), m_size); + else + { + T* pDst = m_p; + T* pDst_end = pDst + m_size; + while (pDst != pDst_end) + *pDst++ = o; + } + } + + // Caller assumes ownership of the heap block associated with the container. Container is cleared. + inline void* assume_ownership() + { + T* p = m_p; + m_p = NULL; + m_size = 0; + m_capacity = 0; + return p; + } + + // Caller is granting ownership of the indicated heap block. + // Block must have size constructed elements, and have enough room for capacity elements. + inline bool grant_ownership(T* p, uint32_t size, uint32_t capacity) + { + // To to prevent the caller from obviously shooting themselves in the foot. + if (((p + capacity) > m_p) && (p < (m_p + m_capacity))) + { + // Can grant ownership of a block inside the container itself! + assert(0); + return false; + } + + if (size > capacity) + { + assert(0); + return false; + } + + if (!p) + { + if (capacity) + { + assert(0); + return false; + } + } + else if (!capacity) + { + assert(0); + return false; + } + + clear(); + m_p = p; + m_size = size; + m_capacity = capacity; + return true; + } + + private: + T* m_p; + uint32_t m_size; + uint32_t m_capacity; + + template<typename Q> struct is_vector { enum { cFlag = false }; }; + template<typename Q> struct is_vector< vector<Q> > { enum { cFlag = true }; }; + + static void object_mover(void* pDst_void, void* pSrc_void, uint32_t num) + { + T* pSrc = static_cast<T*>(pSrc_void); + T* const pSrc_end = pSrc + num; + T* pDst = static_cast<T*>(pDst_void); + + while (pSrc != pSrc_end) + { + // placement new + new (static_cast<void*>(pDst)) T(*pSrc); + pSrc->~T(); + ++pSrc; + ++pDst; + } + } + + inline bool increase_capacity(uint32_t min_new_capacity, bool grow_hint, bool nofail = false) + { + return reinterpret_cast<elemental_vector*>(this)->increase_capacity( + min_new_capacity, grow_hint, sizeof(T), + (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T) || (is_vector<T>::cFlag)) ? NULL : object_mover, nofail); + } + }; + + template<typename T> struct bitwise_movable< vector<T> > { enum { cFlag = true }; }; + + // Hash map + + template <typename T> + struct hasher + { + inline size_t operator() (const T& key) const { return static_cast<size_t>(key); } + }; + + template <typename T> + struct equal_to + { + inline bool operator()(const T& a, const T& b) const { return a == b; } + }; + + // Important: The Hasher and Equals objects must be bitwise movable! + template<typename Key, typename Value = empty_type, typename Hasher = hasher<Key>, typename Equals = equal_to<Key> > + class hash_map + { + public: + class iterator; + class const_iterator; + + private: + friend class iterator; + friend class const_iterator; + + enum state + { + cStateInvalid = 0, + cStateValid = 1 + }; + + enum + { + cMinHashSize = 4U + }; + + public: + typedef hash_map<Key, Value, Hasher, Equals> hash_map_type; + typedef std::pair<Key, Value> value_type; + typedef Key key_type; + typedef Value referent_type; + typedef Hasher hasher_type; + typedef Equals equals_type; + + hash_map() : + m_hash_shift(32), m_num_valid(0), m_grow_threshold(0) + { + } + + hash_map(const hash_map& other) : + m_values(other.m_values), + m_hash_shift(other.m_hash_shift), + m_hasher(other.m_hasher), + m_equals(other.m_equals), + m_num_valid(other.m_num_valid), + m_grow_threshold(other.m_grow_threshold) + { + } + + hash_map& operator= (const hash_map& other) + { + if (this == &other) + return *this; + + clear(); + + m_values = other.m_values; + m_hash_shift = other.m_hash_shift; + m_num_valid = other.m_num_valid; + m_grow_threshold = other.m_grow_threshold; + m_hasher = other.m_hasher; + m_equals = other.m_equals; + + return *this; + } + + inline ~hash_map() + { + clear(); + } + + const Equals& get_equals() const { return m_equals; } + Equals& get_equals() { return m_equals; } + + void set_equals(const Equals& equals) { m_equals = equals; } + + const Hasher& get_hasher() const { return m_hasher; } + Hasher& get_hasher() { return m_hasher; } + + void set_hasher(const Hasher& hasher) { m_hasher = hasher; } + + inline void clear() + { + if (!m_values.empty()) + { + if (BASISU_HAS_DESTRUCTOR(Key) || BASISU_HAS_DESTRUCTOR(Value)) + { + node* p = &get_node(0); + node* p_end = p + m_values.size(); + + uint32_t num_remaining = m_num_valid; + while (p != p_end) + { + if (p->state) + { + destruct_value_type(p); + num_remaining--; + if (!num_remaining) + break; + } + + p++; + } + } + + m_values.clear_no_destruction(); + + m_hash_shift = 32; + m_num_valid = 0; + m_grow_threshold = 0; + } + } + + inline void reset() + { + if (!m_num_valid) + return; + + if (BASISU_HAS_DESTRUCTOR(Key) || BASISU_HAS_DESTRUCTOR(Value)) + { + node* p = &get_node(0); + node* p_end = p + m_values.size(); + + uint32_t num_remaining = m_num_valid; + while (p != p_end) + { + if (p->state) + { + destruct_value_type(p); + p->state = cStateInvalid; + + num_remaining--; + if (!num_remaining) + break; + } + + p++; + } + } + else if (sizeof(node) <= 32) + { + memset(&m_values[0], 0, m_values.size_in_bytes()); + } + else + { + node* p = &get_node(0); + node* p_end = p + m_values.size(); + + uint32_t num_remaining = m_num_valid; + while (p != p_end) + { + if (p->state) + { + p->state = cStateInvalid; + + num_remaining--; + if (!num_remaining) + break; + } + + p++; + } + } + + m_num_valid = 0; + } + + inline uint32_t size() + { + return m_num_valid; + } + + inline uint32_t get_table_size() + { + return m_values.size(); + } + + inline bool empty() + { + return !m_num_valid; + } + + inline void reserve(uint32_t new_capacity) + { + uint64_t new_hash_size = helpers::maximum(1U, new_capacity); + + new_hash_size = new_hash_size * 2ULL; + + if (!helpers::is_power_of_2(new_hash_size)) + new_hash_size = helpers::next_pow2(new_hash_size); + + new_hash_size = helpers::maximum<uint64_t>(cMinHashSize, new_hash_size); + + new_hash_size = helpers::minimum<uint64_t>(0x80000000UL, new_hash_size); + + if (new_hash_size > m_values.size()) + rehash((uint32_t)new_hash_size); + } + + class iterator + { + friend class hash_map<Key, Value, Hasher, Equals>; + friend class hash_map<Key, Value, Hasher, Equals>::const_iterator; + + public: + inline iterator() : m_pTable(NULL), m_index(0) { } + inline iterator(hash_map_type& table, uint32_t index) : m_pTable(&table), m_index(index) { } + inline iterator(const iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { } + + inline iterator& operator= (const iterator& other) + { + m_pTable = other.m_pTable; + m_index = other.m_index; + return *this; + } + + // post-increment + inline iterator operator++(int) + { + iterator result(*this); + ++*this; + return result; + } + + // pre-increment + inline iterator& operator++() + { + probe(); + return *this; + } + + inline value_type& operator*() const { return *get_cur(); } + inline value_type* operator->() const { return get_cur(); } + + inline bool operator == (const iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); } + inline bool operator != (const iterator& b) const { return !(*this == b); } + inline bool operator == (const const_iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); } + inline bool operator != (const const_iterator& b) const { return !(*this == b); } + + private: + hash_map_type* m_pTable; + uint32_t m_index; + + inline value_type* get_cur() const + { + assert(m_pTable && (m_index < m_pTable->m_values.size())); + assert(m_pTable->get_node_state(m_index) == cStateValid); + + return &m_pTable->get_node(m_index); + } + + inline void probe() + { + assert(m_pTable); + m_index = m_pTable->find_next(m_index); + } + }; + + class const_iterator + { + friend class hash_map<Key, Value, Hasher, Equals>; + friend class hash_map<Key, Value, Hasher, Equals>::iterator; + + public: + inline const_iterator() : m_pTable(NULL), m_index(0) { } + inline const_iterator(const hash_map_type& table, uint32_t index) : m_pTable(&table), m_index(index) { } + inline const_iterator(const iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { } + inline const_iterator(const const_iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { } + + inline const_iterator& operator= (const const_iterator& other) + { + m_pTable = other.m_pTable; + m_index = other.m_index; + return *this; + } + + inline const_iterator& operator= (const iterator& other) + { + m_pTable = other.m_pTable; + m_index = other.m_index; + return *this; + } + + // post-increment + inline const_iterator operator++(int) + { + const_iterator result(*this); + ++*this; + return result; + } + + // pre-increment + inline const_iterator& operator++() + { + probe(); + return *this; + } + + inline const value_type& operator*() const { return *get_cur(); } + inline const value_type* operator->() const { return get_cur(); } + + inline bool operator == (const const_iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); } + inline bool operator != (const const_iterator& b) const { return !(*this == b); } + inline bool operator == (const iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); } + inline bool operator != (const iterator& b) const { return !(*this == b); } + + private: + const hash_map_type* m_pTable; + uint32_t m_index; + + inline const value_type* get_cur() const + { + assert(m_pTable && (m_index < m_pTable->m_values.size())); + assert(m_pTable->get_node_state(m_index) == cStateValid); + + return &m_pTable->get_node(m_index); + } + + inline void probe() + { + assert(m_pTable); + m_index = m_pTable->find_next(m_index); + } + }; + + inline const_iterator begin() const + { + if (!m_num_valid) + return end(); + + return const_iterator(*this, find_next(UINT32_MAX)); + } + + inline const_iterator end() const + { + return const_iterator(*this, m_values.size()); + } + + inline iterator begin() + { + if (!m_num_valid) + return end(); + + return iterator(*this, find_next(UINT32_MAX)); + } + + inline iterator end() + { + return iterator(*this, m_values.size()); + } + + // insert_result.first will always point to inserted key/value (or the already existing key/value). + // insert_resutt.second will be true if a new key/value was inserted, or false if the key already existed (in which case first will point to the already existing value). + typedef std::pair<iterator, bool> insert_result; + + inline insert_result insert(const Key& k, const Value& v = Value()) + { + insert_result result; + if (!insert_no_grow(result, k, v)) + { + grow(); + + // This must succeed. + if (!insert_no_grow(result, k, v)) + { + fprintf(stderr, "insert() failed"); + abort(); + } + } + + return result; + } + + inline insert_result insert(const value_type& v) + { + return insert(v.first, v.second); + } + + inline const_iterator find(const Key& k) const + { + return const_iterator(*this, find_index(k)); + } + + inline iterator find(const Key& k) + { + return iterator(*this, find_index(k)); + } + + inline bool erase(const Key& k) + { + uint32_t i = find_index(k); + + if (i >= m_values.size()) + return false; + + node* pDst = &get_node(i); + destruct_value_type(pDst); + pDst->state = cStateInvalid; + + m_num_valid--; + + for (; ; ) + { + uint32_t r, j = i; + + node* pSrc = pDst; + + do + { + if (!i) + { + i = m_values.size() - 1; + pSrc = &get_node(i); + } + else + { + i--; + pSrc--; + } + + if (!pSrc->state) + return true; + + r = hash_key(pSrc->first); + + } while ((i <= r && r < j) || (r < j && j < i) || (j < i && i <= r)); + + move_node(pDst, pSrc); + + pDst = pSrc; + } + } + + inline void swap(hash_map_type& other) + { + m_values.swap(other.m_values); + std::swap(m_hash_shift, other.m_hash_shift); + std::swap(m_num_valid, other.m_num_valid); + std::swap(m_grow_threshold, other.m_grow_threshold); + std::swap(m_hasher, other.m_hasher); + std::swap(m_equals, other.m_equals); + } + + private: + struct node : public value_type + { + uint8_t state; + }; + + static inline void construct_value_type(value_type* pDst, const Key& k, const Value& v) + { + if (BASISU_IS_BITWISE_COPYABLE(Key)) + memcpy(&pDst->first, &k, sizeof(Key)); + else + scalar_type<Key>::construct(&pDst->first, k); + + if (BASISU_IS_BITWISE_COPYABLE(Value)) + memcpy(&pDst->second, &v, sizeof(Value)); + else + scalar_type<Value>::construct(&pDst->second, v); + } + + static inline void construct_value_type(value_type* pDst, const value_type* pSrc) + { + if ((BASISU_IS_BITWISE_COPYABLE(Key)) && (BASISU_IS_BITWISE_COPYABLE(Value))) + { + memcpy(pDst, pSrc, sizeof(value_type)); + } + else + { + if (BASISU_IS_BITWISE_COPYABLE(Key)) + memcpy(&pDst->first, &pSrc->first, sizeof(Key)); + else + scalar_type<Key>::construct(&pDst->first, pSrc->first); + + if (BASISU_IS_BITWISE_COPYABLE(Value)) + memcpy(&pDst->second, &pSrc->second, sizeof(Value)); + else + scalar_type<Value>::construct(&pDst->second, pSrc->second); + } + } + + static inline void destruct_value_type(value_type* p) + { + scalar_type<Key>::destruct(&p->first); + scalar_type<Value>::destruct(&p->second); + } + + // Moves *pSrc to *pDst efficiently. + // pDst should NOT be constructed on entry. + static inline void move_node(node* pDst, node* pSrc, bool update_src_state = true) + { + assert(!pDst->state); + + if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Key) && BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Value)) + { + memcpy(pDst, pSrc, sizeof(node)); + } + else + { + if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Key)) + memcpy(&pDst->first, &pSrc->first, sizeof(Key)); + else + { + scalar_type<Key>::construct(&pDst->first, pSrc->first); + scalar_type<Key>::destruct(&pSrc->first); + } + + if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Value)) + memcpy(&pDst->second, &pSrc->second, sizeof(Value)); + else + { + scalar_type<Value>::construct(&pDst->second, pSrc->second); + scalar_type<Value>::destruct(&pSrc->second); + } + + pDst->state = cStateValid; + } + + if (update_src_state) + pSrc->state = cStateInvalid; + } + + struct raw_node + { + inline raw_node() + { + node* p = reinterpret_cast<node*>(this); + p->state = cStateInvalid; + } + + inline ~raw_node() + { + node* p = reinterpret_cast<node*>(this); + if (p->state) + hash_map_type::destruct_value_type(p); + } + + inline raw_node(const raw_node& other) + { + node* pDst = reinterpret_cast<node*>(this); + const node* pSrc = reinterpret_cast<const node*>(&other); + + if (pSrc->state) + { + hash_map_type::construct_value_type(pDst, pSrc); + pDst->state = cStateValid; + } + else + pDst->state = cStateInvalid; + } + + inline raw_node& operator= (const raw_node& rhs) + { + if (this == &rhs) + return *this; + + node* pDst = reinterpret_cast<node*>(this); + const node* pSrc = reinterpret_cast<const node*>(&rhs); + + if (pSrc->state) + { + if (pDst->state) + { + pDst->first = pSrc->first; + pDst->second = pSrc->second; + } + else + { + hash_map_type::construct_value_type(pDst, pSrc); + pDst->state = cStateValid; + } + } + else if (pDst->state) + { + hash_map_type::destruct_value_type(pDst); + pDst->state = cStateInvalid; + } + + return *this; + } + + uint8_t m_bits[sizeof(node)]; + }; + + typedef basisu::vector<raw_node> node_vector; + + node_vector m_values; + uint32_t m_hash_shift; + + Hasher m_hasher; + Equals m_equals; + + uint32_t m_num_valid; + + uint32_t m_grow_threshold; + + inline uint32_t hash_key(const Key& k) const + { + assert((1U << (32U - m_hash_shift)) == m_values.size()); + + uint32_t hash = static_cast<uint32_t>(m_hasher(k)); + + // Fibonacci hashing + hash = (2654435769U * hash) >> m_hash_shift; + + assert(hash < m_values.size()); + return hash; + } + + inline const node& get_node(uint32_t index) const + { + return *reinterpret_cast<const node*>(&m_values[index]); + } + + inline node& get_node(uint32_t index) + { + return *reinterpret_cast<node*>(&m_values[index]); + } + + inline state get_node_state(uint32_t index) const + { + return static_cast<state>(get_node(index).state); + } + + inline void set_node_state(uint32_t index, bool valid) + { + get_node(index).state = valid; + } + + inline void grow() + { + uint64_t n = m_values.size() * 3ULL; // was * 2 + + if (!helpers::is_power_of_2(n)) + n = helpers::next_pow2(n); + + if (n > 0x80000000UL) + n = 0x80000000UL; + + rehash(helpers::maximum<uint32_t>(cMinHashSize, (uint32_t)n)); + } + + inline void rehash(uint32_t new_hash_size) + { + assert(new_hash_size >= m_num_valid); + assert(helpers::is_power_of_2(new_hash_size)); + + if ((new_hash_size < m_num_valid) || (new_hash_size == m_values.size())) + return; + + hash_map new_map; + new_map.m_values.resize(new_hash_size); + new_map.m_hash_shift = 32U - helpers::floor_log2i(new_hash_size); + assert(new_hash_size == (1U << (32U - new_map.m_hash_shift))); + new_map.m_grow_threshold = UINT_MAX; + + node* pNode = reinterpret_cast<node*>(m_values.begin()); + node* pNode_end = pNode + m_values.size(); + + while (pNode != pNode_end) + { + if (pNode->state) + { + new_map.move_into(pNode); + + if (new_map.m_num_valid == m_num_valid) + break; + } + + pNode++; + } + + new_map.m_grow_threshold = (new_hash_size + 1U) >> 1U; + + m_values.clear_no_destruction(); + m_hash_shift = 32; + + swap(new_map); + } + + inline uint32_t find_next(uint32_t index) const + { + index++; + + if (index >= m_values.size()) + return index; + + const node* pNode = &get_node(index); + + for (; ; ) + { + if (pNode->state) + break; + + if (++index >= m_values.size()) + break; + + pNode++; + } + + return index; + } + + inline uint32_t find_index(const Key& k) const + { + if (m_num_valid) + { + uint32_t index = hash_key(k); + const node* pNode = &get_node(index); + + if (pNode->state) + { + if (m_equals(pNode->first, k)) + return index; + + const uint32_t orig_index = index; + + for (; ; ) + { + if (!index) + { + index = m_values.size() - 1; + pNode = &get_node(index); + } + else + { + index--; + pNode--; + } + + if (index == orig_index) + break; + + if (!pNode->state) + break; + + if (m_equals(pNode->first, k)) + return index; + } + } + } + + return m_values.size(); + } + + inline bool insert_no_grow(insert_result& result, const Key& k, const Value& v = Value()) + { + if (!m_values.size()) + return false; + + uint32_t index = hash_key(k); + node* pNode = &get_node(index); + + if (pNode->state) + { + if (m_equals(pNode->first, k)) + { + result.first = iterator(*this, index); + result.second = false; + return true; + } + + const uint32_t orig_index = index; + + for (; ; ) + { + if (!index) + { + index = m_values.size() - 1; + pNode = &get_node(index); + } + else + { + index--; + pNode--; + } + + if (orig_index == index) + return false; + + if (!pNode->state) + break; + + if (m_equals(pNode->first, k)) + { + result.first = iterator(*this, index); + result.second = false; + return true; + } + } + } + + if (m_num_valid >= m_grow_threshold) + return false; + + construct_value_type(pNode, k, v); + + pNode->state = cStateValid; + + m_num_valid++; + assert(m_num_valid <= m_values.size()); + + result.first = iterator(*this, index); + result.second = true; + + return true; + } + + inline void move_into(node* pNode) + { + uint32_t index = hash_key(pNode->first); + node* pDst_node = &get_node(index); + + if (pDst_node->state) + { + const uint32_t orig_index = index; + + for (; ; ) + { + if (!index) + { + index = m_values.size() - 1; + pDst_node = &get_node(index); + } + else + { + index--; + pDst_node--; + } + + if (index == orig_index) + { + assert(false); + return; + } + + if (!pDst_node->state) + break; + } + } + + move_node(pDst_node, pNode, false); + + m_num_valid++; + } + }; + + template<typename Key, typename Value, typename Hasher, typename Equals> + struct bitwise_movable< hash_map<Key, Value, Hasher, Equals> > { enum { cFlag = true }; }; + +#if BASISU_HASHMAP_TEST + extern void hash_map_test(); +#endif + +} // namespace basisu + +namespace std +{ + template<typename T> + inline void swap(basisu::vector<T>& a, basisu::vector<T>& b) + { + a.swap(b); + } + + template<typename Key, typename Value, typename Hasher, typename Equals> + inline void swap(basisu::hash_map<Key, Value, Hasher, Equals>& a, basisu::hash_map<Key, Value, Hasher, Equals>& b) + { + a.swap(b); + } + +} // namespace std diff --git a/thirdparty/basis_universal/transcoder/basisu_containers_impl.h b/thirdparty/basis_universal/transcoder/basisu_containers_impl.h new file mode 100644 index 0000000000..6555171419 --- /dev/null +++ b/thirdparty/basis_universal/transcoder/basisu_containers_impl.h @@ -0,0 +1,311 @@ +// basisu_containers_impl.h +// Do not include directly + +#ifdef _MSC_VER +#pragma warning (disable:4127) // warning C4127: conditional expression is constant +#endif + +namespace basisu +{ + bool elemental_vector::increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pMover, bool nofail) + { + assert(m_size <= m_capacity); + + if (sizeof(void *) == sizeof(uint64_t)) + assert(min_new_capacity < (0x400000000ULL / element_size)); + else + assert(min_new_capacity < (0x7FFF0000U / element_size)); + + if (m_capacity >= min_new_capacity) + return true; + + size_t new_capacity = min_new_capacity; + if ((grow_hint) && (!helpers::is_power_of_2((uint64_t)new_capacity))) + { + new_capacity = (size_t)helpers::next_pow2((uint64_t)new_capacity); + + assert(new_capacity && (new_capacity > m_capacity)); + + if (new_capacity < min_new_capacity) + { + if (nofail) + return false; + fprintf(stderr, "vector too large\n"); + abort(); + } + } + + const size_t desired_size = element_size * new_capacity; + size_t actual_size = 0; + if (!pMover) + { + void* new_p = realloc(m_p, desired_size); + if (!new_p) + { + if (nofail) + return false; + + char buf[256]; +#ifdef _MSC_VER + sprintf_s(buf, sizeof(buf), "vector: realloc() failed allocating %u bytes", (uint32_t)desired_size); +#else + sprintf(buf, "vector: realloc() failed allocating %u bytes", (uint32_t)desired_size); +#endif + fprintf(stderr, "%s", buf); + abort(); + } + +#ifdef _MSC_VER + actual_size = _msize(new_p); +#elif HAS_MALLOC_USABLE_SIZE + actual_size = malloc_usable_size(new_p); +#else + actual_size = desired_size; +#endif + m_p = new_p; + } + else + { + void* new_p = malloc(desired_size); + if (!new_p) + { + if (nofail) + return false; + + char buf[256]; +#ifdef _MSC_VER + sprintf_s(buf, sizeof(buf), "vector: malloc() failed allocating %u bytes", (uint32_t)desired_size); +#else + sprintf(buf, "vector: malloc() failed allocating %u bytes", (uint32_t)desired_size); +#endif + fprintf(stderr, "%s", buf); + abort(); + } + +#ifdef _MSC_VER + actual_size = _msize(new_p); +#elif HAS_MALLOC_USABLE_SIZE + actual_size = malloc_usable_size(new_p); +#else + actual_size = desired_size; +#endif + + (*pMover)(new_p, m_p, m_size); + + if (m_p) + free(m_p); + + m_p = new_p; + } + + if (actual_size > desired_size) + m_capacity = static_cast<uint32_t>(actual_size / element_size); + else + m_capacity = static_cast<uint32_t>(new_capacity); + + return true; + } + +#if BASISU_HASHMAP_TEST + +#define HASHMAP_TEST_VERIFY(c) do { if (!(c)) handle_hashmap_test_verify_failure(__LINE__); } while(0) + + static void handle_hashmap_test_verify_failure(int line) + { + fprintf(stderr, "HASHMAP_TEST_VERIFY() faild on line %i\n", line); + abort(); + } + + class counted_obj + { + public: + counted_obj(uint32_t v = 0) : + m_val(v) + { + m_count++; + } + + counted_obj(const counted_obj& obj) : + m_val(obj.m_val) + { + m_count++; + } + + ~counted_obj() + { + assert(m_count > 0); + m_count--; + } + + static uint32_t m_count; + + uint32_t m_val; + + operator size_t() const { return m_val; } + + bool operator== (const counted_obj& rhs) const { return m_val == rhs.m_val; } + bool operator== (const uint32_t rhs) const { return m_val == rhs; } + + }; + + uint32_t counted_obj::m_count; + + static uint32_t urand32() + { + uint32_t a = rand(); + uint32_t b = rand() << 15; + uint32_t c = rand() << (32 - 15); + return a ^ b ^ c; + } + + static int irand32(int l, int h) + { + assert(l < h); + if (l >= h) + return l; + + uint32_t range = static_cast<uint32_t>(h - l); + + uint32_t rnd = urand32(); + + uint32_t rnd_range = static_cast<uint32_t>((((uint64_t)range) * ((uint64_t)rnd)) >> 32U); + + int result = l + rnd_range; + assert((result >= l) && (result < h)); + return result; + } + + void hash_map_test() + { + { + basisu::hash_map<uint64_t, uint64_t> k; + basisu::hash_map<uint64_t, uint64_t> l; + std::swap(k, l); + + k.begin(); + k.end(); + k.clear(); + k.empty(); + k.erase(0); + k.insert(0, 1); + k.find(0); + k.get_equals(); + k.get_hasher(); + k.get_table_size(); + k.reset(); + k.reserve(1); + k = l; + k.set_equals(l.get_equals()); + k.set_hasher(l.get_hasher()); + k.get_table_size(); + } + + uint32_t seed = 0; + for (; ; ) + { + seed++; + + typedef basisu::hash_map<counted_obj, counted_obj> my_hash_map; + my_hash_map m; + + const uint32_t n = irand32(0, 100000); + + printf("%u\n", n); + + srand(seed); // r1.seed(seed); + + basisu::vector<int> q; + + uint32_t count = 0; + for (uint32_t i = 0; i < n; i++) + { + uint32_t v = urand32() & 0x7FFFFFFF; + my_hash_map::insert_result res = m.insert(counted_obj(v), counted_obj(v ^ 0xdeadbeef)); + if (res.second) + { + count++; + q.push_back(v); + } + } + + HASHMAP_TEST_VERIFY(m.size() == count); + + srand(seed); + + my_hash_map cm(m); + m.clear(); + m = cm; + cm.reset(); + + for (uint32_t i = 0; i < n; i++) + { + uint32_t v = urand32() & 0x7FFFFFFF; + my_hash_map::const_iterator it = m.find(counted_obj(v)); + HASHMAP_TEST_VERIFY(it != m.end()); + HASHMAP_TEST_VERIFY(it->first == v); + HASHMAP_TEST_VERIFY(it->second == (v ^ 0xdeadbeef)); + } + + for (uint32_t t = 0; t < 2; t++) + { + const uint32_t nd = irand32(1, q.size() + 1); + for (uint32_t i = 0; i < nd; i++) + { + uint32_t p = irand32(0, q.size()); + + int k = q[p]; + if (k >= 0) + { + q[p] = -k - 1; + + bool s = m.erase(counted_obj(k)); + HASHMAP_TEST_VERIFY(s); + } + } + + typedef basisu::hash_map<uint32_t, empty_type> uint_hash_set; + uint_hash_set s; + + for (uint32_t i = 0; i < q.size(); i++) + { + int v = q[i]; + + if (v >= 0) + { + my_hash_map::const_iterator it = m.find(counted_obj(v)); + HASHMAP_TEST_VERIFY(it != m.end()); + HASHMAP_TEST_VERIFY(it->first == (uint32_t)v); + HASHMAP_TEST_VERIFY(it->second == ((uint32_t)v ^ 0xdeadbeef)); + + s.insert(v); + } + else + { + my_hash_map::const_iterator it = m.find(counted_obj(-v - 1)); + HASHMAP_TEST_VERIFY(it == m.end()); + } + } + + uint32_t found_count = 0; + for (my_hash_map::const_iterator it = m.begin(); it != m.end(); ++it) + { + HASHMAP_TEST_VERIFY(it->second == ((uint32_t)it->first ^ 0xdeadbeef)); + + uint_hash_set::const_iterator fit(s.find((uint32_t)it->first)); + HASHMAP_TEST_VERIFY(fit != s.end()); + + HASHMAP_TEST_VERIFY(fit->first == it->first); + + found_count++; + } + + HASHMAP_TEST_VERIFY(found_count == s.size()); + } + + HASHMAP_TEST_VERIFY(counted_obj::m_count == m.size() * 2); + } + } + +#endif // BASISU_HASHMAP_TEST + +} // namespace basisu diff --git a/thirdparty/basis_universal/transcoder/basisu_file_headers.h b/thirdparty/basis_universal/transcoder/basisu_file_headers.h index c90b3f3af0..4316d738e6 100644 --- a/thirdparty/basis_universal/transcoder/basisu_file_headers.h +++ b/thirdparty/basis_universal/transcoder/basisu_file_headers.h @@ -1,5 +1,5 @@ // basis_file_headers.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2020 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,8 +20,11 @@ namespace basist // Slice desc header flags enum basis_slice_desc_flags { - cSliceDescFlagsIsAlphaData = 1, - cSliceDescFlagsFrameIsIFrame = 2 // Video only: Frame doesn't refer to previous frame (no usage of conditional replenishment pred symbols) + cSliceDescFlagsHasAlpha = 1, + + // Video only: Frame doesn't refer to previous frame (no usage of conditional replenishment pred symbols) + // Currently the first frame is always an I-Frame, all subsequent frames are P-Frames. This will eventually be changed to periodic I-Frames. + cSliceDescFlagsFrameIsIFrame = 2 }; #pragma pack(push) @@ -38,7 +41,7 @@ namespace basist basisu::packed_uint<2> m_num_blocks_x; // The slice's block X dimensions. Each block is 4x4 pixels. The slice's pixel resolution may or may not be a power of 2. basisu::packed_uint<2> m_num_blocks_y; // The slice's block Y dimensions. - basisu::packed_uint<4> m_file_ofs; // Offset from the header to the start of the slice's data + basisu::packed_uint<4> m_file_ofs; // Offset from the start of the file to the start of the slice's data basisu::packed_uint<4> m_file_size; // The size of the compressed slice data in bytes basisu::packed_uint<2> m_slice_data_crc16; // The CRC16 of the compressed slice data, for extra-paranoid use cases @@ -47,9 +50,21 @@ namespace basist // File header files enum basis_header_flags { - cBASISHeaderFlagETC1S = 1, // Always set for basis universal files - cBASISHeaderFlagYFlipped = 2, // Set if the texture had to be Y flipped before encoding - cBASISHeaderFlagHasAlphaSlices = 4 // True if the odd slices contain alpha data + // Always set for ETC1S files. Not set for UASTC files. + cBASISHeaderFlagETC1S = 1, + + // Set if the texture had to be Y flipped before encoding. The actual interpretation of this (is Y up or down?) is up to the user. + cBASISHeaderFlagYFlipped = 2, + + // Set if any slices contain alpha (for ETC1S, if the odd slices contain alpha data) + cBASISHeaderFlagHasAlphaSlices = 4, + + // For ETC1S files, this will be true if the file utilizes a codebook from another .basis file. + cBASISHeaderFlagUsesGlobalCodebook = 8, + + // Set if the texture data is sRGB, otherwise it's linear. + // In reality, we have no idea if the texture data is actually linear or sRGB. This is the m_perceptual parameter passed to the compressor. + cBASISHeaderFlagSRGB = 16, }; // The image type field attempts to describe how to interpret the image data in a Basis file. @@ -71,6 +86,12 @@ namespace basist cBASISMaxUSPerFrame = 0xFFFFFF }; + enum class basis_tex_format + { + cETC1S = 0, + cUASTC4x4 = 1 + }; + struct basis_file_header { enum @@ -82,16 +103,16 @@ namespace basist basisu::packed_uint<2> m_sig; // 2 byte file signature basisu::packed_uint<2> m_ver; // Baseline file version basisu::packed_uint<2> m_header_size; // Header size in bytes, sizeof(basis_file_header) - basisu::packed_uint<2> m_header_crc16; // crc16 of the remaining header data + basisu::packed_uint<2> m_header_crc16; // CRC16 of the remaining header data basisu::packed_uint<4> m_data_size; // The total size of all data after the header basisu::packed_uint<2> m_data_crc16; // The CRC16 of all data after the header - basisu::packed_uint<3> m_total_slices; // The total # of compressed slices (1 slice per image, or 2 for alpha basis files) + basisu::packed_uint<3> m_total_slices; // The total # of compressed slices (1 slice per image, or 2 for alpha .basis files) basisu::packed_uint<3> m_total_images; // The total # of images - basisu::packed_uint<1> m_format; // enum basist::block_format + basisu::packed_uint<1> m_tex_format; // enum basis_tex_format basisu::packed_uint<2> m_flags; // enum basist::header_flags basisu::packed_uint<1> m_tex_type; // enum basist::basis_texture_type basisu::packed_uint<3> m_us_per_frame; // Framerate of video, in microseconds per frame @@ -101,11 +122,11 @@ namespace basist basisu::packed_uint<4> m_userdata1; // For client use basisu::packed_uint<2> m_total_endpoints; // The number of endpoints in the endpoint codebook - basisu::packed_uint<4> m_endpoint_cb_file_ofs; // The compressed endpoint codebook's file offset relative to the header + basisu::packed_uint<4> m_endpoint_cb_file_ofs; // The compressed endpoint codebook's file offset relative to the start of the file basisu::packed_uint<3> m_endpoint_cb_file_size; // The compressed endpoint codebook's size in bytes basisu::packed_uint<2> m_total_selectors; // The number of selectors in the endpoint codebook - basisu::packed_uint<4> m_selector_cb_file_ofs; // The compressed selectors codebook's file offset relative to the header + basisu::packed_uint<4> m_selector_cb_file_ofs; // The compressed selectors codebook's file offset relative to the start of the file basisu::packed_uint<3> m_selector_cb_file_size; // The compressed selector codebook's size in bytes basisu::packed_uint<4> m_tables_file_ofs; // The file offset of the compressed Huffman codelength tables, for decompressing slices diff --git a/thirdparty/basis_universal/transcoder/basisu_global_selector_cb.h b/thirdparty/basis_universal/transcoder/basisu_global_selector_cb.h index 695b0b3b97..8ab5098898 100644 --- a/thirdparty/basis_universal/transcoder/basisu_global_selector_cb.h +++ b/thirdparty/basis_universal/transcoder/basisu_global_selector_cb.h @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2020 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/thirdparty/basis_universal/transcoder/basisu_global_selector_palette.h b/thirdparty/basis_universal/transcoder/basisu_global_selector_palette.h index b0260541c3..8bedf94710 100644 --- a/thirdparty/basis_universal/transcoder/basisu_global_selector_palette.h +++ b/thirdparty/basis_universal/transcoder/basisu_global_selector_palette.h @@ -1,5 +1,7 @@ // basisu_global_selector_palette.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. +// +// TODO: NONE of this is used in .basis/.ktx2 files. It will be deleted soon. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -609,7 +611,7 @@ namespace basist uint8_t m_selectors[16]; }; - typedef std::vector<etc1_selector_palette_entry> etc1_selector_palette_entry_vec; + typedef basisu::vector<etc1_selector_palette_entry> etc1_selector_palette_entry_vec; extern const uint32_t g_global_selector_cb[]; extern const uint32_t g_global_selector_cb_size; @@ -628,7 +630,7 @@ namespace basist void set(uint32_t palette_index, const etc1_global_palette_entry_modifier &modifier) { m_palette_index = palette_index; m_modifier = modifier; } }; - typedef std::vector<etc1_global_selector_codebook_entry_id> etc1_global_selector_codebook_entry_id_vec; + typedef basisu::vector<etc1_global_selector_codebook_entry_id> etc1_global_selector_codebook_entry_id_vec; class etc1_global_selector_codebook { diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp index d15b6013d9..29eb3c0d55 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp @@ -1,5 +1,5 @@ // basisu_transcoder.cpp -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,65 +15,88 @@ #include "basisu_transcoder.h" #include <limits.h> -#include <vector> +#include "basisu_containers_impl.h" + +#ifndef BASISD_IS_BIG_ENDIAN +// TODO: This doesn't work on OSX. How can this be so difficult? +//#if defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN) || defined(BIG_ENDIAN) +// #define BASISD_IS_BIG_ENDIAN (1) +//#else + #define BASISD_IS_BIG_ENDIAN (0) +//#endif +#endif + +#ifndef BASISD_USE_UNALIGNED_WORD_READS + #ifdef __EMSCRIPTEN__ + // Can't use unaligned loads/stores with WebAssembly. + #define BASISD_USE_UNALIGNED_WORD_READS (0) + #elif defined(_M_AMD64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__) + #define BASISD_USE_UNALIGNED_WORD_READS (1) + #else + #define BASISD_USE_UNALIGNED_WORD_READS (0) + #endif +#endif -// The supported .basis file header version. Keep in sync with BASIS_FILE_VERSION. #define BASISD_SUPPORTED_BASIS_VERSION (0x13) +#ifndef BASISD_SUPPORT_KTX2 + #error Must have defined BASISD_SUPPORT_KTX2 +#endif + +#ifndef BASISD_SUPPORT_KTX2_ZSTD +#error Must have defined BASISD_SUPPORT_KTX2_ZSTD +#endif + // Set to 1 for fuzz testing. This will disable all CRC16 checks on headers and compressed data. #ifndef BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS -#define BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS 0 + #define BASISU_NO_HEADER_OR_DATA_CRC16_CHECKS 0 #endif #ifndef BASISD_SUPPORT_DXT1 -#define BASISD_SUPPORT_DXT1 1 + #define BASISD_SUPPORT_DXT1 1 #endif #ifndef BASISD_SUPPORT_DXT5A -#define BASISD_SUPPORT_DXT5A 1 + #define BASISD_SUPPORT_DXT5A 1 #endif // Disable all BC7 transcoders if necessary (useful when cross compiling to Javascript) #if defined(BASISD_SUPPORT_BC7) && !BASISD_SUPPORT_BC7 - #ifndef BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - #define BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY 0 - #endif #ifndef BASISD_SUPPORT_BC7_MODE5 - #define BASISD_SUPPORT_BC7_MODE5 0 + #define BASISD_SUPPORT_BC7_MODE5 0 #endif #endif // !BASISD_SUPPORT_BC7 -// BC7 mode 6 opaque only is the highest quality (compared to ETC1), but the tables are massive. -// For web/mobile use you probably should disable this. -#ifndef BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY -#define BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY 1 -#endif - -// BC7 mode 5 supports both opaque and opaque+alpha textures, and uses substantially less memory than BC7 mode 6 and even BC1. +// BC7 mode 5 supports both opaque and opaque+alpha textures, and uses less memory BC1. #ifndef BASISD_SUPPORT_BC7_MODE5 -#define BASISD_SUPPORT_BC7_MODE5 1 + #define BASISD_SUPPORT_BC7_MODE5 1 #endif #ifndef BASISD_SUPPORT_PVRTC1 -#define BASISD_SUPPORT_PVRTC1 1 + #define BASISD_SUPPORT_PVRTC1 1 #endif #ifndef BASISD_SUPPORT_ETC2_EAC_A8 -#define BASISD_SUPPORT_ETC2_EAC_A8 1 + #define BASISD_SUPPORT_ETC2_EAC_A8 1 +#endif + +// Set BASISD_SUPPORT_UASTC to 0 to completely disable support for transcoding UASTC files. +#ifndef BASISD_SUPPORT_UASTC + #define BASISD_SUPPORT_UASTC 1 #endif #ifndef BASISD_SUPPORT_ASTC -#define BASISD_SUPPORT_ASTC 1 + #define BASISD_SUPPORT_ASTC 1 #endif // Note that if BASISD_SUPPORT_ATC is enabled, BASISD_SUPPORT_DXT5A should also be enabled for alpha support. #ifndef BASISD_SUPPORT_ATC -#define BASISD_SUPPORT_ATC 1 + #define BASISD_SUPPORT_ATC 1 #endif // Support for ETC2 EAC R11 and ETC2 EAC RG11 #ifndef BASISD_SUPPORT_ETC2_EAC_RG11 -#define BASISD_SUPPORT_ETC2_EAC_RG11 1 + #define BASISD_SUPPORT_ETC2_EAC_RG11 1 #endif // If BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY is 1, opaque blocks will be transcoded to ASTC at slightly higher quality (higher than BC1), but the transcoder tables will be 2x as large. @@ -89,26 +112,25 @@ #endif #ifndef BASISD_SUPPORT_FXT1 -#define BASISD_SUPPORT_FXT1 1 + #define BASISD_SUPPORT_FXT1 1 #endif #ifndef BASISD_SUPPORT_PVRTC2 -#define BASISD_SUPPORT_PVRTC2 1 + #define BASISD_SUPPORT_PVRTC2 1 #endif #if BASISD_SUPPORT_PVRTC2 -#if !BASISD_SUPPORT_ATC -#error BASISD_SUPPORT_ATC must be 1 if BASISD_SUPPORT_PVRTC2 is 1 -#endif + #if !BASISD_SUPPORT_ATC + #error BASISD_SUPPORT_ATC must be 1 if BASISD_SUPPORT_PVRTC2 is 1 + #endif #endif #if BASISD_SUPPORT_ATC -#if !BASISD_SUPPORT_DXT5A -#error BASISD_SUPPORT_DXT5A must be 1 if BASISD_SUPPORT_ATC is 1 -#endif + #if !BASISD_SUPPORT_DXT5A + #error BASISD_SUPPORT_DXT5A must be 1 if BASISD_SUPPORT_ATC is 1 + #endif #endif -#define BASISD_WRITE_NEW_BC7_TABLES 0 #define BASISD_WRITE_NEW_BC7_MODE5_TABLES 0 #define BASISD_WRITE_NEW_DXT1_TABLES 0 #define BASISD_WRITE_NEW_ETC2_EAC_A8_TABLES 0 @@ -117,7 +139,16 @@ #define BASISD_WRITE_NEW_ETC2_EAC_R11_TABLES 0 #ifndef BASISD_ENABLE_DEBUG_FLAGS -#define BASISD_ENABLE_DEBUG_FLAGS 0 + #define BASISD_ENABLE_DEBUG_FLAGS 0 +#endif + +// If KTX2 support is enabled, we may need Zstd for decompression of supercompressed UASTC files. Include this header. +#if BASISD_SUPPORT_KTX2 + // If BASISD_SUPPORT_KTX2_ZSTD is 0, UASTC files compressed with Zstd cannot be loaded. + #if BASISD_SUPPORT_KTX2_ZSTD + // We only use two Zstd API's: ZSTD_decompress() and ZSTD_isError() + #include "../zstd/zstd.h" + #endif #endif namespace basisu @@ -131,7 +162,7 @@ namespace basisu void debug_printf(const char* pFmt, ...) { -#if BASISU_DEVEL_MESSAGES +#if BASISU_FORCE_DEVEL_MESSAGES g_debug_printf = true; #endif if (g_debug_printf) @@ -146,9 +177,6 @@ namespace basisu namespace basist { -#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY -#include "basisu_transcoder_tables_bc7_m6.inc" -#endif #if BASISD_ENABLE_DEBUG_FLAGS static uint32_t g_debug_flags = 0; @@ -165,16 +193,28 @@ namespace basist void set_debug_flags(uint32_t f) { - (void)f; + BASISU_NOTE_UNUSED(f); #if BASISD_ENABLE_DEBUG_FLAGS g_debug_flags = f; #endif } + + inline uint16_t byteswap_uint16(uint16_t v) + { + return static_cast<uint16_t>((v >> 8) | (v << 8)); + } + + static inline int32_t clampi(int32_t value, int32_t low, int32_t high) { if (value < low) value = low; else if (value > high) value = high; return value; } + static inline float clampf(float value, float low, float high) { if (value < low) value = low; else if (value > high) value = high; return value; } + static inline float saturate(float value) { return clampf(value, 0, 1.0f); } + + static inline uint8_t mul_8(uint32_t v, uint32_t q) { v = v * q + 128; return (uint8_t)((v + (v >> 8)) >> 8); } + uint16_t crc16(const void* r, size_t size, uint16_t crc) { crc = ~crc; - const uint8_t* p = reinterpret_cast<const uint8_t*>(r); + const uint8_t* p = static_cast<const uint8_t*>(r); for (; size; --size) { const uint16_t q = *p++ ^ (crc >> 8); @@ -279,6 +319,9 @@ namespace basist DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables, 1); DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables16, 16); DECLARE_ETC1_INTEN_TABLE(g_etc1_inten_tables48, 3 * 16); + + //const uint8_t g_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 }; + const uint8_t g_selector_index_to_etc1[cETC1SelectorValues] = { 3, 2, 0, 1 }; static const uint8_t g_etc_5_to_8[32] = { 0, 8, 16, 24, 33, 41, 49, 57, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 198, 206, 214, 222, 231, 239, 247, 255 }; @@ -522,11 +565,39 @@ namespace basist return static_cast<uint16_t>(b | (g << 5U) | (r << 10U)); } + inline uint16_t get_base4_color(uint32_t idx) const + { + uint32_t r, g, b; + if (idx) + { + r = get_byte_bits(cETC1AbsColor4R2BitOffset, 4); + g = get_byte_bits(cETC1AbsColor4G2BitOffset, 4); + b = get_byte_bits(cETC1AbsColor4B2BitOffset, 4); + } + else + { + r = get_byte_bits(cETC1AbsColor4R1BitOffset, 4); + g = get_byte_bits(cETC1AbsColor4G1BitOffset, 4); + b = get_byte_bits(cETC1AbsColor4B1BitOffset, 4); + } + return static_cast<uint16_t>(b | (g << 4U) | (r << 8U)); + } + inline color32 get_base5_color_unscaled() const { return color32(m_differential.m_red1, m_differential.m_green1, m_differential.m_blue1, 255); } + inline bool get_flip_bit() const + { + return (m_bytes[3] & 1) != 0; + } + + inline bool get_diff_bit() const + { + return (m_bytes[3] & 2) != 0; + } + inline uint32_t get_inten_table(uint32_t subblock_id) const { assert(subblock_id < 2); @@ -534,6 +605,38 @@ namespace basist return (m_bytes[3] >> ofs) & 7; } + inline uint16_t get_delta3_color() const + { + const uint32_t r = get_byte_bits(cETC1DeltaColor3RBitOffset, 3); + const uint32_t g = get_byte_bits(cETC1DeltaColor3GBitOffset, 3); + const uint32_t b = get_byte_bits(cETC1DeltaColor3BBitOffset, 3); + return static_cast<uint16_t>(b | (g << 3U) | (r << 6U)); + } + + void get_block_colors(color32* pBlock_colors, uint32_t subblock_index) const + { + color32 b; + + if (get_diff_bit()) + { + if (subblock_index) + unpack_color5(b, get_base5_color(), get_delta3_color(), true, 255); + else + unpack_color5(b, get_base5_color(), true); + } + else + { + b = unpack_color4(get_base4_color(subblock_index), true, 255); + } + + const int* pInten_table = g_etc1_inten_tables[get_inten_table(subblock_index)]; + + pBlock_colors[0].set_noclamp_rgba(clamp255(b.r + pInten_table[0]), clamp255(b.g + pInten_table[0]), clamp255(b.b + pInten_table[0]), 255); + pBlock_colors[1].set_noclamp_rgba(clamp255(b.r + pInten_table[1]), clamp255(b.g + pInten_table[1]), clamp255(b.b + pInten_table[1]), 255); + pBlock_colors[2].set_noclamp_rgba(clamp255(b.r + pInten_table[2]), clamp255(b.g + pInten_table[2]), clamp255(b.b + pInten_table[2]), 255); + pBlock_colors[3].set_noclamp_rgba(clamp255(b.r + pInten_table[3]), clamp255(b.g + pInten_table[3]), clamp255(b.b + pInten_table[3]), 255); + } + static uint16_t pack_color4(const color32& color, bool scaled, uint32_t bias = 127U) { return pack_color4(color.r, color.g, color.b, scaled, bias); @@ -592,7 +695,17 @@ namespace basist return static_cast<uint16_t>(b | (g << 3) | (r << 6)); } - static color32 unpack_color5(uint16_t packed_color5, bool scaled, uint32_t alpha = 255) + static void unpack_delta3(int& r, int& g, int& b, uint16_t packed_delta3) + { + r = (packed_delta3 >> 6) & 7; + g = (packed_delta3 >> 3) & 7; + b = packed_delta3 & 7; + if (r >= 4) r -= 8; + if (g >= 4) g -= 8; + if (b >= 4) b -= 8; + } + + static color32 unpack_color5(uint16_t packed_color5, bool scaled, uint32_t alpha) { uint32_t b = packed_color5 & 31U; uint32_t g = (packed_color5 >> 5U) & 31U; @@ -605,7 +718,9 @@ namespace basist r = (r << 3U) | (r >> 2U); } - return color32(r, g, b, alpha); + assert(alpha <= 255); + + return color32(cNoClamp, r, g, b, alpha); } static void unpack_color5(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color5, bool scaled) @@ -615,6 +730,64 @@ namespace basist g = c.g; b = c.b; } + + static void unpack_color5(color32& result, uint16_t packed_color5, bool scaled) + { + result = unpack_color5(packed_color5, scaled, 255); + } + + static bool unpack_color5(color32& result, uint16_t packed_color5, uint16_t packed_delta3, bool scaled, uint32_t alpha) + { + int dr, dg, db; + unpack_delta3(dr, dg, db, packed_delta3); + + int r = ((packed_color5 >> 10U) & 31U) + dr; + int g = ((packed_color5 >> 5U) & 31U) + dg; + int b = (packed_color5 & 31U) + db; + + bool success = true; + if (static_cast<uint32_t>(r | g | b) > 31U) + { + success = false; + r = basisu::clamp<int>(r, 0, 31); + g = basisu::clamp<int>(g, 0, 31); + b = basisu::clamp<int>(b, 0, 31); + } + + if (scaled) + { + b = (b << 3U) | (b >> 2U); + g = (g << 3U) | (g >> 2U); + r = (r << 3U) | (r >> 2U); + } + + result.set_noclamp_rgba(r, g, b, basisu::minimum(alpha, 255U)); + return success; + } + + static color32 unpack_color4(uint16_t packed_color4, bool scaled, uint32_t alpha) + { + uint32_t b = packed_color4 & 15U; + uint32_t g = (packed_color4 >> 4U) & 15U; + uint32_t r = (packed_color4 >> 8U) & 15U; + + if (scaled) + { + b = (b << 4U) | b; + g = (g << 4U) | g; + r = (r << 4U) | r; + } + + return color32(cNoClamp, r, g, b, basisu::minimum(alpha, 255U)); + } + + static void unpack_color4(uint32_t& r, uint32_t& g, uint32_t& b, uint16_t packed_color4, bool scaled) + { + color32 c(unpack_color4(packed_color4, scaled, 0)); + r = c.r; + g = c.g; + b = c.b; + } static void get_diff_subblock_colors(color32* pDst, uint16_t packed_color5, uint32_t table_idx) { @@ -823,197 +996,6 @@ namespace basist uint32_t m_high; }; -#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - static dxt_selector_range g_etc1_to_bc7_selector_ranges[] = - { - { 0, 0 }, - { 1, 1 }, - { 2, 2 }, - { 3, 3 }, - - { 0, 3 }, - - { 1, 3 }, - { 0, 2 }, - - { 1, 2 }, - - { 2, 3 }, - { 0, 1 }, - }; - const uint32_t NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES = sizeof(g_etc1_to_bc7_selector_ranges) / sizeof(g_etc1_to_bc7_selector_ranges[0]); - - static uint32_t g_etc1_to_bc7_m6_selector_range_index[4][4]; - - static const uint8_t g_etc1_to_bc7_selector_mappings[][4] = - { -#if 1 - { 5 * 0, 5 * 0, 5 * 0, 5 * 0 }, - { 5 * 0, 5 * 0, 5 * 0, 5 * 1 }, - { 5 * 0, 5 * 0, 5 * 0, 5 * 2 }, - { 5 * 0, 5 * 0, 5 * 0, 5 * 3 }, - { 5 * 0, 5 * 0, 5 * 1, 5 * 1 }, - { 5 * 0, 5 * 0, 5 * 1, 5 * 2 }, - { 5 * 0, 5 * 0, 5 * 1, 5 * 3 }, - { 5 * 0, 5 * 0, 5 * 2, 5 * 2 }, - { 5 * 0, 5 * 0, 5 * 2, 5 * 3 }, - { 5 * 0, 5 * 0, 5 * 3, 5 * 3 }, - { 5 * 0, 5 * 1, 5 * 1, 5 * 1 }, - { 5 * 0, 5 * 1, 5 * 1, 5 * 2 }, - { 5 * 0, 5 * 1, 5 * 1, 5 * 3 }, - { 5 * 0, 5 * 1, 5 * 2, 5 * 2 }, - { 5 * 0, 5 * 1, 5 * 2, 5 * 3 }, - { 5 * 0, 5 * 1, 5 * 3, 5 * 3 }, - { 5 * 0, 5 * 2, 5 * 2, 5 * 2 }, - { 5 * 0, 5 * 2, 5 * 2, 5 * 3 }, - { 5 * 0, 5 * 2, 5 * 3, 5 * 3 }, - { 5 * 0, 5 * 3, 5 * 3, 5 * 3 }, - { 5 * 1, 5 * 1, 5 * 1, 5 * 1 }, - { 5 * 1, 5 * 1, 5 * 1, 5 * 2 }, - { 5 * 1, 5 * 1, 5 * 1, 5 * 3 }, - { 5 * 1, 5 * 1, 5 * 2, 5 * 2 }, - { 5 * 1, 5 * 1, 5 * 2, 5 * 3 }, - { 5 * 1, 5 * 1, 5 * 3, 5 * 3 }, - { 5 * 1, 5 * 2, 5 * 2, 5 * 2 }, - { 5 * 1, 5 * 2, 5 * 2, 5 * 3 }, - { 5 * 1, 5 * 2, 5 * 3, 5 * 3 }, - { 5 * 1, 5 * 3, 5 * 3, 5 * 3 }, - { 5 * 2, 5 * 2, 5 * 2, 5 * 2 }, - { 5 * 2, 5 * 2, 5 * 2, 5 * 3 }, - { 5 * 2, 5 * 2, 5 * 3, 5 * 3 }, - { 5 * 2, 5 * 3, 5 * 3, 5 * 3 }, - { 5 * 3, 5 * 3, 5 * 3, 5 * 3 }, - - { 0, 1, 2, 3 }, - { 0, 0, 1, 1 }, - { 0, 0, 0, 1 }, - { 0, 2, 4, 6 }, - { 0, 3, 6, 9 }, - { 0, 4, 8, 12 }, - - { 0, 4, 9, 15 }, - { 0, 6, 11, 15 }, - - { 1, 2, 3, 4 }, - { 1, 3, 5, 7 }, - - { 1, 8, 8, 14 }, -#else - { 5 * 0, 5 * 0, 5 * 1, 5 * 1 }, - { 5 * 0, 5 * 0, 5 * 1, 5 * 2 }, - { 5 * 0, 5 * 0, 5 * 1, 5 * 3 }, - { 5 * 0, 5 * 0, 5 * 2, 5 * 3 }, - { 5 * 0, 5 * 1, 5 * 1, 5 * 1 }, - { 5 * 0, 5 * 1, 5 * 2, 5 * 2 }, - { 5 * 0, 5 * 1, 5 * 2, 5 * 3 }, - { 5 * 0, 5 * 2, 5 * 3, 5 * 3 }, - { 5 * 1, 5 * 2, 5 * 2, 5 * 2 }, -#endif - { 5 * 1, 5 * 2, 5 * 3, 5 * 3 }, - { 8, 8, 8, 8 }, - }; - const uint32_t NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS = sizeof(g_etc1_to_bc7_selector_mappings) / sizeof(g_etc1_to_bc7_selector_mappings[0]); - - static uint8_t g_etc1_to_bc7_selector_mappings_inv[NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS][4]; - - // encoding from LSB to MSB: low8, high8, error16, size is [32*8][NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES][NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS] - extern const uint32_t* g_etc1_to_bc7_m6_table[]; - - const uint16_t s_bptc_table_aWeight4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; - -#if BASISD_WRITE_NEW_BC7_TABLES - static void create_etc1_to_bc7_m6_conversion_table() - { - FILE* pFile = NULL; - - pFile = fopen("basisu_decoder_tables_bc7_m6.inc", "w"); - - for (int inten = 0; inten < 8; inten++) - { - for (uint32_t g = 0; g < 32; g++) - { - color32 block_colors[4]; - decoder_etc_block::get_diff_subblock_colors(block_colors, decoder_etc_block::pack_color5(color32(g, g, g, 255), false), inten); - - fprintf(pFile, "static const uint32_t g_etc1_to_bc7_m6_table%u[] = {\n", g + inten * 32); - uint32_t n = 0; - - for (uint32_t sr = 0; sr < NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES; sr++) - { - const uint32_t low_selector = g_etc1_to_bc7_selector_ranges[sr].m_low; - const uint32_t high_selector = g_etc1_to_bc7_selector_ranges[sr].m_high; - - for (uint32_t m = 0; m < NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS; m++) - { - uint32_t best_lo = 0; - uint32_t best_hi = 0; - uint64_t best_err = UINT64_MAX; - - for (uint32_t hi = 0; hi <= 127; hi++) - { - for (uint32_t lo = 0; lo <= 127; lo++) - { - uint32_t bc7_block_colors[16]; - - bc7_block_colors[0] = lo << 1; - bc7_block_colors[15] = (hi << 1) | 1; - - for (uint32_t i = 1; i < 15; i++) - bc7_block_colors[i] = (bc7_block_colors[0] * (64 - s_bptc_table_aWeight4[i]) + bc7_block_colors[15] * s_bptc_table_aWeight4[i] + 32) >> 6; - - uint64_t total_err = 0; - - for (uint32_t s = low_selector; s <= high_selector; s++) - { - int err = (int)block_colors[s].g - (int)bc7_block_colors[g_etc1_to_bc7_selector_mappings[m][s]]; - - total_err += err * err; - } - - if (total_err < best_err) - { - best_err = total_err; - best_lo = lo; - best_hi = hi; - } - } // lo - - } // hi - - best_err = basisu::minimum<uint32_t>(best_err, 0xFFFF); - - const uint32_t index = (g + inten * 32) * (NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS) + (sr * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS) + m; - - uint32_t v = best_err | (best_lo << 18) | (best_hi << 25); - - fprintf(pFile, "0x%X,", v); - n++; - if ((n & 31) == 31) - fprintf(pFile, "\n"); - - } // m - } // sr - - fprintf(pFile, "};\n"); - - } // g - } // inten - - fprintf(pFile, "const uint32_t *g_etc1_to_bc7_m6_table[] = {\n"); - - for (uint32_t i = 0; i < 32 * 8; i++) - { - fprintf(pFile, "g_etc1_to_bc7_m6_table%u, ", i); - if ((i & 15) == 15) - fprintf(pFile, "\n"); - } - - fprintf(pFile, "};\n"); - fclose(pFile); - } -#endif -#endif - struct etc1_to_dxt1_56_solution { uint8_t m_lo; @@ -1064,7 +1046,9 @@ namespace basist static const etc1_to_dxt1_56_solution g_etc1_to_dxt_5[32 * 8 * NUM_ETC1_TO_DXT1_SELECTOR_MAPPINGS * NUM_ETC1_TO_DXT1_SELECTOR_RANGES] = { #include "basisu_transcoder_tables_dxt1_5.inc" }; +#endif // BASISD_SUPPORT_DXT1 +#if BASISD_SUPPORT_DXT1 || BASISD_SUPPORT_UASTC // First saw the idea for optimal BC1 single-color block encoding using lookup tables in ryg_dxt. struct bc1_match_entry { @@ -1089,14 +1073,15 @@ namespace basist if (sel == 1) { // Selector 1 - e = abs(((hi_e * 2 + lo_e) / 3) - i) + ((abs(hi_e - lo_e) >> 5)); + e = basisu::iabs(((hi_e * 2 + lo_e) / 3) - i); + e += (basisu::iabs(hi_e - lo_e) * 3) / 100; } else { assert(sel == 0); // Selector 0 - e = abs(hi_e - i); + e = basisu::iabs(hi_e - i); } if (e < lowest_e) @@ -1111,7 +1096,7 @@ namespace basist } // lo } } -#endif // BASISD_SUPPORT_DXT1 +#endif #if BASISD_WRITE_NEW_DXT1_TABLES static void create_etc1_to_dxt1_5_conversion_table() @@ -1268,7 +1253,8 @@ namespace basist } #endif -#if BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11 + +#if BASISD_SUPPORT_UASTC || BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11 static const int8_t g_eac_modifier_table[16][8] = { { -3, -6, -9, -15, 2, 5, 8, 14 }, @@ -1344,6 +1330,9 @@ namespace basist } }; +#endif // #if BASISD_SUPPORT_UASTC BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11 + +#if BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_ETC2_EAC_RG11 static const dxt_selector_range s_etc2_eac_selector_ranges[] = { { 0, 3 }, @@ -1372,8 +1361,8 @@ namespace basist uint32_t m_base; uint32_t m_table; uint32_t m_multiplier; - std::vector<uint8_t> m_selectors; - std::vector<uint8_t> m_selectors_temp; + basisu::vector<uint8_t> m_selectors; + basisu::vector<uint8_t> m_selectors_temp; }; static uint64_t pack_eac_a8_exhaustive(pack_eac_a8_results& results, const uint8_t* pPixels, uint32_t num_pixels) @@ -1769,8 +1758,8 @@ namespace basist uint32_t m_base; uint32_t m_table; uint32_t m_multiplier; - std::vector<uint8_t> m_selectors; - std::vector<uint8_t> m_selectors_temp; + basisu::vector<uint8_t> m_selectors; + basisu::vector<uint8_t> m_selectors_temp; }; static uint64_t pack_eac_r11_exhaustive(pack_eac_r11_results& results, const uint8_t* pPixels, uint32_t num_pixels) @@ -1924,14 +1913,28 @@ namespace basist #if BASISD_SUPPORT_PVRTC2 static void transcoder_init_pvrtc2(); #endif + +#if BASISD_SUPPORT_UASTC + void uastc_init(); +#endif + + static bool g_transcoder_initialized; // Library global initialization. Requires ~9 milliseconds when compiled and executed natively on a Core i7 2.2 GHz. // If this is too slow, these computed tables can easilky be moved to be compiled in. void basisu_transcoder_init() { - static bool s_initialized; - if (s_initialized) + if (g_transcoder_initialized) + { + BASISU_DEVEL_ERROR("basisu_transcoder::basisu_transcoder_init: Called more than once\n"); return; + } + + BASISU_DEVEL_ERROR("basisu_transcoder::basisu_transcoder_init: Initializing (this is not an error)\n"); + +#if BASISD_SUPPORT_UASTC + uastc_init(); +#endif #if BASISD_SUPPORT_ASTC transcoder_init_astc(); @@ -1943,11 +1946,6 @@ namespace basist exit(0); #endif -#if BASISD_WRITE_NEW_BC7_TABLES - create_etc1_to_bc7_m6_conversion_table(); - exit(0); -#endif - #if BASISD_WRITE_NEW_BC7_MODE5_TABLES create_etc1_to_bc7_m5_color_conversion_table(); create_etc1_to_bc7_m5_alpha_conversion_table(); @@ -1975,7 +1973,7 @@ namespace basist exit(0); #endif -#if BASISD_SUPPORT_DXT1 +#if BASISD_SUPPORT_DXT1 || BASISD_SUPPORT_UASTC uint8_t bc1_expand5[32]; for (int i = 0; i < 32; i++) bc1_expand5[i] = static_cast<uint8_t>((i << 3) | (i >> 2)); @@ -1988,6 +1986,17 @@ namespace basist prepare_bc1_single_color_table(g_bc1_match6_equals_1, bc1_expand6, 64, 64, 1); prepare_bc1_single_color_table(g_bc1_match6_equals_0, bc1_expand6, 1, 64, 0); +#if 0 + for (uint32_t i = 0; i < 256; i++) + { + printf("%u %u %u\n", i, (i * 63 + 127) / 255, g_bc1_match6_equals_0[i].m_hi); + } + exit(0); +#endif + +#endif + +#if BASISD_SUPPORT_DXT1 for (uint32_t i = 0; i < NUM_ETC1_TO_DXT1_SELECTOR_RANGES; i++) { uint32_t l = g_etc1_to_dxt1_selector_ranges[i].m_low; @@ -2023,19 +2032,6 @@ namespace basist } #endif -#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - for (uint32_t i = 0; i < NUM_ETC1_TO_BC7_M6_SELECTOR_RANGES; i++) - { - uint32_t l = g_etc1_to_bc7_selector_ranges[i].m_low; - uint32_t h = g_etc1_to_bc7_selector_ranges[i].m_high; - g_etc1_to_bc7_m6_selector_range_index[l][h] = i; - } - - for (uint32_t sm = 0; sm < NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS; sm++) - for (uint32_t j = 0; j < 4; j++) - g_etc1_to_bc7_selector_mappings_inv[sm][j] = 15 - g_etc1_to_bc7_selector_mappings[sm][j]; -#endif - #if BASISD_SUPPORT_BC7_MODE5 transcoder_init_bc7_mode5(); #endif @@ -2048,7 +2044,7 @@ namespace basist transcoder_init_pvrtc2(); #endif - s_initialized = true; + g_transcoder_initialized = true; } #if BASISD_SUPPORT_DXT1 @@ -2780,7 +2776,7 @@ namespace basist // PVRTC -#if BASISD_SUPPORT_PVRTC1 +#if BASISD_SUPPORT_PVRTC1 || BASISD_SUPPORT_UASTC static const uint16_t g_pvrtc_swizzle_table[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, @@ -3304,6 +3300,7 @@ namespace basist } }; +#if 0 static const uint8_t g_pvrtc_bilinear_weights[16][4] = { { 4, 4, 4, 4 }, { 2, 6, 2, 6 }, { 8, 0, 8, 0 }, { 6, 2, 6, 2 }, @@ -3311,6 +3308,7 @@ namespace basist { 8, 8, 0, 0 }, { 4, 12, 0, 0 }, { 16, 0, 0, 0 }, { 12, 4, 0, 0 }, { 6, 6, 2, 2 }, { 3, 9, 1, 3 }, { 12, 0, 4, 0 }, { 9, 3, 3, 1 }, }; +#endif struct pvrtc1_temp_block { @@ -3402,7 +3400,9 @@ namespace basist color32 c(get_endpoint_8888(endpoints, endpoint_index)); return c.r + c.g + c.b + c.a; } +#endif +#if BASISD_SUPPORT_PVRTC1 // TODO: Support decoding a non-pow2 ETC1S texture into the next larger pow2 PVRTC texture. static void fixup_pvrtc1_4_modulation_rgb(const decoder_etc_block* pETC_Blocks, const uint32_t* pPVRTC_endpoints, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y) { @@ -3411,7 +3411,7 @@ namespace basist const uint32_t x_bits = basisu::total_bits(x_mask); const uint32_t y_bits = basisu::total_bits(y_mask); const uint32_t min_bits = basisu::minimum(x_bits, y_bits); - const uint32_t max_bits = basisu::maximum(x_bits, y_bits); + //const uint32_t max_bits = basisu::maximum(x_bits, y_bits); const uint32_t swizzle_mask = (1 << (min_bits * 2)) - 1; uint32_t block_index = 0; @@ -3592,7 +3592,7 @@ namespace basist const uint32_t x_bits = basisu::total_bits(x_mask); const uint32_t y_bits = basisu::total_bits(y_mask); const uint32_t min_bits = basisu::minimum(x_bits, y_bits); - const uint32_t max_bits = basisu::maximum(x_bits, y_bits); + //const uint32_t max_bits = basisu::maximum(x_bits, y_bits); const uint32_t swizzle_mask = (1 << (min_bits * 2)) - 1; uint32_t block_index = 0; @@ -3763,257 +3763,6 @@ namespace basist } #endif // BASISD_SUPPORT_PVRTC1 -#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - struct bc7_mode_6 - { - struct - { - uint64_t m_mode : 7; - uint64_t m_r0 : 7; - uint64_t m_r1 : 7; - uint64_t m_g0 : 7; - uint64_t m_g1 : 7; - uint64_t m_b0 : 7; - uint64_t m_b1 : 7; - uint64_t m_a0 : 7; - uint64_t m_a1 : 7; - uint64_t m_p0 : 1; - } m_lo; - - union - { - struct - { - uint64_t m_p1 : 1; - uint64_t m_s00 : 3; - uint64_t m_s10 : 4; - uint64_t m_s20 : 4; - uint64_t m_s30 : 4; - - uint64_t m_s01 : 4; - uint64_t m_s11 : 4; - uint64_t m_s21 : 4; - uint64_t m_s31 : 4; - - uint64_t m_s02 : 4; - uint64_t m_s12 : 4; - uint64_t m_s22 : 4; - uint64_t m_s32 : 4; - - uint64_t m_s03 : 4; - uint64_t m_s13 : 4; - uint64_t m_s23 : 4; - uint64_t m_s33 : 4; - - } m_hi; - - uint64_t m_hi_bits; - }; - }; - - static void convert_etc1s_to_bc7_m6(bc7_mode_6* pDst_block, const endpoint *pEndpoint, const selector* pSelector) - { -#if !BASISD_WRITE_NEW_BC7_TABLES - const uint32_t low_selector = pSelector->m_lo_selector; - const uint32_t high_selector = pSelector->m_hi_selector; - - const uint32_t base_color_r = pEndpoint->m_color5.r; - const uint32_t base_color_g = pEndpoint->m_color5.g; - const uint32_t base_color_b = pEndpoint->m_color5.b; - const uint32_t inten_table = pEndpoint->m_inten5; - - if (pSelector->m_num_unique_selectors <= 2) - { - // Only two unique selectors so just switch to block truncation coding (BTC) to avoid quality issues on extreme blocks. - pDst_block->m_lo.m_mode = 64; - - pDst_block->m_lo.m_a0 = 127; - pDst_block->m_lo.m_a1 = 127; - - color32 block_colors[4]; - - decoder_etc_block::get_block_colors5(block_colors, color32(base_color_r, base_color_g, base_color_b, 255), inten_table); - - const uint32_t r0 = block_colors[low_selector].r; - const uint32_t g0 = block_colors[low_selector].g; - const uint32_t b0 = block_colors[low_selector].b; - const uint32_t low_bits0 = (r0 & 1) + (g0 & 1) + (b0 & 1); - uint32_t p0 = low_bits0 >= 2; - - const uint32_t r1 = block_colors[high_selector].r; - const uint32_t g1 = block_colors[high_selector].g; - const uint32_t b1 = block_colors[high_selector].b; - const uint32_t low_bits1 = (r1 & 1) + (g1 & 1) + (b1 & 1); - uint32_t p1 = low_bits1 >= 2; - - pDst_block->m_lo.m_r0 = r0 >> 1; - pDst_block->m_lo.m_g0 = g0 >> 1; - pDst_block->m_lo.m_b0 = b0 >> 1; - pDst_block->m_lo.m_p0 = p0; - - pDst_block->m_lo.m_r1 = r1 >> 1; - pDst_block->m_lo.m_g1 = g1 >> 1; - pDst_block->m_lo.m_b1 = b1 >> 1; - - uint32_t output_low_selector = 0; - uint32_t output_bit_offset = 1; - uint64_t output_hi_bits = p1; - - for (uint32_t y = 0; y < 4; y++) - { - for (uint32_t x = 0; x < 4; x++) - { - uint32_t s = pSelector->get_selector(x, y); - uint32_t os = (s == low_selector) ? output_low_selector : (15 ^ output_low_selector); - - uint32_t num_bits = 4; - - if ((x | y) == 0) - { - if (os & 8) - { - pDst_block->m_lo.m_r0 = r1 >> 1; - pDst_block->m_lo.m_g0 = g1 >> 1; - pDst_block->m_lo.m_b0 = b1 >> 1; - pDst_block->m_lo.m_p0 = p1; - - pDst_block->m_lo.m_r1 = r0 >> 1; - pDst_block->m_lo.m_g1 = g0 >> 1; - pDst_block->m_lo.m_b1 = b0 >> 1; - - output_hi_bits &= ~1ULL; - output_hi_bits |= p0; - std::swap(p0, p1); - - output_low_selector = 15; - os = 0; - } - - num_bits = 3; - } - - output_hi_bits |= (static_cast<uint64_t>(os) << output_bit_offset); - output_bit_offset += num_bits; - } - } - - pDst_block->m_hi_bits = output_hi_bits; - - assert(pDst_block->m_hi.m_p1 == p1); - - return; - } - - uint32_t selector_range_table = g_etc1_to_bc7_m6_selector_range_index[low_selector][high_selector]; - - const uint32_t* pTable_r = g_etc1_to_bc7_m6_table[base_color_r + inten_table * 32] + (selector_range_table * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS); - const uint32_t* pTable_g = g_etc1_to_bc7_m6_table[base_color_g + inten_table * 32] + (selector_range_table * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS); - const uint32_t* pTable_b = g_etc1_to_bc7_m6_table[base_color_b + inten_table * 32] + (selector_range_table * NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS); - -#if 1 - assert(NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS == 48); - - uint32_t best_err0 = UINT_MAX, best_err1 = UINT_MAX; - -#define DO_ITER2(idx) \ - { \ - uint32_t v0 = ((pTable_r[(idx)+0] + pTable_g[(idx)+0] + pTable_b[(idx)+0]) << 14) | ((idx) + 0); if (v0 < best_err0) best_err0 = v0; \ - uint32_t v1 = ((pTable_r[(idx)+1] + pTable_g[(idx)+1] + pTable_b[(idx)+1]) << 14) | ((idx) + 1); if (v1 < best_err1) best_err1 = v1; \ - } -#define DO_ITER4(idx) DO_ITER2(idx); DO_ITER2((idx) + 2); -#define DO_ITER8(idx) DO_ITER4(idx); DO_ITER4((idx) + 4); -#define DO_ITER16(idx) DO_ITER8(idx); DO_ITER8((idx) + 8); - - DO_ITER16(0); - DO_ITER16(16); - DO_ITER16(32); -#undef DO_ITER2 -#undef DO_ITER4 -#undef DO_ITER8 -#undef DO_ITER16 - - uint32_t best_err = basisu::minimum(best_err0, best_err1); - uint32_t best_mapping = best_err & 0xFF; - //best_err >>= 14; -#else - uint32_t best_err = UINT_MAX; - uint32_t best_mapping = 0; - assert((NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS % 2) == 0); - for (uint32_t m = 0; m < NUM_ETC1_TO_BC7_M6_SELECTOR_MAPPINGS; m += 2) - { -#define DO_ITER(idx) { uint32_t total_err = (pTable_r[idx] + pTable_g[idx] + pTable_b[idx]) & 0x3FFFF; if (total_err < best_err) { best_err = total_err; best_mapping = idx; } } - DO_ITER(m); - DO_ITER(m + 1); -#undef DO_ITER - } -#endif - - pDst_block->m_lo.m_mode = 64; - - pDst_block->m_lo.m_a0 = 127; - pDst_block->m_lo.m_a1 = 127; - - uint64_t v = 0; - const uint8_t* pSelectors_xlat; - - if (g_etc1_to_bc7_selector_mappings[best_mapping][pSelector->get_selector(0, 0)] & 8) - { - pDst_block->m_lo.m_r1 = (pTable_r[best_mapping] >> 18) & 0x7F; - pDst_block->m_lo.m_g1 = (pTable_g[best_mapping] >> 18) & 0x7F; - pDst_block->m_lo.m_b1 = (pTable_b[best_mapping] >> 18) & 0x7F; - - pDst_block->m_lo.m_r0 = (pTable_r[best_mapping] >> 25) & 0x7F; - pDst_block->m_lo.m_g0 = (pTable_g[best_mapping] >> 25) & 0x7F; - pDst_block->m_lo.m_b0 = (pTable_b[best_mapping] >> 25) & 0x7F; - - pDst_block->m_lo.m_p0 = 1; - pDst_block->m_hi.m_p1 = 0; - - v = 0; - pSelectors_xlat = &g_etc1_to_bc7_selector_mappings_inv[best_mapping][0]; - } - else - { - pDst_block->m_lo.m_r0 = (pTable_r[best_mapping] >> 18) & 0x7F; - pDst_block->m_lo.m_g0 = (pTable_g[best_mapping] >> 18) & 0x7F; - pDst_block->m_lo.m_b0 = (pTable_b[best_mapping] >> 18) & 0x7F; - - pDst_block->m_lo.m_r1 = (pTable_r[best_mapping] >> 25) & 0x7F; - pDst_block->m_lo.m_g1 = (pTable_g[best_mapping] >> 25) & 0x7F; - pDst_block->m_lo.m_b1 = (pTable_b[best_mapping] >> 25) & 0x7F; - - pDst_block->m_lo.m_p0 = 0; - pDst_block->m_hi.m_p1 = 1; - - v = 1; - pSelectors_xlat = &g_etc1_to_bc7_selector_mappings[best_mapping][0]; - } - - uint64_t v1 = 0, v2 = 0, v3 = 0; - -#define DO_X(x, s0, s1, s2, s3) { \ - v |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[0] >> ((x) * 2)) & 3] << (s0)); \ - v1 |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[1] >> ((x) * 2)) & 3] << (s1)); \ - v2 |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[2] >> ((x) * 2)) & 3] << (s2)); \ - v3 |= ((uint64_t)pSelectors_xlat[(pSelector->m_selectors[3] >> ((x) * 2)) & 3] << (s3)); } - - // 1 4 8 12 - // 16 20 24 28 - // 32 36 40 44 - // 48 52 56 60 - - DO_X(0, 1, 16, 32, 48); - DO_X(1, 4, 20, 36, 52); - DO_X(2, 8, 24, 40, 56); - DO_X(3, 12, 28, 44, 60); -#undef DO_X - - pDst_block->m_hi_bits = v | v1 | v2 | v3; -#endif - - } -#endif // BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - #if BASISD_SUPPORT_BC7_MODE5 static dxt_selector_range g_etc1_to_bc7_m5_selector_ranges[] = { @@ -4085,7 +3834,7 @@ namespace basist assert(num_bits < 32); assert(val < (1ULL << num_bits)); - uint32_t mask = (1 << num_bits) - 1; + uint32_t mask = static_cast<uint32_t>((1ULL << num_bits) - 1); while (num_bits) { @@ -4425,9 +4174,11 @@ namespace basist { bc7_mode_5* pDst_block = static_cast<bc7_mode_5*>(pDst); + // First ensure the block is cleared to all 0's static_cast<uint64_t*>(pDst)[0] = 0; static_cast<uint64_t*>(pDst)[1] = 0; + // Set alpha to 255 pDst_block->m_lo.m_mode = 1 << 5; pDst_block->m_lo.m_a0 = 255; pDst_block->m_lo.m_a1_0 = 63; @@ -4690,7 +4441,11 @@ namespace basist set_block_bits((uint8_t*)pDst, output_bits, 31, 97); } #endif // BASISD_SUPPORT_BC7_MODE5 - + +#if BASISD_SUPPORT_ETC2_EAC_A8 || BASISD_SUPPORT_UASTC + static const uint8_t g_etc2_eac_a8_sel4[6] = { 0x92, 0x49, 0x24, 0x92, 0x49, 0x24 }; +#endif + #if BASISD_SUPPORT_ETC2_EAC_A8 static void convert_etc1s_to_etc2_eac_a8(eac_block* pDst_block, const endpoint* pEndpoints, const selector* pSelector) { @@ -4712,8 +4467,7 @@ namespace basist pDst_block->m_multiplier = 1; // selectors are all 4's - static const uint8_t s_etc2_eac_a8_sel4[6] = { 0x92, 0x49, 0x24, 0x92, 0x49, 0x24 }; - memcpy(pDst_block->m_selectors, s_etc2_eac_a8_sel4, sizeof(s_etc2_eac_a8_sel4)); + memcpy(pDst_block->m_selectors, g_etc2_eac_a8_sel4, sizeof(g_etc2_eac_a8_sel4)); return; } @@ -5325,31 +5079,30 @@ namespace basist #endif -#if BASISD_SUPPORT_ASTC - struct astc_block_params - { - // 2 groups of 5, but only a max of 8 are used (RRGGBBAA00) - uint8_t m_endpoints[10]; - uint8_t m_weights[32]; - }; - +#if BASISD_SUPPORT_UASTC || BASISD_SUPPORT_ASTC // Table encodes 5 trits to 8 output bits. 3^5 entries. // Inverse of the trit bit manipulation process in https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-integer-sequence-encoding - static const uint8_t g_astc_trit_encode[243] = { 0, 1, 2, 4, 5, 6, 8, 9, 10, 16, 17, 18, 20, 21, 22, 24, 25, 26, 3, 7, 11, 19, 23, 27, 12, 13, 14, 32, 33, 34, 36, 37, 38, 40, 41, 42, 48, 49, 50, 52, 53, 54, 56, 57, 58, 35, 39, - 43, 51, 55, 59, 44, 45, 46, 64, 65, 66, 68, 69, 70, 72, 73, 74, 80, 81, 82, 84, 85, 86, 88, 89, 90, 67, 71, 75, 83, 87, 91, 76, 77, 78, 128, 129, 130, 132, 133, 134, 136, 137, 138, 144, 145, 146, 148, 149, 150, 152, 153, 154, - 131, 135, 139, 147, 151, 155, 140, 141, 142, 160, 161, 162, 164, 165, 166, 168, 169, 170, 176, 177, 178, 180, 181, 182, 184, 185, 186, 163, 167, 171, 179, 183, 187, 172, 173, 174, 192, 193, 194, 196, 197, 198, 200, 201, 202, - 208, 209, 210, 212, 213, 214, 216, 217, 218, 195, 199, 203, 211, 215, 219, 204, 205, 206, 96, 97, 98, 100, 101, 102, 104, 105, 106, 112, 113, 114, 116, 117, 118, 120, 121, 122, 99, 103, 107, 115, 119, 123, 108, 109, 110, 224, - 225, 226, 228, 229, 230, 232, 233, 234, 240, 241, 242, 244, 245, 246, 248, 249, 250, 227, 231, 235, 243, 247, 251, 236, 237, 238, 28, 29, 30, 60, 61, 62, 92, 93, 94, 156, 157, 158, 188, 189, 190, 220, 221, 222, 31, 63, 95, 159, + static const uint8_t g_astc_trit_encode[243] = { 0, 1, 2, 4, 5, 6, 8, 9, 10, 16, 17, 18, 20, 21, 22, 24, 25, 26, 3, 7, 11, 19, 23, 27, 12, 13, 14, 32, 33, 34, 36, 37, 38, 40, 41, 42, 48, 49, 50, 52, 53, 54, 56, 57, 58, 35, 39, + 43, 51, 55, 59, 44, 45, 46, 64, 65, 66, 68, 69, 70, 72, 73, 74, 80, 81, 82, 84, 85, 86, 88, 89, 90, 67, 71, 75, 83, 87, 91, 76, 77, 78, 128, 129, 130, 132, 133, 134, 136, 137, 138, 144, 145, 146, 148, 149, 150, 152, 153, 154, + 131, 135, 139, 147, 151, 155, 140, 141, 142, 160, 161, 162, 164, 165, 166, 168, 169, 170, 176, 177, 178, 180, 181, 182, 184, 185, 186, 163, 167, 171, 179, 183, 187, 172, 173, 174, 192, 193, 194, 196, 197, 198, 200, 201, 202, + 208, 209, 210, 212, 213, 214, 216, 217, 218, 195, 199, 203, 211, 215, 219, 204, 205, 206, 96, 97, 98, 100, 101, 102, 104, 105, 106, 112, 113, 114, 116, 117, 118, 120, 121, 122, 99, 103, 107, 115, 119, 123, 108, 109, 110, 224, + 225, 226, 228, 229, 230, 232, 233, 234, 240, 241, 242, 244, 245, 246, 248, 249, 250, 227, 231, 235, 243, 247, 251, 236, 237, 238, 28, 29, 30, 60, 61, 62, 92, 93, 94, 156, 157, 158, 188, 189, 190, 220, 221, 222, 31, 63, 95, 159, 191, 223, 124, 125, 126 }; + // Extracts bits [low,high] + static inline uint32_t astc_extract_bits(uint32_t bits, int low, int high) + { + return (bits >> low) & ((1 << (high - low + 1)) - 1); + } + // Writes bits to output in an endian safe way - static inline void astc_set_bits(uint32_t *pOutput, int &bit_pos, uint32_t value, int total_bits) + static inline void astc_set_bits(uint32_t* pOutput, int& bit_pos, uint32_t value, uint32_t total_bits) { uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput); - + while (total_bits) { - const uint32_t bits_to_write = std::min(total_bits, 8 - (bit_pos & 7)); + const uint32_t bits_to_write = basisu::minimum<int>(total_bits, 8 - (bit_pos & 7)); pBytes[bit_pos >> 3] |= static_cast<uint8_t>(value << (bit_pos & 7)); @@ -5359,14 +5112,8 @@ namespace basist } } - // Extracts bits [low,high] - static inline uint32_t astc_extract_bits(uint32_t bits, int low, int high) - { - return (bits >> low) & ((1 << (high - low + 1)) - 1); - } - // Encodes 5 values to output, usable for any range that uses trits and bits - static void astc_encode_trits(uint32_t *pOutput, const uint8_t *pValues, int& bit_pos, int n) + static void astc_encode_trits(uint32_t* pOutput, const uint8_t* pValues, int& bit_pos, int n) { // First extract the trits and the bits from the 5 input values int trits = 0, bits[5]; @@ -5374,9 +5121,9 @@ namespace basist for (int i = 0; i < 5; i++) { static const int s_muls[5] = { 1, 3, 9, 27, 81 }; - + const int t = pValues[i] >> n; - + trits += t * s_muls[i]; bits[i] = pValues[i] & bit_mask; } @@ -5386,14 +5133,23 @@ namespace basist assert(trits < 243); const int T = g_astc_trit_encode[trits]; - + // Now interleave the 8 encoded trit bits with the bits to form the encoded output. See table 94. astc_set_bits(pOutput, bit_pos, bits[0] | (astc_extract_bits(T, 0, 1) << n) | (bits[1] << (2 + n)), n * 2 + 2); - astc_set_bits(pOutput, bit_pos, astc_extract_bits(T, 2, 3) | (bits[2] << 2) | (astc_extract_bits(T, 4, 4) << (2 + n)) | (bits[3] << (3 + n)) | (astc_extract_bits(T, 5, 6) << (3 + n * 2)) | + astc_set_bits(pOutput, bit_pos, astc_extract_bits(T, 2, 3) | (bits[2] << 2) | (astc_extract_bits(T, 4, 4) << (2 + n)) | (bits[3] << (3 + n)) | (astc_extract_bits(T, 5, 6) << (3 + n * 2)) | (bits[4] << (5 + n * 2)) | (astc_extract_bits(T, 7, 7) << (5 + n * 3)), n * 3 + 6); } +#endif // #if BASISD_SUPPORT_UASTC || BASISD_SUPPORT_ASTC +#if BASISD_SUPPORT_ASTC + struct astc_block_params + { + // 2 groups of 5, but only a max of 8 are used (RRGGBBAA00) + uint8_t m_endpoints[10]; + uint8_t m_weights[32]; + }; + // Packs a single format ASTC block using Color Endpoint Mode 12 (LDR RGBA direct), endpoint BISE range 13, 2-bit weights (range 2). // We're always going to output blocks containing alpha, even if the input doesn't have alpha, for simplicity. // Each block always has 4x4 weights, uses range 13 BISE encoding on the endpoints (0-47), and each weight ranges from 0-3. This encoding should be roughly equal in quality vs. BC1 for color. @@ -6255,12 +6011,15 @@ namespace basist static const etc1s_to_atc_solution g_etc1s_to_pvrtc2_45[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = { #include "basisu_transcoder_tables_pvrtc2_45.inc" }; - + +#if 0 static const etc1s_to_atc_solution g_etc1s_to_pvrtc2_alpha_33[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = { #include "basisu_transcoder_tables_pvrtc2_alpha_33.inc" }; #endif +#endif + static const etc1s_to_atc_solution g_etc1s_to_atc_55[32 * 8 * NUM_ETC1S_TO_ATC_SELECTOR_MAPPINGS * NUM_ETC1S_TO_ATC_SELECTOR_RANGES] = { #include "basisu_transcoder_tables_atc_55.inc" }; @@ -7167,10 +6926,7 @@ namespace basist } typedef struct { float c[4]; } vec4F; - - static inline int32_t clampi(int32_t value, int32_t low, int32_t high) { if (value < low) value = low; else if (value > high) value = high; return value; } - static inline float clampf(float value, float low, float high) { if (value < low) value = low; else if (value > high) value = high; return value; } - static inline float saturate(float value) { return clampf(value, 0, 1.0f); } + static inline vec4F* vec4F_set_scalar(vec4F* pV, float x) { pV->c[0] = x; pV->c[1] = x; pV->c[2] = x; pV->c[3] = x; return pV; } static inline vec4F* vec4F_set(vec4F* pV, float x, float y, float z, float w) { pV->c[0] = x; pV->c[1] = y; pV->c[2] = z; pV->c[3] = w; return pV; } static inline vec4F* vec4F_saturate_in_place(vec4F* pV) { pV->c[0] = saturate(pV->c[0]); pV->c[1] = saturate(pV->c[1]); pV->c[2] = saturate(pV->c[2]); pV->c[3] = saturate(pV->c[3]); return pV; } @@ -7188,7 +6944,7 @@ namespace basist } static inline int sq(int x) { return x * x; } - + // PVRTC2 is a slightly borked format for alpha: In Non-Interpolated mode, the way AlphaB8 is exanded from 4 to 8 bits means it can never be 0. // This is actually very bad, because on 100% transparent blocks which have non-trivial color pixels, part of the color channel will leak into alpha! // And there's nothing straightforward we can do because using the other modes is too expensive/complex. I can see why Apple didn't adopt it. @@ -7461,7 +7217,7 @@ namespace basist } vec4F_normalize_in_place(&axis); - + if (vec4F_dot(&axis, &axis) < .5f) vec4F_set_scalar(&axis, .5f); @@ -7488,7 +7244,15 @@ namespace basist minColor = vec4F_saturate(&c0); maxColor = vec4F_saturate(&c1); if (minColor.c[3] > maxColor.c[3]) - std::swap(minColor, maxColor); + { + // VS 2019 release Code Generator issue + //std::swap(minColor, maxColor); + + float a = minColor.c[0], b = minColor.c[1], c = minColor.c[2], d = minColor.c[3]; + minColor.c[0] = maxColor.c[0]; minColor.c[1] = maxColor.c[1]; minColor.c[2] = maxColor.c[2]; minColor.c[3] = maxColor.c[3]; + minColor.c[0] = maxColor.c[0]; minColor.c[1] = maxColor.c[1]; minColor.c[2] = maxColor.c[2]; minColor.c[3] = maxColor.c[3]; + maxColor.c[0] = a; maxColor.c[1] = b; maxColor.c[2] = c; maxColor.c[3] = d; + } } else { @@ -7648,7 +7412,7 @@ namespace basist uint32_t m = (le * 5 + he * 3) / 8; - int err = labs((int)v - (int)m); + int err = (int)labs((int)v - (int)m); if (err < lowest_err) { lowest_err = err; @@ -7671,7 +7435,7 @@ namespace basist uint32_t le = (l << 1); le = (le << 4) | le; - int err = labs((int)v - (int)le); + int err = (int)labs((int)v - (int)le); if (err < lowest_err) { lowest_err = err; @@ -7693,7 +7457,7 @@ namespace basist uint32_t he = (h << 1) | 1; he = (he << 4) | he; - int err = labs((int)v - (int)he); + int err = (int)labs((int)v - (int)he); if (err < lowest_err) { lowest_err = err; @@ -7722,7 +7486,7 @@ namespace basist uint32_t m = (le * 5 + he * 3) / 8; - int err = labs((int)v - (int)m); + int err = (int)labs((int)v - (int)m); if (err < lowest_err) { lowest_err = err; @@ -7752,7 +7516,7 @@ namespace basist uint32_t m = (le * 5 + he * 3) / 8; - int err = labs((int)v - (int)m); + int err = (int)labs((int)v - (int)m); if (err < lowest_err) { lowest_err = err; @@ -7768,59 +7532,65 @@ namespace basist } #endif // BASISD_SUPPORT_PVRTC2 - basisu_lowlevel_transcoder::basisu_lowlevel_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) : + basisu_lowlevel_etc1s_transcoder::basisu_lowlevel_etc1s_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) : + m_pGlobal_codebook(nullptr), m_pGlobal_sel_codebook(pGlobal_sel_codebook), m_selector_history_buf_size(0) { } - bool basisu_lowlevel_transcoder::decode_palettes( + bool basisu_lowlevel_etc1s_transcoder::decode_palettes( uint32_t num_endpoints, const uint8_t* pEndpoints_data, uint32_t endpoints_data_size, uint32_t num_selectors, const uint8_t* pSelectors_data, uint32_t selectors_data_size) { + if (m_pGlobal_codebook) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 11\n"); + return false; + } bitwise_decoder sym_codec; huffman_decoding_table color5_delta_model0, color5_delta_model1, color5_delta_model2, inten_delta_model; if (!sym_codec.init(pEndpoints_data, endpoints_data_size)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 0\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 0\n"); return false; } if (!sym_codec.read_huffman_table(color5_delta_model0)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 1\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 1\n"); return false; } if (!sym_codec.read_huffman_table(color5_delta_model1)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 1a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 1a\n"); return false; } if (!sym_codec.read_huffman_table(color5_delta_model2)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 2a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 2a\n"); return false; } if (!sym_codec.read_huffman_table(inten_delta_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 2b\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 2b\n"); return false; } if (!color5_delta_model0.is_valid() || !color5_delta_model1.is_valid() || !color5_delta_model2.is_valid() || !inten_delta_model.is_valid()) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 2b\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 2b\n"); return false; } const bool endpoints_are_grayscale = sym_codec.get_bits(1) != 0; - m_endpoints.resize(num_endpoints); + m_local_endpoints.resize(num_endpoints); color32 prev_color5(16, 16, 16, 0); uint32_t prev_inten = 0; @@ -7828,8 +7598,8 @@ namespace basist for (uint32_t i = 0; i < num_endpoints; i++) { uint32_t inten_delta = sym_codec.decode_huffman(inten_delta_model); - m_endpoints[i].m_inten5 = static_cast<uint8_t>((inten_delta + prev_inten) & 7); - prev_inten = m_endpoints[i].m_inten5; + m_local_endpoints[i].m_inten5 = static_cast<uint8_t>((inten_delta + prev_inten) & 7); + prev_inten = m_local_endpoints[i].m_inten5; for (uint32_t c = 0; c < (endpoints_are_grayscale ? 1U : 3U); c++) { @@ -7843,25 +7613,25 @@ namespace basist int v = (prev_color5[c] + delta) & 31; - m_endpoints[i].m_color5[c] = static_cast<uint8_t>(v); + m_local_endpoints[i].m_color5[c] = static_cast<uint8_t>(v); prev_color5[c] = static_cast<uint8_t>(v); } if (endpoints_are_grayscale) { - m_endpoints[i].m_color5[1] = m_endpoints[i].m_color5[0]; - m_endpoints[i].m_color5[2] = m_endpoints[i].m_color5[0]; + m_local_endpoints[i].m_color5[1] = m_local_endpoints[i].m_color5[0]; + m_local_endpoints[i].m_color5[2] = m_local_endpoints[i].m_color5[0]; } } sym_codec.stop(); - m_selectors.resize(num_selectors); + m_local_selectors.resize(num_selectors); if (!sym_codec.init(pSelectors_data, selectors_data_size)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 5\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 5\n"); return false; } @@ -7880,12 +7650,12 @@ namespace basist { if (!sym_codec.read_huffman_table(mod_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 6\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 6\n"); return false; } if (!mod_model.is_valid()) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 6a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 6a\n"); return false; } } @@ -7902,7 +7672,7 @@ namespace basist if (pal_index >= m_pGlobal_sel_codebook->size()) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 7z\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 7z\n"); return false; } @@ -7911,9 +7681,9 @@ namespace basist // TODO: Optimize this for (uint32_t y = 0; y < 4; y++) for (uint32_t x = 0; x < 4; x++) - m_selectors[i].set_selector(x, y, e[x + y * 4]); + m_local_selectors[i].set_selector(x, y, e[x + y * 4]); - m_selectors[i].init_flags(); + m_local_selectors[i].init_flags(); } } else @@ -7928,12 +7698,12 @@ namespace basist basist::huffman_decoding_table uses_global_cb_bitflags_model; if (!sym_codec.read_huffman_table(uses_global_cb_bitflags_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 7\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 7\n"); return false; } if (!uses_global_cb_bitflags_model.is_valid()) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 7a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 7a\n"); return false; } @@ -7942,12 +7712,12 @@ namespace basist { if (!sym_codec.read_huffman_table(global_mod_indices_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 8\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 8\n"); return false; } if (!global_mod_indices_model.is_valid()) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 8a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 8a\n"); return false; } } @@ -7975,7 +7745,7 @@ namespace basist if (pal_index >= m_pGlobal_sel_codebook->size()) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 8b\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 8b\n"); return false; } @@ -7983,7 +7753,7 @@ namespace basist for (uint32_t y = 0; y < 4; y++) for (uint32_t x = 0; x < 4; x++) - m_selectors[q].set_selector(x, y, e[x + y * 4]); + m_local_selectors[q].set_selector(x, y, e[x + y * 4]); } else { @@ -7992,11 +7762,11 @@ namespace basist uint32_t cur_byte = sym_codec.get_bits(8); for (uint32_t k = 0; k < 4; k++) - m_selectors[q].set_selector(k, j, (cur_byte >> (k * 2)) & 3); + m_local_selectors[q].set_selector(k, j, (cur_byte >> (k * 2)) & 3); } } - m_selectors[q].init_flags(); + m_local_selectors[q].init_flags(); } } else @@ -8012,23 +7782,23 @@ namespace basist uint32_t cur_byte = sym_codec.get_bits(8); for (uint32_t k = 0; k < 4; k++) - m_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3); + m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3); } - m_selectors[i].init_flags(); + m_local_selectors[i].init_flags(); } } else { if (!sym_codec.read_huffman_table(delta_selector_pal_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 10\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 10\n"); return false; } if ((num_selectors > 1) && (!delta_selector_pal_model.is_valid())) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_palettes: fail 10a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_palettes: fail 10a\n"); return false; } @@ -8044,9 +7814,9 @@ namespace basist prev_bytes[j] = static_cast<uint8_t>(cur_byte); for (uint32_t k = 0; k < 4; k++) - m_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3); + m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3); } - m_selectors[i].init_flags(); + m_local_selectors[i].init_flags(); continue; } @@ -8058,9 +7828,9 @@ namespace basist prev_bytes[j] = static_cast<uint8_t>(cur_byte); for (uint32_t k = 0; k < 4; k++) - m_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3); + m_local_selectors[i].set_selector(k, j, (cur_byte >> (k * 2)) & 3); } - m_selectors[i].init_flags(); + m_local_selectors[i].init_flags(); } } } @@ -8071,60 +7841,60 @@ namespace basist return true; } - bool basisu_lowlevel_transcoder::decode_tables(const uint8_t* pTable_data, uint32_t table_data_size) + bool basisu_lowlevel_etc1s_transcoder::decode_tables(const uint8_t* pTable_data, uint32_t table_data_size) { basist::bitwise_decoder sym_codec; if (!sym_codec.init(pTable_data, table_data_size)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 0\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 0\n"); return false; } if (!sym_codec.read_huffman_table(m_endpoint_pred_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 1\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 1\n"); return false; } if (m_endpoint_pred_model.get_code_sizes().size() == 0) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 1a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 1a\n"); return false; } if (!sym_codec.read_huffman_table(m_delta_endpoint_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 2\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 2\n"); return false; } if (m_delta_endpoint_model.get_code_sizes().size() == 0) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 2a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 2a\n"); return false; } if (!sym_codec.read_huffman_table(m_selector_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 3\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 3\n"); return false; } if (m_selector_model.get_code_sizes().size() == 0) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 3a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 3a\n"); return false; } if (!sym_codec.read_huffman_table(m_selector_history_buf_rle_model)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 4\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 4\n"); return false; } if (m_selector_history_buf_rle_model.get_code_sizes().size() == 0) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::decode_tables: fail 4a\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::decode_tables: fail 4a\n"); return false; } @@ -8135,27 +7905,37 @@ namespace basist return true; } - bool basisu_lowlevel_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels, + bool basisu_lowlevel_etc1s_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const bool is_video, const bool is_alpha_slice, const uint32_t level_index, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, bool transcode_alpha, void *pAlpha_blocks, uint32_t output_rows_in_pixels) { - (void)transcode_alpha; - (void)pAlpha_blocks; + // 'pDst_blocks' unused when disabling *all* hardware transcode options + // (and 'bc1_allow_threecolor_blocks' when disabling DXT) + BASISU_NOTE_UNUSED(pDst_blocks); + BASISU_NOTE_UNUSED(bc1_allow_threecolor_blocks); + BASISU_NOTE_UNUSED(transcode_alpha); + BASISU_NOTE_UNUSED(pAlpha_blocks); + + assert(g_transcoder_initialized); + if (!g_transcoder_initialized) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: Transcoder not globally initialized.\n"); + return false; + } if (!pState) pState = &m_def_state; - const bool is_video = (header.m_tex_type == cBASISTexTypeVideoFrames); const uint32_t total_blocks = num_blocks_x * num_blocks_y; if (!output_row_pitch_in_blocks_or_pixels) { if (basis_block_format_is_uncompressed(fmt)) - output_row_pitch_in_blocks_or_pixels = slice_desc.m_orig_width; + output_row_pitch_in_blocks_or_pixels = orig_width; else { if (fmt == block_format::cFXT1_RGB) - output_row_pitch_in_blocks_or_pixels = (slice_desc.m_orig_width + 7) / 8; + output_row_pitch_in_blocks_or_pixels = (orig_width + 7) / 8; else output_row_pitch_in_blocks_or_pixels = num_blocks_x; } @@ -8164,23 +7944,23 @@ namespace basist if (basis_block_format_is_uncompressed(fmt)) { if (!output_rows_in_pixels) - output_rows_in_pixels = slice_desc.m_orig_height; + output_rows_in_pixels = orig_height; } - std::vector<uint32_t>* pPrev_frame_indices = nullptr; + basisu::vector<uint32_t>* pPrev_frame_indices = nullptr; if (is_video) { // TODO: Add check to make sure the caller hasn't tried skipping past p-frames - const bool alpha_flag = (slice_desc.m_flags & cSliceDescFlagsIsAlphaData) != 0; - const uint32_t level_index = slice_desc.m_level_index; + //const bool alpha_flag = (slice_desc.m_flags & cSliceDescFlagsHasAlpha) != 0; + //const uint32_t level_index = slice_desc.m_level_index; if (level_index >= basisu_transcoder_state::cMaxPrevFrameLevels) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: unsupported level_index\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: unsupported level_index\n"); return false; } - pPrev_frame_indices = &pState->m_prev_frame_indices[alpha_flag][level_index]; + pPrev_frame_indices = &pState->m_prev_frame_indices[is_alpha_slice][level_index]; if (pPrev_frame_indices->size() < total_blocks) pPrev_frame_indices->resize(total_blocks); } @@ -8189,14 +7969,12 @@ namespace basist if (!sym_codec.init(pImage_data, image_data_size)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: sym_codec.init failed\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: sym_codec.init failed\n"); return false; } approx_move_to_front selector_history_buf(m_selector_history_buf_size); - - const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = (uint32_t)m_selectors.size(); - const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = m_selector_history_buf_size + SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX; + uint32_t cur_selector_rle_count = 0; decoder_etc_block block; @@ -8212,7 +7990,7 @@ namespace basist pPVRTC_work_mem = malloc(num_blocks_x * num_blocks_y * (sizeof(decoder_etc_block) + sizeof(uint32_t))); if (!pPVRTC_work_mem) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: malloc failed\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: malloc failed\n"); return false; } pPVRTC_endpoints = (uint32_t*) & ((decoder_etc_block*)pPVRTC_work_mem)[num_blocks_x * num_blocks_y]; @@ -8228,6 +8006,16 @@ namespace basist int prev_endpoint_pred_sym = 0; int endpoint_pred_repeat_count = 0; uint32_t prev_endpoint_index = 0; + const endpoint_vec& endpoints = m_pGlobal_codebook ? m_pGlobal_codebook->m_local_endpoints : m_local_endpoints; + const selector_vec& selectors = m_pGlobal_codebook ? m_pGlobal_codebook->m_local_selectors : m_local_selectors; + if (!endpoints.size() || !selectors.size()) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: global codebooks must be unpacked first\n"); + return false; + } + + const uint32_t SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX = (uint32_t)selectors.size(); + const uint32_t SELECTOR_HISTORY_BUF_RLE_SYMBOL_INDEX = m_selector_history_buf_size + SELECTOR_HISTORY_BUF_FIRST_SYMBOL_INDEX; for (uint32_t block_y = 0; block_y < num_blocks_y; block_y++) { @@ -8279,7 +8067,7 @@ namespace basist // Left if (!block_x) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (0)\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: invalid datastream (0)\n"); if (pPVRTC_work_mem) free(pPVRTC_work_mem); return false; @@ -8292,7 +8080,7 @@ namespace basist // Upper if (!block_y) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (1)\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: invalid datastream (1)\n"); if (pPVRTC_work_mem) free(pPVRTC_work_mem); return false; @@ -8314,7 +8102,7 @@ namespace basist // Upper left if ((!block_x) || (!block_y)) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (2)\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: invalid datastream (2)\n"); if (pPVRTC_work_mem) free(pPVRTC_work_mem); return false; @@ -8329,8 +8117,8 @@ namespace basist const uint32_t delta_sym = sym_codec.decode_huffman(m_delta_endpoint_model); endpoint_index = delta_sym + prev_endpoint_index; - if (endpoint_index >= m_endpoints.size()) - endpoint_index -= (int)m_endpoints.size(); + if (endpoint_index >= endpoints.size()) + endpoint_index -= (int)endpoints.size(); } pState->m_block_endpoint_preds[cur_block_endpoint_pred_array][block_x].m_endpoint_index = (uint16_t)endpoint_index; @@ -8345,7 +8133,7 @@ namespace basist { cur_selector_rle_count--; - selector_sym = (int)m_selectors.size(); + selector_sym = (int)selectors.size(); } else { @@ -8363,28 +8151,28 @@ namespace basist if (cur_selector_rle_count > total_blocks) { // The file is corrupted or we've got a bug. - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (3)\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: invalid datastream (3)\n"); if (pPVRTC_work_mem) free(pPVRTC_work_mem); return false; } - selector_sym = (int)m_selectors.size(); + selector_sym = (int)selectors.size(); cur_selector_rle_count--; } } - if (selector_sym >= (int)m_selectors.size()) + if (selector_sym >= (int)selectors.size()) { assert(m_selector_history_buf_size > 0); - int history_buf_index = selector_sym - (int)m_selectors.size(); + int history_buf_index = selector_sym - (int)selectors.size(); if (history_buf_index >= (int)selector_history_buf.size()) { // The file is corrupted or we've got a bug. - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (4)\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: invalid datastream (4)\n"); if (pPVRTC_work_mem) free(pPVRTC_work_mem); return false; @@ -8404,10 +8192,10 @@ namespace basist } } - if ((endpoint_index >= m_endpoints.size()) || (selector_index >= m_selectors.size())) + if ((endpoint_index >= endpoints.size()) || (selector_index >= selectors.size())) { // The file is corrupted or we've got a bug. - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: invalid datastream (5)\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: invalid datastream (5)\n"); if (pPVRTC_work_mem) free(pPVRTC_work_mem); return false; @@ -8428,8 +8216,8 @@ namespace basist } #endif - const endpoint* pEndpoints = &m_endpoints[endpoint_index]; - const selector* pSelector = &m_selectors[selector_index]; + const endpoint* pEndpoints = &endpoints[endpoint_index]; + const selector* pSelector = &selectors[selector_index]; switch (fmt) { @@ -8448,9 +8236,8 @@ namespace basist } case block_format::cBC1: { - void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; - #if BASISD_SUPPORT_DXT1 + void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; #if BASISD_ENABLE_DEBUG_FLAGS if (g_debug_flags & (cDebugFlagVisBC1Sels | cDebugFlagVisBC1Endpoints)) convert_etc1s_to_dxt1_vis(static_cast<dxt1_block*>(pDst_block), pEndpoints, pSelector, bc1_allow_threecolor_blocks); @@ -8534,8 +8321,8 @@ namespace basist const uint16_t* pAlpha_block = reinterpret_cast<uint16_t*>(static_cast<uint8_t*>(pAlpha_blocks) + (block_x + block_y * num_blocks_x) * sizeof(uint32_t)); - const endpoint* pAlpha_endpoints = &m_endpoints[pAlpha_block[0]]; - const selector* pAlpha_selector = &m_selectors[pAlpha_block[1]]; + const endpoint* pAlpha_endpoints = &endpoints[pAlpha_block[0]]; + const selector* pAlpha_selector = &selectors[pAlpha_block[1]]; const color32& alpha_base_color = pAlpha_endpoints->m_color5; const uint32_t alpha_inten_table = pAlpha_endpoints->m_inten5; @@ -8559,16 +8346,7 @@ namespace basist break; } - case block_format::cBC7_M6_OPAQUE_ONLY: - { -#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; - convert_etc1s_to_bc7_m6(static_cast<bc7_mode_6*>(pDst_block), pEndpoints, pSelector); -#else - assert(0); -#endif - break; - } + case block_format::cBC7: // for more consistency with UASTC case block_format::cBC7_M5_COLOR: { #if BASISD_SUPPORT_BC7_MODE5 @@ -8603,7 +8381,7 @@ namespace basist { #if BASISD_SUPPORT_ASTC void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; - convert_etc1s_to_astc_4x4(pDst_block, pEndpoints, pSelector, transcode_alpha, &m_endpoints[0], &m_selectors[0]); + convert_etc1s_to_astc_4x4(pDst_block, pEndpoints, pSelector, transcode_alpha, &endpoints[0], &selectors[0]); #else assert(0); #endif @@ -8648,8 +8426,8 @@ namespace basist assert(transcode_alpha); void* pDst_block = static_cast<uint8_t*>(pDst_blocks) + (block_x + block_y * output_row_pitch_in_blocks_or_pixels) * output_block_or_pixel_stride_in_bytes; - - convert_etc1s_to_pvrtc2_rgba(pDst_block, pEndpoints, pSelector, &m_endpoints[0], &m_selectors[0]); + + convert_etc1s_to_pvrtc2_rgba(pDst_block, pEndpoints, pSelector, &endpoints[0], &selectors[0]); #endif break; } @@ -8665,8 +8443,8 @@ namespace basist assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); int colors[4]; decoder_etc_block::get_block_colors5_g(colors, pEndpoints->m_color5, pEndpoints->m_inten5); @@ -8705,8 +8483,8 @@ namespace basist assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); color32 colors[4]; decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); @@ -8734,8 +8512,8 @@ namespace basist assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); color32 colors[4]; decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); @@ -8765,8 +8543,8 @@ namespace basist assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); color32 colors[4]; decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); @@ -8775,12 +8553,20 @@ namespace basist if (fmt == block_format::cRGB565) { for (uint32_t i = 0; i < 4; i++) - packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 3) << 11) | ((colors[i].g >> 2) << 5) | (colors[i].b >> 3)); + { + packed_colors[i] = static_cast<uint16_t>((mul_8(colors[i].r, 31) << 11) | (mul_8(colors[i].g, 63) << 5) | mul_8(colors[i].b, 31)); + if (BASISD_IS_BIG_ENDIAN) + packed_colors[i] = byteswap_uint16(packed_colors[i]); + } } else { for (uint32_t i = 0; i < 4; i++) - packed_colors[i] = static_cast<uint16_t>(((colors[i].b >> 3) << 11) | ((colors[i].g >> 2) << 5) | (colors[i].r >> 3)); + { + packed_colors[i] = static_cast<uint16_t>((mul_8(colors[i].b, 31) << 11) | (mul_8(colors[i].g, 63) << 5) | mul_8(colors[i].r, 31)); + if (BASISD_IS_BIG_ENDIAN) + packed_colors[i] = byteswap_uint16(packed_colors[i]); + } } for (uint32_t y = 0; y < max_y; y++) @@ -8800,15 +8586,17 @@ namespace basist assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); color32 colors[4]; decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); uint16_t packed_colors[4]; for (uint32_t i = 0; i < 4; i++) - packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 4) << 12) | ((colors[i].g >> 4) << 8) | ((colors[i].b >> 4) << 4)); + { + packed_colors[i] = static_cast<uint16_t>((mul_8(colors[i].r, 15) << 12) | (mul_8(colors[i].g, 15) << 8) | (mul_8(colors[i].b, 15) << 4)); + } for (uint32_t y = 0; y < max_y; y++) { @@ -8817,7 +8605,14 @@ namespace basist for (uint32_t x = 0; x < max_x; x++) { uint16_t cur = reinterpret_cast<uint16_t*>(pDst_pixels)[x]; + if (BASISD_IS_BIG_ENDIAN) + cur = byteswap_uint16(cur); + cur = (cur & 0xF) | packed_colors[(s >> (x * 2)) & 3]; + + if (BASISD_IS_BIG_ENDIAN) + cur = byteswap_uint16(cur); + reinterpret_cast<uint16_t*>(pDst_pixels)[x] = cur; } @@ -8831,15 +8626,19 @@ namespace basist assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); color32 colors[4]; decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); uint16_t packed_colors[4]; for (uint32_t i = 0; i < 4; i++) - packed_colors[i] = static_cast<uint16_t>(((colors[i].r >> 4) << 12) | ((colors[i].g >> 4) << 8) | ((colors[i].b >> 4) << 4) | 0xF); + { + packed_colors[i] = static_cast<uint16_t>((mul_8(colors[i].r, 15) << 12) | (mul_8(colors[i].g, 15) << 8) | (mul_8(colors[i].b, 15) << 4) | 0xF); + if (BASISD_IS_BIG_ENDIAN) + packed_colors[i] = byteswap_uint16(packed_colors[i]); + } for (uint32_t y = 0; y < max_y; y++) { @@ -8858,22 +8657,28 @@ namespace basist assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); - const uint32_t max_x = basisu::minimum<int>(4, output_row_pitch_in_blocks_or_pixels - block_x * 4); - const uint32_t max_y = basisu::minimum<int>(4, output_rows_in_pixels - block_y * 4); + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); color32 colors[4]; decoder_etc_block::get_block_colors5(colors, pEndpoints->m_color5, pEndpoints->m_inten5); uint16_t packed_colors[4]; for (uint32_t i = 0; i < 4; i++) - packed_colors[i] = colors[i].g >> 4; + { + packed_colors[i] = mul_8(colors[i].g, 15); + if (BASISD_IS_BIG_ENDIAN) + packed_colors[i] = byteswap_uint16(packed_colors[i]); + } for (uint32_t y = 0; y < max_y; y++) { const uint32_t s = pSelector->m_selectors[y]; for (uint32_t x = 0; x < max_x; x++) + { reinterpret_cast<uint16_t*>(pDst_pixels)[x] = packed_colors[(s >> (x * 2)) & 3]; + } pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t); } @@ -8903,7 +8708,7 @@ namespace basist if (endpoint_pred_repeat_count != 0) { - BASISU_DEVEL_ERROR("basisu_lowlevel_transcoder::transcode_slice: endpoint_pred_repeat_count != 0. The file is corrupted or this is a bug\n"); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_slice: endpoint_pred_repeat_count != 0. The file is corrupted or this is a bug\n"); return false; } @@ -8914,7 +8719,7 @@ namespace basist if (fmt == block_format::cPVRTC1_4_RGB) fixup_pvrtc1_4_modulation_rgb((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y); else if (fmt == block_format::cPVRTC1_4_RGBA) - fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pAlpha_blocks, &m_endpoints[0], &m_selectors[0]); + fixup_pvrtc1_4_modulation_rgba((decoder_etc_block*)pPVRTC_work_mem, pPVRTC_endpoints, pDst_blocks, num_blocks_x, num_blocks_y, pAlpha_blocks, &endpoints[0], &selectors[0]); #endif // BASISD_SUPPORT_PVRTC1 if (pPVRTC_work_mem) @@ -8923,8 +8728,1187 @@ namespace basist return true; } + bool basis_validate_output_buffer_size(transcoder_texture_format target_format, + uint32_t output_blocks_buf_size_in_blocks_or_pixels, + uint32_t orig_width, uint32_t orig_height, + uint32_t output_row_pitch_in_blocks_or_pixels, + uint32_t output_rows_in_pixels, + uint32_t total_slice_blocks) + { + if (basis_transcoder_format_is_uncompressed(target_format)) + { + // Assume the output buffer is orig_width by orig_height + if (!output_row_pitch_in_blocks_or_pixels) + output_row_pitch_in_blocks_or_pixels = orig_width; + + if (!output_rows_in_pixels) + output_rows_in_pixels = orig_height; + + // Now make sure the output buffer is large enough, or we'll overwrite memory. + if (output_blocks_buf_size_in_blocks_or_pixels < (output_rows_in_pixels * output_row_pitch_in_blocks_or_pixels)) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: output_blocks_buf_size_in_blocks_or_pixels < (output_rows_in_pixels * output_row_pitch_in_blocks_or_pixels)\n"); + return false; + } + } + else if (target_format == transcoder_texture_format::cTFFXT1_RGB) + { + const uint32_t num_blocks_fxt1_x = (orig_width + 7) / 8; + const uint32_t num_blocks_fxt1_y = (orig_height + 3) / 4; + const uint32_t total_blocks_fxt1 = num_blocks_fxt1_x * num_blocks_fxt1_y; + + if (output_blocks_buf_size_in_blocks_or_pixels < total_blocks_fxt1) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: output_blocks_buf_size_in_blocks_or_pixels < total_blocks_fxt1\n"); + return false; + } + } + else + { + if (output_blocks_buf_size_in_blocks_or_pixels < total_slice_blocks) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: output_blocks_buf_size_in_blocks_or_pixels < transcode_image\n"); + return false; + } + } + return true; + } + + bool basisu_lowlevel_etc1s_transcoder::transcode_image( + transcoder_texture_format target_format, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + const uint8_t* pCompressed_data, uint32_t compressed_data_length, + uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, + uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length, + uint32_t decode_flags, + bool basis_file_has_alpha_slices, + bool is_video, + uint32_t output_row_pitch_in_blocks_or_pixels, + basisu_transcoder_state* pState, + uint32_t output_rows_in_pixels) + { + if (((uint64_t)rgb_offset + rgb_length) > (uint64_t)compressed_data_length) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: source data buffer too small (color)\n"); + return false; + } + + if (alpha_length) + { + if (((uint64_t)alpha_offset + alpha_length) > (uint64_t)compressed_data_length) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: source data buffer too small (alpha)\n"); + return false; + } + } + else + { + assert(!basis_file_has_alpha_slices); + } + + if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGB) || (target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)) + { + if ((!basisu::is_pow2(num_blocks_x * 4)) || (!basisu::is_pow2(num_blocks_y * 4))) + { + // PVRTC1 only supports power of 2 dimensions + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC1 only supports power of 2 dimensions\n"); + return false; + } + } + + if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices)) + { + // Switch to PVRTC1 RGB if the input doesn't have alpha. + target_format = transcoder_texture_format::cTFPVRTC1_4_RGB; + } + + const bool transcode_alpha_data_to_opaque_formats = (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0; + const uint32_t bytes_per_block_or_pixel = basis_get_bytes_per_block_or_pixel(target_format); + const uint32_t total_slice_blocks = num_blocks_x * num_blocks_y; + + if (!basis_validate_output_buffer_size(target_format, output_blocks_buf_size_in_blocks_or_pixels, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, output_rows_in_pixels, total_slice_blocks)) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: output buffer size too small\n"); + return false; + } + + bool status = false; + + const uint8_t* pData = pCompressed_data + rgb_offset; + uint32_t data_len = rgb_length; + bool is_alpha_slice = false; + + // If the caller wants us to transcode the mip level's alpha data, then use the next slice. + if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) + { + pData = pCompressed_data + alpha_offset; + data_len = alpha_length; + is_alpha_slice = true; + } + + switch (target_format) + { + case transcoder_texture_format::cTFETC1_RGB: + { + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cETC1, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ETC1 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBC1_RGB: + { +#if !BASISD_SUPPORT_DXT1 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: BC1/DXT1 unsupported\n"); + return false; +#else + // status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cBC1, bytes_per_block_or_pixel, true, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC1 failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFBC4_R: + { +#if !BASISD_SUPPORT_DXT5A + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: BC4/DXT5A unsupported\n"); + return false; +#else + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cBC4, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC4 failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFPVRTC1_4_RGB: + { +#if !BASISD_SUPPORT_PVRTC1 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC1 4 unsupported\n"); + return false; +#else + // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?) + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cPVRTC1_4_RGB, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to PVRTC1 4 RGB failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + { +#if !BASISD_SUPPORT_PVRTC1 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC1 4 unsupported\n"); + return false; +#else + assert(basis_file_has_alpha_slices); + assert(alpha_length); + + // Temp buffer to hold alpha block endpoint/selector indices + basisu::vector<uint32_t> temp_block_indices(total_slice_blocks); + + // First transcode alpha data to temp buffer + //status = transcode_slice(pData, data_size, slice_index + 1, &temp_block_indices[0], total_slice_blocks, block_format::cIndices, sizeof(uint32_t), decode_flags, pSlice_descs[slice_index].m_num_blocks_x, pState); + status = transcode_slice(&temp_block_indices[0], num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cIndices, sizeof(uint32_t), false, is_video, true, level_index, orig_width, orig_height, num_blocks_x, pState, false, nullptr, 0); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to PVRTC1 4 RGBA failed (0)\n"); + } + else + { + // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?) + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGBA, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, &temp_block_indices[0]); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cPVRTC1_4_RGBA, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, &temp_block_indices[0], 0); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to PVRTC1 4 RGBA failed (1)\n"); + } + } + + break; +#endif + } + case transcoder_texture_format::cTFBC7_RGBA: + case transcoder_texture_format::cTFBC7_ALT: + { +#if !BASISD_SUPPORT_BC7_MODE5 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: BC7 unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + // We used to support transcoding just alpha to BC7 - but is that useful at all? + + // First transcode the color slice. The cBC7_M5_COLOR transcoder will output opaque mode 5 blocks. + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M5_COLOR, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cBC7_M5_COLOR, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + + if ((status) && (basis_file_has_alpha_slices)) + { + // Now transcode the alpha slice. The cBC7_M5_ALPHA transcoder will now change the opaque mode 5 blocks to blocks with alpha. + //status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M5_ALPHA, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cBC7_M5_ALPHA, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + } + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC7 failed (0)\n"); + } + + break; +#endif + } + case transcoder_texture_format::cTFETC2_RGBA: + { +#if !BASISD_SUPPORT_ETC2_EAC_A8 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: ETC2 EAC A8 unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + + if (basis_file_has_alpha_slices) + { + // First decode the alpha data + //status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_A8, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cETC2_EAC_A8, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + } + else + { + //write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_A8, 16, output_row_pitch_in_blocks_or_pixels); + basisu_transcoder::write_opaque_alpha_blocks(num_blocks_x, num_blocks_y, pOutput_blocks, block_format::cETC2_EAC_A8, 16, output_row_pitch_in_blocks_or_pixels); + status = true; + } + + if (status) + { + // Now decode the color data + //status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice((uint8_t *)pOutput_blocks + 8, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cETC1, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ETC2 RGB failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ETC2 A failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFBC3_RGBA: + { +#if !BASISD_SUPPORT_DXT1 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: DXT1 unsupported\n"); + return false; +#elif !BASISD_SUPPORT_DXT5A + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: DXT5A unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + + // First decode the alpha data + if (basis_file_has_alpha_slices) + { + //status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cBC4, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + } + else + { + basisu_transcoder::write_opaque_alpha_blocks(num_blocks_x, num_blocks_y, pOutput_blocks, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); + status = true; + } + + if (status) + { + // Now decode the color data. Forbid 3 color blocks, which aren't allowed in BC3. + //status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, 16, decode_flags | cDecodeFlagsBC1ForbidThreeColorBlocks, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice((uint8_t *)pOutput_blocks + 8, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cBC1, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC3 RGB failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC3 A failed\n"); + } + + break; +#endif + } + case transcoder_texture_format::cTFBC5_RG: + { +#if !BASISD_SUPPORT_DXT5A + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: DXT5A unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + + //bool transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + // uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const bool is_video, const bool is_alpha_slice, const uint32_t level_index, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + // basisu_transcoder_state* pState = nullptr, bool astc_transcode_alpha = false, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0); + + // Decode the R data (actually the green channel of the color data slice in the basis file) + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cBC4, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (status) + { + if (basis_file_has_alpha_slices) + { + // Decode the G data (actually the green channel of the alpha data slice in the basis file) + //status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice((uint8_t *)pOutput_blocks + 8, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cBC4, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC5 1 failed\n"); + } + } + else + { + basisu_transcoder::write_opaque_alpha_blocks(num_blocks_x, num_blocks_y, (uint8_t*)pOutput_blocks + 8, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); + status = true; + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to BC5 channel 0 failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFASTC_4x4_RGBA: + { +#if !BASISD_SUPPORT_ASTC + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: ASTC unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + + if (basis_file_has_alpha_slices) + { + // First decode the alpha data to the output (we're using the output texture as a temp buffer here). + //status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cIndices, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cIndices, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (status) + { + // Now decode the color data and transcode to ASTC. The transcoder function will read the alpha selector data from the output texture as it converts and + // transcode both the alpha and color data at the same time to ASTC. + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, 16, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cASTC_4x4, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, true, nullptr, output_rows_in_pixels); + } + } + else + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cASTC_4x4, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ASTC failed (0)\n"); + } + + break; +#endif + } + case transcoder_texture_format::cTFATC_RGB: + { +#if !BASISD_SUPPORT_ATC + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: ATC unsupported\n"); + return false; +#else + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cATC_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cATC_RGB, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ATC_RGB failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFATC_RGBA: + { +#if !BASISD_SUPPORT_ATC + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: ATC unsupported\n"); + return false; +#elif !BASISD_SUPPORT_DXT5A + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: DXT5A unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + + // First decode the alpha data + if (basis_file_has_alpha_slices) + { + //status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cBC4, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + } + else + { + basisu_transcoder::write_opaque_alpha_blocks(num_blocks_x, num_blocks_y, pOutput_blocks, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); + status = true; + } + + if (status) + { + //status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cATC_RGB, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice((uint8_t *)pOutput_blocks + 8, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cATC_RGB, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ATC RGB failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ATC A failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFPVRTC2_4_RGB: + { +#if !BASISD_SUPPORT_PVRTC2 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC2 unsupported\n"); + return false; +#else + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cPVRTC2_4_RGB, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to cPVRTC2_4_RGB failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + { +#if !BASISD_SUPPORT_PVRTC2 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC2 unsupported\n"); + return false; +#else + if (basis_file_has_alpha_slices) + { + // First decode the alpha data to the output (we're using the output texture as a temp buffer here). + //status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cIndices, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cIndices, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to failed\n"); + } + else + { + // Now decode the color data and transcode to PVRTC2 RGBA. + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGBA, bytes_per_block_or_pixel, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cPVRTC2_4_RGBA, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, true, nullptr, output_rows_in_pixels); + } + } + else + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cPVRTC2_4_RGB, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to cPVRTC2_4_RGBA failed\n"); + } + + break; +#endif + } + case transcoder_texture_format::cTFRGBA32: + { + // Raw 32bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. + + // First decode the alpha data + if (basis_file_has_alpha_slices) + //status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cA32, sizeof(uint32_t), false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + else + status = true; + + if (status) + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? block_format::cRGB32 : block_format::cRGBA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, basis_file_has_alpha_slices ? block_format::cRGB32 : block_format::cRGBA32, sizeof(uint32_t), false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to RGBA32 RGB failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to RGBA32 A failed\n"); + } + + break; + } + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + { + // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. + + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, (fmt == transcoder_texture_format::cTFRGB565) ? block_format::cRGB565 : block_format::cBGR565, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, (target_format == transcoder_texture_format::cTFRGB565) ? block_format::cRGB565 : block_format::cBGR565, sizeof(uint16_t), false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to RGB565 RGB failed\n"); + } + + break; + } + case transcoder_texture_format::cTFRGBA4444: + { + // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. + + // First decode the alpha data + if (basis_file_has_alpha_slices) + //status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA4444_ALPHA, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cRGBA4444_ALPHA, sizeof(uint16_t), false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + else + status = true; + + if (status) + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? block_format::cRGBA4444_COLOR : block_format::cRGBA4444_COLOR_OPAQUE, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, basis_file_has_alpha_slices ? block_format::cRGBA4444_COLOR : block_format::cRGBA4444_COLOR_OPAQUE, sizeof(uint16_t), false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to RGBA4444 RGB failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to RGBA4444 A failed\n"); + } + + break; + } + case transcoder_texture_format::cTFFXT1_RGB: + { +#if !BASISD_SUPPORT_FXT1 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: FXT1 unsupported\n"); + return false; +#else + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cFXT1_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cFXT1_RGB, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to FXT1_RGB failed\n"); + } + break; +#endif + } + case transcoder_texture_format::cTFETC2_EAC_R11: + { +#if !BASISD_SUPPORT_ETC2_EAC_RG11 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: EAC_RG11 unsupported\n"); + return false; +#else + //status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pData, data_len, block_format::cETC2_EAC_R11, bytes_per_block_or_pixel, false, is_video, is_alpha_slice, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ETC2_EAC_R11 failed\n"); + } + + break; +#endif + } + case transcoder_texture_format::cTFETC2_EAC_RG11: + { +#if !BASISD_SUPPORT_ETC2_EAC_RG11 + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: EAC_RG11 unsupported\n"); + return false; +#else + assert(bytes_per_block_or_pixel == 16); + + if (basis_file_has_alpha_slices) + { + // First decode the alpha data to G + //status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice((uint8_t *)pOutput_blocks + 8, num_blocks_x, num_blocks_y, pCompressed_data + alpha_offset, alpha_length, block_format::cETC2_EAC_R11, bytes_per_block_or_pixel, false, is_video, true, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + } + else + { + basisu_transcoder::write_opaque_alpha_blocks(num_blocks_x, num_blocks_y, (uint8_t*)pOutput_blocks + 8, block_format::cETC2_EAC_R11, 16, output_row_pitch_in_blocks_or_pixels); + status = true; + } + + if (status) + { + // Now decode the color data to R + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + rgb_offset, rgb_length, block_format::cETC2_EAC_R11, bytes_per_block_or_pixel, false, is_video, false, level_index, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, false, nullptr, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ETC2_EAC_R11 R failed\n"); + } + } + else + { + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: transcode_slice() to ETC2_EAC_R11 G failed\n"); + } + + break; +#endif + } + default: + { + assert(0); + BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: Invalid fmt\n"); + break; + } + } + + return status; + } + + basisu_lowlevel_uastc_transcoder::basisu_lowlevel_uastc_transcoder() + { + } + + bool basisu_lowlevel_uastc_transcoder::transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, bool has_alpha, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels, + basisu_transcoder_state* pState, uint32_t output_rows_in_pixels, int channel0, int channel1, uint32_t decode_flags) + { + BASISU_NOTE_UNUSED(pState); + BASISU_NOTE_UNUSED(bc1_allow_threecolor_blocks); + + assert(g_transcoder_initialized); + if (!g_transcoder_initialized) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_slice: Transcoder not globally initialized.\n"); + return false; + } + +#if BASISD_SUPPORT_UASTC + const uint32_t total_blocks = num_blocks_x * num_blocks_y; + + if (!output_row_pitch_in_blocks_or_pixels) + { + if (basis_block_format_is_uncompressed(fmt)) + output_row_pitch_in_blocks_or_pixels = orig_width; + else + { + if (fmt == block_format::cFXT1_RGB) + output_row_pitch_in_blocks_or_pixels = (orig_width + 7) / 8; + else + output_row_pitch_in_blocks_or_pixels = num_blocks_x; + } + } + + if (basis_block_format_is_uncompressed(fmt)) + { + if (!output_rows_in_pixels) + output_rows_in_pixels = orig_height; + } + + uint32_t total_expected_block_bytes = sizeof(uastc_block) * total_blocks; + if (image_data_size < total_expected_block_bytes) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_slice: image_data_size < total_expected_block_bytes The file is corrupted or this is a bug.\n"); + return false; + } + + const uastc_block* pSource_block = reinterpret_cast<const uastc_block *>(pImage_data); + + const bool high_quality = (decode_flags & cDecodeFlagsHighQuality) != 0; + const bool from_alpha = has_alpha && (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0; + + bool status = false; + if ((fmt == block_format::cPVRTC1_4_RGB) || (fmt == block_format::cPVRTC1_4_RGBA)) + { + if (fmt == block_format::cPVRTC1_4_RGBA) + transcode_uastc_to_pvrtc1_4_rgba((const uastc_block*)pImage_data, pDst_blocks, num_blocks_x, num_blocks_y, high_quality); + else + transcode_uastc_to_pvrtc1_4_rgb((const uastc_block *)pImage_data, pDst_blocks, num_blocks_x, num_blocks_y, high_quality, from_alpha); + } + else + { + for (uint32_t block_y = 0; block_y < num_blocks_y; ++block_y) + { + void* pDst_block = (uint8_t*)pDst_blocks + block_y * output_row_pitch_in_blocks_or_pixels * output_block_or_pixel_stride_in_bytes; + + for (uint32_t block_x = 0; block_x < num_blocks_x; ++block_x, ++pSource_block, pDst_block = (uint8_t *)pDst_block + output_block_or_pixel_stride_in_bytes) + { + switch (fmt) + { + case block_format::cETC1: + { + if (from_alpha) + status = transcode_uastc_to_etc1(*pSource_block, pDst_block, 3); + else + status = transcode_uastc_to_etc1(*pSource_block, pDst_block); + break; + } + case block_format::cETC2_RGBA: + { + status = transcode_uastc_to_etc2_rgba(*pSource_block, pDst_block); + break; + } + case block_format::cBC1: + { + status = transcode_uastc_to_bc1(*pSource_block, pDst_block, high_quality); + break; + } + case block_format::cBC3: + { + status = transcode_uastc_to_bc3(*pSource_block, pDst_block, high_quality); + break; + } + case block_format::cBC4: + { + if (channel0 < 0) + channel0 = 0; + status = transcode_uastc_to_bc4(*pSource_block, pDst_block, high_quality, channel0); + break; + } + case block_format::cBC5: + { + if (channel0 < 0) + channel0 = 0; + if (channel1 < 0) + channel1 = 3; + status = transcode_uastc_to_bc5(*pSource_block, pDst_block, high_quality, channel0, channel1); + break; + } + case block_format::cBC7: + case block_format::cBC7_M5_COLOR: // for consistently with ETC1S + { + status = transcode_uastc_to_bc7(*pSource_block, pDst_block); + break; + } + case block_format::cASTC_4x4: + { + status = transcode_uastc_to_astc(*pSource_block, pDst_block); + break; + } + case block_format::cETC2_EAC_R11: + { + if (channel0 < 0) + channel0 = 0; + status = transcode_uastc_to_etc2_eac_r11(*pSource_block, pDst_block, high_quality, channel0); + break; + } + case block_format::cETC2_EAC_RG11: + { + if (channel0 < 0) + channel0 = 0; + if (channel1 < 0) + channel1 = 3; + status = transcode_uastc_to_etc2_eac_rg11(*pSource_block, pDst_block, high_quality, channel0, channel1); + break; + } + case block_format::cRGBA32: + { + color32 block_pixels[4][4]; + status = unpack_uastc(*pSource_block, (color32 *)block_pixels, false); + + assert(sizeof(uint32_t) == output_block_or_pixel_stride_in_bytes); + uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint32_t); + + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); + + for (uint32_t y = 0; y < max_y; y++) + { + for (uint32_t x = 0; x < max_x; x++) + { + const color32& c = block_pixels[y][x]; + + pDst_pixels[0 + 4 * x] = c.r; + pDst_pixels[1 + 4 * x] = c.g; + pDst_pixels[2 + 4 * x] = c.b; + pDst_pixels[3 + 4 * x] = c.a; + } + + pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint32_t); + } + + break; + } + case block_format::cRGB565: + case block_format::cBGR565: + { + color32 block_pixels[4][4]; + status = unpack_uastc(*pSource_block, (color32*)block_pixels, false); + + assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); + uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); + + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); + + for (uint32_t y = 0; y < max_y; y++) + { + for (uint32_t x = 0; x < max_x; x++) + { + const color32& c = block_pixels[y][x]; + + const uint16_t packed = (fmt == block_format::cRGB565) ? static_cast<uint16_t>((mul_8(c.r, 31) << 11) | (mul_8(c.g, 63) << 5) | mul_8(c.b, 31)) : + static_cast<uint16_t>((mul_8(c.b, 31) << 11) | (mul_8(c.g, 63) << 5) | mul_8(c.r, 31)); + + pDst_pixels[x * 2 + 0] = (uint8_t)(packed & 0xFF); + pDst_pixels[x * 2 + 1] = (uint8_t)((packed >> 8) & 0xFF); + } + + pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t); + } + + break; + } + case block_format::cRGBA4444: + { + color32 block_pixels[4][4]; + status = unpack_uastc(*pSource_block, (color32*)block_pixels, false); + + assert(sizeof(uint16_t) == output_block_or_pixel_stride_in_bytes); + uint8_t* pDst_pixels = static_cast<uint8_t*>(pDst_blocks) + (block_x * 4 + block_y * 4 * output_row_pitch_in_blocks_or_pixels) * sizeof(uint16_t); + + const uint32_t max_x = basisu::minimum<int>(4, (int)output_row_pitch_in_blocks_or_pixels - (int)block_x * 4); + const uint32_t max_y = basisu::minimum<int>(4, (int)output_rows_in_pixels - (int)block_y * 4); + + for (uint32_t y = 0; y < max_y; y++) + { + for (uint32_t x = 0; x < max_x; x++) + { + const color32& c = block_pixels[y][x]; + + const uint16_t packed = static_cast<uint16_t>((mul_8(c.r, 15) << 12) | (mul_8(c.g, 15) << 8) | (mul_8(c.b, 15) << 4) | mul_8(c.a, 15)); + + pDst_pixels[x * 2 + 0] = (uint8_t)(packed & 0xFF); + pDst_pixels[x * 2 + 1] = (uint8_t)((packed >> 8) & 0xFF); + } + + pDst_pixels += output_row_pitch_in_blocks_or_pixels * sizeof(uint16_t); + } + break; + } + default: + assert(0); + break; + + } + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_slice: Transcoder failed to unpack a UASTC block - this is a bug, or the data was corrupted\n"); + return false; + } + + } // block_x + + } // block_y + } + + return true; +#else + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_slice: UASTC is unsupported\n"); + + BASISU_NOTE_UNUSED(decode_flags); + BASISU_NOTE_UNUSED(channel0); + BASISU_NOTE_UNUSED(channel1); + BASISU_NOTE_UNUSED(output_rows_in_pixels); + BASISU_NOTE_UNUSED(output_row_pitch_in_blocks_or_pixels); + BASISU_NOTE_UNUSED(output_block_or_pixel_stride_in_bytes); + BASISU_NOTE_UNUSED(fmt); + BASISU_NOTE_UNUSED(image_data_size); + BASISU_NOTE_UNUSED(pImage_data); + BASISU_NOTE_UNUSED(num_blocks_x); + BASISU_NOTE_UNUSED(num_blocks_y); + BASISU_NOTE_UNUSED(pDst_blocks); + + return false; +#endif + } + + bool basisu_lowlevel_uastc_transcoder::transcode_image( + transcoder_texture_format target_format, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + const uint8_t* pCompressed_data, uint32_t compressed_data_length, + uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, + uint32_t slice_offset, uint32_t slice_length, + uint32_t decode_flags, + bool has_alpha, + bool is_video, + uint32_t output_row_pitch_in_blocks_or_pixels, + basisu_transcoder_state* pState, + uint32_t output_rows_in_pixels, + int channel0, int channel1) + { + BASISU_NOTE_UNUSED(is_video); + BASISU_NOTE_UNUSED(level_index); + + if (((uint64_t)slice_offset + slice_length) > (uint64_t)compressed_data_length) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: source data buffer too small\n"); + return false; + } + + if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGB) || (target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)) + { + if ((!basisu::is_pow2(num_blocks_x * 4)) || (!basisu::is_pow2(num_blocks_y * 4))) + { + // PVRTC1 only supports power of 2 dimensions + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: PVRTC1 only supports power of 2 dimensions\n"); + return false; + } + } + + if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!has_alpha)) + { + // Switch to PVRTC1 RGB if the input doesn't have alpha. + target_format = transcoder_texture_format::cTFPVRTC1_4_RGB; + } + + const bool transcode_alpha_data_to_opaque_formats = (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0; + const uint32_t bytes_per_block_or_pixel = basis_get_bytes_per_block_or_pixel(target_format); + const uint32_t total_slice_blocks = num_blocks_x * num_blocks_y; + + if (!basis_validate_output_buffer_size(target_format, output_blocks_buf_size_in_blocks_or_pixels, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, output_rows_in_pixels, total_slice_blocks)) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: output buffer size too small\n"); + return false; + } + + bool status = false; + + // UASTC4x4 + switch (target_format) + { + case transcoder_texture_format::cTFETC1_RGB: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC1, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1); + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to ETC1 failed\n"); + } + break; + } + case transcoder_texture_format::cTFETC2_RGBA: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_RGBA, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC2_RGBA, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to ETC2 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBC1_RGB: + { + // TODO: ETC1S allows BC1 from alpha channel. That doesn't seem actually useful, though. + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC1, + bytes_per_block_or_pixel, true, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC1 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBC3_RGBA: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC3, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC3, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, channel0, channel1); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC3 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBC4_R: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, + // nullptr, 0, + // ((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC4, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, + ((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC4 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBC5_RG: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC5, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, + // nullptr, 0, + // 0, 3); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC5, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, + 0, 3); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC5 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBC7_RGBA: + case transcoder_texture_format::cTFBC7_ALT: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBC7, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to BC7 failed\n"); + } + break; + } + case transcoder_texture_format::cTFPVRTC1_4_RGB: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGB, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cPVRTC1_4_RGB, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to PVRTC1 RGB 4bpp failed\n"); + } + break; + } + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGBA, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cPVRTC1_4_RGBA, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to PVRTC1 RGBA 4bpp failed\n"); + } + break; + } + case transcoder_texture_format::cTFASTC_4x4_RGBA: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cASTC_4x4, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to ASTC 4x4 failed\n"); + } + break; + } + case transcoder_texture_format::cTFATC_RGB: + case transcoder_texture_format::cTFATC_RGBA: + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: UASTC->ATC currently unsupported\n"); + return false; + } + case transcoder_texture_format::cTFFXT1_RGB: + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: UASTC->FXT1 currently unsupported\n"); + return false; + } + case transcoder_texture_format::cTFPVRTC2_4_RGB: + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: UASTC->PVRTC2 currently unsupported\n"); + return false; + } + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: UASTC->PVRTC2 currently unsupported\n"); + return false; + } + case transcoder_texture_format::cTFETC2_EAC_R11: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, + // nullptr, 0, + // ((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC2_EAC_R11, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, + ((has_alpha) && (transcode_alpha_data_to_opaque_formats)) ? 3 : 0); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to EAC R11 failed\n"); + } + break; + } + case transcoder_texture_format::cTFETC2_EAC_RG11: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_RG11, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, + // nullptr, 0, + // 0, 3); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cETC2_EAC_RG11, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels, + 0, 3); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_basisu_lowlevel_uastc_transcodertranscoder::transcode_image: transcode_slice() to EAC RG11 failed\n"); + } + break; + } + case transcoder_texture_format::cTFRGBA32: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA32, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cRGBA32, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGBA32 failed\n"); + } + break; + } + case transcoder_texture_format::cTFRGB565: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGB565, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cRGB565, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGB565 failed\n"); + } + break; + } + case transcoder_texture_format::cTFBGR565: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBGR565, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cBGR565, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGB565 failed\n"); + } + break; + } + case transcoder_texture_format::cTFRGBA4444: + { + //status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA4444, bytes_per_block_or_pixel, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + status = transcode_slice(pOutput_blocks, num_blocks_x, num_blocks_y, pCompressed_data + slice_offset, slice_length, block_format::cRGBA4444, + bytes_per_block_or_pixel, false, has_alpha, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + if (!status) + { + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: transcode_slice() to RGBA4444 failed\n"); + } + break; + } + default: + { + assert(0); + BASISU_DEVEL_ERROR("basisu_lowlevel_uastc_transcoder::transcode_image: Invalid format\n"); + break; + } + } + + return status; + } + basisu_transcoder::basisu_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook) : - m_lowlevel_decoder(pGlobal_sel_codebook) + m_lowlevel_etc1s_decoder(pGlobal_sel_codebook), + m_ready_to_transcode(false) { } @@ -9027,22 +10011,33 @@ namespace basist return false; } - if (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) { - if (pHeader->m_total_slices & 1) + if (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) { - BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid alpha basis file\n"); + if (pHeader->m_total_slices & 1) + { + BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid alpha .basis file\n"); + return false; + } + } + + // This flag dates back to pre-Basis Universal, when .basis supported full ETC1 too. + if ((pHeader->m_flags & cBASISHeaderFlagETC1S) == 0) + { + BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: Invalid .basis file (ETC1S check)\n"); return false; } } - - if ((pHeader->m_flags & cBASISHeaderFlagETC1S) == 0) + else { - // We only support ETC1S in basis universal - BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: invalid basis file (ETC1S flag check)\n"); - return false; + if ((pHeader->m_flags & cBASISHeaderFlagETC1S) != 0) + { + BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: Invalid .basis file (ETC1S check)\n"); + return false; + } } - + if ((pHeader->m_slice_desc_file_ofs >= data_size) || ((data_size - pHeader->m_slice_desc_file_ofs) < (sizeof(basis_slice_desc) * pHeader->m_total_slices)) ) @@ -9103,6 +10098,19 @@ namespace basist return pHeader->m_total_images; } + basis_tex_format basisu_transcoder::get_tex_format(const void* pData, uint32_t data_size) const + { + if (!validate_header_quick(pData, data_size)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::get_total_images: header validation failed\n"); + return basis_tex_format::cETC1S; + } + + const basis_file_header* pHeader = static_cast<const basis_file_header*>(pData); + + return (basis_tex_format)(uint32_t)pHeader->m_tex_format; + } + bool basisu_transcoder::get_image_info(const void* pData, uint32_t data_size, basisu_image_info& image_info, uint32_t image_index) const { if (!validate_header_quick(pData, data_size)) @@ -9145,8 +10153,17 @@ namespace basist image_info.m_image_index = image_index; image_info.m_total_levels = total_levels; - image_info.m_alpha_flag = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0; + + image_info.m_alpha_flag = false; + + // For ETC1S, if anything has alpha all images have alpha. For UASTC, we only report alpha when the image actually has alpha. + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) + image_info.m_alpha_flag = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0; + else + image_info.m_alpha_flag = (slice_desc.m_flags & cSliceDescFlagsHasAlpha) != 0; + image_info.m_iframe_flag = (slice_desc.m_flags & cSliceDescFlagsFrameIsIFrame) != 0; + image_info.m_width = slice_desc.m_num_blocks_x * 4; image_info.m_height = slice_desc.m_num_blocks_y * 4; image_info.m_orig_width = slice_desc.m_orig_width; @@ -9264,7 +10281,13 @@ namespace basist image_info.m_image_index = image_index; image_info.m_level_index = level_index; - image_info.m_alpha_flag = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0; + + // For ETC1S, if anything has alpha all images have alpha. For UASTC, we only report alpha when the image actually has alpha. + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) + image_info.m_alpha_flag = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0; + else + image_info.m_alpha_flag = (slice_desc.m_flags & cSliceDescFlagsHasAlpha) != 0; + image_info.m_iframe_flag = (slice_desc.m_flags & cSliceDescFlagsFrameIsIFrame) != 0; image_info.m_width = slice_desc.m_num_blocks_x * 4; image_info.m_height = slice_desc.m_num_blocks_y * 4; @@ -9275,6 +10298,21 @@ namespace basist image_info.m_total_blocks = image_info.m_num_blocks_x * image_info.m_num_blocks_y; image_info.m_first_slice_index = slice_index; + image_info.m_rgb_file_ofs = slice_desc.m_file_ofs; + image_info.m_rgb_file_len = slice_desc.m_file_size; + image_info.m_alpha_file_ofs = 0; + image_info.m_alpha_file_len = 0; + + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) + { + if (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) + { + assert((slice_index + 1) < (int)pHeader->m_total_slices); + image_info.m_alpha_file_ofs = pSlice_descs[slice_index + 1].m_file_ofs; + image_info.m_alpha_file_len = pSlice_descs[slice_index + 1].m_file_size; + } + } + return true; } @@ -9294,14 +10332,20 @@ namespace basist file_info.m_total_header_size = sizeof(basis_file_header) + pHeader->m_total_slices * sizeof(basis_slice_desc); file_info.m_total_selectors = pHeader->m_total_selectors; + file_info.m_selector_codebook_ofs = pHeader->m_selector_cb_file_ofs; file_info.m_selector_codebook_size = pHeader->m_selector_cb_file_size; file_info.m_total_endpoints = pHeader->m_total_endpoints; + file_info.m_endpoint_codebook_ofs = pHeader->m_endpoint_cb_file_ofs; file_info.m_endpoint_codebook_size = pHeader->m_endpoint_cb_file_size; + file_info.m_tables_ofs = pHeader->m_tables_file_ofs; file_info.m_tables_size = pHeader->m_tables_file_size; - file_info.m_etc1s = (pHeader->m_flags & cBASISHeaderFlagETC1S) != 0; + file_info.m_tex_format = static_cast<basis_tex_format>(static_cast<int>(pHeader->m_tex_format)); + + file_info.m_etc1s = (pHeader->m_tex_format == (int)basis_tex_format::cETC1S); + file_info.m_y_flipped = (pHeader->m_flags & cBASISHeaderFlagYFlipped) != 0; file_info.m_has_alpha_slices = (pHeader->m_flags & cBASISHeaderFlagHasAlphaSlices) != 0; @@ -9346,7 +10390,7 @@ namespace basist slice_info.m_image_index = pSlice_descs[i].m_image_index; slice_info.m_level_index = pSlice_descs[i].m_level_index; slice_info.m_unpacked_slice_crc16 = pSlice_descs[i].m_slice_data_crc16; - slice_info.m_alpha_flag = (pSlice_descs[i].m_flags & cSliceDescFlagsIsAlphaData) != 0; + slice_info.m_alpha_flag = (pSlice_descs[i].m_flags & cSliceDescFlagsHasAlpha) != 0; slice_info.m_iframe_flag = (pSlice_descs[i].m_flags & cSliceDescFlagsFrameIsIFrame) != 0; if (pSlice_descs[i].m_image_index >= pHeader->m_total_images) @@ -9366,15 +10410,9 @@ namespace basist return true; } - - bool basisu_transcoder::start_transcoding(const void* pData, uint32_t data_size) const + + bool basisu_transcoder::start_transcoding(const void* pData, uint32_t data_size) { - if (m_lowlevel_decoder.m_endpoints.size()) - { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: already called start_transcoding\n"); - return true; - } - if (!validate_header_quick(pData, data_size)) { BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: header validation failed\n"); @@ -9382,59 +10420,123 @@ namespace basist } const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData); - const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData); - if (!pHeader->m_endpoint_cb_file_size || !pHeader->m_selector_cb_file_size || !pHeader->m_tables_file_size) + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted (0)\n"); - } + if (m_lowlevel_etc1s_decoder.m_local_endpoints.size()) + { + m_lowlevel_etc1s_decoder.clear(); + } - if ((pHeader->m_endpoint_cb_file_ofs > data_size) || (pHeader->m_selector_cb_file_ofs > data_size) || (pHeader->m_tables_file_ofs > data_size)) - { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (1)\n"); - return false; - } + if (pHeader->m_flags & cBASISHeaderFlagUsesGlobalCodebook) + { + if (!m_lowlevel_etc1s_decoder.get_global_codebooks()) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: File uses global codebooks, but set_global_codebooks() has not been called\n"); + return false; + } + if (!m_lowlevel_etc1s_decoder.get_global_codebooks()->get_endpoints().size()) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: Global codebooks must be unpacked first by calling start_transcoding()\n"); + return false; + } + if ((m_lowlevel_etc1s_decoder.get_global_codebooks()->get_endpoints().size() != pHeader->m_total_endpoints) || + (m_lowlevel_etc1s_decoder.get_global_codebooks()->get_selectors().size() != pHeader->m_total_selectors)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: Global codebook size mismatch (wrong codebooks for file).\n"); + return false; + } + if (!pHeader->m_tables_file_size) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted (2)\n"); + return false; + } + if (pHeader->m_tables_file_ofs > data_size) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (4)\n"); + return false; + } + if (pHeader->m_tables_file_size > (data_size - pHeader->m_tables_file_ofs)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (5)\n"); + return false; + } + } + else + { + if (!pHeader->m_endpoint_cb_file_size || !pHeader->m_selector_cb_file_size || !pHeader->m_tables_file_size) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted (0)\n"); + return false; + } - if (pHeader->m_endpoint_cb_file_size > (data_size - pHeader->m_endpoint_cb_file_ofs)) - { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (2)\n"); - return false; - } + if ((pHeader->m_endpoint_cb_file_ofs > data_size) || (pHeader->m_selector_cb_file_ofs > data_size) || (pHeader->m_tables_file_ofs > data_size)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (1)\n"); + return false; + } - if (pHeader->m_selector_cb_file_size > (data_size - pHeader->m_selector_cb_file_ofs)) - { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (3)\n"); - return false; - } + if (pHeader->m_endpoint_cb_file_size > (data_size - pHeader->m_endpoint_cb_file_ofs)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (2)\n"); + return false; + } - if (pHeader->m_tables_file_size > (data_size - pHeader->m_tables_file_ofs)) - { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (3)\n"); - return false; - } + if (pHeader->m_selector_cb_file_size > (data_size - pHeader->m_selector_cb_file_ofs)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (3)\n"); + return false; + } - if (!m_lowlevel_decoder.decode_palettes( - pHeader->m_total_endpoints, pDataU8 + pHeader->m_endpoint_cb_file_ofs, pHeader->m_endpoint_cb_file_size, - pHeader->m_total_selectors, pDataU8 + pHeader->m_selector_cb_file_ofs, pHeader->m_selector_cb_file_size)) - { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: decode_palettes failed\n"); - return false; - } + if (pHeader->m_tables_file_size > (data_size - pHeader->m_tables_file_ofs)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: file is corrupted or passed in buffer too small (3)\n"); + return false; + } - if (!m_lowlevel_decoder.decode_tables(pDataU8 + pHeader->m_tables_file_ofs, pHeader->m_tables_file_size)) + if (!m_lowlevel_etc1s_decoder.decode_palettes( + pHeader->m_total_endpoints, pDataU8 + pHeader->m_endpoint_cb_file_ofs, pHeader->m_endpoint_cb_file_size, + pHeader->m_total_selectors, pDataU8 + pHeader->m_selector_cb_file_ofs, pHeader->m_selector_cb_file_size)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: decode_palettes failed\n"); + return false; + } + } + + if (!m_lowlevel_etc1s_decoder.decode_tables(pDataU8 + pHeader->m_tables_file_ofs, pHeader->m_tables_file_size)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: decode_tables failed\n"); + return false; + } + } + else { - BASISU_DEVEL_ERROR("basisu_transcoder::start_transcoding: decode_tables failed\n"); - return false; + // Nothing special to do for UASTC. + if (m_lowlevel_etc1s_decoder.m_local_endpoints.size()) + { + m_lowlevel_etc1s_decoder.clear(); + } } + + m_ready_to_transcode = true; + + return true; + } + bool basisu_transcoder::stop_transcoding() + { + m_lowlevel_etc1s_decoder.clear(); + + m_ready_to_transcode = false; + return true; } bool basisu_transcoder::transcode_slice(const void* pData, uint32_t data_size, uint32_t slice_index, void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, void *pAlpha_blocks, uint32_t output_rows_in_pixels) const + uint32_t output_block_or_pixel_stride_in_bytes, uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state* pState, void *pAlpha_blocks, uint32_t output_rows_in_pixels, int channel0, int channel1) const { - if (!m_lowlevel_decoder.m_endpoints.size()) + if (!m_ready_to_transcode) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: must call start_transcoding first\n"); return false; @@ -9529,16 +10631,26 @@ namespace basist BASISU_DEVEL_ERROR("basisu_transcoder::transcode_slice: invalid slice_desc.m_file_size, or passed in buffer too small\n"); return false; } - - return m_lowlevel_decoder.transcode_slice(pOutput_blocks, slice_desc.m_num_blocks_x, slice_desc.m_num_blocks_y, - pDataU8 + slice_desc.m_file_ofs, slice_desc.m_file_size, - fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, - (decode_flags & cDecodeFlagsOutputHasAlphaIndices) != 0, pAlpha_blocks, output_rows_in_pixels); + + if (pHeader->m_tex_format == (int)basis_tex_format::cUASTC4x4) + { + return m_lowlevel_uastc_decoder.transcode_slice(pOutput_blocks, slice_desc.m_num_blocks_x, slice_desc.m_num_blocks_y, + pDataU8 + slice_desc.m_file_ofs, slice_desc.m_file_size, + fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, + output_rows_in_pixels, channel0, channel1, decode_flags); + } + else + { + return m_lowlevel_etc1s_decoder.transcode_slice(pOutput_blocks, slice_desc.m_num_blocks_x, slice_desc.m_num_blocks_y, + pDataU8 + slice_desc.m_file_ofs, slice_desc.m_file_size, + fmt, output_block_or_pixel_stride_in_bytes, (decode_flags & cDecodeFlagsBC1ForbidThreeColorBlocks) == 0, *pHeader, slice_desc, output_row_pitch_in_blocks_or_pixels, pState, + (decode_flags & cDecodeFlagsOutputHasAlphaIndices) != 0, pAlpha_blocks, output_rows_in_pixels); + } } int basisu_transcoder::find_first_slice_index(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index) const { - (void)data_size; + BASISU_NOTE_UNUSED(data_size); const basis_file_header* pHeader = reinterpret_cast<const basis_file_header*>(pData); const uint8_t* pDataU8 = static_cast<const uint8_t*>(pData); @@ -9576,9 +10688,16 @@ namespace basist const basis_slice_desc& slice_desc = pSlice_descs[slice_iter]; if ((slice_desc.m_image_index == image_index) && (slice_desc.m_level_index == level_index)) { - const bool slice_alpha = (slice_desc.m_flags & cSliceDescFlagsIsAlphaData) != 0; - if (slice_alpha == alpha_data) + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) + { + const bool slice_alpha = (slice_desc.m_flags & cSliceDescFlagsHasAlpha) != 0; + if (slice_alpha == alpha_data) + return slice_iter; + } + else + { return slice_iter; + } } } @@ -9587,12 +10706,16 @@ namespace basist return -1; } - static void write_opaque_alpha_blocks( + void basisu_transcoder::write_opaque_alpha_blocks( uint32_t num_blocks_x, uint32_t num_blocks_y, - void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, block_format fmt, + void* pOutput_blocks, block_format fmt, uint32_t block_stride_in_bytes, uint32_t output_row_pitch_in_blocks_or_pixels) { - BASISU_NOTE_UNUSED(output_blocks_buf_size_in_blocks_or_pixels); + // 'num_blocks_y', 'pOutput_blocks' & 'block_stride_in_bytes' unused + // when disabling BASISD_SUPPORT_ETC2_EAC_A8 *and* BASISD_SUPPORT_DXT5A + BASISU_NOTE_UNUSED(num_blocks_y); + BASISU_NOTE_UNUSED(pOutput_blocks); + BASISU_NOTE_UNUSED(block_stride_in_bytes); if (!output_row_pitch_in_blocks_or_pixels) output_row_pitch_in_blocks_or_pixels = num_blocks_x; @@ -9606,8 +10729,7 @@ namespace basist blk.m_table = 13; // Selectors are all 4's - static const uint8_t s_etc2_eac_a8_sel4[6] = { 0x92, 0x49, 0x24, 0x92, 0x49, 0x24 }; - memcpy(&blk.m_selectors, s_etc2_eac_a8_sel4, sizeof(s_etc2_eac_a8_sel4)); + memcpy(&blk.m_selectors, g_etc2_eac_a8_sel4, sizeof(g_etc2_eac_a8_sel4)); for (uint32_t y = 0; y < num_blocks_y; y++) { @@ -9648,9 +10770,9 @@ namespace basist transcoder_texture_format fmt, uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, basisu_transcoder_state *pState, uint32_t output_rows_in_pixels) const { - const uint32_t bytes_per_block = basis_get_bytes_per_block(fmt); + const uint32_t bytes_per_block_or_pixel = basis_get_bytes_per_block_or_pixel(fmt); - if (!m_lowlevel_decoder.m_endpoints.size()) + if (!m_ready_to_transcode) { BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: must call start_transcoding() first\n"); return false; @@ -9693,37 +10815,40 @@ namespace basist fmt = transcoder_texture_format::cTFPVRTC1_4_RGB; } - if (pSlice_descs[slice_index].m_flags & cSliceDescFlagsIsAlphaData) + if (pHeader->m_tex_format == (int)basis_tex_format::cETC1S) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has out of order alpha slice\n"); - - // The first slice shouldn't have alpha data in a properly formed basis file - return false; - } - - if (basis_file_has_alpha_slices) - { - // The alpha data should immediately follow the color data, and have the same resolution. - if ((slice_index + 1U) >= pHeader->m_total_slices) + if (pSlice_descs[slice_index].m_flags & cSliceDescFlagsHasAlpha) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has missing alpha slice\n"); - // basis file is missing the alpha slice - return false; - } + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has out of order alpha slice\n"); - // Basic sanity checks - if ((pSlice_descs[slice_index + 1].m_flags & cSliceDescFlagsIsAlphaData) == 0) - { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has missing alpha slice (flag check)\n"); - // This slice should have alpha data + // The first slice shouldn't have alpha data in a properly formed basis file return false; } - if ((pSlice_descs[slice_index].m_num_blocks_x != pSlice_descs[slice_index + 1].m_num_blocks_x) || (pSlice_descs[slice_index].m_num_blocks_y != pSlice_descs[slice_index + 1].m_num_blocks_y)) + if (basis_file_has_alpha_slices) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file slice dimensions bad\n"); - // Alpha slice should have been the same res as the color slice - return false; + // The alpha data should immediately follow the color data, and have the same resolution. + if ((slice_index + 1U) >= pHeader->m_total_slices) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has missing alpha slice\n"); + // basis file is missing the alpha slice + return false; + } + + // Basic sanity checks + if ((pSlice_descs[slice_index + 1].m_flags & cSliceDescFlagsHasAlpha) == 0) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file has missing alpha slice (flag check)\n"); + // This slice should have alpha data + return false; + } + + if ((pSlice_descs[slice_index].m_num_blocks_x != pSlice_descs[slice_index + 1].m_num_blocks_x) || (pSlice_descs[slice_index].m_num_blocks_y != pSlice_descs[slice_index + 1].m_num_blocks_y)) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: alpha basis file slice dimensions bad\n"); + // Alpha slice should have been the same res as the color slice + return false; + } } } @@ -9735,798 +10860,6745 @@ namespace basist { // The transcoder doesn't write beyond total_slice_blocks, so we need to clear the rest ourselves. // For GL usage, PVRTC1 4bpp image size is (max(width, 8)* max(height, 8) * 4 + 7) / 8. - // However, for KTX and internally in Basis this formula isn't used, it's just ((width+3)/4) * ((height+3)/4) * bytes_per_block. This is all the transcoder actually writes to memory. - memset(static_cast<uint8_t*>(pOutput_blocks) + total_slice_blocks * bytes_per_block, 0, (output_blocks_buf_size_in_blocks_or_pixels - total_slice_blocks) * bytes_per_block); + // However, for KTX and internally in Basis this formula isn't used, it's just ((width+3)/4) * ((height+3)/4) * bytes_per_block_or_pixel. This is all the transcoder actually writes to memory. + memset(static_cast<uint8_t*>(pOutput_blocks) + total_slice_blocks * bytes_per_block_or_pixel, 0, (output_blocks_buf_size_in_blocks_or_pixels - total_slice_blocks) * bytes_per_block_or_pixel); } - + + if (pHeader->m_tex_format == (int)basis_tex_format::cUASTC4x4) + { + const basis_slice_desc* pSlice_desc = &pSlice_descs[slice_index]; + + // Use the container independent image transcode method. + status = m_lowlevel_uastc_decoder.transcode_image(fmt, + pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, + (const uint8_t*)pData, data_size, pSlice_desc->m_num_blocks_x, pSlice_desc->m_num_blocks_y, pSlice_desc->m_orig_width, pSlice_desc->m_orig_height, pSlice_desc->m_level_index, + pSlice_desc->m_file_ofs, pSlice_desc->m_file_size, + decode_flags, basis_file_has_alpha_slices, pHeader->m_tex_type == cBASISTexTypeVideoFrames, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + } + else + { + // ETC1S + const basis_slice_desc* pSlice_desc = &pSlice_descs[slice_index]; + const basis_slice_desc* pAlpha_slice_desc = basis_file_has_alpha_slices ? &pSlice_descs[slice_index + 1] : nullptr; + + assert((pSlice_desc->m_flags & cSliceDescFlagsHasAlpha) == 0); + + if (pAlpha_slice_desc) + { + // Basic sanity checks + assert((pAlpha_slice_desc->m_flags & cSliceDescFlagsHasAlpha) != 0); + assert(pSlice_desc->m_num_blocks_x == pAlpha_slice_desc->m_num_blocks_x); + assert(pSlice_desc->m_num_blocks_y == pAlpha_slice_desc->m_num_blocks_y); + assert(pSlice_desc->m_level_index == pAlpha_slice_desc->m_level_index); + } + + // Use the container independent image transcode method. + status = m_lowlevel_etc1s_decoder.transcode_image(fmt, + pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, + (const uint8_t *)pData, data_size, pSlice_desc->m_num_blocks_x, pSlice_desc->m_num_blocks_y, pSlice_desc->m_orig_width, pSlice_desc->m_orig_height, pSlice_desc->m_level_index, + pSlice_desc->m_file_ofs, pSlice_desc->m_file_size, + (pAlpha_slice_desc != nullptr) ? (uint32_t)pAlpha_slice_desc->m_file_ofs : 0U, (pAlpha_slice_desc != nullptr) ? (uint32_t)pAlpha_slice_desc->m_file_size : 0U, + decode_flags, basis_file_has_alpha_slices, pHeader->m_tex_type == cBASISTexTypeVideoFrames, output_row_pitch_in_blocks_or_pixels, pState, output_rows_in_pixels); + + } // if (pHeader->m_tex_format == (int)basis_tex_format::cUASTC4x4) + + if (!status) + { + BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: Returning false\n"); + } + else + { + //BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: Returning true\n"); + } + + return status; + } + + uint32_t basis_get_bytes_per_block_or_pixel(transcoder_texture_format fmt) + { switch (fmt) { case transcoder_texture_format::cTFETC1_RGB: + case transcoder_texture_format::cTFBC1_RGB: + case transcoder_texture_format::cTFBC4_R: + case transcoder_texture_format::cTFPVRTC1_4_RGB: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + case transcoder_texture_format::cTFATC_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + case transcoder_texture_format::cTFETC2_EAC_R11: + return 8; + case transcoder_texture_format::cTFBC7_RGBA: + case transcoder_texture_format::cTFBC7_ALT: + case transcoder_texture_format::cTFETC2_RGBA: + case transcoder_texture_format::cTFBC3_RGBA: + case transcoder_texture_format::cTFBC5_RG: + case transcoder_texture_format::cTFASTC_4x4_RGBA: + case transcoder_texture_format::cTFATC_RGBA: + case transcoder_texture_format::cTFFXT1_RGB: + case transcoder_texture_format::cTFETC2_EAC_RG11: + return 16; + case transcoder_texture_format::cTFRGBA32: + return sizeof(uint32_t); + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: + return sizeof(uint16_t); + default: + assert(0); + BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); + break; + } + return 0; + } + + const char* basis_get_format_name(transcoder_texture_format fmt) + { + switch (fmt) { - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + case transcoder_texture_format::cTFETC1_RGB: return "ETC1_RGB"; + case transcoder_texture_format::cTFBC1_RGB: return "BC1_RGB"; + case transcoder_texture_format::cTFBC4_R: return "BC4_R"; + case transcoder_texture_format::cTFPVRTC1_4_RGB: return "PVRTC1_4_RGB"; + case transcoder_texture_format::cTFPVRTC1_4_RGBA: return "PVRTC1_4_RGBA"; + case transcoder_texture_format::cTFBC7_RGBA: return "BC7_RGBA"; + case transcoder_texture_format::cTFBC7_ALT: return "BC7_RGBA"; + case transcoder_texture_format::cTFETC2_RGBA: return "ETC2_RGBA"; + case transcoder_texture_format::cTFBC3_RGBA: return "BC3_RGBA"; + case transcoder_texture_format::cTFBC5_RG: return "BC5_RG"; + case transcoder_texture_format::cTFASTC_4x4_RGBA: return "ASTC_RGBA"; + case transcoder_texture_format::cTFATC_RGB: return "ATC_RGB"; + case transcoder_texture_format::cTFATC_RGBA: return "ATC_RGBA"; + case transcoder_texture_format::cTFRGBA32: return "RGBA32"; + case transcoder_texture_format::cTFRGB565: return "RGB565"; + case transcoder_texture_format::cTFBGR565: return "BGR565"; + case transcoder_texture_format::cTFRGBA4444: return "RGBA4444"; + case transcoder_texture_format::cTFFXT1_RGB: return "FXT1_RGB"; + case transcoder_texture_format::cTFPVRTC2_4_RGB: return "PVRTC2_4_RGB"; + case transcoder_texture_format::cTFPVRTC2_4_RGBA: return "PVRTC2_4_RGBA"; + case transcoder_texture_format::cTFETC2_EAC_R11: return "ETC2_EAC_R11"; + case transcoder_texture_format::cTFETC2_EAC_RG11: return "ETC2_EAC_RG11"; + default: + assert(0); + BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); + break; + } + return ""; + } - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + const char* basis_get_block_format_name(block_format fmt) + { + switch (fmt) + { + case block_format::cETC1: return "ETC1"; + case block_format::cBC1: return "BC1"; + case block_format::cPVRTC1_4_RGB: return "PVRTC1_4_RGB"; + case block_format::cPVRTC1_4_RGBA: return "PVRTC1_4_RGBA"; + case block_format::cBC7: return "BC7"; + case block_format::cETC2_RGBA: return "ETC2_RGBA"; + case block_format::cBC3: return "BC3"; + case block_format::cASTC_4x4: return "ASTC_4x4"; + case block_format::cATC_RGB: return "ATC_RGB"; + case block_format::cRGBA32: return "RGBA32"; + case block_format::cRGB565: return "RGB565"; + case block_format::cBGR565: return "BGR565"; + case block_format::cRGBA4444: return "RGBA4444"; + case block_format::cFXT1_RGB: return "FXT1_RGB"; + case block_format::cPVRTC2_4_RGB: return "PVRTC2_4_RGB"; + case block_format::cPVRTC2_4_RGBA: return "PVRTC2_4_RGBA"; + case block_format::cETC2_EAC_R11: return "ETC2_EAC_R11"; + case block_format::cETC2_EAC_RG11: return "ETC2_EAC_RG11"; + default: + assert(0); + BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); + break; + } + return ""; + } + + const char* basis_get_texture_type_name(basis_texture_type tex_type) + { + switch (tex_type) + { + case cBASISTexType2D: return "2D"; + case cBASISTexType2DArray: return "2D array"; + case cBASISTexTypeCubemapArray: return "cubemap array"; + case cBASISTexTypeVideoFrames: return "video"; + case cBASISTexTypeVolume: return "3D"; + default: + assert(0); + BASISU_DEVEL_ERROR("basis_get_texture_type_name: Invalid tex_type\n"); + break; + } + return ""; + } + + bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt) + { + switch (fmt) + { + case transcoder_texture_format::cTFETC2_RGBA: + case transcoder_texture_format::cTFBC3_RGBA: + case transcoder_texture_format::cTFASTC_4x4_RGBA: + case transcoder_texture_format::cTFBC7_RGBA: + case transcoder_texture_format::cTFBC7_ALT: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + case transcoder_texture_format::cTFATC_RGBA: + case transcoder_texture_format::cTFRGBA32: + case transcoder_texture_format::cTFRGBA4444: + return true; + default: + break; + } + return false; + } + + basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt) + { + switch (fmt) + { + case transcoder_texture_format::cTFETC1_RGB: return basisu::texture_format::cETC1; + case transcoder_texture_format::cTFBC1_RGB: return basisu::texture_format::cBC1; + case transcoder_texture_format::cTFBC4_R: return basisu::texture_format::cBC4; + case transcoder_texture_format::cTFPVRTC1_4_RGB: return basisu::texture_format::cPVRTC1_4_RGB; + case transcoder_texture_format::cTFPVRTC1_4_RGBA: return basisu::texture_format::cPVRTC1_4_RGBA; + case transcoder_texture_format::cTFBC7_RGBA: return basisu::texture_format::cBC7; + case transcoder_texture_format::cTFBC7_ALT: return basisu::texture_format::cBC7; + case transcoder_texture_format::cTFETC2_RGBA: return basisu::texture_format::cETC2_RGBA; + case transcoder_texture_format::cTFBC3_RGBA: return basisu::texture_format::cBC3; + case transcoder_texture_format::cTFBC5_RG: return basisu::texture_format::cBC5; + case transcoder_texture_format::cTFASTC_4x4_RGBA: return basisu::texture_format::cASTC4x4; + case transcoder_texture_format::cTFATC_RGB: return basisu::texture_format::cATC_RGB; + case transcoder_texture_format::cTFATC_RGBA: return basisu::texture_format::cATC_RGBA_INTERPOLATED_ALPHA; + case transcoder_texture_format::cTFRGBA32: return basisu::texture_format::cRGBA32; + case transcoder_texture_format::cTFRGB565: return basisu::texture_format::cRGB565; + case transcoder_texture_format::cTFBGR565: return basisu::texture_format::cBGR565; + case transcoder_texture_format::cTFRGBA4444: return basisu::texture_format::cRGBA4444; + case transcoder_texture_format::cTFFXT1_RGB: return basisu::texture_format::cFXT1_RGB; + case transcoder_texture_format::cTFPVRTC2_4_RGB: return basisu::texture_format::cPVRTC2_4_RGBA; + case transcoder_texture_format::cTFPVRTC2_4_RGBA: return basisu::texture_format::cPVRTC2_4_RGBA; + case transcoder_texture_format::cTFETC2_EAC_R11: return basisu::texture_format::cETC2_R11_EAC; + case transcoder_texture_format::cTFETC2_EAC_RG11: return basisu::texture_format::cETC2_RG11_EAC; + default: + assert(0); + BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); + break; + } + return basisu::texture_format::cInvalidTextureFormat; + } + + bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type) + { + switch (tex_type) + { + case transcoder_texture_format::cTFRGBA32: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: + return true; + default: + break; + } + return false; + } + + bool basis_block_format_is_uncompressed(block_format blk_fmt) + { + switch (blk_fmt) + { + case block_format::cRGB32: + case block_format::cRGBA32: + case block_format::cA32: + case block_format::cRGB565: + case block_format::cBGR565: + case block_format::cRGBA4444: + case block_format::cRGBA4444_COLOR: + case block_format::cRGBA4444_ALPHA: + case block_format::cRGBA4444_COLOR_OPAQUE: + return true; + default: + break; + } + return false; + } + + uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt) + { + switch (fmt) + { + case transcoder_texture_format::cTFRGBA32: + return sizeof(uint32_t); + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: + return sizeof(uint16_t); + default: + break; + } + return 0; + } + + uint32_t basis_get_block_width(transcoder_texture_format tex_type) + { + switch (tex_type) + { + case transcoder_texture_format::cTFFXT1_RGB: + return 8; + default: + break; + } + return 4; + } + + uint32_t basis_get_block_height(transcoder_texture_format tex_type) + { + BASISU_NOTE_UNUSED(tex_type); + return 4; + } + + bool basis_is_format_supported(transcoder_texture_format tex_type, basis_tex_format fmt) + { + if (fmt == basis_tex_format::cUASTC4x4) + { +#if BASISD_SUPPORT_UASTC + switch (tex_type) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC1 failed\n"); + // These niche formats aren't currently supported for UASTC - everything else is. + case transcoder_texture_format::cTFPVRTC2_4_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + case transcoder_texture_format::cTFATC_RGB: + case transcoder_texture_format::cTFATC_RGBA: + case transcoder_texture_format::cTFFXT1_RGB: + return false; + default: + return true; } - break; +#endif } - case transcoder_texture_format::cTFBC1_RGB: + else { -#if !BASISD_SUPPORT_DXT1 - return false; + switch (tex_type) + { + // ETC1 and uncompressed are always supported. + case transcoder_texture_format::cTFETC1_RGB: + case transcoder_texture_format::cTFRGBA32: + case transcoder_texture_format::cTFRGB565: + case transcoder_texture_format::cTFBGR565: + case transcoder_texture_format::cTFRGBA4444: + return true; +#if BASISD_SUPPORT_DXT1 + case transcoder_texture_format::cTFBC1_RGB: + return true; +#endif +#if BASISD_SUPPORT_DXT5A + case transcoder_texture_format::cTFBC4_R: + case transcoder_texture_format::cTFBC5_RG: + return true; +#endif +#if BASISD_SUPPORT_DXT1 && BASISD_SUPPORT_DXT5A + case transcoder_texture_format::cTFBC3_RGBA: + return true; +#endif +#if BASISD_SUPPORT_PVRTC1 + case transcoder_texture_format::cTFPVRTC1_4_RGB: + case transcoder_texture_format::cTFPVRTC1_4_RGBA: + return true; +#endif +#if BASISD_SUPPORT_BC7_MODE5 + case transcoder_texture_format::cTFBC7_RGBA: + case transcoder_texture_format::cTFBC7_ALT: + return true; +#endif +#if BASISD_SUPPORT_ETC2_EAC_A8 + case transcoder_texture_format::cTFETC2_RGBA: + return true; +#endif +#if BASISD_SUPPORT_ASTC + case transcoder_texture_format::cTFASTC_4x4_RGBA: + return true; +#endif +#if BASISD_SUPPORT_ATC + case transcoder_texture_format::cTFATC_RGB: + case transcoder_texture_format::cTFATC_RGBA: + return true; +#endif +#if BASISD_SUPPORT_FXT1 + case transcoder_texture_format::cTFFXT1_RGB: + return true; +#endif +#if BASISD_SUPPORT_PVRTC2 + case transcoder_texture_format::cTFPVRTC2_4_RGB: + case transcoder_texture_format::cTFPVRTC2_4_RGBA: + return true; #endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; +#if BASISD_SUPPORT_ETC2_EAC_RG11 + case transcoder_texture_format::cTFETC2_EAC_R11: + case transcoder_texture_format::cTFETC2_EAC_RG11: + return true; +#endif + default: + break; + } + } - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + return false; + } + + // ------------------------------------------------------------------------------------------------------ + // UASTC + // ------------------------------------------------------------------------------------------------------ + +#if BASISD_SUPPORT_UASTC + const astc_bc7_common_partition2_desc g_astc_bc7_common_partitions2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2] = + { + { 0, 28, false }, { 1, 20, false }, { 2, 16, true }, { 3, 29, false }, + { 4, 91, true }, { 5, 9, false }, { 6, 107, true }, { 7, 72, true }, + { 8, 149, false }, { 9, 204, true }, { 10, 50, false }, { 11, 114, true }, + { 12, 496, true }, { 13, 17, true }, { 14, 78, false }, { 15, 39, true }, + { 17, 252, true }, { 18, 828, true }, { 19, 43, false }, { 20, 156, false }, + { 21, 116, false }, { 22, 210, true }, { 23, 476, true }, { 24, 273, false }, + { 25, 684, true }, { 26, 359, false }, { 29, 246, true }, { 32, 195, true }, + { 33, 694, true }, { 52, 524, true } + }; + + const bc73_astc2_common_partition_desc g_bc7_3_astc2_common_partitions[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS] = + { + { 10, 36, 4 }, { 11, 48, 4 }, { 0, 61, 3 }, { 2, 137, 4 }, + { 8, 161, 5 }, { 13, 183, 4 }, { 1, 226, 2 }, { 33, 281, 2 }, + { 40, 302, 3 }, { 20, 307, 4 }, { 21, 479, 0 }, { 58, 495, 3 }, + { 3, 593, 0 }, { 32, 594, 2 }, { 59, 605, 1 }, { 34, 799, 3 }, + { 20, 812, 1 }, { 14, 988, 4 }, { 31, 993, 3 } + }; + + const astc_bc7_common_partition3_desc g_astc_bc7_common_partitions3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3] = + { + { 4, 260, 0 }, { 8, 74, 5 }, { 9, 32, 5 }, { 10, 156, 2 }, + { 11, 183, 2 }, { 12, 15, 0 }, { 13, 745, 4 }, { 20, 0, 1 }, + { 35, 335, 1 }, { 36, 902, 5 }, { 57, 254, 0 } + }; + + const uint8_t g_astc_to_bc7_partition_index_perm_tables[6][3] = { { 0, 1, 2 }, { 1, 2, 0 }, { 2, 0, 1 }, { 2, 1, 0 }, { 0, 2, 1 }, { 1, 0, 2 } }; + + const uint8_t g_bc7_to_astc_partition_index_perm_tables[6][3] = { { 0, 1, 2 }, { 2, 0, 1 }, { 1, 2, 0 }, { 2, 1, 0 }, { 0, 2, 1 }, { 1, 0, 2 } }; + + uint32_t bc7_convert_partition_index_3_to_2(uint32_t p, uint32_t k) + { + assert(k < 6); + switch (k >> 1) + { + case 0: + if (p <= 1) + p = 0; + else + p = 1; + break; + case 1: + if (p == 0) + p = 0; + else + p = 1; + break; + case 2: + if ((p == 0) || (p == 2)) + p = 0; + else + p = 1; + break; + } + if (k & 1) + p = 1 - p; + return p; + } + + static const uint8_t g_zero_pattern[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + const uint8_t g_astc_bc7_patterns2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][16] = + { + { 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1 }, { 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1 }, { 1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 }, { 0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1 }, + { 1,1,1,1,1,1,1,0,1,1,1,0,1,1,0,0 }, { 0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1 }, { 1,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0 }, { 1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0 }, + { 0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1 }, { 1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1 }, { 1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0 }, + { 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0 }, { 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 }, { 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1 }, { 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 }, + { 1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1 }, { 1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,1 }, { 0,1,1,1,0,0,1,1,0,0,0,1,0,0,0,0 }, { 0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0 }, + { 0,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0 }, { 1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,1 }, { 1,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0 }, { 0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0 }, + { 1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1 }, { 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0 }, { 1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1 }, { 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 }, + { 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0 }, { 1,0,0,1,0,0,1,1,0,1,1,0,1,1,0,0 } + }; + + const uint8_t g_astc_bc7_patterns3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][16] = + { + { 0,0,0,0,0,0,0,0,1,1,2,2,1,1,2,2 }, { 1,1,1,1,1,1,1,1,0,0,0,0,2,2,2,2 }, { 1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2 }, { 1,1,1,1,2,2,2,2,0,0,0,0,0,0,0,0 }, + { 1,1,2,0,1,1,2,0,1,1,2,0,1,1,2,0 }, { 0,1,1,2,0,1,1,2,0,1,1,2,0,1,1,2 }, { 0,2,1,1,0,2,1,1,0,2,1,1,0,2,1,1 }, { 2,0,0,0,2,0,0,0,2,1,1,1,2,1,1,1 }, + { 2,0,1,2,2,0,1,2,2,0,1,2,2,0,1,2 }, { 1,1,1,1,0,0,0,0,2,2,2,2,1,1,1,1 }, { 0,0,2,2,0,0,1,1,0,0,1,1,0,0,2,2 } + }; + + const uint8_t g_bc7_3_astc2_patterns2[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][16] = + { + { 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0 }, { 0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0 }, { 1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,1,0,0,1,1,0,0,1,1 }, + { 1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1 }, { 0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0 }, { 0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1 }, { 0,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1 }, + { 1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0 }, { 0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0 }, { 1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0 }, + { 0,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1 }, { 1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0 }, { 1,1,0,0,1,1,0,0,1,1,0,0,1,0,0,0 }, + { 1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,0 }, { 0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0 }, { 1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0 } + }; + + const uint8_t g_astc_bc7_pattern2_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][3] = + { + { 0, 2 }, { 0, 3 }, { 1, 0 }, { 0, 3 }, { 7, 0 }, { 0, 2 }, { 3, 0 }, { 7, 0 }, + { 0, 11 }, { 2, 0 }, { 0, 7 }, { 11, 0 }, { 3, 0 }, { 8, 0 }, { 0, 4 }, { 12, 0 }, + { 1, 0 }, { 8, 0 }, { 0, 1 }, { 0, 2 }, { 0, 4 }, { 8, 0 }, { 1, 0 }, { 0, 2 }, + { 4, 0 }, { 0, 1 }, { 4, 0 }, { 1, 0 }, { 4, 0 }, { 1, 0 } + }; + + const uint8_t g_astc_bc7_pattern3_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][3] = + { + { 0, 8, 10 }, { 8, 0, 12 }, { 4, 0, 12 }, { 8, 0, 4 }, { 3, 0, 2 }, { 0, 1, 3 }, { 0, 2, 1 }, { 1, 9, 0 }, { 1, 2, 0 }, { 4, 0, 8 }, { 0, 6, 2 } + }; + + const uint8_t g_bc7_3_astc2_patterns2_anchors[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][3] = + { + { 0, 4 }, { 0, 2 }, { 2, 0 }, { 0, 7 }, { 8, 0 }, { 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 0 }, { 0, 1 }, { 0, 8 }, { 2, 0 }, { 0, 1 }, { 0, 7 }, { 12, 0 }, { 2, 0 }, { 9, 0 }, { 0, 2 }, { 4, 0 } + }; + + const uint32_t g_uastc_mode_huff_codes[TOTAL_UASTC_MODES + 1][2] = + { + { 0x1, 4 }, + { 0x35, 6 }, + { 0x1D, 5 }, + { 0x3, 5 }, + + { 0x13, 5 }, + { 0xB, 5 }, + { 0x1B, 5 }, + { 0x7, 5 }, + + { 0x17, 5 }, + { 0xF, 5 }, + { 0x2, 3 }, + { 0x0, 2 }, + + { 0x6, 3 }, + { 0x1F, 5 }, + { 0xD, 5 }, + { 0x5, 7 }, + + { 0x15, 6 }, + { 0x25, 6 }, + { 0x9, 4 }, + { 0x45, 7 } // future expansion + }; + + // If g_uastc_mode_huff_codes[] changes this table must be updated! + static const uint8_t g_uastc_huff_modes[128] = + { + 11,0,10,3,11,15,12,7,11,18,10,5,11,14,12,9,11,0,10,4,11,16,12,8,11,18,10,6,11,2,12,13,11,0,10,3,11,17,12,7,11,18,10,5,11,14,12,9,11,0,10,4,11,1,12,8,11,18,10,6,11,2,12,13,11,0,10,3,11, + 19,12,7,11,18,10,5,11,14,12,9,11,0,10,4,11,16,12,8,11,18,10,6,11,2,12,13,11,0,10,3,11,17,12,7,11,18,10,5,11,14,12,9,11,0,10,4,11,1,12,8,11,18,10,6,11,2,12,13 + }; + + const uint8_t g_uastc_mode_weight_bits[TOTAL_UASTC_MODES] = { 4, 2, 3, 2, 2, 3, 2, 2, 0, 2, 4, 2, 3, 1, 2, 4, 2, 2, 5 }; + const uint8_t g_uastc_mode_weight_ranges[TOTAL_UASTC_MODES] = { 8, 2, 5, 2, 2, 5, 2, 2, 0, 2, 8, 2, 5, 0, 2, 8, 2, 2, 11 }; + const uint8_t g_uastc_mode_endpoint_ranges[TOTAL_UASTC_MODES] = { 19, 20, 8, 7, 12, 20, 18, 12, 0, 8, 13, 13, 19, 20, 20, 20, 20, 20, 11 }; + const uint8_t g_uastc_mode_subsets[TOTAL_UASTC_MODES] = { 1, 1, 2, 3, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1 }; + const uint8_t g_uastc_mode_planes[TOTAL_UASTC_MODES] = { 1, 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1 }; + const uint8_t g_uastc_mode_comps[TOTAL_UASTC_MODES] = { 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 3 }; + const uint8_t g_uastc_mode_has_etc1_bias[TOTAL_UASTC_MODES] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; + const uint8_t g_uastc_mode_has_bc1_hint0[TOTAL_UASTC_MODES] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; + const uint8_t g_uastc_mode_has_bc1_hint1[TOTAL_UASTC_MODES] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; + const uint8_t g_uastc_mode_cem[TOTAL_UASTC_MODES] = { 8, 8, 8, 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 12, 12, 4, 4, 4, 8 }; + const uint8_t g_uastc_mode_has_alpha[TOTAL_UASTC_MODES] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }; + const uint8_t g_uastc_mode_is_la[TOTAL_UASTC_MODES] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0 }; + const uint8_t g_uastc_mode_total_hint_bits[TOTAL_UASTC_MODES] = { 15, 15, 15, 15, 15, 15, 15, 15, 0, 23, 17, 17, 17, 23, 23, 23, 23, 23, 15 }; + + // bits, trits, quints + const int g_astc_bise_range_table[TOTAL_ASTC_RANGES][3] = + { + { 1, 0, 0 }, // 0-1 0 + { 0, 1, 0 }, // 0-2 1 + { 2, 0, 0 }, // 0-3 2 + { 0, 0, 1 }, // 0-4 3 + + { 1, 1, 0 }, // 0-5 4 + { 3, 0, 0 }, // 0-7 5 + { 1, 0, 1 }, // 0-9 6 + { 2, 1, 0 }, // 0-11 7 + + { 4, 0, 0 }, // 0-15 8 + { 2, 0, 1 }, // 0-19 9 + { 3, 1, 0 }, // 0-23 10 + { 5, 0, 0 }, // 0-31 11 + + { 3, 0, 1 }, // 0-39 12 + { 4, 1, 0 }, // 0-47 13 + { 6, 0, 0 }, // 0-63 14 + { 4, 0, 1 }, // 0-79 15 + + { 5, 1, 0 }, // 0-95 16 + { 7, 0, 0 }, // 0-127 17 + { 5, 0, 1 }, // 0-159 18 + { 6, 1, 0 }, // 0-191 19 + + { 8, 0, 0 }, // 0-255 20 + }; + + int astc_get_levels(int range) + { + assert(range < (int)BC7ENC_TOTAL_ASTC_RANGES); + return (1 + 2 * g_astc_bise_range_table[range][1] + 4 * g_astc_bise_range_table[range][2]) << g_astc_bise_range_table[range][0]; + } + + // g_astc_unquant[] is the inverse of g_astc_sorted_order_unquant[] + astc_quant_bin g_astc_unquant[BC7ENC_TOTAL_ASTC_RANGES][256]; // [ASTC encoded endpoint index] + + // Taken right from the ASTC spec. + static struct + { + const char* m_pB_str; + uint32_t m_c; + } g_astc_endpoint_unquant_params[BC7ENC_TOTAL_ASTC_RANGES] = + { + { "", 0 }, + { "", 0 }, + { "", 0 }, + { "", 0 }, + { "000000000", 204, }, // 0-5 + { "", 0 }, + { "000000000", 113, }, // 0-9 + { "b000b0bb0", 93 }, // 0-11 + { "", 0 }, + { "b0000bb00", 54 }, // 0-19 + { "cb000cbcb", 44 }, // 0-23 + { "", 0 }, + { "cb0000cbc", 26 }, // 0-39 + { "dcb000dcb", 22 }, // 0-47 + { "", 0 }, + { "dcb0000dc", 13 }, // 0-79 + { "edcb000ed", 11 }, // 0-95 + { "", 0 }, + { "edcb0000e", 6 }, // 0-159 + { "fedcb000f", 5 }, // 0-191 + { "", 0 }, + }; + + bool astc_is_valid_endpoint_range(uint32_t range) + { + if ((g_astc_bise_range_table[range][1] == 0) && (g_astc_bise_range_table[range][2] == 0)) + return true; + + return g_astc_endpoint_unquant_params[range].m_c != 0; + } + + uint32_t unquant_astc_endpoint(uint32_t packed_bits, uint32_t packed_trits, uint32_t packed_quints, uint32_t range) + { + assert(range < BC7ENC_TOTAL_ASTC_RANGES); + + const uint32_t bits = g_astc_bise_range_table[range][0]; + const uint32_t trits = g_astc_bise_range_table[range][1]; + const uint32_t quints = g_astc_bise_range_table[range][2]; + + uint32_t val = 0; + if ((!trits) && (!quints)) + { + assert(!packed_trits && !packed_quints); + + int bits_left = 8; + while (bits_left > 0) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC1 failed\n"); + uint32_t v = packed_bits; + + int n = basisu::minimumi(bits_left, bits); + if (n < (int)bits) + v >>= (bits - n); + + assert(v < (1U << n)); + + val |= (v << (bits_left - n)); + bits_left -= n; } - break; } - case transcoder_texture_format::cTFBC4_R: + else { -#if !BASISD_SUPPORT_DXT5A - return false; -#endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + const uint32_t A = (packed_bits & 1) ? 511 : 0; + const uint32_t C = g_astc_endpoint_unquant_params[range].m_c; + const uint32_t D = trits ? packed_trits : packed_quints; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + assert(C); + + uint32_t B = 0; + for (uint32_t i = 0; i < 9; i++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC4 failed\n"); + B <<= 1; + + char c = g_astc_endpoint_unquant_params[range].m_pB_str[i]; + if (c != '0') + { + c -= 'a'; + B |= ((packed_bits >> c) & 1); + } } - break; + + val = D * C + B; + val = val ^ A; + val = (A & 0x80) | (val >> 2); } - case transcoder_texture_format::cTFPVRTC1_4_RGB: + + return val; + } + + uint32_t unquant_astc_endpoint_val(uint32_t packed_val, uint32_t range) + { + assert(range < BC7ENC_TOTAL_ASTC_RANGES); + assert(packed_val < (uint32_t)astc_get_levels(range)); + + const uint32_t bits = g_astc_bise_range_table[range][0]; + const uint32_t trits = g_astc_bise_range_table[range][1]; + const uint32_t quints = g_astc_bise_range_table[range][2]; + + if ((!trits) && (!quints)) + return unquant_astc_endpoint(packed_val, 0, 0, range); + else if (trits) + return unquant_astc_endpoint(packed_val & ((1 << bits) - 1), packed_val >> bits, 0, range); + else + return unquant_astc_endpoint(packed_val & ((1 << bits) - 1), 0, packed_val >> bits, range); + } + + // BC7 - Various BC7 tables/helpers + const uint32_t g_bc7_weights1[2] = { 0, 64 }; + const uint32_t g_bc7_weights2[4] = { 0, 21, 43, 64 }; + const uint32_t g_bc7_weights3[8] = { 0, 9, 18, 27, 37, 46, 55, 64 }; + const uint32_t g_bc7_weights4[16] = { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; + const uint32_t g_astc_weights4[16] = { 0, 4, 8, 12, 17, 21, 25, 29, 35, 39, 43, 47, 52, 56, 60, 64 }; + const uint32_t g_astc_weights5[32] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64 }; + const uint32_t g_astc_weights_3levels[3] = { 0, 32, 64 }; + + const uint8_t g_bc7_partition1[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + + const uint8_t g_bc7_partition2[64 * 16] = + { + 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1, 0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1, 0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1, 0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1, 0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1, 0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1, 0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1, 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1, 0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, + 0,0,0,0,1,0,0,0,1,1,1,0,1,1,1,1, 0,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,0, 0,1,1,1,0,0,1,1,0,0,0,1,0,0,0,0, 0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,1,1,0,0,1,1,1,0, 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0, 0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1, + 0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0, 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, 0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0, 0,0,0,1,0,1,1,1,1,1,1,0,1,0,0,0, 0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, 0,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0, 0,0,1,1,1,0,0,1,1,0,0,1,1,1,0,0, + 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1, 0,1,0,1,1,0,1,0,0,1,0,1,1,0,1,0, 0,0,1,1,0,0,1,1,1,1,0,0,1,1,0,0, 0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0, 0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0, 0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1, 0,1,0,1,1,0,1,0,1,0,1,0,0,1,0,1, + 0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,0, 0,0,0,1,0,0,1,1,1,1,0,0,1,0,0,0, 0,0,1,1,0,0,1,0,0,1,0,0,1,1,0,0, 0,0,1,1,1,0,1,1,1,1,0,1,1,1,0,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,0,1,1,1,1,0,0,1,1,0,0,0,0,1,1, 0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1, 0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0, + 0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0, 0,0,1,0,0,1,1,1,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,1,1,1,0,0,1,0, 0,0,0,0,0,1,0,0,1,1,1,0,0,1,0,0, 0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,1, 0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,1, 0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0, 0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,0, + 0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,1, 0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1, 0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,1, 0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1, 0,0,0,0,1,1,1,1,0,0,1,1,0,0,1,1, 0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,0, 0,0,1,0,0,0,1,0,1,1,1,0,1,1,1,0, 0,1,0,0,0,1,0,0,0,1,1,1,0,1,1,1 + }; + + const uint8_t g_bc7_partition3[64 * 16] = + { + 0,0,1,1,0,0,1,1,0,2,2,1,2,2,2,2, 0,0,0,1,0,0,1,1,2,2,1,1,2,2,2,1, 0,0,0,0,2,0,0,1,2,2,1,1,2,2,1,1, 0,2,2,2,0,0,2,2,0,0,1,1,0,1,1,1, 0,0,0,0,0,0,0,0,1,1,2,2,1,1,2,2, 0,0,1,1,0,0,1,1,0,0,2,2,0,0,2,2, 0,0,2,2,0,0,2,2,1,1,1,1,1,1,1,1, 0,0,1,1,0,0,1,1,2,2,1,1,2,2,1,1, + 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2, 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2, 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2, 0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2, 0,1,1,2,0,1,1,2,0,1,1,2,0,1,1,2, 0,1,2,2,0,1,2,2,0,1,2,2,0,1,2,2, 0,0,1,1,0,1,1,2,1,1,2,2,1,2,2,2, 0,0,1,1,2,0,0,1,2,2,0,0,2,2,2,0, + 0,0,0,1,0,0,1,1,0,1,1,2,1,1,2,2, 0,1,1,1,0,0,1,1,2,0,0,1,2,2,0,0, 0,0,0,0,1,1,2,2,1,1,2,2,1,1,2,2, 0,0,2,2,0,0,2,2,0,0,2,2,1,1,1,1, 0,1,1,1,0,1,1,1,0,2,2,2,0,2,2,2, 0,0,0,1,0,0,0,1,2,2,2,1,2,2,2,1, 0,0,0,0,0,0,1,1,0,1,2,2,0,1,2,2, 0,0,0,0,1,1,0,0,2,2,1,0,2,2,1,0, + 0,1,2,2,0,1,2,2,0,0,1,1,0,0,0,0, 0,0,1,2,0,0,1,2,1,1,2,2,2,2,2,2, 0,1,1,0,1,2,2,1,1,2,2,1,0,1,1,0, 0,0,0,0,0,1,1,0,1,2,2,1,1,2,2,1, 0,0,2,2,1,1,0,2,1,1,0,2,0,0,2,2, 0,1,1,0,0,1,1,0,2,0,0,2,2,2,2,2, 0,0,1,1,0,1,2,2,0,1,2,2,0,0,1,1, 0,0,0,0,2,0,0,0,2,2,1,1,2,2,2,1, + 0,0,0,0,0,0,0,2,1,1,2,2,1,2,2,2, 0,2,2,2,0,0,2,2,0,0,1,2,0,0,1,1, 0,0,1,1,0,0,1,2,0,0,2,2,0,2,2,2, 0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0, 0,0,0,0,1,1,1,1,2,2,2,2,0,0,0,0, 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0, 0,1,2,0,2,0,1,2,1,2,0,1,0,1,2,0, 0,0,1,1,2,2,0,0,1,1,2,2,0,0,1,1, + 0,0,1,1,1,1,2,2,2,2,0,0,0,0,1,1, 0,1,0,1,0,1,0,1,2,2,2,2,2,2,2,2, 0,0,0,0,0,0,0,0,2,1,2,1,2,1,2,1, 0,0,2,2,1,1,2,2,0,0,2,2,1,1,2,2, 0,0,2,2,0,0,1,1,0,0,2,2,0,0,1,1, 0,2,2,0,1,2,2,1,0,2,2,0,1,2,2,1, 0,1,0,1,2,2,2,2,2,2,2,2,0,1,0,1, 0,0,0,0,2,1,2,1,2,1,2,1,2,1,2,1, + 0,1,0,1,0,1,0,1,0,1,0,1,2,2,2,2, 0,2,2,2,0,1,1,1,0,2,2,2,0,1,1,1, 0,0,0,2,1,1,1,2,0,0,0,2,1,1,1,2, 0,0,0,0,2,1,1,2,2,1,1,2,2,1,1,2, 0,2,2,2,0,1,1,1,0,1,1,1,0,2,2,2, 0,0,0,2,1,1,1,2,1,1,1,2,0,0,0,2, 0,1,1,0,0,1,1,0,0,1,1,0,2,2,2,2, 0,0,0,0,0,0,0,0,2,1,1,2,2,1,1,2, + 0,1,1,0,0,1,1,0,2,2,2,2,2,2,2,2, 0,0,2,2,0,0,1,1,0,0,1,1,0,0,2,2, 0,0,2,2,1,1,2,2,1,1,2,2,0,0,2,2, 0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,2, 0,0,0,2,0,0,0,1,0,0,0,2,0,0,0,1, 0,2,2,2,1,2,2,2,0,2,2,2,1,2,2,2, 0,1,0,1,2,2,2,2,2,2,2,2,2,2,2,2, 0,1,1,1,2,0,1,1,2,2,0,1,2,2,2,0, + }; + + const uint8_t g_bc7_table_anchor_index_second_subset[64] = { 15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15, 15, 2, 8, 2, 2, 8, 8,15, 2, 8, 2, 2, 8, 8, 2, 2, 15,15, 6, 8, 2, 8,15,15, 2, 8, 2, 2, 2,15,15, 6, 6, 2, 6, 8,15,15, 2, 2, 15,15,15,15,15, 2, 2,15 }; + + const uint8_t g_bc7_table_anchor_index_third_subset_1[64] = + { + 3, 3,15,15, 8, 3,15,15, 8, 8, 6, 6, 6, 5, 3, 3, 3, 3, 8,15, 3, 3, 6,10, 5, 8, 8, 6, 8, 5,15,15, 8,15, 3, 5, 6,10, 8,15, 15, 3,15, 5,15,15,15,15, 3,15, 5, 5, 5, 8, 5,10, 5,10, 8,13,15,12, 3, 3 + }; + + const uint8_t g_bc7_table_anchor_index_third_subset_2[64] = + { + 15, 8, 8, 3,15,15, 3, 8, 15,15,15,15,15,15,15, 8, 15, 8,15, 3,15, 8,15, 8, 3,15, 6,10,15,15,10, 8, 15, 3,15,10,10, 8, 9,10, 6,15, 8,15, 3, 6, 6, 8, 15, 3,15,15,15,15,15,15, 15,15,15,15, 3,15,15, 8 + }; + + const uint8_t g_bc7_num_subsets[8] = { 3, 2, 3, 2, 1, 1, 1, 2 }; + const uint8_t g_bc7_partition_bits[8] = { 4, 6, 6, 6, 0, 0, 0, 6 }; + const uint8_t g_bc7_color_index_bitcount[8] = { 3, 3, 2, 2, 2, 2, 4, 2 }; + + const uint8_t g_bc7_mode_has_p_bits[8] = { 1, 1, 0, 1, 0, 0, 1, 1 }; + const uint8_t g_bc7_mode_has_shared_p_bits[8] = { 0, 1, 0, 0, 0, 0, 0, 0 }; + const uint8_t g_bc7_color_precision_table[8] = { 4, 6, 5, 7, 5, 7, 7, 5 }; + const int8_t g_bc7_alpha_precision_table[8] = { 0, 0, 0, 0, 6, 8, 7, 5 }; + + const uint8_t g_bc7_alpha_index_bitcount[8] = { 0, 0, 0, 0, 3, 2, 4, 2 }; + + endpoint_err g_bc7_mode_6_optimal_endpoints[256][2]; // [c][pbit] + endpoint_err g_bc7_mode_5_optimal_endpoints[256]; // [c] + + static inline void bc7_set_block_bits(uint8_t* pBytes, uint32_t val, uint32_t num_bits, uint32_t* pCur_ofs) + { + assert((num_bits <= 32) && (val < (1ULL << num_bits))); + while (num_bits) { -#if !BASISD_SUPPORT_PVRTC1 - return false; -#endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + const uint32_t n = basisu::minimumu(8 - (*pCur_ofs & 7), num_bits); + pBytes[*pCur_ofs >> 3] |= (uint8_t)(val << (*pCur_ofs & 7)); + val >>= n; + num_bits -= n; + *pCur_ofs += n; + } + assert(*pCur_ofs <= 128); + } - // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?) - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + // TODO: Optimize this. + void encode_bc7_block(void* pBlock, const bc7_optimization_results* pResults) + { + const uint32_t best_mode = pResults->m_mode; + + const uint32_t total_subsets = g_bc7_num_subsets[best_mode]; + const uint32_t total_partitions = 1 << g_bc7_partition_bits[best_mode]; + //const uint32_t num_rotations = 1 << g_bc7_rotation_bits[best_mode]; + //const uint32_t num_index_selectors = (best_mode == 4) ? 2 : 1; + + const uint8_t* pPartition; + if (total_subsets == 1) + pPartition = &g_bc7_partition1[0]; + else if (total_subsets == 2) + pPartition = &g_bc7_partition2[pResults->m_partition * 16]; + else + pPartition = &g_bc7_partition3[pResults->m_partition * 16]; + + uint8_t color_selectors[16]; + memcpy(color_selectors, pResults->m_selectors, 16); + + uint8_t alpha_selectors[16]; + memcpy(alpha_selectors, pResults->m_alpha_selectors, 16); + + color_quad_u8 low[3], high[3]; + memcpy(low, pResults->m_low, sizeof(low)); + memcpy(high, pResults->m_high, sizeof(high)); + + uint32_t pbits[3][2]; + memcpy(pbits, pResults->m_pbits, sizeof(pbits)); + + int anchor[3] = { -1, -1, -1 }; + + for (uint32_t k = 0; k < total_subsets; k++) + { + uint32_t anchor_index = 0; + if (k) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGB failed\n"); + if ((total_subsets == 3) && (k == 1)) + anchor_index = g_bc7_table_anchor_index_third_subset_1[pResults->m_partition]; + else if ((total_subsets == 3) && (k == 2)) + anchor_index = g_bc7_table_anchor_index_third_subset_2[pResults->m_partition]; + else + anchor_index = g_bc7_table_anchor_index_second_subset[pResults->m_partition]; + } + + anchor[k] = anchor_index; + + const uint32_t color_index_bits = get_bc7_color_index_size(best_mode, pResults->m_index_selector); + const uint32_t num_color_indices = 1 << color_index_bits; + + if (color_selectors[anchor_index] & (num_color_indices >> 1)) + { + for (uint32_t i = 0; i < 16; i++) + if (pPartition[i] == k) + color_selectors[i] = (uint8_t)((num_color_indices - 1) - color_selectors[i]); + + if (get_bc7_mode_has_seperate_alpha_selectors(best_mode)) + { + for (uint32_t q = 0; q < 3; q++) + { + uint8_t t = low[k].m_c[q]; + low[k].m_c[q] = high[k].m_c[q]; + high[k].m_c[q] = t; + } + } + else + { + color_quad_u8 tmp = low[k]; + low[k] = high[k]; + high[k] = tmp; + } + + if (!g_bc7_mode_has_shared_p_bits[best_mode]) + { + uint32_t t = pbits[k][0]; + pbits[k][0] = pbits[k][1]; + pbits[k][1] = t; + } + } + + if (get_bc7_mode_has_seperate_alpha_selectors(best_mode)) + { + const uint32_t alpha_index_bits = get_bc7_alpha_index_size(best_mode, pResults->m_index_selector); + const uint32_t num_alpha_indices = 1 << alpha_index_bits; + + if (alpha_selectors[anchor_index] & (num_alpha_indices >> 1)) + { + for (uint32_t i = 0; i < 16; i++) + if (pPartition[i] == k) + alpha_selectors[i] = (uint8_t)((num_alpha_indices - 1) - alpha_selectors[i]); + + uint8_t t = low[k].m_c[3]; + low[k].m_c[3] = high[k].m_c[3]; + high[k].m_c[3] = t; + } } - break; } - case transcoder_texture_format::cTFPVRTC1_4_RGBA: + + uint8_t* pBlock_bytes = (uint8_t*)(pBlock); + memset(pBlock_bytes, 0, BC7ENC_BLOCK_SIZE); + + uint32_t cur_bit_ofs = 0; + bc7_set_block_bits(pBlock_bytes, 1 << best_mode, best_mode + 1, &cur_bit_ofs); + + if ((best_mode == 4) || (best_mode == 5)) + bc7_set_block_bits(pBlock_bytes, pResults->m_rotation, 2, &cur_bit_ofs); + + if (best_mode == 4) + bc7_set_block_bits(pBlock_bytes, pResults->m_index_selector, 1, &cur_bit_ofs); + + if (total_partitions > 1) + bc7_set_block_bits(pBlock_bytes, pResults->m_partition, (total_partitions == 64) ? 6 : 4, &cur_bit_ofs); + + const uint32_t total_comps = (best_mode >= 4) ? 4 : 3; + for (uint32_t comp = 0; comp < total_comps; comp++) { -#if !BASISD_SUPPORT_PVRTC1 - return false; -#endif - assert(basis_file_has_alpha_slices); + for (uint32_t subset = 0; subset < total_subsets; subset++) + { + bc7_set_block_bits(pBlock_bytes, low[subset].m_c[comp], (comp == 3) ? g_bc7_alpha_precision_table[best_mode] : g_bc7_color_precision_table[best_mode], &cur_bit_ofs); + bc7_set_block_bits(pBlock_bytes, high[subset].m_c[comp], (comp == 3) ? g_bc7_alpha_precision_table[best_mode] : g_bc7_color_precision_table[best_mode], &cur_bit_ofs); + } + } - // Temp buffer to hold alpha block endpoint/selector indices - std::vector<uint32_t> temp_block_indices(total_slice_blocks); + if (g_bc7_mode_has_p_bits[best_mode]) + { + for (uint32_t subset = 0; subset < total_subsets; subset++) + { + bc7_set_block_bits(pBlock_bytes, pbits[subset][0], 1, &cur_bit_ofs); + if (!g_bc7_mode_has_shared_p_bits[best_mode]) + bc7_set_block_bits(pBlock_bytes, pbits[subset][1], 1, &cur_bit_ofs); + } + } - // First transcode alpha data to temp buffer - status = transcode_slice(pData, data_size, slice_index + 1, &temp_block_indices[0], total_slice_blocks, block_format::cIndices, sizeof(uint32_t), decode_flags, pSlice_descs[slice_index].m_num_blocks_x, pState); - if (!status) + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGBA failed (0)\n"); + int idx = x + y * 4; + + uint32_t n = pResults->m_index_selector ? get_bc7_alpha_index_size(best_mode, pResults->m_index_selector) : get_bc7_color_index_size(best_mode, pResults->m_index_selector); + + if ((idx == anchor[0]) || (idx == anchor[1]) || (idx == anchor[2])) + n--; + + bc7_set_block_bits(pBlock_bytes, pResults->m_index_selector ? alpha_selectors[idx] : color_selectors[idx], n, &cur_bit_ofs); } - else + } + + if (get_bc7_mode_has_seperate_alpha_selectors(best_mode)) + { + for (uint32_t y = 0; y < 4; y++) { - // output_row_pitch_in_blocks_or_pixels is actually ignored because we're transcoding to PVRTC1. (Print a dev warning if it's != 0?) - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC1_4_RGBA, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState, &temp_block_indices[0]); - if (!status) + for (uint32_t x = 0; x < 4; x++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to PVRTC1 4 RGBA failed (1)\n"); + int idx = x + y * 4; + + uint32_t n = pResults->m_index_selector ? get_bc7_color_index_size(best_mode, pResults->m_index_selector) : get_bc7_alpha_index_size(best_mode, pResults->m_index_selector); + + if ((idx == anchor[0]) || (idx == anchor[1]) || (idx == anchor[2])) + n--; + + bc7_set_block_bits(pBlock_bytes, pResults->m_index_selector ? color_selectors[idx] : alpha_selectors[idx], n, &cur_bit_ofs); } } + } - break; + assert(cur_bit_ofs == 128); + } + + // ASTC + static inline void astc_set_bits_1_to_9(uint32_t* pDst, int& bit_offset, uint32_t code, uint32_t codesize) + { + uint8_t* pBuf = reinterpret_cast<uint8_t*>(pDst); + + assert(codesize <= 9); + if (codesize) + { + uint32_t byte_bit_offset = bit_offset & 7; + uint32_t val = code << byte_bit_offset; + + uint32_t index = bit_offset >> 3; + pBuf[index] |= (uint8_t)val; + + if (codesize > (8 - byte_bit_offset)) + pBuf[index + 1] |= (uint8_t)(val >> 8); + + bit_offset += codesize; } - case transcoder_texture_format::cTFBC7_M6_RGB: + } + + void pack_astc_solid_block(void* pDst_block, const color32& color) + { + uint32_t r = color[0], g = color[1], b = color[2]; + uint32_t a = color[3]; + + uint32_t* pOutput = static_cast<uint32_t*>(pDst_block); + uint8_t* pBytes = reinterpret_cast<uint8_t*>(pDst_block); + + pBytes[0] = 0xfc; pBytes[1] = 0xfd; pBytes[2] = 0xff; pBytes[3] = 0xff; + + pOutput[1] = 0xffffffff; + pOutput[2] = 0; + pOutput[3] = 0; + + int bit_pos = 64; + astc_set_bits(reinterpret_cast<uint32_t*>(pDst_block), bit_pos, r | (r << 8), 16); + astc_set_bits(reinterpret_cast<uint32_t*>(pDst_block), bit_pos, g | (g << 8), 16); + astc_set_bits(reinterpret_cast<uint32_t*>(pDst_block), bit_pos, b | (b << 8), 16); + astc_set_bits(reinterpret_cast<uint32_t*>(pDst_block), bit_pos, a | (a << 8), 16); + } + + // See 23.21 https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.inline.html#_partition_pattern_generation +#ifdef _DEBUG + static inline uint32_t astc_hash52(uint32_t v) + { + uint32_t p = v; + p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4; + p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3; + p ^= p << 6; p ^= p >> 17; + return p; + } + + int astc_compute_texel_partition(int seed, int x, int y, int z, int partitioncount, bool small_block) + { + if (small_block) + { + x <<= 1; y <<= 1; z <<= 1; + } + seed += (partitioncount - 1) * 1024; + uint32_t rnum = astc_hash52(seed); + uint8_t seed1 = rnum & 0xF; + uint8_t seed2 = (rnum >> 4) & 0xF; + uint8_t seed3 = (rnum >> 8) & 0xF; + uint8_t seed4 = (rnum >> 12) & 0xF; + uint8_t seed5 = (rnum >> 16) & 0xF; + uint8_t seed6 = (rnum >> 20) & 0xF; + uint8_t seed7 = (rnum >> 24) & 0xF; + uint8_t seed8 = (rnum >> 28) & 0xF; + uint8_t seed9 = (rnum >> 18) & 0xF; + uint8_t seed10 = (rnum >> 22) & 0xF; + uint8_t seed11 = (rnum >> 26) & 0xF; + uint8_t seed12 = ((rnum >> 30) | (rnum << 2)) & 0xF; + + seed1 *= seed1; seed2 *= seed2; + seed3 *= seed3; seed4 *= seed4; + seed5 *= seed5; seed6 *= seed6; + seed7 *= seed7; seed8 *= seed8; + seed9 *= seed9; seed10 *= seed10; + seed11 *= seed11; seed12 *= seed12; + + int sh1, sh2, sh3; + if (seed & 1) + { + sh1 = (seed & 2 ? 4 : 5); sh2 = (partitioncount == 3 ? 6 : 5); + } + else { -#if !BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - return false; + sh1 = (partitioncount == 3 ? 6 : 5); sh2 = (seed & 2 ? 4 : 5); + } + sh3 = (seed & 0x10) ? sh1 : sh2; + + seed1 >>= sh1; seed2 >>= sh2; seed3 >>= sh1; seed4 >>= sh2; + seed5 >>= sh1; seed6 >>= sh2; seed7 >>= sh1; seed8 >>= sh2; + seed9 >>= sh3; seed10 >>= sh3; seed11 >>= sh3; seed12 >>= sh3; + + int a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14); + int b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10); + int c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6); + int d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2); + + a &= 0x3F; b &= 0x3F; c &= 0x3F; d &= 0x3F; + + if (partitioncount < 4) d = 0; + if (partitioncount < 3) c = 0; + + if (a >= b && a >= c && a >= d) + return 0; + else if (b >= c && b >= d) + return 1; + else if (c >= d) + return 2; + else + return 3; + } #endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M6_OPAQUE_ONLY, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + static const uint8_t g_astc_quint_encode[125] = + { + 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 24, 25, 26, 27, 28, 5, 13, 21, 29, 6, 32, 33, 34, 35, 36, 40, 41, 42, 43, 44, 48, 49, 50, 51, 52, 56, 57, + 58, 59, 60, 37, 45, 53, 61, 14, 64, 65, 66, 67, 68, 72, 73, 74, 75, 76, 80, 81, 82, 83, 84, 88, 89, 90, 91, 92, 69, 77, 85, 93, 22, 96, 97, 98, 99, 100, 104, + 105, 106, 107, 108, 112, 113, 114, 115, 116, 120, 121, 122, 123, 124, 101, 109, 117, 125, 30, 102, 103, 70, 71, 38, 110, 111, 78, 79, 46, 118, 119, 86, 87, 54, + 126, 127, 94, 95, 62, 39, 47, 55, 63, 31 + }; + + // Encodes 3 values to output, usable for any range that uses quints and bits + static inline void astc_encode_quints(uint32_t* pOutput, const uint8_t* pValues, int& bit_pos, int n) + { + // First extract the trits and the bits from the 5 input values + int quints = 0, bits[3]; + const uint32_t bit_mask = (1 << n) - 1; + for (int i = 0; i < 3; i++) + { + static const int s_muls[3] = { 1, 5, 25 }; + + const int t = pValues[i] >> n; + + quints += t * s_muls[i]; + bits[i] = pValues[i] & bit_mask; + } + + // Encode the quints, by inverting the bit manipulations done by the decoder, converting 3 quints into 7-bits. + // See https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-integer-sequence-encoding + + assert(quints < 125); + const int T = g_astc_quint_encode[quints]; + + // Now interleave the 7 encoded quint bits with the bits to form the encoded output. See table 95-96. + astc_set_bits(pOutput, bit_pos, bits[0] | (astc_extract_bits(T, 0, 2) << n) | (bits[1] << (3 + n)) | (astc_extract_bits(T, 3, 4) << (3 + n * 2)) | + (bits[2] << (5 + n * 2)) | (astc_extract_bits(T, 5, 6) << (5 + n * 3)), 7 + n * 3); + } + + // Packs values using ASTC's BISE to output buffer. + static void astc_pack_bise(uint32_t* pDst, const uint8_t* pSrc_vals, int bit_pos, int num_vals, int range) + { + uint32_t temp[5] = { 0, 0, 0, 0, 0 }; + + const int num_bits = g_astc_bise_range_table[range][0]; + + int group_size = 0; + if (g_astc_bise_range_table[range][1]) + group_size = 5; + else if (g_astc_bise_range_table[range][2]) + group_size = 3; + + if (group_size) + { + // Range has trits or quints - pack each group of 5 or 3 values + const int total_groups = (group_size == 5) ? ((num_vals + 4) / 5) : ((num_vals + 2) / 3); + + for (int group_index = 0; group_index < total_groups; group_index++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC7 m6 opaque only failed\n"); + uint8_t vals[5] = { 0, 0, 0, 0, 0 }; + + const int limit = basisu::minimum(group_size, num_vals - group_index * group_size); + for (int i = 0; i < limit; i++) + vals[i] = pSrc_vals[group_index * group_size + i]; + + if (group_size == 5) + astc_encode_trits(temp, vals, bit_pos, num_bits); + else + astc_encode_quints(temp, vals, bit_pos, num_bits); + } + } + else + { + for (int i = 0; i < num_vals; i++) + astc_set_bits_1_to_9(temp, bit_pos, pSrc_vals[i], num_bits); + } + + pDst[0] |= temp[0]; pDst[1] |= temp[1]; + pDst[2] |= temp[2]; pDst[3] |= temp[3]; + } + + const uint32_t ASTC_BLOCK_MODE_BITS = 11; + const uint32_t ASTC_PART_BITS = 2; + const uint32_t ASTC_CEM_BITS = 4; + const uint32_t ASTC_PARTITION_INDEX_BITS = 10; + const uint32_t ASTC_CCS_BITS = 2; + + const uint32_t g_uastc_mode_astc_block_mode[TOTAL_UASTC_MODES] = { 0x242, 0x42, 0x53, 0x42, 0x42, 0x53, 0x442, 0x42, 0, 0x42, 0x242, 0x442, 0x53, 0x441, 0x42, 0x242, 0x42, 0x442, 0x253 }; + + bool pack_astc_block(uint32_t* pDst, const astc_block_desc* pBlock, uint32_t uastc_mode) + { + assert(uastc_mode < TOTAL_UASTC_MODES); + uint8_t* pDst_bytes = reinterpret_cast<uint8_t*>(pDst); + + const int total_weights = pBlock->m_dual_plane ? 32 : 16; + + // Set mode bits - see Table 146-147 + uint32_t mode = g_uastc_mode_astc_block_mode[uastc_mode]; + pDst_bytes[0] = (uint8_t)mode; + pDst_bytes[1] = (uint8_t)(mode >> 8); + + memset(pDst_bytes + 2, 0, 16 - 2); + + int bit_pos = ASTC_BLOCK_MODE_BITS; + + // We only support 1-5 bit weight indices + assert(!g_astc_bise_range_table[pBlock->m_weight_range][1] && !g_astc_bise_range_table[pBlock->m_weight_range][2]); + const int bits_per_weight = g_astc_bise_range_table[pBlock->m_weight_range][0]; + + // See table 143 - PART + astc_set_bits_1_to_9(pDst, bit_pos, pBlock->m_subsets - 1, ASTC_PART_BITS); + + if (pBlock->m_subsets == 1) + astc_set_bits_1_to_9(pDst, bit_pos, pBlock->m_cem, ASTC_CEM_BITS); + else + { + // See table 145 + astc_set_bits(pDst, bit_pos, pBlock->m_partition_seed, ASTC_PARTITION_INDEX_BITS); + + // Table 150 - we assume all CEM's are equal, so write 2 0's along with the CEM + astc_set_bits_1_to_9(pDst, bit_pos, (pBlock->m_cem << 2) & 63, ASTC_CEM_BITS + 2); + } + + if (pBlock->m_dual_plane) + { + const int total_weight_bits = total_weights * bits_per_weight; + + // See Illegal Encodings 23.24 + // https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.inline.html#_illegal_encodings + assert((total_weight_bits >= 24) && (total_weight_bits <= 96)); + + int ccs_bit_pos = 128 - total_weight_bits - ASTC_CCS_BITS; + astc_set_bits_1_to_9(pDst, ccs_bit_pos, pBlock->m_ccs, ASTC_CCS_BITS); + } + + const int num_cem_pairs = (1 + (pBlock->m_cem >> 2)) * pBlock->m_subsets; + assert(num_cem_pairs <= 9); + + astc_pack_bise(pDst, pBlock->m_endpoints, bit_pos, num_cem_pairs * 2, g_uastc_mode_endpoint_ranges[uastc_mode]); + + // Write the weight bits in reverse bit order. + switch (bits_per_weight) + { + case 1: + { + const uint32_t N = 1; + for (int i = 0; i < total_weights; i++) + { + const uint32_t ofs = 128 - N - i; + assert((ofs >> 3) < 16); + pDst_bytes[ofs >> 3] |= (pBlock->m_weights[i] << (ofs & 7)); } break; } - case transcoder_texture_format::cTFBC7_M5_RGBA: + case 2: { -#if !BASISD_SUPPORT_BC7_MODE5 - return false; -#else - assert(bytes_per_block == 16); + const uint32_t N = 2; + for (int i = 0; i < total_weights; i++) + { + static const uint8_t s_reverse_bits2[4] = { 0, 2, 1, 3 }; + const uint32_t ofs = 128 - N - (i * N); + assert((ofs >> 3) < 16); + pDst_bytes[ofs >> 3] |= (s_reverse_bits2[pBlock->m_weights[i]] << (ofs & 7)); + } + break; + } + case 3: + { + const uint32_t N = 3; + for (int i = 0; i < total_weights; i++) + { + static const uint8_t s_reverse_bits3[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - // First transcode the color slice. The cBC7_M5_COLOR transcoder will output opaque mode 5 blocks. - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M5_COLOR, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + const uint32_t ofs = 128 - N - (i * N); + const uint32_t rev = s_reverse_bits3[pBlock->m_weights[i]] << (ofs & 7); - if ((status) && (basis_file_has_alpha_slices)) + uint32_t index = ofs >> 3; + assert(index < 16); + pDst_bytes[index++] |= rev & 0xFF; + if (index < 16) + pDst_bytes[index++] |= (rev >> 8); + } + break; + } + case 4: + { + const uint32_t N = 4; + for (int i = 0; i < total_weights; i++) { - // Now transcode the alpha slice. The cBC7_M5_ALPHA transcoder will now change the opaque mode 5 blocks to blocks with alpha. - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC7_M5_ALPHA, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + static const uint8_t s_reverse_bits4[16] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; + const int ofs = 128 - N - (i * N); + assert(ofs >= 0 && (ofs >> 3) < 16); + pDst_bytes[ofs >> 3] |= (s_reverse_bits4[pBlock->m_weights[i]] << (ofs & 7)); + } + break; + } + case 5: + { + const uint32_t N = 5; + for (int i = 0; i < total_weights; i++) + { + static const uint8_t s_reverse_bits5[32] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31 }; + + const uint32_t ofs = 128 - N - (i * N); + const uint32_t rev = s_reverse_bits5[pBlock->m_weights[i]] << (ofs & 7); + + uint32_t index = ofs >> 3; + assert(index < 16); + pDst_bytes[index++] |= rev & 0xFF; + if (index < 16) + pDst_bytes[index++] |= (rev >> 8); } break; -#endif } - case transcoder_texture_format::cTFETC2_RGBA: + default: + assert(0); + break; + } + + return true; + } + + const uint8_t* get_anchor_indices(uint32_t subsets, uint32_t mode, uint32_t common_pattern, const uint8_t*& pPartition_pattern) + { + const uint8_t* pSubset_anchor_indices = g_zero_pattern; + pPartition_pattern = g_zero_pattern; + + if (subsets >= 2) { -#if !BASISD_SUPPORT_ETC2_EAC_A8 - return false; + if (subsets == 3) + { + pPartition_pattern = &g_astc_bc7_patterns3[common_pattern][0]; + pSubset_anchor_indices = &g_astc_bc7_pattern3_anchors[common_pattern][0]; + } + else if (mode == 7) + { + pPartition_pattern = &g_bc7_3_astc2_patterns2[common_pattern][0]; + pSubset_anchor_indices = &g_bc7_3_astc2_patterns2_anchors[common_pattern][0]; + } + else + { + pPartition_pattern = &g_astc_bc7_patterns2[common_pattern][0]; + pSubset_anchor_indices = &g_astc_bc7_pattern2_anchors[common_pattern][0]; + } + } + + return pSubset_anchor_indices; + } + + static inline uint32_t read_bit(const uint8_t* pBuf, uint32_t& bit_offset) + { + uint32_t byte_bits = pBuf[bit_offset >> 3] >> (bit_offset & 7); + bit_offset += 1; + return byte_bits & 1; + } + + static inline uint32_t read_bits1_to_9(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize) + { + assert(codesize <= 9); + if (!codesize) + return 0; + + if ((BASISD_IS_BIG_ENDIAN) || (!BASISD_USE_UNALIGNED_WORD_READS) || (bit_offset >= 112)) + { + const uint8_t* pBytes = &pBuf[bit_offset >> 3U]; + + uint32_t byte_bit_offset = bit_offset & 7U; + + uint32_t bits = pBytes[0] >> byte_bit_offset; + uint32_t bits_read = basisu::minimum<int>(codesize, 8 - byte_bit_offset); + + uint32_t bits_remaining = codesize - bits_read; + if (bits_remaining) + bits |= ((uint32_t)pBytes[1]) << bits_read; + + bit_offset += codesize; + + return bits & ((1U << codesize) - 1U); + } + + uint32_t byte_bit_offset = bit_offset & 7U; + const uint16_t w = *(const uint16_t *)(&pBuf[bit_offset >> 3U]); + bit_offset += codesize; + return (w >> byte_bit_offset) & ((1U << codesize) - 1U); + } + + inline uint64_t read_bits64(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize) + { + assert(codesize <= 64U); + uint64_t bits = 0; + uint32_t total_bits = 0; + + while (total_bits < codesize) + { + uint32_t byte_bit_offset = bit_offset & 7U; + uint32_t bits_to_read = basisu::minimum<int>(codesize - total_bits, 8U - byte_bit_offset); + + uint32_t byte_bits = pBuf[bit_offset >> 3U] >> byte_bit_offset; + byte_bits &= ((1U << bits_to_read) - 1U); + + bits |= ((uint64_t)(byte_bits) << total_bits); + + total_bits += bits_to_read; + bit_offset += bits_to_read; + } + + return bits; + } + + static inline uint32_t read_bits1_to_9_fst(const uint8_t* pBuf, uint32_t& bit_offset, uint32_t codesize) + { + assert(codesize <= 9); + if (!codesize) + return 0; + assert(bit_offset < 112); + + if ((BASISD_IS_BIG_ENDIAN) || (!BASISD_USE_UNALIGNED_WORD_READS)) + { + const uint8_t* pBytes = &pBuf[bit_offset >> 3U]; + + uint32_t byte_bit_offset = bit_offset & 7U; + + uint32_t bits = pBytes[0] >> byte_bit_offset; + uint32_t bits_read = basisu::minimum<int>(codesize, 8 - byte_bit_offset); + + uint32_t bits_remaining = codesize - bits_read; + if (bits_remaining) + bits |= ((uint32_t)pBytes[1]) << bits_read; + + bit_offset += codesize; + + return bits & ((1U << codesize) - 1U); + } + + uint32_t byte_bit_offset = bit_offset & 7U; + const uint16_t w = *(const uint16_t*)(&pBuf[bit_offset >> 3U]); + bit_offset += codesize; + return (w >> byte_bit_offset)& ((1U << codesize) - 1U); + } + + bool unpack_uastc(const uastc_block& blk, unpacked_uastc_block& unpacked, bool blue_contract_check, bool read_hints) + { + //memset(&unpacked, 0, sizeof(unpacked)); + +#if 0 + uint8_t table[128]; + memset(table, 0xFF, sizeof(table)); + + { + for (uint32_t mode = 0; mode <= TOTAL_UASTC_MODES; mode++) + { + const uint32_t code = g_uastc_mode_huff_codes[mode][0]; + const uint32_t codesize = g_uastc_mode_huff_codes[mode][1]; + + table[code] = mode; + + uint32_t bits_left = 7 - codesize; + for (uint32_t i = 0; i < (1 << bits_left); i++) + table[code | (i << codesize)] = mode; + } + + for (uint32_t i = 0; i < 128; i++) + printf("%u,", table[i]); + exit(0); + } #endif - assert(bytes_per_block == 16); - if (basis_file_has_alpha_slices) + const int mode = g_uastc_huff_modes[blk.m_bytes[0] & 127]; + if (mode >= (int)TOTAL_UASTC_MODES) + return false; + + unpacked.m_mode = mode; + + uint32_t bit_ofs = g_uastc_mode_huff_codes[mode][1]; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + unpacked.m_solid_color.r = (uint8_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 8); + unpacked.m_solid_color.g = (uint8_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 8); + unpacked.m_solid_color.b = (uint8_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 8); + unpacked.m_solid_color.a = (uint8_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 8); + + if (read_hints) { - // First decode the alpha data - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_A8, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + unpacked.m_etc1_flip = false; + unpacked.m_etc1_diff = read_bit(blk.m_bytes, bit_ofs) != 0; + unpacked.m_etc1_inten0 = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 3); + unpacked.m_etc1_inten1 = 0; + unpacked.m_etc1_selector = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 2); + unpacked.m_etc1_r = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 5); + unpacked.m_etc1_g = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 5); + unpacked.m_etc1_b = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 5); + unpacked.m_etc1_bias = 0; + unpacked.m_etc2_hints = 0; } + + return true; + } + + if (read_hints) + { + if (g_uastc_mode_has_bc1_hint0[mode]) + unpacked.m_bc1_hint0 = read_bit(blk.m_bytes, bit_ofs) != 0; + else + unpacked.m_bc1_hint0 = false; + + if (g_uastc_mode_has_bc1_hint1[mode]) + unpacked.m_bc1_hint1 = read_bit(blk.m_bytes, bit_ofs) != 0; else + unpacked.m_bc1_hint1 = false; + + unpacked.m_etc1_flip = read_bit(blk.m_bytes, bit_ofs) != 0; + unpacked.m_etc1_diff = read_bit(blk.m_bytes, bit_ofs) != 0; + unpacked.m_etc1_inten0 = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 3); + unpacked.m_etc1_inten1 = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 3); + + if (g_uastc_mode_has_etc1_bias[mode]) + unpacked.m_etc1_bias = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 5); + else + unpacked.m_etc1_bias = 0; + + if (g_uastc_mode_has_alpha[mode]) { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_A8, 16, output_row_pitch_in_blocks_or_pixels); - status = true; + unpacked.m_etc2_hints = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 8); + //assert(unpacked.m_etc2_hints > 0); } + else + unpacked.m_etc2_hints = 0; + } + else + bit_ofs += g_uastc_mode_total_hint_bits[mode]; + + uint32_t subsets = 1; + switch (mode) + { + case 2: + case 4: + case 7: + case 9: + case 16: + unpacked.m_common_pattern = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 5); + subsets = 2; + break; + case 3: + unpacked.m_common_pattern = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 4); + subsets = 3; + break; + default: + break; + } - if (status) + uint32_t part_seed = 0; + switch (mode) + { + case 2: + case 4: + case 9: + case 16: + if (unpacked.m_common_pattern >= TOTAL_ASTC_BC7_COMMON_PARTITIONS2) + return false; + + part_seed = g_astc_bc7_common_partitions2[unpacked.m_common_pattern].m_astc; + break; + case 3: + if (unpacked.m_common_pattern >= TOTAL_ASTC_BC7_COMMON_PARTITIONS3) + return false; + + part_seed = g_astc_bc7_common_partitions3[unpacked.m_common_pattern].m_astc; + break; + case 7: + if (unpacked.m_common_pattern >= TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS) + return false; + + part_seed = g_bc7_3_astc2_common_partitions[unpacked.m_common_pattern].m_astc2; + break; + default: + break; + } + + uint32_t total_planes = 1; + switch (mode) + { + case 6: + case 11: + case 13: + unpacked.m_astc.m_ccs = (int)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, 2); + total_planes = 2; + break; + case 17: + unpacked.m_astc.m_ccs = 3; + total_planes = 2; + break; + default: + break; + } + + unpacked.m_astc.m_dual_plane = (total_planes == 2); + + unpacked.m_astc.m_subsets = subsets; + unpacked.m_astc.m_partition_seed = part_seed; + + const uint32_t total_comps = g_uastc_mode_comps[mode]; + + const uint32_t weight_bits = g_uastc_mode_weight_bits[mode]; + + unpacked.m_astc.m_weight_range = g_uastc_mode_weight_ranges[mode]; + + const uint32_t total_values = total_comps * 2 * subsets; + const uint32_t endpoint_range = g_uastc_mode_endpoint_ranges[mode]; + + const uint32_t cem = g_uastc_mode_cem[mode]; + unpacked.m_astc.m_cem = cem; + + const uint32_t ep_bits = g_astc_bise_range_table[endpoint_range][0]; + const uint32_t ep_trits = g_astc_bise_range_table[endpoint_range][1]; + const uint32_t ep_quints = g_astc_bise_range_table[endpoint_range][2]; + + uint32_t total_tqs = 0; + uint32_t bundle_size = 0, mul = 0; + if (ep_trits) + { + total_tqs = (total_values + 4) / 5; + bundle_size = 5; + mul = 3; + } + else if (ep_quints) + { + total_tqs = (total_values + 2) / 3; + bundle_size = 3; + mul = 5; + } + + uint32_t tq_values[8]; + for (uint32_t i = 0; i < total_tqs; i++) + { + uint32_t num_bits = ep_trits ? 8 : 7; + if (i == (total_tqs - 1)) { - // Now decode the color data - status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC1, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + uint32_t num_remaining = total_values - (total_tqs - 1) * bundle_size; + if (ep_trits) + { + switch (num_remaining) + { + case 1: num_bits = 2; break; + case 2: num_bits = 4; break; + case 3: num_bits = 5; break; + case 4: num_bits = 7; break; + default: break; + } + } + else if (ep_quints) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2 RGB failed\n"); + switch (num_remaining) + { + case 1: num_bits = 3; break; + case 2: num_bits = 5; break; + default: break; + } } } - else + + tq_values[i] = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, num_bits); + } // i + + uint32_t accum = 0; + uint32_t accum_remaining = 0; + uint32_t next_tq_index = 0; + + for (uint32_t i = 0; i < total_values; i++) + { + uint32_t value = (uint32_t)read_bits1_to_9_fst(blk.m_bytes, bit_ofs, ep_bits); + + if (total_tqs) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2 A failed\n"); + if (!accum_remaining) + { + assert(next_tq_index < total_tqs); + accum = tq_values[next_tq_index++]; + accum_remaining = bundle_size; + } + + // TODO: Optimize with tables + uint32_t v = accum % mul; + accum /= mul; + accum_remaining--; + + value |= (v << ep_bits); } - break; + + unpacked.m_astc.m_endpoints[i] = (uint8_t)value; } - case transcoder_texture_format::cTFBC3_RGBA: + + const uint8_t* pPartition_pattern; + const uint8_t* pSubset_anchor_indices = get_anchor_indices(subsets, mode, unpacked.m_common_pattern, pPartition_pattern); + +#ifdef _DEBUG + for (uint32_t i = 0; i < 16; i++) + assert(pPartition_pattern[i] == astc_compute_texel_partition(part_seed, i & 3, i >> 2, 0, subsets, true)); + + for (uint32_t subset_index = 0; subset_index < subsets; subset_index++) { -#if !BASISD_SUPPORT_DXT1 - return false; -#endif -#if !BASISD_SUPPORT_DXT5A - return false; + uint32_t anchor_index = 0; + + for (uint32_t i = 0; i < 16; i++) + { + if (pPartition_pattern[i] == subset_index) + { + anchor_index = i; + break; + } + } + + assert(pSubset_anchor_indices[subset_index] == anchor_index); + } #endif - assert(bytes_per_block == 16); - // First decode the alpha data - if (basis_file_has_alpha_slices) +#if 0 + const uint32_t total_planes_shift = total_planes - 1; + for (uint32_t i = 0; i < 16 * total_planes; i++) + { + uint32_t num_bits = weight_bits; + for (uint32_t s = 0; s < subsets; s++) { - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (pSubset_anchor_indices[s] == (i >> total_planes_shift)) + { + num_bits--; + break; + } } + + unpacked.m_astc.m_weights[i] = (uint8_t)read_bits1_to_9(blk.m_bytes, bit_ofs, num_bits); + } +#endif + + if (mode == 18) + { + // Mode 18 is the only mode with more than 64 weight bits. + for (uint32_t i = 0; i < 16; i++) + unpacked.m_astc.m_weights[i] = (uint8_t)read_bits1_to_9(blk.m_bytes, bit_ofs, i ? weight_bits : (weight_bits - 1)); + } + else + { + // All other modes have <= 64 weight bits. + uint64_t bits; + + // Read the weight bits + if ((BASISD_IS_BIG_ENDIAN) || (!BASISD_USE_UNALIGNED_WORD_READS)) + bits = read_bits64(blk.m_bytes, bit_ofs, basisu::minimum<int>(64, 128 - (int)bit_ofs)); else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); - status = true; +#ifdef __EMSCRIPTEN__ + bits = blk.m_dwords[2]; + bits |= (((uint64_t)blk.m_dwords[3]) << 32U); +#else + bits = blk.m_qwords[1]; +#endif + + if (bit_ofs >= 64U) + bits >>= (bit_ofs - 64U); + else + { + assert(bit_ofs >= 56U); + + uint32_t bits_needed = 64U - bit_ofs; + bits <<= bits_needed; + bits |= (blk.m_bytes[7] >> (8U - bits_needed)); + } } + + bit_ofs = 0; - if (status) + const uint32_t mask = (1U << weight_bits) - 1U; + const uint32_t anchor_mask = (1U << (weight_bits - 1U)) - 1U; + + if (total_planes == 2) { - // Now decode the color data. Forbid 3 color blocks, which aren't allowed in BC3. - status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC1, 16, decode_flags | cDecodeFlagsBC1ForbidThreeColorBlocks, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + // Dual plane modes always have a single subset, and the first 2 weights are anchors. + + unpacked.m_astc.m_weights[0] = (uint8_t)((uint32_t)(bits >> bit_ofs) & anchor_mask); + bit_ofs += (weight_bits - 1); + + unpacked.m_astc.m_weights[1] = (uint8_t)((uint32_t)(bits >> bit_ofs) & anchor_mask); + bit_ofs += (weight_bits - 1); + + for (uint32_t i = 2; i < 32; i++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC3 RGB failed\n"); + unpacked.m_astc.m_weights[i] = (uint8_t)((uint32_t)(bits >> bit_ofs) & mask); + bit_ofs += weight_bits; } } else { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC3 A failed\n"); - } + if (subsets == 1) + { + // Specialize the single subset case. + if (weight_bits == 4) + { + assert(bit_ofs == 0); + + // Specialize the most common case: 4-bit weights. + unpacked.m_astc.m_weights[0] = (uint8_t)((uint32_t)(bits) & 7); + unpacked.m_astc.m_weights[1] = (uint8_t)((uint32_t)(bits >> 3) & 15); + unpacked.m_astc.m_weights[2] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 1)) & 15); + unpacked.m_astc.m_weights[3] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 2)) & 15); + + unpacked.m_astc.m_weights[4] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 3)) & 15); + unpacked.m_astc.m_weights[5] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 4)) & 15); + unpacked.m_astc.m_weights[6] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 5)) & 15); + unpacked.m_astc.m_weights[7] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 6)) & 15); + + unpacked.m_astc.m_weights[8] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 7)) & 15); + unpacked.m_astc.m_weights[9] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 8)) & 15); + unpacked.m_astc.m_weights[10] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 9)) & 15); + unpacked.m_astc.m_weights[11] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 10)) & 15); + + unpacked.m_astc.m_weights[12] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 11)) & 15); + unpacked.m_astc.m_weights[13] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 12)) & 15); + unpacked.m_astc.m_weights[14] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 13)) & 15); + unpacked.m_astc.m_weights[15] = (uint8_t)((uint32_t)(bits >> (3 + 4 * 14)) & 15); + } + else + { + // First weight is always an anchor. + unpacked.m_astc.m_weights[0] = (uint8_t)((uint32_t)(bits >> bit_ofs) & anchor_mask); + bit_ofs += (weight_bits - 1); - break; + for (uint32_t i = 1; i < 16; i++) + { + unpacked.m_astc.m_weights[i] = (uint8_t)((uint32_t)(bits >> bit_ofs) & mask); + bit_ofs += weight_bits; + } + } + } + else + { + const uint32_t a0 = pSubset_anchor_indices[0], a1 = pSubset_anchor_indices[1], a2 = pSubset_anchor_indices[2]; + + for (uint32_t i = 0; i < 16; i++) + { + if ((i == a0) || (i == a1) || (i == a2)) + { + unpacked.m_astc.m_weights[i] = (uint8_t)((uint32_t)(bits >> bit_ofs) & anchor_mask); + bit_ofs += (weight_bits - 1); + } + else + { + unpacked.m_astc.m_weights[i] = (uint8_t)((uint32_t)(bits >> bit_ofs) & mask); + bit_ofs += weight_bits; + } + } + } + } } - case transcoder_texture_format::cTFBC5_RG: + + if ((blue_contract_check) && (total_comps >= 3)) { -#if !BASISD_SUPPORT_DXT5A - return false; -#endif - assert(bytes_per_block == 16); + // We only need to disable ASTC Blue Contraction when we'll be packing to ASTC. The other transcoders don't care. + bool invert_subset[3] = { false, false, false }; + bool any_flag = false; - // Decode the R data (actually the green channel of the color data slice in the basis file) - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (status) + for (uint32_t subset_index = 0; subset_index < subsets; subset_index++) { - if (basis_file_has_alpha_slices) + const int s0 = g_astc_unquant[endpoint_range][unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + 0]].m_unquant + + g_astc_unquant[endpoint_range][unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + 2]].m_unquant + + g_astc_unquant[endpoint_range][unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + 4]].m_unquant; + + const int s1 = g_astc_unquant[endpoint_range][unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + 1]].m_unquant + + g_astc_unquant[endpoint_range][unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + 3]].m_unquant + + g_astc_unquant[endpoint_range][unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + 5]].m_unquant; + + if (s1 < s0) { - // Decode the G data (actually the green channel of the alpha data slice in the basis file) - status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + for (uint32_t c = 0; c < total_comps; c++) + std::swap(unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + c * 2 + 0], unpacked.m_astc.m_endpoints[subset_index * total_comps * 2 + c * 2 + 1]); + + invert_subset[subset_index] = true; + any_flag = true; + } + } + + if (any_flag) + { + const uint32_t weight_mask = (1 << weight_bits) - 1; + + for (uint32_t i = 0; i < 16; i++) + { + uint32_t subset = pPartition_pattern[i]; + + if (invert_subset[subset]) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC5 1 failed\n"); + unpacked.m_astc.m_weights[i * total_planes] = (uint8_t)(weight_mask - unpacked.m_astc.m_weights[i * total_planes]); + + if (total_planes == 2) + unpacked.m_astc.m_weights[i * total_planes + 1] = (uint8_t)(weight_mask - unpacked.m_astc.m_weights[i * total_planes + 1]); } } + } + } + + return true; + } + + static const uint32_t* g_astc_weight_tables[6] = { nullptr, g_bc7_weights1, g_bc7_weights2, g_bc7_weights3, g_astc_weights4, g_astc_weights5 }; + + bool unpack_uastc(uint32_t mode, uint32_t common_pattern, const color32& solid_color, const astc_block_desc& astc, color32* pPixels, bool srgb) + { + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + for (uint32_t i = 0; i < 16; i++) + pPixels[i] = solid_color; + return true; + } + + color32 endpoints[3][2]; + + const uint32_t total_subsets = g_uastc_mode_subsets[mode]; + const uint32_t total_comps = basisu::minimum<uint32_t>(4U, g_uastc_mode_comps[mode]); + const uint32_t endpoint_range = g_uastc_mode_endpoint_ranges[mode]; + const uint32_t total_planes = g_uastc_mode_planes[mode]; + const uint32_t weight_bits = g_uastc_mode_weight_bits[mode]; + const uint32_t weight_levels = 1 << weight_bits; + + for (uint32_t subset_index = 0; subset_index < total_subsets; subset_index++) + { + if (total_comps == 2) + { + const uint32_t ll = g_astc_unquant[endpoint_range][astc.m_endpoints[subset_index * total_comps * 2 + 0 * 2 + 0]].m_unquant; + const uint32_t lh = g_astc_unquant[endpoint_range][astc.m_endpoints[subset_index * total_comps * 2 + 0 * 2 + 1]].m_unquant; + + const uint32_t al = g_astc_unquant[endpoint_range][astc.m_endpoints[subset_index * total_comps * 2 + 1 * 2 + 0]].m_unquant; + const uint32_t ah = g_astc_unquant[endpoint_range][astc.m_endpoints[subset_index * total_comps * 2 + 1 * 2 + 1]].m_unquant; + + endpoints[subset_index][0].set_noclamp_rgba(ll, ll, ll, al); + endpoints[subset_index][1].set_noclamp_rgba(lh, lh, lh, ah); + } + else + { + for (uint32_t comp_index = 0; comp_index < total_comps; comp_index++) + { + endpoints[subset_index][0][comp_index] = g_astc_unquant[endpoint_range][astc.m_endpoints[subset_index * total_comps * 2 + comp_index * 2 + 0]].m_unquant; + endpoints[subset_index][1][comp_index] = g_astc_unquant[endpoint_range][astc.m_endpoints[subset_index * total_comps * 2 + comp_index * 2 + 1]].m_unquant; + } + for (uint32_t comp_index = total_comps; comp_index < 4; comp_index++) + { + endpoints[subset_index][0][comp_index] = 255; + endpoints[subset_index][1][comp_index] = 255; + } + } + } + + color32 block_colors[3][32]; + + const uint32_t* pWeights = g_astc_weight_tables[weight_bits]; + + for (uint32_t subset_index = 0; subset_index < total_subsets; subset_index++) + { + for (uint32_t l = 0; l < weight_levels; l++) + { + if (total_comps == 2) + { + const uint8_t lc = (uint8_t)astc_interpolate(endpoints[subset_index][0][0], endpoints[subset_index][1][0], pWeights[l], srgb); + const uint8_t ac = (uint8_t)astc_interpolate(endpoints[subset_index][0][3], endpoints[subset_index][1][3], pWeights[l], srgb); + + block_colors[subset_index][l].set(lc, lc, lc, ac); + } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); - status = true; + uint32_t comp_index; + for (comp_index = 0; comp_index < total_comps; comp_index++) + block_colors[subset_index][l][comp_index] = (uint8_t)astc_interpolate(endpoints[subset_index][0][comp_index], endpoints[subset_index][1][comp_index], pWeights[l], srgb); + + for (; comp_index < 4; comp_index++) + block_colors[subset_index][l][comp_index] = 255; } } + } + + const uint8_t* pPartition_pattern = g_zero_pattern; + + if (total_subsets >= 2) + { + if (total_subsets == 3) + pPartition_pattern = &g_astc_bc7_patterns3[common_pattern][0]; + else if (mode == 7) + pPartition_pattern = &g_bc7_3_astc2_patterns2[common_pattern][0]; else + pPartition_pattern = &g_astc_bc7_patterns2[common_pattern][0]; + +#ifdef _DEBUG + for (uint32_t i = 0; i < 16; i++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to BC5 channel 0 failed\n"); + assert(pPartition_pattern[i] == (uint8_t)astc_compute_texel_partition(astc.m_partition_seed, i & 3, i >> 2, 0, total_subsets, true)); } - break; +#endif } - case transcoder_texture_format::cTFASTC_4x4_RGBA: + + if (total_planes == 1) { -#if !BASISD_SUPPORT_ASTC + if (total_subsets == 1) + { + for (uint32_t i = 0; i < 16; i++) + { + assert(astc.m_weights[i] < weight_levels); + pPixels[i] = block_colors[0][astc.m_weights[i]]; + } + } + else + { + for (uint32_t i = 0; i < 16; i++) + { + assert(astc.m_weights[i] < weight_levels); + pPixels[i] = block_colors[pPartition_pattern[i]][astc.m_weights[i]]; + } + } + } + else + { + assert(total_subsets == 1); + + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t subset_index = 0; // pPartition_pattern[i]; + + const uint32_t weight_index0 = astc.m_weights[i * 2]; + const uint32_t weight_index1 = astc.m_weights[i * 2 + 1]; + + assert(weight_index0 < weight_levels && weight_index1 < weight_levels); + + color32& c = pPixels[i]; + for (uint32_t comp = 0; comp < 4; comp++) + { + if ((int)comp == astc.m_ccs) + c[comp] = block_colors[subset_index][weight_index1][comp]; + else + c[comp] = block_colors[subset_index][weight_index0][comp]; + } + } + } + + return true; + } + + bool unpack_uastc(const unpacked_uastc_block& unpacked_blk, color32* pPixels, bool srgb) + { + return unpack_uastc(unpacked_blk.m_mode, unpacked_blk.m_common_pattern, unpacked_blk.m_solid_color, unpacked_blk.m_astc, pPixels, srgb); + } + + bool unpack_uastc(const uastc_block& blk, color32* pPixels, bool srgb) + { + unpacked_uastc_block unpacked_blk; + + if (!unpack_uastc(blk, unpacked_blk, false, false)) return false; -#endif - assert(bytes_per_block == 16); - if (basis_file_has_alpha_slices) + return unpack_uastc(unpacked_blk, pPixels, srgb); + } + + // Determines the best shared pbits to use to encode xl/xh + static void determine_shared_pbits( + uint32_t total_comps, uint32_t comp_bits, float xl[4], float xh[4], + color_quad_u8& bestMinColor, color_quad_u8& bestMaxColor, uint32_t best_pbits[2]) + { + const uint32_t total_bits = comp_bits + 1; + assert(total_bits >= 4 && total_bits <= 8); + + const int iscalep = (1 << total_bits) - 1; + const float scalep = (float)iscalep; + + float best_err = 1e+9f; + + for (int p = 0; p < 2; p++) + { + color_quad_u8 xMinColor, xMaxColor; + for (uint32_t c = 0; c < 4; c++) { - // First decode the alpha data to the output (we're using the output texture as a temp buffer here). - status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cIndices, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + xMinColor.m_c[c] = (uint8_t)(clampi(((int)((xl[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + xMaxColor.m_c[c] = (uint8_t)(clampi(((int)((xh[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + } + + color_quad_u8 scaledLow, scaledHigh; + + for (uint32_t i = 0; i < 4; i++) + { + scaledLow.m_c[i] = (xMinColor.m_c[i] << (8 - total_bits)); + scaledLow.m_c[i] |= (scaledLow.m_c[i] >> total_bits); + assert(scaledLow.m_c[i] <= 255); + + scaledHigh.m_c[i] = (xMaxColor.m_c[i] << (8 - total_bits)); + scaledHigh.m_c[i] |= (scaledHigh.m_c[i] >> total_bits); + assert(scaledHigh.m_c[i] <= 255); + } + + float err = 0; + for (uint32_t i = 0; i < total_comps; i++) + err += basisu::squaref((scaledLow.m_c[i] / 255.0f) - xl[i]) + basisu::squaref((scaledHigh.m_c[i] / 255.0f) - xh[i]); + + if (err < best_err) + { + best_err = err; + best_pbits[0] = p; + best_pbits[1] = p; + for (uint32_t j = 0; j < 4; j++) + { + bestMinColor.m_c[j] = xMinColor.m_c[j] >> 1; + bestMaxColor.m_c[j] = xMaxColor.m_c[j] >> 1; + } + } + } + } + + // Determines the best unique pbits to use to encode xl/xh + static void determine_unique_pbits( + uint32_t total_comps, uint32_t comp_bits, float xl[4], float xh[4], + color_quad_u8& bestMinColor, color_quad_u8& bestMaxColor, uint32_t best_pbits[2]) + { + const uint32_t total_bits = comp_bits + 1; + const int iscalep = (1 << total_bits) - 1; + const float scalep = (float)iscalep; + + float best_err0 = 1e+9f; + float best_err1 = 1e+9f; + + for (int p = 0; p < 2; p++) + { + color_quad_u8 xMinColor, xMaxColor; + + for (uint32_t c = 0; c < 4; c++) + { + xMinColor.m_c[c] = (uint8_t)(clampi(((int)((xl[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + xMaxColor.m_c[c] = (uint8_t)(clampi(((int)((xh[c] * scalep - p) / 2.0f + .5f)) * 2 + p, p, iscalep - 1 + p)); + } + + color_quad_u8 scaledLow, scaledHigh; + for (uint32_t i = 0; i < 4; i++) + { + scaledLow.m_c[i] = (xMinColor.m_c[i] << (8 - total_bits)); + scaledLow.m_c[i] |= (scaledLow.m_c[i] >> total_bits); + assert(scaledLow.m_c[i] <= 255); + + scaledHigh.m_c[i] = (xMaxColor.m_c[i] << (8 - total_bits)); + scaledHigh.m_c[i] |= (scaledHigh.m_c[i] >> total_bits); + assert(scaledHigh.m_c[i] <= 255); + } + + float err0 = 0, err1 = 0; + for (uint32_t i = 0; i < total_comps; i++) + { + err0 += basisu::squaref(scaledLow.m_c[i] - xl[i] * 255.0f); + err1 += basisu::squaref(scaledHigh.m_c[i] - xh[i] * 255.0f); + } + + if (err0 < best_err0) + { + best_err0 = err0; + best_pbits[0] = p; + + bestMinColor.m_c[0] = xMinColor.m_c[0] >> 1; + bestMinColor.m_c[1] = xMinColor.m_c[1] >> 1; + bestMinColor.m_c[2] = xMinColor.m_c[2] >> 1; + bestMinColor.m_c[3] = xMinColor.m_c[3] >> 1; + } + + if (err1 < best_err1) + { + best_err1 = err1; + best_pbits[1] = p; + + bestMaxColor.m_c[0] = xMaxColor.m_c[0] >> 1; + bestMaxColor.m_c[1] = xMaxColor.m_c[1] >> 1; + bestMaxColor.m_c[2] = xMaxColor.m_c[2] >> 1; + bestMaxColor.m_c[3] = xMaxColor.m_c[3] >> 1; + } + } + } + + bool transcode_uastc_to_astc(const uastc_block& src_blk, void* pDst) + { + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, true, false)) + return false; + + bool success = false; + if (unpacked_src_blk.m_mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + pack_astc_solid_block(pDst, unpacked_src_blk.m_solid_color); + success = true; + } + else + { + success = pack_astc_block(static_cast<uint32_t*>(pDst), &unpacked_src_blk.m_astc, unpacked_src_blk.m_mode); + } + + return success; + } + + bool transcode_uastc_to_bc7(const unpacked_uastc_block& unpacked_src_blk, bc7_optimization_results& dst_blk) + { + memset(&dst_blk, 0, sizeof(dst_blk)); + + const uint32_t mode = unpacked_src_blk.m_mode; + + const uint32_t endpoint_range = g_uastc_mode_endpoint_ranges[mode]; + const uint32_t total_comps = g_uastc_mode_comps[mode]; + + switch (mode) + { + case 0: + case 5: + case 10: + case 12: + case 14: + case 15: + case 18: + { + // MODE 0: DualPlane: 0, WeightRange: 8 (16), Subsets: 1, EndpointRange: 19 (192) - BC7 MODE6 RGB + // MODE 5: DualPlane: 0, WeightRange : 5 (8), Subsets : 1, EndpointRange : 20 (256) - BC7 MODE6 RGB + // MODE 10 DualPlane: 0, WeightRange: 8 (16), Subsets: 1, EndpointRange: 13 (48) - BC7 MODE6 + // MODE 12: DualPlane: 0, WeightRange : 5 (8), Subsets : 1, EndpointRange : 19 (192) - BC7 MODE6 + // MODE 14: DualPlane: 0, WeightRange : 2 (4), Subsets : 1, EndpointRange : 20 (256) - BC7 MODE6 + // MODE 18: DualPlane: 0, WeightRange : 11 (32), Subsets : 1, CEM : 8, EndpointRange : 11 (32) - BC7 MODE6 + // MODE 15: DualPlane: 0, WeightRange : 8 (16), Subsets : 1, CEM : 4 (LA Direct), EndpointRange : 20 (256) - BC7 MODE6 + dst_blk.m_mode = 6; + + float xl[4], xh[4]; + if (total_comps == 2) + { + xl[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[0]].m_unquant / 255.0f; + xh[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[1]].m_unquant / 255.0f; + + xl[1] = xl[0]; + xh[1] = xh[0]; + + xl[2] = xl[0]; + xh[2] = xh[0]; + + xl[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[2]].m_unquant / 255.0f; + xh[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[3]].m_unquant / 255.0f; + } + else + { + xl[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[0]].m_unquant / 255.0f; + xl[1] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[2]].m_unquant / 255.0f; + xl[2] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[4]].m_unquant / 255.0f; + + xh[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[1]].m_unquant / 255.0f; + xh[1] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[3]].m_unquant / 255.0f; + xh[2] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[5]].m_unquant / 255.0f; + + if (total_comps == 4) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to failed\n"); + xl[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[6]].m_unquant / 255.0f; + xh[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[7]].m_unquant / 255.0f; } else { - // Now decode the color data and transcode to ASTC. The transcoder function will read the alpha selector data from the output texture as it converts and - // transcode both the alpha and color data at the same time to ASTC. - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, 16, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); + xl[3] = 1.0f; + xh[3] = 1.0f; } } + + uint32_t best_pbits[2]; + color_quad_u8 bestMinColor, bestMaxColor; + determine_unique_pbits((total_comps == 2) ? 4 : total_comps, 7, xl, xh, bestMinColor, bestMaxColor, best_pbits); + + dst_blk.m_low[0] = bestMinColor; + dst_blk.m_high[0] = bestMaxColor; + + if (total_comps == 3) + { + dst_blk.m_low[0].m_c[3] = 127; + dst_blk.m_high[0].m_c[3] = 127; + } + + dst_blk.m_pbits[0][0] = best_pbits[0]; + dst_blk.m_pbits[0][1] = best_pbits[1]; + + if (mode == 18) + { + const uint8_t s_bc7_5_to_4[32] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 }; + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = s_bc7_5_to_4[unpacked_src_blk.m_astc.m_weights[i]]; + } + else if (mode == 14) + { + const uint8_t s_bc7_2_to_4[4] = { 0, 5, 10, 15 }; + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = s_bc7_2_to_4[unpacked_src_blk.m_astc.m_weights[i]]; + } + else if ((mode == 5) || (mode == 12)) + { + const uint8_t s_bc7_3_to_4[8] = { 0, 2, 4, 6, 9, 11, 13, 15 }; + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = s_bc7_3_to_4[unpacked_src_blk.m_astc.m_weights[i]]; + } else - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cASTC_4x4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + { + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; + } break; } - case transcoder_texture_format::cTFATC_RGB: + case 1: { -#if !BASISD_SUPPORT_ATC - return false; -#endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + // DualPlane: 0, WeightRange : 2 (4), Subsets : 1, EndpointRange : 20 (256) - BC7 MODE3 + // Mode 1 uses endpoint range 20 - no need to use ASTC dequant tables. + dst_blk.m_mode = 3; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cATC_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + float xl[4], xh[4]; + xl[0] = unpacked_src_blk.m_astc.m_endpoints[0] / 255.0f; + xl[1] = unpacked_src_blk.m_astc.m_endpoints[2] / 255.0f; + xl[2] = unpacked_src_blk.m_astc.m_endpoints[4] / 255.0f; + xl[3] = 1.0f; + + xh[0] = unpacked_src_blk.m_astc.m_endpoints[1] / 255.0f; + xh[1] = unpacked_src_blk.m_astc.m_endpoints[3] / 255.0f; + xh[2] = unpacked_src_blk.m_astc.m_endpoints[5] / 255.0f; + xh[3] = 1.0f; + + uint32_t best_pbits[2]; + color_quad_u8 bestMinColor, bestMaxColor; + memset(&bestMinColor, 0, sizeof(bestMinColor)); + memset(&bestMaxColor, 0, sizeof(bestMaxColor)); + determine_unique_pbits(3, 7, xl, xh, bestMinColor, bestMaxColor, best_pbits); + + for (uint32_t i = 0; i < 3; i++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC_RGB failed\n"); + dst_blk.m_low[0].m_c[i] = bestMinColor.m_c[i]; + dst_blk.m_high[0].m_c[i] = bestMaxColor.m_c[i]; + dst_blk.m_low[1].m_c[i] = bestMinColor.m_c[i]; + dst_blk.m_high[1].m_c[i] = bestMaxColor.m_c[i]; } + dst_blk.m_pbits[0][0] = best_pbits[0]; + dst_blk.m_pbits[0][1] = best_pbits[1]; + dst_blk.m_pbits[1][0] = best_pbits[0]; + dst_blk.m_pbits[1][1] = best_pbits[1]; + + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; + break; } - case transcoder_texture_format::cTFATC_RGBA: + case 2: { -#if !BASISD_SUPPORT_ATC - return false; -#endif -#if !BASISD_SUPPORT_DXT5A - return false; -#endif - assert(bytes_per_block == 16); + // 2. DualPlane: 0, WeightRange : 5 (8), Subsets : 2, EndpointRange : 8 (16) - BC7 MODE1 + dst_blk.m_mode = 1; + dst_blk.m_partition = g_astc_bc7_common_partitions2[unpacked_src_blk.m_common_pattern].m_bc7; - // First decode the alpha data - if (basis_file_has_alpha_slices) + const bool invert_partition = g_astc_bc7_common_partitions2[unpacked_src_blk.m_common_pattern].m_invert; + + float xl[4], xh[4]; + xl[3] = 1.0f; + xh[3] = 1.0f; + + for (uint32_t subset = 0; subset < 2; subset++) { - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + for (uint32_t i = 0; i < 3; i++) + { + uint32_t v = unpacked_src_blk.m_astc.m_endpoints[i * 2 + subset * 6]; + v = (v << 4) | v; + xl[i] = v / 255.0f; + + v = unpacked_src_blk.m_astc.m_endpoints[i * 2 + subset * 6 + 1]; + v = (v << 4) | v; + xh[i] = v / 255.0f; + } + + uint32_t best_pbits[2] = { 0, 0 }; + color_quad_u8 bestMinColor, bestMaxColor; + memset(&bestMinColor, 0, sizeof(bestMinColor)); + memset(&bestMaxColor, 0, sizeof(bestMaxColor)); + determine_shared_pbits(3, 6, xl, xh, bestMinColor, bestMaxColor, best_pbits); + + const uint32_t bc7_subset_index = invert_partition ? (1 - subset) : subset; + + for (uint32_t i = 0; i < 3; i++) + { + dst_blk.m_low[bc7_subset_index].m_c[i] = bestMinColor.m_c[i]; + dst_blk.m_high[bc7_subset_index].m_c[i] = bestMaxColor.m_c[i]; + } + + dst_blk.m_pbits[bc7_subset_index][0] = best_pbits[0]; + } // subset + + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; + + break; + } + case 3: + { + // DualPlane: 0, WeightRange : 2 (4), Subsets : 3, EndpointRange : 7 (12) - BC7 MODE2 + dst_blk.m_mode = 2; + dst_blk.m_partition = g_astc_bc7_common_partitions3[unpacked_src_blk.m_common_pattern].m_bc7; + + const uint32_t perm = g_astc_bc7_common_partitions3[unpacked_src_blk.m_common_pattern].m_astc_to_bc7_perm; + + for (uint32_t subset = 0; subset < 3; subset++) + { + for (uint32_t comp = 0; comp < 3; comp++) + { + uint32_t lo = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[comp * 2 + 0 + subset * 6]].m_unquant; + uint32_t hi = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[comp * 2 + 1 + subset * 6]].m_unquant; + + // TODO: I think this can be improved by using tables like Basis Universal does with ETC1S conversion. + lo = (lo * 31 + 127) / 255; + hi = (hi * 31 + 127) / 255; + + const uint32_t bc7_subset_index = g_astc_to_bc7_partition_index_perm_tables[perm][subset]; + + dst_blk.m_low[bc7_subset_index].m_c[comp] = (uint8_t)lo; + dst_blk.m_high[bc7_subset_index].m_c[comp] = (uint8_t)hi; + } + } + + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; + + break; + } + case 4: + { + // 4. DualPlane: 0, WeightRange: 2 (4), Subsets: 2, EndpointRange: 12 (40) - BC7 MODE3 + dst_blk.m_mode = 3; + dst_blk.m_partition = g_astc_bc7_common_partitions2[unpacked_src_blk.m_common_pattern].m_bc7; + + const bool invert_partition = g_astc_bc7_common_partitions2[unpacked_src_blk.m_common_pattern].m_invert; + + float xl[4], xh[4]; + xl[3] = 1.0f; + xh[3] = 1.0f; + + for (uint32_t subset = 0; subset < 2; subset++) + { + for (uint32_t i = 0; i < 3; i++) + { + xl[i] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[i * 2 + subset * 6]].m_unquant / 255.0f; + xh[i] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[i * 2 + subset * 6 + 1]].m_unquant / 255.0f; + } + + uint32_t best_pbits[2] = { 0, 0 }; + color_quad_u8 bestMinColor, bestMaxColor; + memset(&bestMinColor, 0, sizeof(bestMinColor)); + memset(&bestMaxColor, 0, sizeof(bestMaxColor)); + determine_unique_pbits(3, 7, xl, xh, bestMinColor, bestMaxColor, best_pbits); + + const uint32_t bc7_subset_index = invert_partition ? (1 - subset) : subset; + + for (uint32_t i = 0; i < 3; i++) + { + dst_blk.m_low[bc7_subset_index].m_c[i] = bestMinColor.m_c[i]; + dst_blk.m_high[bc7_subset_index].m_c[i] = bestMaxColor.m_c[i]; + } + dst_blk.m_low[bc7_subset_index].m_c[3] = 127; + dst_blk.m_high[bc7_subset_index].m_c[3] = 127; + + dst_blk.m_pbits[bc7_subset_index][0] = best_pbits[0]; + dst_blk.m_pbits[bc7_subset_index][1] = best_pbits[1]; + + } // subset + + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; + + break; + } + case 6: + case 11: + case 13: + case 17: + { + // MODE 6: DualPlane: 1, WeightRange : 2 (4), Subsets : 1, EndpointRange : 18 (160) - BC7 MODE5 RGB + // MODE 11: DualPlane: 1, WeightRange: 2 (4), Subsets: 1, EndpointRange: 13 (48) - BC7 MODE5 + // MODE 13: DualPlane: 1, WeightRange: 0 (2), Subsets : 1, EndpointRange : 20 (256) - BC7 MODE5 + // MODE 17: DualPlane: 1, WeightRange: 2 (4), Subsets: 1, CEM: 4 (LA Direct), EndpointRange: 20 (256) - BC7 MODE5 + dst_blk.m_mode = 5; + dst_blk.m_rotation = (unpacked_src_blk.m_astc.m_ccs + 1) & 3; + + if (total_comps == 2) + { + assert(unpacked_src_blk.m_astc.m_ccs == 3); + + dst_blk.m_low->m_c[0] = (uint8_t)((g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[0]].m_unquant * 127 + 127) / 255); + dst_blk.m_high->m_c[0] = (uint8_t)((g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[1]].m_unquant * 127 + 127) / 255); + + dst_blk.m_low->m_c[1] = dst_blk.m_low->m_c[0]; + dst_blk.m_high->m_c[1] = dst_blk.m_high->m_c[0]; + + dst_blk.m_low->m_c[2] = dst_blk.m_low->m_c[0]; + dst_blk.m_high->m_c[2] = dst_blk.m_high->m_c[0]; + + dst_blk.m_low->m_c[3] = (uint8_t)(g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[2]].m_unquant); + dst_blk.m_high->m_c[3] = (uint8_t)(g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[3]].m_unquant); } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cBC4, 16, output_row_pitch_in_blocks_or_pixels); - status = true; + for (uint32_t astc_comp = 0; astc_comp < 4; astc_comp++) + { + uint32_t bc7_comp = astc_comp; + // ASTC and BC7 handle dual plane component rotations differently: + // ASTC: 2nd plane separately interpolates the CCS channel. + // BC7: 2nd plane channel is swapped with alpha, 2nd plane controls alpha interpolation, then we swap alpha with the desired channel. + if (astc_comp == (uint32_t)unpacked_src_blk.m_astc.m_ccs) + bc7_comp = 3; + else if (astc_comp == 3) + bc7_comp = unpacked_src_blk.m_astc.m_ccs; + + uint32_t l = 255, h = 255; + if (astc_comp < total_comps) + { + l = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[astc_comp * 2 + 0]].m_unquant; + h = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[astc_comp * 2 + 1]].m_unquant; + } + + if (bc7_comp < 3) + { + l = (l * 127 + 127) / 255; + h = (h * 127 + 127) / 255; + } + + dst_blk.m_low->m_c[bc7_comp] = (uint8_t)l; + dst_blk.m_high->m_c[bc7_comp] = (uint8_t)h; + } } - if (status) + if (mode == 13) { - status = transcode_slice(pData, data_size, slice_index, (uint8_t*)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cATC_RGB, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + for (uint32_t i = 0; i < 16; i++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC RGB failed\n"); + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i * 2] ? 3 : 0; + dst_blk.m_alpha_selectors[i] = unpacked_src_blk.m_astc.m_weights[i * 2 + 1] ? 3 : 0; } } else { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ATC A failed\n"); + for (uint32_t i = 0; i < 16; i++) + { + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i * 2]; + dst_blk.m_alpha_selectors[i] = unpacked_src_blk.m_astc.m_weights[i * 2 + 1]; + } } + break; } - case transcoder_texture_format::cTFPVRTC2_4_RGB: + case 7: { -#if !BASISD_SUPPORT_PVRTC2 - return false; -#endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + // DualPlane: 0, WeightRange : 2 (4), Subsets : 2, EndpointRange : 12 (40) - BC7 MODE2 + dst_blk.m_mode = 2; + dst_blk.m_partition = g_bc7_3_astc2_common_partitions[unpacked_src_blk.m_common_pattern].m_bc73; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + const uint32_t common_pattern_k = g_bc7_3_astc2_common_partitions[unpacked_src_blk.m_common_pattern].k; + + for (uint32_t bc7_part = 0; bc7_part < 3; bc7_part++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to cPVRTC2_4_RGB failed\n"); + const uint32_t astc_part = bc7_convert_partition_index_3_to_2(bc7_part, common_pattern_k); + + for (uint32_t c = 0; c < 3; c++) + { + dst_blk.m_low[bc7_part].m_c[c] = (g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[c * 2 + 0 + astc_part * 6]].m_unquant * 31 + 127) / 255; + dst_blk.m_high[bc7_part].m_c[c] = (g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[c * 2 + 1 + astc_part * 6]].m_unquant * 31 + 127) / 255; + } } + + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; + break; } - case transcoder_texture_format::cTFPVRTC2_4_RGBA: + case UASTC_MODE_INDEX_SOLID_COLOR: { -#if !BASISD_SUPPORT_PVRTC2 - return false; -#endif - if (basis_file_has_alpha_slices) + // Void-Extent: Solid Color RGBA (BC7 MODE5 or MODE6) + const color32& solid_color = unpacked_src_blk.m_solid_color; + + uint32_t best_err0 = g_bc7_mode_6_optimal_endpoints[solid_color.r][0].m_error + g_bc7_mode_6_optimal_endpoints[solid_color.g][0].m_error + + g_bc7_mode_6_optimal_endpoints[solid_color.b][0].m_error + g_bc7_mode_6_optimal_endpoints[solid_color.a][0].m_error; + + uint32_t best_err1 = g_bc7_mode_6_optimal_endpoints[solid_color.r][1].m_error + g_bc7_mode_6_optimal_endpoints[solid_color.g][1].m_error + + g_bc7_mode_6_optimal_endpoints[solid_color.b][1].m_error + g_bc7_mode_6_optimal_endpoints[solid_color.a][1].m_error; + + if (best_err0 > 0 && best_err1 > 0) { - // First decode the alpha data to the output (we're using the output texture as a temp buffer here). - status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t*)pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cIndices, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + dst_blk.m_mode = 5; + + for (uint32_t c = 0; c < 3; c++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to failed\n"); + dst_blk.m_low[0].m_c[c] = g_bc7_mode_5_optimal_endpoints[solid_color.c[c]].m_lo; + dst_blk.m_high[0].m_c[c] = g_bc7_mode_5_optimal_endpoints[solid_color.c[c]].m_hi; } - else + + memset(dst_blk.m_selectors, BC7ENC_MODE_5_OPTIMAL_INDEX, 16); + + dst_blk.m_low[0].m_c[3] = solid_color.c[3]; + dst_blk.m_high[0].m_c[3] = solid_color.c[3]; + + //memset(dst_blk.m_alpha_selectors, 0, 16); + } + else + { + dst_blk.m_mode = 6; + + uint32_t best_p = 0; + if (best_err1 < best_err0) + best_p = 1; + + for (uint32_t c = 0; c < 4; c++) { - // Now decode the color data and transcode to PVRTC2 RGBA. - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGBA, bytes_per_block, decode_flags | cDecodeFlagsOutputHasAlphaIndices, output_row_pitch_in_blocks_or_pixels, pState); + dst_blk.m_low[0].m_c[c] = g_bc7_mode_6_optimal_endpoints[solid_color.c[c]][best_p].m_lo; + dst_blk.m_high[0].m_c[c] = g_bc7_mode_6_optimal_endpoints[solid_color.c[c]][best_p].m_hi; } + + dst_blk.m_pbits[0][0] = best_p; + dst_blk.m_pbits[0][1] = best_p; + memset(dst_blk.m_selectors, BC7ENC_MODE_6_OPTIMAL_INDEX, 16); } - else - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cPVRTC2_4_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + break; + } + case 9: + case 16: + { + // 9. DualPlane: 0, WeightRange : 2 (4), Subsets : 2, EndpointRange : 8 (16) - BC7 MODE7 + // 16. DualPlane: 0, WeightRange: 2 (4), Subsets: 2, CEM: 4 (LA Direct), EndpointRange: 20 (256) - BC7 MODE7 + + dst_blk.m_mode = 7; + dst_blk.m_partition = g_astc_bc7_common_partitions2[unpacked_src_blk.m_common_pattern].m_bc7; + + const bool invert_partition = g_astc_bc7_common_partitions2[unpacked_src_blk.m_common_pattern].m_invert; + + for (uint32_t astc_subset = 0; astc_subset < 2; astc_subset++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to cPVRTC2_4_RGBA failed\n"); - } + float xl[4], xh[4]; + + if (total_comps == 2) + { + xl[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[0 + astc_subset * 4]].m_unquant / 255.0f; + xh[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[1 + astc_subset * 4]].m_unquant / 255.0f; + + xl[1] = xl[0]; + xh[1] = xh[0]; + + xl[2] = xl[0]; + xh[2] = xh[0]; + + xl[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[2 + astc_subset * 4]].m_unquant / 255.0f; + xh[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[3 + astc_subset * 4]].m_unquant / 255.0f; + } + else + { + xl[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[0 + astc_subset * 8]].m_unquant / 255.0f; + xl[1] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[2 + astc_subset * 8]].m_unquant / 255.0f; + xl[2] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[4 + astc_subset * 8]].m_unquant / 255.0f; + xl[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[6 + astc_subset * 8]].m_unquant / 255.0f; + + xh[0] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[1 + astc_subset * 8]].m_unquant / 255.0f; + xh[1] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[3 + astc_subset * 8]].m_unquant / 255.0f; + xh[2] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[5 + astc_subset * 8]].m_unquant / 255.0f; + xh[3] = g_astc_unquant[endpoint_range][unpacked_src_blk.m_astc.m_endpoints[7 + astc_subset * 8]].m_unquant / 255.0f; + } + + uint32_t best_pbits[2] = { 0, 0 }; + color_quad_u8 bestMinColor, bestMaxColor; + memset(&bestMinColor, 0, sizeof(bestMinColor)); + memset(&bestMaxColor, 0, sizeof(bestMaxColor)); + determine_unique_pbits(4, 5, xl, xh, bestMinColor, bestMaxColor, best_pbits); + + const uint32_t bc7_subset_index = invert_partition ? (1 - astc_subset) : astc_subset; + + dst_blk.m_low[bc7_subset_index] = bestMinColor; + dst_blk.m_high[bc7_subset_index] = bestMaxColor; + + dst_blk.m_pbits[bc7_subset_index][0] = best_pbits[0]; + dst_blk.m_pbits[bc7_subset_index][1] = best_pbits[1]; + } // astc_subset + + for (uint32_t i = 0; i < 16; i++) + dst_blk.m_selectors[i] = unpacked_src_blk.m_astc.m_weights[i]; break; } - case transcoder_texture_format::cTFRGBA32: + default: + return false; + } + + return true; + } + + bool transcode_uastc_to_bc7(const uastc_block& src_blk, bc7_optimization_results& dst_blk) + { + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false, false)) + return false; + + return transcode_uastc_to_bc7(unpacked_src_blk, dst_blk); + } + + bool transcode_uastc_to_bc7(const uastc_block& src_blk, void* pDst) + { + bc7_optimization_results temp; + if (!transcode_uastc_to_bc7(src_blk, temp)) + return false; + + encode_bc7_block(pDst, &temp); + return true; + } + + color32 apply_etc1_bias(const color32 &block_color, uint32_t bias, uint32_t limit, uint32_t subblock) + { + color32 result; + + for (uint32_t c = 0; c < 3; c++) { - // Raw 32bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. + static const int s_divs[3] = { 1, 3, 9 }; - // First decode the alpha data - if (basis_file_has_alpha_slices) - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + int delta = 0; + + switch (bias) + { + case 2: delta = subblock ? 0 : ((c == 0) ? -1 : 0); break; + case 5: delta = subblock ? 0 : ((c == 1) ? -1 : 0); break; + case 6: delta = subblock ? 0 : ((c == 2) ? -1 : 0); break; + + case 7: delta = subblock ? 0 : ((c == 0) ? 1 : 0); break; + case 11: delta = subblock ? 0 : ((c == 1) ? 1 : 0); break; + case 15: delta = subblock ? 0 : ((c == 2) ? 1 : 0); break; + + case 18: delta = subblock ? ((c == 0) ? -1 : 0) : 0; break; + case 19: delta = subblock ? ((c == 1) ? -1 : 0) : 0; break; + case 20: delta = subblock ? ((c == 2) ? -1 : 0) : 0; break; + + case 21: delta = subblock ? ((c == 0) ? 1 : 0) : 0; break; + case 24: delta = subblock ? ((c == 1) ? 1 : 0) : 0; break; + case 8: delta = subblock ? ((c == 2) ? 1 : 0) : 0; break; + + case 10: delta = -2; break; + + case 27: delta = subblock ? 0 : -1; break; + case 28: delta = subblock ? -1 : 1; break; + case 29: delta = subblock ? 1 : 0; break; + case 30: delta = subblock ? -1 : 0; break; + case 31: delta = subblock ? 0 : 1; break; + + default: + delta = ((bias / s_divs[c]) % 3) - 1; + break; + } + + int v = block_color[c]; + if (v == 0) + { + if (delta == -2) + v += 3; + else + v += delta + 1; + } + else if (v == (int)limit) + { + v += (delta - 1); + } else - status = true; + { + v += delta; + if ((v < 0) || (v > (int)limit)) + v = (v - delta) - delta; + } - if (status) + assert(v >= 0); + assert(v <= (int)limit); + + result[c] = (uint8_t)v; + } + + return result; + } + + static void etc1_determine_selectors(decoder_etc_block& dst_blk, const color32* pSource_pixels, uint32_t first_subblock, uint32_t last_subblock) + { + static const uint8_t s_tran[4] = { 1, 0, 2, 3 }; + + uint16_t l_bitmask = 0; + uint16_t h_bitmask = 0; + + for (uint32_t subblock = first_subblock; subblock < last_subblock; subblock++) + { + color32 block_colors[4]; + dst_blk.get_block_colors(block_colors, subblock); + + uint32_t block_y[4]; + for (uint32_t i = 0; i < 4; i++) + block_y[i] = block_colors[i][0] * 54 + block_colors[i][1] * 183 + block_colors[i][2] * 19; + + const uint32_t block_y01 = block_y[0] + block_y[1]; + const uint32_t block_y12 = block_y[1] + block_y[2]; + const uint32_t block_y23 = block_y[2] + block_y[3]; + + // X0 X0 X0 X0 X1 X1 X1 X1 X2 X2 X2 X2 X3 X3 X3 X3 + // Y0 Y1 Y2 Y3 Y0 Y1 Y2 Y3 Y0 Y1 Y2 Y3 Y0 Y1 Y2 Y3 + + if (dst_blk.get_flip_bit()) { - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? block_format::cRGB32 : block_format::cRGBA32, sizeof(uint32_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); - if (!status) + uint32_t ofs = subblock * 2; + + for (uint32_t y = 0; y < 2; y++) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA32 RGB failed\n"); + for (uint32_t x = 0; x < 4; x++) + { + const color32& c = pSource_pixels[x + (subblock * 2 + y) * 4]; + const uint32_t l = c[0] * 108 + c[1] * 366 + c[2] * 38; + + uint32_t t = s_tran[(l < block_y01) + (l < block_y12) + (l < block_y23)]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ofs += 4; + } + + ofs = (int)ofs + 1 - 4 * 4; } } else { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA32 A failed\n"); + uint32_t ofs = (subblock * 2) * 4; + for (uint32_t x = 0; x < 2; x++) + { + for (uint32_t y = 0; y < 4; y++) + { + const color32& c = pSource_pixels[subblock * 2 + x + y * 4]; + const uint32_t l = c[0] * 108 + c[1] * 366 + c[2] * 38; + + uint32_t t = s_tran[(l < block_y01) + (l < block_y12) + (l < block_y23)]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ++ofs; + } + } } + } - break; + dst_blk.m_bytes[7] = (uint8_t)(l_bitmask); + dst_blk.m_bytes[6] = (uint8_t)(l_bitmask >> 8); + dst_blk.m_bytes[5] = (uint8_t)(h_bitmask); + dst_blk.m_bytes[4] = (uint8_t)(h_bitmask >> 8); + } + + static const uint8_t s_etc1_solid_selectors[4][4] = { { 255, 255, 255, 255 }, { 255, 255, 0, 0 }, { 0, 0, 0, 0 }, {0, 0, 255, 255 } }; + + struct etc_coord2 + { + uint8_t m_x, m_y; + }; + + // [flip][subblock][pixel_index] + const etc_coord2 g_etc1_pixel_coords[2][2][8] = + { + { + { + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 } + }, + { + { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, + { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 } + } + }, + { + { + { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, + { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 } + }, + { + { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 }, + { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 } + }, } - case transcoder_texture_format::cTFRGB565: - case transcoder_texture_format::cTFBGR565: + }; + + void transcode_uastc_to_etc1(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst) + { + decoder_etc_block& dst_blk = *static_cast<decoder_etc_block*>(pDst); + + if (unpacked_src_blk.m_mode == UASTC_MODE_INDEX_SOLID_COLOR) { - // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. - - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + dst_blk.m_bytes[3] = (uint8_t)((unpacked_src_blk.m_etc1_diff << 1) | (unpacked_src_blk.m_etc1_inten0 << 5) | (unpacked_src_blk.m_etc1_inten0 << 2)); - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, (fmt == transcoder_texture_format::cTFRGB565) ? block_format::cRGB565 : block_format::cBGR565, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); - if (!status) + if (unpacked_src_blk.m_etc1_diff) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGB565 RGB failed\n"); + dst_blk.m_bytes[0] = (uint8_t)(unpacked_src_blk.m_etc1_r << 3); + dst_blk.m_bytes[1] = (uint8_t)(unpacked_src_blk.m_etc1_g << 3); + dst_blk.m_bytes[2] = (uint8_t)(unpacked_src_blk.m_etc1_b << 3); + } + else + { + dst_blk.m_bytes[0] = (uint8_t)(unpacked_src_blk.m_etc1_r | (unpacked_src_blk.m_etc1_r << 4)); + dst_blk.m_bytes[1] = (uint8_t)(unpacked_src_blk.m_etc1_g | (unpacked_src_blk.m_etc1_g << 4)); + dst_blk.m_bytes[2] = (uint8_t)(unpacked_src_blk.m_etc1_b | (unpacked_src_blk.m_etc1_b << 4)); } - break; + memcpy(dst_blk.m_bytes + 4, &s_etc1_solid_selectors[unpacked_src_blk.m_etc1_selector][0], 4); + + return; } - case transcoder_texture_format::cTFRGBA4444: + + const bool flip = unpacked_src_blk.m_etc1_flip != 0; + const bool diff = unpacked_src_blk.m_etc1_diff != 0; + + dst_blk.m_bytes[3] = (uint8_t)((int)flip | (diff << 1) | (unpacked_src_blk.m_etc1_inten0 << 5) | (unpacked_src_blk.m_etc1_inten1 << 2)); + + const uint32_t limit = diff ? 31 : 15; + + color32 block_colors[2]; + + for (uint32_t subset = 0; subset < 2; subset++) { - // Raw 16bpp pixels, decoded in the usual raster order (NOT block order) into an image in memory. + uint32_t avg_color[3]; + memset(avg_color, 0, sizeof(avg_color)); - // First decode the alpha data - if (basis_file_has_alpha_slices) - status = transcode_slice(pData, data_size, slice_index + 1, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cRGBA4444_ALPHA, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); + for (uint32_t j = 0; j < 8; j++) + { + const etc_coord2& c = g_etc1_pixel_coords[flip][subset][j]; + + avg_color[0] += block_pixels[c.m_y][c.m_x].r; + avg_color[1] += block_pixels[c.m_y][c.m_x].g; + avg_color[2] += block_pixels[c.m_y][c.m_x].b; + } // j + + block_colors[subset][0] = (uint8_t)((avg_color[0] * limit + 1020) / (8 * 255)); + block_colors[subset][1] = (uint8_t)((avg_color[1] * limit + 1020) / (8 * 255)); + block_colors[subset][2] = (uint8_t)((avg_color[2] * limit + 1020) / (8 * 255)); + block_colors[subset][3] = 0; + + if (g_uastc_mode_has_etc1_bias[unpacked_src_blk.m_mode]) + { + block_colors[subset] = apply_etc1_bias(block_colors[subset], unpacked_src_blk.m_etc1_bias, limit, subset); + } + + } // subset + + if (diff) + { + int dr = block_colors[1].r - block_colors[0].r; + int dg = block_colors[1].g - block_colors[0].g; + int db = block_colors[1].b - block_colors[0].b; + + dr = basisu::clamp<int>(dr, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + dg = basisu::clamp<int>(dg, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + db = basisu::clamp<int>(db, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + + if (dr < 0) dr += 8; + if (dg < 0) dg += 8; + if (db < 0) db += 8; + + dst_blk.m_bytes[0] = (uint8_t)((block_colors[0].r << 3) | dr); + dst_blk.m_bytes[1] = (uint8_t)((block_colors[0].g << 3) | dg); + dst_blk.m_bytes[2] = (uint8_t)((block_colors[0].b << 3) | db); + } + else + { + dst_blk.m_bytes[0] = (uint8_t)(block_colors[1].r | (block_colors[0].r << 4)); + dst_blk.m_bytes[1] = (uint8_t)(block_colors[1].g | (block_colors[0].g << 4)); + dst_blk.m_bytes[2] = (uint8_t)(block_colors[1].b | (block_colors[0].b << 4)); + } + + etc1_determine_selectors(dst_blk, &block_pixels[0][0], 0, 2); + } + + bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst) + { + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + color32 block_pixels[4][4]; + if (unpacked_src_blk.m_mode != UASTC_MODE_INDEX_SOLID_COLOR) + { + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + } + + transcode_uastc_to_etc1(unpacked_src_blk, block_pixels, pDst); + + return true; + } + + static inline int gray_distance2(const uint8_t c, int y) + { + int gray_dist = (int)c - y; + return gray_dist * gray_dist; + } + + static bool pack_etc1_y_estimate_flipped(const uint8_t* pSrc_pixels, + int& upper_avg, int& lower_avg, int& left_avg, int& right_avg) + { + int sums[2][2]; + +#define GET_XY(x, y) pSrc_pixels[(x) + ((y) * 4)] + + sums[0][0] = GET_XY(0, 0) + GET_XY(0, 1) + GET_XY(1, 0) + GET_XY(1, 1); + sums[1][0] = GET_XY(2, 0) + GET_XY(2, 1) + GET_XY(3, 0) + GET_XY(3, 1); + sums[0][1] = GET_XY(0, 2) + GET_XY(0, 3) + GET_XY(1, 2) + GET_XY(1, 3); + sums[1][1] = GET_XY(2, 2) + GET_XY(2, 3) + GET_XY(3, 2) + GET_XY(3, 3); + + upper_avg = (sums[0][0] + sums[1][0] + 4) / 8; + lower_avg = (sums[0][1] + sums[1][1] + 4) / 8; + left_avg = (sums[0][0] + sums[0][1] + 4) / 8; + right_avg = (sums[1][0] + sums[1][1] + 4) / 8; + +#undef GET_XY +#define GET_XY(x, y, a) gray_distance2(pSrc_pixels[(x) + ((y) * 4)], a) + + int upper_gray_dist = 0, lower_gray_dist = 0, left_gray_dist = 0, right_gray_dist = 0; + for (uint32_t i = 0; i < 4; i++) + { + for (uint32_t j = 0; j < 2; j++) + { + upper_gray_dist += GET_XY(i, j, upper_avg); + lower_gray_dist += GET_XY(i, 2 + j, lower_avg); + left_gray_dist += GET_XY(j, i, left_avg); + right_gray_dist += GET_XY(2 + j, i, right_avg); + } + } + +#undef GET_XY + + int upper_lower_sum = upper_gray_dist + lower_gray_dist; + int left_right_sum = left_gray_dist + right_gray_dist; + + return upper_lower_sum < left_right_sum; + } + + // Base Sel Table + // XXXXX XX XXX + static const uint16_t g_etc1_y_solid_block_configs[256] = + { + 0,781,64,161,260,192,33,131,96,320,65,162,261,193,34,291,97,224,66,163,262,194,35,549,98,4,67,653,164,195,523,36,99,5,578,68,165,353,196,37,135,100,324,69,166,354,197,38,295,101,228,70,167, + 355,198,39,553,102,8,71,608,168,199,527,40,103,9,582,72,169,357,200,41,139,104,328,73,170,358,201,42,299,105,232,74,171,359,202,43,557,106,12,75,612,172,203,531,44,107,13,586,76,173,361, + 204,45,143,108,332,77,174,362,205,46,303,109,236,78,175,363,206,47,561,110,16,79,616,176,207,535,48,111,17,590,80,177,365,208,49,147,112,336,81,178,366,209,50,307,113,240,82,179,367,210, + 51,565,114,20,83,620,180,211,539,52,115,21,594,84,181,369,212,53,151,116,340,85,182,370,213,54,311,117,244,86,183,371,214,55,569,118,24,87,624,184,215,543,56,119,25,598,88,185,373,216,57, + 155,120,344,89,186,374,217,58,315,121,248,90,187,375,218,59,573,122,28,91,628,188,219,754,60,123,29,602,92,189,377,220,61,159,124,348,93,190,378,221,62,319,125,252,94,191,379,222,63,882,126 + }; + + // individual + // table base sel0 sel1 sel2 sel3 + static const uint16_t g_etc1_y_solid_block_4i_configs[256] = + { + 0xA000,0xA800,0x540B,0xAA01,0xAA01,0xFE00,0xFF00,0xFF00,0x8,0x5515,0x5509,0x5509,0xAA03,0x5508,0x5508,0x9508,0xA508,0xA908,0xAA08,0x5513,0xAA09,0xAA09,0xAA05,0xFF08,0xFF08,0x10,0x551D,0x5511,0x5511, + 0xAA0B,0x5510,0x5510,0x9510,0xA510,0xA910,0xAA10,0x551B,0xAA11,0xAA11,0xAA0D,0xFF10,0xFF10,0x18,0x5525,0x5519,0x5519,0xAA13,0x5518,0x5518,0x9518,0xA518,0xA918,0xAA18,0x5523,0xAA19,0xAA19,0xAA15, + 0xFF18,0xFF18,0x20,0x552D,0x5521,0x5521,0xAA1B,0x5520,0x5520,0x9520,0xA520,0xA920,0xAA20,0x552B,0xAA21,0xAA21,0xAA1D,0xFF20,0xFF20,0x28,0x5535,0x5529,0x5529,0xAA23,0x5528,0x5528,0x9528,0xA528,0xA928, + 0xAA28,0x5533,0xAA29,0xAA29,0xAA25,0xFF28,0xFF28,0x30,0x553D,0x5531,0x5531,0xAA2B,0x5530,0x5530,0x9530,0xA530,0xA930,0xAA30,0x553B,0xAA31,0xAA31,0xAA2D,0xFF30,0xFF30,0x38,0x5545,0x5539,0x5539,0xAA33, + 0x5538,0x5538,0x9538,0xA538,0xA938,0xAA38,0x5543,0xAA39,0xAA39,0xAA35,0xFF38,0xFF38,0x40,0x554D,0x5541,0x5541,0xAA3B,0x5540,0x5540,0x9540,0xA540,0xA940,0xAA40,0x554B,0xAA41,0xAA41,0xAA3D,0xFF40,0xFF40, + 0x48,0x5555,0x5549,0x5549,0xAA43,0x5548,0x5548,0x9548,0xA548,0xA948,0xAA48,0x5553,0xAA49,0xAA49,0xAA45,0xFF48,0xFF48,0x50,0x555D,0x5551,0x5551,0xAA4B,0x5550,0x5550,0x9550,0xA550,0xA950,0xAA50,0x555B, + 0xAA51,0xAA51,0xAA4D,0xFF50,0xFF50,0x58,0x5565,0x5559,0x5559,0xAA53,0x5558,0x5558,0x9558,0xA558,0xA958,0xAA58,0x5563,0xAA59,0xAA59,0xAA55,0xFF58,0xFF58,0x60,0x556D,0x5561,0x5561,0xAA5B,0x5560,0x5560, + 0x9560,0xA560,0xA960,0xAA60,0x556B,0xAA61,0xAA61,0xAA5D,0xFF60,0xFF60,0x68,0x5575,0x5569,0x5569,0xAA63,0x5568,0x5568,0x9568,0xA568,0xA968,0xAA68,0x5573,0xAA69,0xAA69,0xAA65,0xFF68,0xFF68,0x70,0x557D, + 0x5571,0x5571,0xAA6B,0x5570,0x5570,0x9570,0xA570,0xA970,0xAA70,0x557B,0xAA71,0xAA71,0xAA6D,0xFF70,0xFF70,0x78,0x78,0x5579,0x5579,0xAA73,0x5578,0x9578,0x2578,0xE6E,0x278 + }; + + static const uint16_t g_etc1_y_solid_block_2i_configs[256] = + { + 0x416,0x800,0xA00,0x50B,0xA01,0xA01,0xF00,0xF00,0xF00,0x8,0x515,0x509,0x509,0xA03,0x508,0x508,0xF01,0xF01,0xA08,0xA08,0x513,0xA09,0xA09,0xA05,0xF08,0xF08,0x10,0x51D,0x511,0x511,0xA0B,0x510,0x510,0xF09, + 0xF09,0xA10,0xA10,0x51B,0xA11,0xA11,0xA0D,0xF10,0xF10,0x18,0x525,0x519,0x519,0xA13,0x518,0x518,0xF11,0xF11,0xA18,0xA18,0x523,0xA19,0xA19,0xA15,0xF18,0xF18,0x20,0x52D,0x521,0x521,0xA1B,0x520,0x520,0xF19, + 0xF19,0xA20,0xA20,0x52B,0xA21,0xA21,0xA1D,0xF20,0xF20,0x28,0x535,0x529,0x529,0xA23,0x528,0x528,0xF21,0xF21,0xA28,0xA28,0x533,0xA29,0xA29,0xA25,0xF28,0xF28,0x30,0x53D,0x531,0x531,0xA2B,0x530,0x530,0xF29, + 0xF29,0xA30,0xA30,0x53B,0xA31,0xA31,0xA2D,0xF30,0xF30,0x38,0x545,0x539,0x539,0xA33,0x538,0x538,0xF31,0xF31,0xA38,0xA38,0x543,0xA39,0xA39,0xA35,0xF38,0xF38,0x40,0x54D,0x541,0x541,0xA3B,0x540,0x540,0xF39, + 0xF39,0xA40,0xA40,0x54B,0xA41,0xA41,0xA3D,0xF40,0xF40,0x48,0x555,0x549,0x549,0xA43,0x548,0x548,0xF41,0xF41,0xA48,0xA48,0x553,0xA49,0xA49,0xA45,0xF48,0xF48,0x50,0x55D,0x551,0x551,0xA4B,0x550,0x550,0xF49, + 0xF49,0xA50,0xA50,0x55B,0xA51,0xA51,0xA4D,0xF50,0xF50,0x58,0x565,0x559,0x559,0xA53,0x558,0x558,0xF51,0xF51,0xA58,0xA58,0x563,0xA59,0xA59,0xA55,0xF58,0xF58,0x60,0x56D,0x561,0x561,0xA5B,0x560,0x560,0xF59, + 0xF59,0xA60,0xA60,0x56B,0xA61,0xA61,0xA5D,0xF60,0xF60,0x68,0x575,0x569,0x569,0xA63,0x568,0x568,0xF61,0xF61,0xA68,0xA68,0x573,0xA69,0xA69,0xA65,0xF68,0xF68,0x70,0x57D,0x571,0x571,0xA6B,0x570,0x570,0xF69, + 0xF69,0xA70,0xA70,0x57B,0xA71,0xA71,0xA6D,0xF70,0xF70,0x78,0x78,0x579,0x579,0xA73,0x578,0x578,0xE6E,0x278 + }; + + static const uint16_t g_etc1_y_solid_block_1i_configs[256] = + { + 0x0,0x116,0x200,0x200,0x10B,0x201,0x201,0x300,0x300,0x8,0x115,0x109,0x109,0x203,0x108,0x108,0x114,0x301,0x204,0x208,0x208,0x113,0x209,0x209,0x205,0x308,0x10,0x11D,0x111,0x111,0x20B,0x110,0x110,0x11C,0x309, + 0x20C,0x210,0x210,0x11B,0x211,0x211,0x20D,0x310,0x18,0x125,0x119,0x119,0x213,0x118,0x118,0x124,0x311,0x214,0x218,0x218,0x123,0x219,0x219,0x215,0x318,0x20,0x12D,0x121,0x121,0x21B,0x120,0x120,0x12C,0x319,0x21C, + 0x220,0x220,0x12B,0x221,0x221,0x21D,0x320,0x28,0x135,0x129,0x129,0x223,0x128,0x128,0x134,0x321,0x224,0x228,0x228,0x133,0x229,0x229,0x225,0x328,0x30,0x13D,0x131,0x131,0x22B,0x130,0x130,0x13C,0x329,0x22C,0x230, + 0x230,0x13B,0x231,0x231,0x22D,0x330,0x38,0x145,0x139,0x139,0x233,0x138,0x138,0x144,0x331,0x234,0x238,0x238,0x143,0x239,0x239,0x235,0x338,0x40,0x14D,0x141,0x141,0x23B,0x140,0x140,0x14C,0x339,0x23C,0x240,0x240, + 0x14B,0x241,0x241,0x23D,0x340,0x48,0x155,0x149,0x149,0x243,0x148,0x148,0x154,0x341,0x244,0x248,0x248,0x153,0x249,0x249,0x245,0x348,0x50,0x15D,0x151,0x151,0x24B,0x150,0x150,0x15C,0x349,0x24C,0x250,0x250,0x15B, + 0x251,0x251,0x24D,0x350,0x58,0x165,0x159,0x159,0x253,0x158,0x158,0x164,0x351,0x254,0x258,0x258,0x163,0x259,0x259,0x255,0x358,0x60,0x16D,0x161,0x161,0x25B,0x160,0x160,0x16C,0x359,0x25C,0x260,0x260,0x16B,0x261, + 0x261,0x25D,0x360,0x68,0x175,0x169,0x169,0x263,0x168,0x168,0x174,0x361,0x264,0x268,0x268,0x173,0x269,0x269,0x265,0x368,0x70,0x17D,0x171,0x171,0x26B,0x170,0x170,0x17C,0x369,0x26C,0x270,0x270,0x17B,0x271,0x271, + 0x26D,0x370,0x78,0x78,0x179,0x179,0x273,0x178,0x178,0x26E,0x278 + }; + + // We don't have any useful hints to accelerate single channel ETC1, so we need to real-time encode from scratch. + bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst, uint32_t channel) + { + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + +#if 0 + for (uint32_t individ = 0; individ < 2; individ++) + { + uint32_t overall_error = 0; + + for (uint32_t c = 0; c < 256; c++) + { + uint32_t best_err = UINT32_MAX; + uint32_t best_individ = 0; + uint32_t best_base = 0; + uint32_t best_sels[4] = { 0,0,0,0 }; + uint32_t best_table = 0; + + const uint32_t limit = individ ? 16 : 32; + + for (uint32_t table = 0; table < 8; table++) + { + for (uint32_t base = 0; base < limit; base++) + { + uint32_t total_e = 0; + uint32_t sels[4] = { 0,0,0,0 }; + + const uint32_t N = 4; + for (uint32_t i = 0; i < basisu::minimum<uint32_t>(N, (256 - c)); i++) + { + uint32_t best_sel_e = UINT32_MAX; + uint32_t best_sel = 0; + + for (uint32_t sel = 0; sel < 4; sel++) + { + int val = individ ? ((base << 4) | base) : ((base << 3) | (base >> 2)); + val = clamp255(val + g_etc1_inten_tables[table][sel]); + + int e = iabs(val - clamp255(c + i)); + if (e < best_sel_e) + { + best_sel_e = e; + best_sel = sel; + } + + } // sel + + sels[i] = best_sel; + total_e += best_sel_e * best_sel_e; + + } // i + + if (total_e < best_err) + { + best_err = total_e; + best_individ = individ; + best_base = base; + memcpy(best_sels, sels, sizeof(best_sels)); + best_table = table; + } + + } // base + } // table + + //printf("%u: %u,%u,%u,%u,%u,%u,%u,%u\n", c, best_err, best_individ, best_table, best_base, best_sels[0], best_sels[1], best_sels[2], best_sels[3]); + + uint32_t encoded = best_table | (best_base << 3) | + (best_sels[0] << 8) | + (best_sels[1] << 10) | + (best_sels[2] << 12) | + (best_sels[3] << 14); + + printf("0x%X,", encoded); + + overall_error += best_err; + } // c + + printf("\n"); + printf("Overall error: %u\n", overall_error); + + } // individ + + exit(0); +#endif + +#if 0 + for (uint32_t individ = 0; individ < 2; individ++) + { + uint32_t overall_error = 0; + + for (uint32_t c = 0; c < 256; c++) + { + uint32_t best_err = UINT32_MAX; + uint32_t best_individ = 0; + uint32_t best_base = 0; + uint32_t best_sels[4] = { 0,0,0,0 }; + uint32_t best_table = 0; + + const uint32_t limit = individ ? 16 : 32; + + for (uint32_t table = 0; table < 8; table++) + { + for (uint32_t base = 0; base < limit; base++) + { + uint32_t total_e = 0; + uint32_t sels[4] = { 0,0,0,0 }; + + const uint32_t N = 1; + for (uint32_t i = 0; i < basisu::minimum<uint32_t>(N, (256 - c)); i++) + { + uint32_t best_sel_e = UINT32_MAX; + uint32_t best_sel = 0; + + for (uint32_t sel = 0; sel < 4; sel++) + { + int val = individ ? ((base << 4) | base) : ((base << 3) | (base >> 2)); + val = clamp255(val + g_etc1_inten_tables[table][sel]); + + int e = iabs(val - clamp255(c + i)); + if (e < best_sel_e) + { + best_sel_e = e; + best_sel = sel; + } + + } // sel + + sels[i] = best_sel; + total_e += best_sel_e * best_sel_e; + + } // i + + if (total_e < best_err) + { + best_err = total_e; + best_individ = individ; + best_base = base; + memcpy(best_sels, sels, sizeof(best_sels)); + best_table = table; + } + + } // base + } // table + + //printf("%u: %u,%u,%u,%u,%u,%u,%u,%u\n", c, best_err, best_individ, best_table, best_base, best_sels[0], best_sels[1], best_sels[2], best_sels[3]); + + uint32_t encoded = best_table | (best_base << 3) | + (best_sels[0] << 8) | + (best_sels[1] << 10) | + (best_sels[2] << 12) | + (best_sels[3] << 14); + + printf("0x%X,", encoded); + + overall_error += best_err; + } // c + + printf("\n"); + printf("Overall error: %u\n", overall_error); + + } // individ + + exit(0); +#endif + + decoder_etc_block& dst_blk = *static_cast<decoder_etc_block*>(pDst); + + if (unpacked_src_blk.m_mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + const uint32_t y = unpacked_src_blk.m_solid_color[channel]; + const uint32_t encoded_config = g_etc1_y_solid_block_configs[y]; + + const uint32_t base = encoded_config & 31; + const uint32_t sel = (encoded_config >> 5) & 3; + const uint32_t table = encoded_config >> 7; + + dst_blk.m_bytes[3] = (uint8_t)(2 | (table << 5) | (table << 2)); + + dst_blk.m_bytes[0] = (uint8_t)(base << 3); + dst_blk.m_bytes[1] = (uint8_t)(base << 3); + dst_blk.m_bytes[2] = (uint8_t)(base << 3); + + memcpy(dst_blk.m_bytes + 4, &s_etc1_solid_selectors[sel][0], 4); + return true; + } + + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + uint8_t block_y[4][4]; + for (uint32_t i = 0; i < 16; i++) + ((uint8_t*)block_y)[i] = ((color32*)block_pixels)[i][channel]; + + int upper_avg, lower_avg, left_avg, right_avg; + bool flip = pack_etc1_y_estimate_flipped(&block_y[0][0], upper_avg, lower_avg, left_avg, right_avg); + + // non-flipped: | | + // vs. + // flipped: -- + // -- + + uint32_t low[2] = { 255, 255 }, high[2] = { 0, 0 }; + + if (flip) + { + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t v = block_y[y][x]; + low[0] = basisu::minimum(low[0], v); + high[0] = basisu::maximum(high[0], v); + } + } + for (uint32_t y = 2; y < 4; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const uint32_t v = block_y[y][x]; + low[1] = basisu::minimum(low[1], v); + high[1] = basisu::maximum(high[1], v); + } + } + } + else + { + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 2; x++) + { + const uint32_t v = block_y[y][x]; + low[0] = basisu::minimum(low[0], v); + high[0] = basisu::maximum(high[0], v); + } + } + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 2; x < 4; x++) + { + const uint32_t v = block_y[y][x]; + low[1] = basisu::minimum(low[1], v); + high[1] = basisu::maximum(high[1], v); + } + } + } + + const uint32_t range[2] = { high[0] - low[0], high[1] - low[1] }; + + dst_blk.m_bytes[3] = (uint8_t)((int)flip); + + if ((range[0] <= 3) && (range[1] <= 3)) + { + // This is primarily for better gradients. + dst_blk.m_bytes[0] = 0; + dst_blk.m_bytes[1] = 0; + dst_blk.m_bytes[2] = 0; + + uint16_t l_bitmask = 0, h_bitmask = 0; + + for (uint32_t subblock = 0; subblock < 2; subblock++) + { + const uint32_t encoded = (range[subblock] == 0) ? g_etc1_y_solid_block_1i_configs[low[subblock]] : ((range[subblock] < 2) ? g_etc1_y_solid_block_2i_configs[low[subblock]] : g_etc1_y_solid_block_4i_configs[low[subblock]]); + + const uint32_t table = encoded & 7; + const uint32_t base = (encoded >> 3) & 31; + assert(base <= 15); + const uint32_t sels[4] = { (encoded >> 8) & 3, (encoded >> 10) & 3, (encoded >> 12) & 3, (encoded >> 14) & 3 }; + + dst_blk.m_bytes[3] |= (uint8_t)(table << (subblock ? 2 : 5)); + + const uint32_t sv = base << (subblock ? 0 : 4); + dst_blk.m_bytes[0] |= (uint8_t)(sv); + dst_blk.m_bytes[1] |= (uint8_t)(sv); + dst_blk.m_bytes[2] |= (uint8_t)(sv); + + if (flip) + { + uint32_t ofs = subblock * 2; + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t t = block_y[y + subblock * 2][x]; + assert(t >= low[subblock] && t <= high[subblock]); + t -= low[subblock]; + assert(t <= 3); + + t = g_selector_index_to_etc1[sels[t]]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ofs += 4; + } + + ofs = (int)ofs + 1 - 4 * 4; + } + } + else + { + uint32_t ofs = (subblock * 2) * 4; + for (uint32_t x = 0; x < 2; x++) + { + for (uint32_t y = 0; y < 4; y++) + { + uint32_t t = block_y[y][x + subblock * 2]; + assert(t >= low[subblock] && t <= high[subblock]); + t -= low[subblock]; + assert(t <= 3); + + t = g_selector_index_to_etc1[sels[t]]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ++ofs; + } + } + } + } // subblock + + dst_blk.m_bytes[7] = (uint8_t)(l_bitmask); + dst_blk.m_bytes[6] = (uint8_t)(l_bitmask >> 8); + dst_blk.m_bytes[5] = (uint8_t)(h_bitmask); + dst_blk.m_bytes[4] = (uint8_t)(h_bitmask >> 8); + + return true; + } + + uint32_t y0 = ((flip ? upper_avg : left_avg) * 31 + 127) / 255; + uint32_t y1 = ((flip ? lower_avg : right_avg) * 31 + 127) / 255; + + bool diff = true; + + int dy = y1 - y0; + + if ((dy < cETC1ColorDeltaMin) || (dy > cETC1ColorDeltaMax)) + { + diff = false; + + y0 = ((flip ? upper_avg : left_avg) * 15 + 127) / 255; + y1 = ((flip ? lower_avg : right_avg) * 15 + 127) / 255; + + dst_blk.m_bytes[0] = (uint8_t)(y1 | (y0 << 4)); + dst_blk.m_bytes[1] = (uint8_t)(y1 | (y0 << 4)); + dst_blk.m_bytes[2] = (uint8_t)(y1 | (y0 << 4)); + } + else + { + dy = basisu::clamp<int>(dy, cETC1ColorDeltaMin, cETC1ColorDeltaMax); + + y1 = y0 + dy; + + if (dy < 0) dy += 8; + + dst_blk.m_bytes[0] = (uint8_t)((y0 << 3) | dy); + dst_blk.m_bytes[1] = (uint8_t)((y0 << 3) | dy); + dst_blk.m_bytes[2] = (uint8_t)((y0 << 3) | dy); + + dst_blk.m_bytes[3] |= 2; + } + + const uint32_t base_y[2] = { diff ? ((y0 << 3) | (y0 >> 2)) : ((y0 << 4) | y0), diff ? ((y1 << 3) | (y1 >> 2)) : ((y1 << 4) | y1) }; + + uint32_t enc_range[2]; + for (uint32_t subset = 0; subset < 2; subset++) + { + const int pos = basisu::iabs((int)high[subset] - (int)base_y[subset]); + const int neg = basisu::iabs((int)base_y[subset] - (int)low[subset]); + + enc_range[subset] = basisu::maximum(pos, neg); + } + + uint16_t l_bitmask = 0, h_bitmask = 0; + for (uint32_t subblock = 0; subblock < 2; subblock++) + { + if ((!diff) && (range[subblock] <= 3)) + { + const uint32_t encoded = (range[subblock] == 0) ? g_etc1_y_solid_block_1i_configs[low[subblock]] : ((range[subblock] < 2) ? g_etc1_y_solid_block_2i_configs[low[subblock]] : g_etc1_y_solid_block_4i_configs[low[subblock]]); + + const uint32_t table = encoded & 7; + const uint32_t base = (encoded >> 3) & 31; + assert(base <= 15); + const uint32_t sels[4] = { (encoded >> 8) & 3, (encoded >> 10) & 3, (encoded >> 12) & 3, (encoded >> 14) & 3 }; + + dst_blk.m_bytes[3] |= (uint8_t)(table << (subblock ? 2 : 5)); + + const uint32_t mask = ~(0xF << (subblock ? 0 : 4)); + + dst_blk.m_bytes[0] &= mask; + dst_blk.m_bytes[1] &= mask; + dst_blk.m_bytes[2] &= mask; + + const uint32_t sv = base << (subblock ? 0 : 4); + dst_blk.m_bytes[0] |= (uint8_t)(sv); + dst_blk.m_bytes[1] |= (uint8_t)(sv); + dst_blk.m_bytes[2] |= (uint8_t)(sv); + + if (flip) + { + uint32_t ofs = subblock * 2; + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t t = block_y[y + subblock * 2][x]; + assert(t >= low[subblock] && t <= high[subblock]); + t -= low[subblock]; + assert(t <= 3); + + t = g_selector_index_to_etc1[sels[t]]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ofs += 4; + } + + ofs = (int)ofs + 1 - 4 * 4; + } + } + else + { + uint32_t ofs = (subblock * 2) * 4; + for (uint32_t x = 0; x < 2; x++) + { + for (uint32_t y = 0; y < 4; y++) + { + uint32_t t = block_y[y][x + subblock * 2]; + assert(t >= low[subblock] && t <= high[subblock]); + t -= low[subblock]; + assert(t <= 3); + + t = g_selector_index_to_etc1[sels[t]]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ++ofs; + } + } + } + + continue; + } // if + + uint32_t best_err = UINT32_MAX; + uint8_t best_sels[8]; + uint32_t best_inten = 0; + + const int base = base_y[subblock]; + + const int low_limit = -base; + const int high_limit = 255 - base; + + assert(low_limit <= 0 && high_limit >= 0); + + uint32_t inten_table_mask = 0xFF; + const uint32_t er = enc_range[subblock]; + // Each one of these tables is expensive to evaluate, so let's only examine the ones we know may be useful. + if (er <= 51) + { + inten_table_mask = 0xF; + + if (er > 22) + inten_table_mask &= ~(1 << 0); + + if ((er < 4) || (er > 39)) + inten_table_mask &= ~(1 << 1); + + if (er < 9) + inten_table_mask &= ~(1 << 2); + + if (er < 12) + inten_table_mask &= ~(1 << 3); + } else - status = true; + { + inten_table_mask &= ~((1 << 0) | (1 << 1)); - if (status) + if (er > 60) + inten_table_mask &= ~(1 << 2); + + if (er > 89) + inten_table_mask &= ~(1 << 3); + + if (er > 120) + inten_table_mask &= ~(1 << 4); + + if (er > 136) + inten_table_mask &= ~(1 << 5); + + if (er > 174) + inten_table_mask &= ~(1 << 6); + } + + for (uint32_t inten = 0; inten < 8; inten++) { - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, basis_file_has_alpha_slices ? block_format::cRGBA4444_COLOR : block_format::cRGBA4444_COLOR_OPAQUE, sizeof(uint16_t), decode_flags, output_row_pitch_in_blocks_or_pixels, pState, nullptr, output_rows_in_pixels); - if (!status) + if ((inten_table_mask & (1 << inten)) == 0) + continue; + + const int t0 = basisu::maximum(low_limit, g_etc1_inten_tables[inten][0]); + const int t1 = basisu::maximum(low_limit, g_etc1_inten_tables[inten][1]); + const int t2 = basisu::minimum(high_limit, g_etc1_inten_tables[inten][2]); + const int t3 = basisu::minimum(high_limit, g_etc1_inten_tables[inten][3]); + assert((t0 <= t1) && (t1 <= t2) && (t2 <= t3)); + + const int tv[4] = { t2, t3, t1, t0 }; + + const int thresh01 = t0 + t1; + const int thresh12 = t1 + t2; + const int thresh23 = t2 + t3; + + assert(thresh01 <= thresh12 && thresh12 <= thresh23); + + static const uint8_t s_table[4] = { 1, 0, 2, 3 }; + + uint32_t total_err = 0; + uint8_t sels[8]; + + if (flip) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA4444 RGB failed\n"); + if (((int)high[subblock] - base) * 2 < thresh01) + { + memset(sels, 3, 8); + + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const int delta = (int)block_y[y + subblock * 2][x] - base; + + const uint32_t c = 3; + + uint32_t e = basisu::iabs(tv[c] - delta); + total_err += e * e; + } + if (total_err >= best_err) + break; + } + } + else if (((int)low[subblock] - base) * 2 >= thresh23) + { + memset(sels, 1, 8); + + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const int delta = (int)block_y[y + subblock * 2][x] - base; + + const uint32_t c = 1; + + uint32_t e = basisu::iabs(tv[c] - delta); + total_err += e * e; + } + if (total_err >= best_err) + break; + } + } + else + { + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + const int delta = (int)block_y[y + subblock * 2][x] - base; + const int delta2 = delta * 2; + + uint32_t c = s_table[(delta2 < thresh01) + (delta2 < thresh12) + (delta2 < thresh23)]; + sels[y * 4 + x] = (uint8_t)c; + + uint32_t e = basisu::iabs(tv[c] - delta); + total_err += e * e; + } + if (total_err >= best_err) + break; + } + } + } + else + { + if (((int)high[subblock] - base) * 2 < thresh01) + { + memset(sels, 3, 8); + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 2; x++) + { + const int delta = (int)block_y[y][x + subblock * 2] - base; + + const uint32_t c = 3; + + uint32_t e = basisu::iabs(tv[c] - delta); + total_err += e * e; + } + if (total_err >= best_err) + break; + } + } + else if (((int)low[subblock] - base) * 2 >= thresh23) + { + memset(sels, 1, 8); + + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 2; x++) + { + const int delta = (int)block_y[y][x + subblock * 2] - base; + + const uint32_t c = 1; + + uint32_t e = basisu::iabs(tv[c] - delta); + total_err += e * e; + } + if (total_err >= best_err) + break; + } + } + else + { + for (uint32_t y = 0; y < 4; y++) + { + for (uint32_t x = 0; x < 2; x++) + { + const int delta = (int)block_y[y][x + subblock * 2] - base; + const int delta2 = delta * 2; + + uint32_t c = s_table[(delta2 < thresh01) + (delta2 < thresh12) + (delta2 < thresh23)]; + sels[y * 2 + x] = (uint8_t)c; + + uint32_t e = basisu::iabs(tv[c] - delta); + total_err += e * e; + } + if (total_err >= best_err) + break; + } + } + } + + if (total_err < best_err) + { + best_err = total_err; + best_inten = inten; + memcpy(best_sels, sels, 8); + } + + } // inten + + //g_inten_hist[best_inten][enc_range[subblock]]++; + + dst_blk.m_bytes[3] |= (uint8_t)(best_inten << (subblock ? 2 : 5)); + + if (flip) + { + uint32_t ofs = subblock * 2; + for (uint32_t y = 0; y < 2; y++) + { + for (uint32_t x = 0; x < 4; x++) + { + uint32_t t = best_sels[y * 4 + x]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ofs += 4; + } + + ofs = (int)ofs + 1 - 4 * 4; } } else { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to RGBA4444 A failed\n"); + uint32_t ofs = (subblock * 2) * 4; + for (uint32_t x = 0; x < 2; x++) + { + for (uint32_t y = 0; y < 4; y++) + { + uint32_t t = best_sels[y * 2 + x]; + + assert(ofs < 16); + l_bitmask |= ((t & 1) << ofs); + h_bitmask |= ((t >> 1) << ofs); + ++ofs; + } + } } - break; + } // subblock + + dst_blk.m_bytes[7] = (uint8_t)(l_bitmask); + dst_blk.m_bytes[6] = (uint8_t)(l_bitmask >> 8); + dst_blk.m_bytes[5] = (uint8_t)(h_bitmask); + dst_blk.m_bytes[4] = (uint8_t)(h_bitmask >> 8); + + return true; + } + + const uint32_t ETC2_EAC_MIN_VALUE_SELECTOR = 3, ETC2_EAC_MAX_VALUE_SELECTOR = 7; + + void transcode_uastc_to_etc2_eac_a8(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst) + { + eac_block& dst = *static_cast<eac_block*>(pDst); + const color32* pSrc_pixels = &block_pixels[0][0]; + + if ((!g_uastc_mode_has_alpha[unpacked_src_blk.m_mode]) || (unpacked_src_blk.m_mode == UASTC_MODE_INDEX_SOLID_COLOR)) + { + const uint32_t a = (unpacked_src_blk.m_mode == UASTC_MODE_INDEX_SOLID_COLOR) ? unpacked_src_blk.m_solid_color[3] : 255; + + dst.m_base = a; + dst.m_table = 13; + dst.m_multiplier = 1; + + memcpy(dst.m_selectors, g_etc2_eac_a8_sel4, sizeof(g_etc2_eac_a8_sel4)); + + return; } - case transcoder_texture_format::cTFFXT1_RGB: + + uint32_t min_a = 255, max_a = 0; + for (uint32_t i = 0; i < 16; i++) { -#if !BASISD_SUPPORT_FXT1 + min_a = basisu::minimum<uint32_t>(min_a, pSrc_pixels[i].a); + max_a = basisu::maximum<uint32_t>(max_a, pSrc_pixels[i].a); + } + + if (min_a == max_a) + { + dst.m_base = min_a; + dst.m_table = 13; + dst.m_multiplier = 1; + + memcpy(dst.m_selectors, g_etc2_eac_a8_sel4, sizeof(g_etc2_eac_a8_sel4)); + return; + } + + const uint32_t table = unpacked_src_blk.m_etc2_hints & 0xF; + const int multiplier = unpacked_src_blk.m_etc2_hints >> 4; + + assert(multiplier >= 1); + + dst.m_multiplier = multiplier; + dst.m_table = table; + + const float range = (float)(g_eac_modifier_table[dst.m_table][ETC2_EAC_MAX_VALUE_SELECTOR] - g_eac_modifier_table[dst.m_table][ETC2_EAC_MIN_VALUE_SELECTOR]); + const int center = (int)roundf(basisu::lerp((float)min_a, (float)max_a, (float)(0 - g_eac_modifier_table[dst.m_table][ETC2_EAC_MIN_VALUE_SELECTOR]) / range)); + + dst.m_base = center; + + const int8_t* pTable = &g_eac_modifier_table[dst.m_table][0]; + + uint32_t vals[8]; + for (uint32_t j = 0; j < 8; j++) + vals[j] = clamp255(center + (pTable[j] * multiplier)); + + uint64_t sels = 0; + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t a = block_pixels[i & 3][i >> 2].a; + + const uint32_t err0 = (basisu::iabs(vals[0] - a) << 3) | 0; + const uint32_t err1 = (basisu::iabs(vals[1] - a) << 3) | 1; + const uint32_t err2 = (basisu::iabs(vals[2] - a) << 3) | 2; + const uint32_t err3 = (basisu::iabs(vals[3] - a) << 3) | 3; + const uint32_t err4 = (basisu::iabs(vals[4] - a) << 3) | 4; + const uint32_t err5 = (basisu::iabs(vals[5] - a) << 3) | 5; + const uint32_t err6 = (basisu::iabs(vals[6] - a) << 3) | 6; + const uint32_t err7 = (basisu::iabs(vals[7] - a) << 3) | 7; + + const uint32_t min_err = basisu::minimum(basisu::minimum(basisu::minimum(basisu::minimum(basisu::minimum(basisu::minimum(err0, err1, err2), err3), err4), err5), err6), err7); + + const uint64_t best_index = min_err & 7; + sels |= (best_index << (45 - i * 3)); + } + + dst.set_selector_bits(sels); + } + + bool transcode_uastc_to_etc2_rgba(const uastc_block& src_blk, void* pDst) + { + eac_block& dst_etc2_eac_a8_blk = *static_cast<eac_block*>(pDst); + decoder_etc_block& dst_etc1_blk = static_cast<decoder_etc_block*>(pDst)[1]; + + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) return false; -#endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cFXT1_RGB, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + color32 block_pixels[4][4]; + if (unpacked_src_blk.m_mode != UASTC_MODE_INDEX_SOLID_COLOR) + { + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + } + + transcode_uastc_to_etc2_eac_a8(unpacked_src_blk, block_pixels, &dst_etc2_eac_a8_blk); + + transcode_uastc_to_etc1(unpacked_src_blk, block_pixels, &dst_etc1_blk); + + return true; + } + + static const uint8_t s_uastc5_to_bc1[32] = { 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1 }; + static const uint8_t s_uastc4_to_bc1[16] = { 0, 0, 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1 }; + static const uint8_t s_uastc3_to_bc1[8] = { 0, 0, 2, 2, 3, 3, 1, 1 }; + static const uint8_t s_uastc2_to_bc1[4] = { 0, 2, 3, 1 }; + static const uint8_t s_uastc1_to_bc1[2] = { 0, 1 }; + const uint8_t* s_uastc_to_bc1_weights[6] = { nullptr, s_uastc1_to_bc1, s_uastc2_to_bc1, s_uastc3_to_bc1, s_uastc4_to_bc1, s_uastc5_to_bc1 }; + + void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride) + { + uint32_t min0_v, max0_v, min1_v, max1_v,min2_v, max2_v, min3_v, max3_v; + + { + min0_v = max0_v = pPixels[0 * stride]; + min1_v = max1_v = pPixels[1 * stride]; + min2_v = max2_v = pPixels[2 * stride]; + min3_v = max3_v = pPixels[3 * stride]; + } + + { + uint32_t v0 = pPixels[4 * stride]; min0_v = basisu::minimum(min0_v, v0); max0_v = basisu::maximum(max0_v, v0); + uint32_t v1 = pPixels[5 * stride]; min1_v = basisu::minimum(min1_v, v1); max1_v = basisu::maximum(max1_v, v1); + uint32_t v2 = pPixels[6 * stride]; min2_v = basisu::minimum(min2_v, v2); max2_v = basisu::maximum(max2_v, v2); + uint32_t v3 = pPixels[7 * stride]; min3_v = basisu::minimum(min3_v, v3); max3_v = basisu::maximum(max3_v, v3); + } + + { + uint32_t v0 = pPixels[8 * stride]; min0_v = basisu::minimum(min0_v, v0); max0_v = basisu::maximum(max0_v, v0); + uint32_t v1 = pPixels[9 * stride]; min1_v = basisu::minimum(min1_v, v1); max1_v = basisu::maximum(max1_v, v1); + uint32_t v2 = pPixels[10 * stride]; min2_v = basisu::minimum(min2_v, v2); max2_v = basisu::maximum(max2_v, v2); + uint32_t v3 = pPixels[11 * stride]; min3_v = basisu::minimum(min3_v, v3); max3_v = basisu::maximum(max3_v, v3); + } + + { + uint32_t v0 = pPixels[12 * stride]; min0_v = basisu::minimum(min0_v, v0); max0_v = basisu::maximum(max0_v, v0); + uint32_t v1 = pPixels[13 * stride]; min1_v = basisu::minimum(min1_v, v1); max1_v = basisu::maximum(max1_v, v1); + uint32_t v2 = pPixels[14 * stride]; min2_v = basisu::minimum(min2_v, v2); max2_v = basisu::maximum(max2_v, v2); + uint32_t v3 = pPixels[15 * stride]; min3_v = basisu::minimum(min3_v, v3); max3_v = basisu::maximum(max3_v, v3); + } + + const uint32_t min_v = basisu::minimum(min0_v, min1_v, min2_v, min3_v); + const uint32_t max_v = basisu::maximum(max0_v, max1_v, max2_v, max3_v); + + uint8_t* pDst_bytes = static_cast<uint8_t*>(pDst); + pDst_bytes[0] = (uint8_t)max_v; + pDst_bytes[1] = (uint8_t)min_v; + + if (max_v == min_v) + { + memset(pDst_bytes + 2, 0, 6); + return; + } + + const uint32_t delta = max_v - min_v; + + // min_v is now 0. Compute thresholds between values by scaling max_v. It's x14 because we're adding two x7 scale factors. + const int t0 = delta * 13; + const int t1 = delta * 11; + const int t2 = delta * 9; + const int t3 = delta * 7; + const int t4 = delta * 5; + const int t5 = delta * 3; + const int t6 = delta * 1; + + // BC4 floors in its divisions, which we compensate for with the 4 bias. + // This function is optimal for all possible inputs (i.e. it outputs the same results as checking all 8 values and choosing the closest one). + const int bias = 4 - min_v * 14; + + static const uint32_t s_tran0[8] = { 1U , 7U , 6U , 5U , 4U , 3U , 2U , 0U }; + static const uint32_t s_tran1[8] = { 1U << 3U, 7U << 3U, 6U << 3U, 5U << 3U, 4U << 3U, 3U << 3U, 2U << 3U, 0U << 3U }; + static const uint32_t s_tran2[8] = { 1U << 6U, 7U << 6U, 6U << 6U, 5U << 6U, 4U << 6U, 3U << 6U, 2U << 6U, 0U << 6U }; + static const uint32_t s_tran3[8] = { 1U << 9U, 7U << 9U, 6U << 9U, 5U << 9U, 4U << 9U, 3U << 9U, 2U << 9U, 0U << 9U }; + + uint64_t a0, a1, a2, a3; + { + const int v0 = pPixels[0 * stride] * 14 + bias; + const int v1 = pPixels[1 * stride] * 14 + bias; + const int v2 = pPixels[2 * stride] * 14 + bias; + const int v3 = pPixels[3 * stride] * 14 + bias; + a0 = s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)]; + a1 = s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)]; + a2 = s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)]; + a3 = s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)]; + } + + { + const int v0 = pPixels[4 * stride] * 14 + bias; + const int v1 = pPixels[5 * stride] * 14 + bias; + const int v2 = pPixels[6 * stride] * 14 + bias; + const int v3 = pPixels[7 * stride] * 14 + bias; + a0 |= (s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)] << 12U); + a1 |= (s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)] << 12U); + a2 |= (s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)] << 12U); + a3 |= (s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)] << 12U); + } + + { + const int v0 = pPixels[8 * stride] * 14 + bias; + const int v1 = pPixels[9 * stride] * 14 + bias; + const int v2 = pPixels[10 * stride] * 14 + bias; + const int v3 = pPixels[11 * stride] * 14 + bias; + a0 |= (((uint64_t)s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)]) << 24U); + a1 |= (((uint64_t)s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)]) << 24U); + a2 |= (((uint64_t)s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)]) << 24U); + a3 |= (((uint64_t)s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)]) << 24U); + } + + { + const int v0 = pPixels[12 * stride] * 14 + bias; + const int v1 = pPixels[13 * stride] * 14 + bias; + const int v2 = pPixels[14 * stride] * 14 + bias; + const int v3 = pPixels[15 * stride] * 14 + bias; + a0 |= (((uint64_t)s_tran0[(v0 >= t0) + (v0 >= t1) + (v0 >= t2) + (v0 >= t3) + (v0 >= t4) + (v0 >= t5) + (v0 >= t6)]) << 36U); + a1 |= (((uint64_t)s_tran1[(v1 >= t0) + (v1 >= t1) + (v1 >= t2) + (v1 >= t3) + (v1 >= t4) + (v1 >= t5) + (v1 >= t6)]) << 36U); + a2 |= (((uint64_t)s_tran2[(v2 >= t0) + (v2 >= t1) + (v2 >= t2) + (v2 >= t3) + (v2 >= t4) + (v2 >= t5) + (v2 >= t6)]) << 36U); + a3 |= (((uint64_t)s_tran3[(v3 >= t0) + (v3 >= t1) + (v3 >= t2) + (v3 >= t3) + (v3 >= t4) + (v3 >= t5) + (v3 >= t6)]) << 36U); + } + + const uint64_t f = a0 | a1 | a2 | a3; + + pDst_bytes[2] = (uint8_t)f; + pDst_bytes[3] = (uint8_t)(f >> 8U); + pDst_bytes[4] = (uint8_t)(f >> 16U); + pDst_bytes[5] = (uint8_t)(f >> 24U); + pDst_bytes[6] = (uint8_t)(f >> 32U); + pDst_bytes[7] = (uint8_t)(f >> 40U); + } + + static void bc1_find_sels(const color32 *pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16]) + { + uint32_t block_r[4], block_g[4], block_b[4]; + + block_r[0] = (lr << 3) | (lr >> 2); block_g[0] = (lg << 2) | (lg >> 4); block_b[0] = (lb << 3) | (lb >> 2); + block_r[3] = (hr << 3) | (hr >> 2); block_g[3] = (hg << 2) | (hg >> 4); block_b[3] = (hb << 3) | (hb >> 2); + block_r[1] = (block_r[0] * 2 + block_r[3]) / 3; block_g[1] = (block_g[0] * 2 + block_g[3]) / 3; block_b[1] = (block_b[0] * 2 + block_b[3]) / 3; + block_r[2] = (block_r[3] * 2 + block_r[0]) / 3; block_g[2] = (block_g[3] * 2 + block_g[0]) / 3; block_b[2] = (block_b[3] * 2 + block_b[0]) / 3; + + int ar = block_r[3] - block_r[0], ag = block_g[3] - block_g[0], ab = block_b[3] - block_b[0]; + + int dots[4]; + for (uint32_t i = 0; i < 4; i++) + dots[i] = (int)block_r[i] * ar + (int)block_g[i] * ag + (int)block_b[i] * ab; + + int t0 = dots[0] + dots[1], t1 = dots[1] + dots[2], t2 = dots[2] + dots[3]; + + ar *= 2; ag *= 2; ab *= 2; + + for (uint32_t i = 0; i < 16; i++) + { + const int d = pSrc_pixels[i].r * ar + pSrc_pixels[i].g * ag + pSrc_pixels[i].b * ab; + static const uint8_t s_sels[4] = { 3, 2, 1, 0 }; + + // Rounding matters here! + // d <= t0: <=, not <, to the later LS step "sees" a wider range of selectors. It matters for quality. + sels[i] = s_sels[(d <= t0) + (d < t1) + (d < t2)]; + } + } + + static inline void bc1_find_sels_2(const color32* pSrc_pixels, uint32_t lr, uint32_t lg, uint32_t lb, uint32_t hr, uint32_t hg, uint32_t hb, uint8_t sels[16]) + { + uint32_t block_r[4], block_g[4], block_b[4]; + + block_r[0] = (lr << 3) | (lr >> 2); block_g[0] = (lg << 2) | (lg >> 4); block_b[0] = (lb << 3) | (lb >> 2); + block_r[3] = (hr << 3) | (hr >> 2); block_g[3] = (hg << 2) | (hg >> 4); block_b[3] = (hb << 3) | (hb >> 2); + block_r[1] = (block_r[0] * 2 + block_r[3]) / 3; block_g[1] = (block_g[0] * 2 + block_g[3]) / 3; block_b[1] = (block_b[0] * 2 + block_b[3]) / 3; + block_r[2] = (block_r[3] * 2 + block_r[0]) / 3; block_g[2] = (block_g[3] * 2 + block_g[0]) / 3; block_b[2] = (block_b[3] * 2 + block_b[0]) / 3; + + int ar = block_r[3] - block_r[0], ag = block_g[3] - block_g[0], ab = block_b[3] - block_b[0]; + + int dots[4]; + for (uint32_t i = 0; i < 4; i++) + dots[i] = (int)block_r[i] * ar + (int)block_g[i] * ag + (int)block_b[i] * ab; + + int t0 = dots[0] + dots[1], t1 = dots[1] + dots[2], t2 = dots[2] + dots[3]; + + ar *= 2; ag *= 2; ab *= 2; + + static const uint8_t s_sels[4] = { 3, 2, 1, 0 }; + + for (uint32_t i = 0; i < 16; i += 4) + { + const int d0 = pSrc_pixels[i+0].r * ar + pSrc_pixels[i+0].g * ag + pSrc_pixels[i+0].b * ab; + const int d1 = pSrc_pixels[i+1].r * ar + pSrc_pixels[i+1].g * ag + pSrc_pixels[i+1].b * ab; + const int d2 = pSrc_pixels[i+2].r * ar + pSrc_pixels[i+2].g * ag + pSrc_pixels[i+2].b * ab; + const int d3 = pSrc_pixels[i+3].r * ar + pSrc_pixels[i+3].g * ag + pSrc_pixels[i+3].b * ab; + + sels[i+0] = s_sels[(d0 <= t0) + (d0 < t1) + (d0 < t2)]; + sels[i+1] = s_sels[(d1 <= t0) + (d1 < t1) + (d1 < t2)]; + sels[i+2] = s_sels[(d2 <= t0) + (d2 < t1) + (d2 < t2)]; + sels[i+3] = s_sels[(d3 <= t0) + (d3 < t1) + (d3 < t2)]; + } + } + + struct vec3F { float c[3]; }; + + static bool compute_least_squares_endpoints_rgb(const color32* pColors, const uint8_t* pSelectors, vec3F* pXl, vec3F* pXh) + { + // Derived from bc7enc16's LS function. + // Least squares using normal equations: http://www.cs.cornell.edu/~bindel/class/cs3220-s12/notes/lec10.pdf + // I did this in matrix form first, expanded out all the ops, then optimized it a bit. + uint32_t uq00_r = 0, uq10_r = 0, ut_r = 0, uq00_g = 0, uq10_g = 0, ut_g = 0, uq00_b = 0, uq10_b = 0, ut_b = 0; + + // This table is: 9 * (w * w), 9 * ((1.0f - w) * w), 9 * ((1.0f - w) * (1.0f - w)) + // where w is [0,1/3,2/3,1]. 9 is the perfect multiplier. + static const uint32_t s_weight_vals[4] = { 0x000009, 0x010204, 0x040201, 0x090000 }; + + uint32_t weight_accum = 0; + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t r = pColors[i].c[0], g = pColors[i].c[1], b = pColors[i].c[2]; + const uint32_t sel = pSelectors[i]; + ut_r += r; + ut_g += g; + ut_b += b; + weight_accum += s_weight_vals[sel]; + uq00_r += sel * r; + uq00_g += sel * g; + uq00_b += sel * b; + } + + float q00_r = (float)uq00_r, q10_r = (float)uq10_r, t_r = (float)ut_r; + float q00_g = (float)uq00_g, q10_g = (float)uq10_g, t_g = (float)ut_g; + float q00_b = (float)uq00_b, q10_b = (float)uq10_b, t_b = (float)ut_b; + + q10_r = t_r * 3.0f - q00_r; + q10_g = t_g * 3.0f - q00_g; + q10_b = t_b * 3.0f - q00_b; + + float z00 = (float)((weight_accum >> 16) & 0xFF); + float z10 = (float)((weight_accum >> 8) & 0xFF); + float z11 = (float)(weight_accum & 0xFF); + float z01 = z10; + + float det = z00 * z11 - z01 * z10; + if (fabs(det) < 1e-8f) + return false; + + det = 3.0f / det; + + float iz00, iz01, iz10, iz11; + iz00 = z11 * det; + iz01 = -z01 * det; + iz10 = -z10 * det; + iz11 = z00 * det; + + pXl->c[0] = iz00 * q00_r + iz01 * q10_r; pXh->c[0] = iz10 * q00_r + iz11 * q10_r; + pXl->c[1] = iz00 * q00_g + iz01 * q10_g; pXh->c[1] = iz10 * q00_g + iz11 * q10_g; + pXl->c[2] = iz00 * q00_b + iz01 * q10_b; pXh->c[2] = iz10 * q00_b + iz11 * q10_b; + + // Check and fix channel singularities - might not be needed, but is in UASTC's encoder. + for (uint32_t c = 0; c < 3; c++) + { + if ((pXl->c[c] < 0.0f) || (pXh->c[c] > 255.0f)) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to FXT1_RGB failed\n"); + uint32_t lo_v = UINT32_MAX, hi_v = 0; + for (uint32_t i = 0; i < 16; i++) + { + lo_v = basisu::minimumu(lo_v, pColors[i].c[c]); + hi_v = basisu::maximumu(hi_v, pColors[i].c[c]); + } + + if (lo_v == hi_v) + { + pXl->c[c] = (float)lo_v; + pXh->c[c] = (float)hi_v; + } } - break; } - case transcoder_texture_format::cTFETC2_EAC_R11: + + return true; + } + + void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb) + { + dxt1_block* pDst_block = static_cast<dxt1_block*>(pDst); + + uint32_t mask = 0xAA; + uint32_t max16 = (g_bc1_match5_equals_1[fr].m_hi << 11) | (g_bc1_match6_equals_1[fg].m_hi << 5) | g_bc1_match5_equals_1[fb].m_hi; + uint32_t min16 = (g_bc1_match5_equals_1[fr].m_lo << 11) | (g_bc1_match6_equals_1[fg].m_lo << 5) | g_bc1_match5_equals_1[fb].m_lo; + + if (min16 == max16) { -#if !BASISD_SUPPORT_ETC2_EAC_RG11 - return false; -#endif - uint32_t slice_index_to_decode = slice_index; - // If the caller wants us to transcode the mip level's alpha data, then use the next slice. - if ((basis_file_has_alpha_slices) && (transcode_alpha_data_to_opaque_formats)) - slice_index_to_decode++; + // Always forbid 3 color blocks + // This is to guarantee that BC3 blocks never use punchthrough alpha (3 color) mode, which isn't supported on some (all?) GPU's. + mask = 0; - status = transcode_slice(pData, data_size, slice_index_to_decode, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, bytes_per_block, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + // Make l > h + if (min16 > 0) + min16--; + else { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2_EAC_R11 failed\n"); + // l = h = 0 + assert(min16 == max16 && max16 == 0); + + max16 = 1; + min16 = 0; + mask = 0x55; } - break; + assert(max16 > min16); } - case transcoder_texture_format::cTFETC2_EAC_RG11: + + if (max16 < min16) { -#if !BASISD_SUPPORT_ETC2_EAC_RG11 - return false; + std::swap(max16, min16); + mask ^= 0x55; + } + + pDst_block->set_low_color(static_cast<uint16_t>(max16)); + pDst_block->set_high_color(static_cast<uint16_t>(min16)); + pDst_block->m_selectors[0] = static_cast<uint8_t>(mask); + pDst_block->m_selectors[1] = static_cast<uint8_t>(mask); + pDst_block->m_selectors[2] = static_cast<uint8_t>(mask); + pDst_block->m_selectors[3] = static_cast<uint8_t>(mask); + } + + static inline uint8_t to_5(uint32_t v) { v = v * 31 + 128; return (uint8_t)((v + (v >> 8)) >> 8); } + static inline uint8_t to_6(uint32_t v) { v = v * 63 + 128; return (uint8_t)((v + (v >> 8)) >> 8); } + + // Good references: squish library, stb_dxt. + void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags) + { + const color32* pSrc_pixels = (const color32*)pPixels; + dxt1_block* pDst_block = static_cast<dxt1_block*>(pDst); + + int avg_r = -1, avg_g = 0, avg_b = 0; + int lr = 0, lg = 0, lb = 0, hr = 0, hg = 0, hb = 0; + uint8_t sels[16]; + + const bool use_sels = (flags & cEncodeBC1UseSelectors) != 0; + if (use_sels) + { + // Caller is jamming in their own selectors for us to try. + const uint32_t s = pDst_block->m_selectors[0] | (pDst_block->m_selectors[1] << 8) | (pDst_block->m_selectors[2] << 16) | (pDst_block->m_selectors[3] << 24); + + static const uint8_t s_sel_tran[4] = { 0, 3, 1, 2 }; + + for (uint32_t i = 0; i < 16; i++) + sels[i] = s_sel_tran[(s >> (i * 2)) & 3]; + } + else + { + const uint32_t fr = pSrc_pixels[0].r, fg = pSrc_pixels[0].g, fb = pSrc_pixels[0].b; + + uint32_t j; + for (j = 1; j < 16; j++) + if ((pSrc_pixels[j].r != fr) || (pSrc_pixels[j].g != fg) || (pSrc_pixels[j].b != fb)) + break; + + if (j == 16) + { + encode_bc1_solid_block(pDst, fr, fg, fb); + return; + } + + // Select 2 colors along the principle axis. (There must be a faster/simpler way.) + int total_r = fr, total_g = fg, total_b = fb; + int max_r = fr, max_g = fg, max_b = fb; + int min_r = fr, min_g = fg, min_b = fb; + for (uint32_t i = 1; i < 16; i++) + { + const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + max_r = basisu::maximum(max_r, r); max_g = basisu::maximum(max_g, g); max_b = basisu::maximum(max_b, b); + min_r = basisu::minimum(min_r, r); min_g = basisu::minimum(min_g, g); min_b = basisu::minimum(min_b, b); + total_r += r; total_g += g; total_b += b; + } + + avg_r = (total_r + 8) >> 4; + avg_g = (total_g + 8) >> 4; + avg_b = (total_b + 8) >> 4; + + int icov[6] = { 0, 0, 0, 0, 0, 0 }; + for (uint32_t i = 0; i < 16; i++) + { + int r = (int)pSrc_pixels[i].r - avg_r; + int g = (int)pSrc_pixels[i].g - avg_g; + int b = (int)pSrc_pixels[i].b - avg_b; + icov[0] += r * r; + icov[1] += r * g; + icov[2] += r * b; + icov[3] += g * g; + icov[4] += g * b; + icov[5] += b * b; + } + + float cov[6]; + for (uint32_t i = 0; i < 6; i++) + cov[i] = static_cast<float>(icov[i])* (1.0f / 255.0f); + +#if 0 + // Seems silly to use full PCA to choose 2 colors. The diff in avg. PSNR between using PCA vs. not is small (~.025 difference). + // TODO: Try 2 or 3 different normalized diagonal vectors, choose the one that results in the largest dot delta + int saxis_r = max_r - min_r; + int saxis_g = max_g - min_g; + int saxis_b = max_b - min_b; +#else + float xr = (float)(max_r - min_r); + float xg = (float)(max_g - min_g); + float xb = (float)(max_b - min_b); + //float xr = (float)(max_r - avg_r); // max-avg is nearly the same, and doesn't require computing min's + //float xg = (float)(max_g - avg_g); + //float xb = (float)(max_b - avg_b); + for (uint32_t power_iter = 0; power_iter < 4; power_iter++) + { + float r = xr * cov[0] + xg * cov[1] + xb * cov[2]; + float g = xr * cov[1] + xg * cov[3] + xb * cov[4]; + float b = xr * cov[2] + xg * cov[4] + xb * cov[5]; + xr = r; xg = g; xb = b; + } + + float k = basisu::maximum(fabsf(xr), fabsf(xg), fabsf(xb)); + int saxis_r = 306, saxis_g = 601, saxis_b = 117; + if (k >= 2) + { + float m = 1024.0f / k; + saxis_r = (int)(xr * m); + saxis_g = (int)(xg * m); + saxis_b = (int)(xb * m); + } #endif - assert(bytes_per_block == 16); + + int low_dot = INT_MAX, high_dot = INT_MIN, low_c = 0, high_c = 0; + for (uint32_t i = 0; i < 16; i++) + { + int dot = pSrc_pixels[i].r * saxis_r + pSrc_pixels[i].g * saxis_g + pSrc_pixels[i].b * saxis_b; + if (dot < low_dot) + { + low_dot = dot; + low_c = i; + } + if (dot > high_dot) + { + high_dot = dot; + high_c = i; + } + } - if (basis_file_has_alpha_slices) + lr = to_5(pSrc_pixels[low_c].r); + lg = to_6(pSrc_pixels[low_c].g); + lb = to_5(pSrc_pixels[low_c].b); + + hr = to_5(pSrc_pixels[high_c].r); + hg = to_6(pSrc_pixels[high_c].g); + hb = to_5(pSrc_pixels[high_c].b); + + bc1_find_sels(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels); + } // if (use_sels) + + const uint32_t total_ls_passes = (flags & cEncodeBC1HigherQuality) ? 3 : (flags & cEncodeBC1HighQuality ? 2 : 1); + for (uint32_t ls_pass = 0; ls_pass < total_ls_passes; ls_pass++) + { + // This is where the real magic happens. We have an array of candidate selectors, so let's use least squares to compute the optimal low/high endpoint colors. + vec3F xl, xh; + if (!compute_least_squares_endpoints_rgb(pSrc_pixels, sels, &xl, &xh)) { - // First decode the alpha data to G - status = transcode_slice(pData, data_size, slice_index + 1, (uint8_t *)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); + if (avg_r < 0) + { + int total_r = 0, total_g = 0, total_b = 0; + for (uint32_t i = 0; i < 16; i++) + { + total_r += pSrc_pixels[i].r; + total_g += pSrc_pixels[i].g; + total_b += pSrc_pixels[i].b; + } + + avg_r = (total_r + 8) >> 4; + avg_g = (total_g + 8) >> 4; + avg_b = (total_b + 8) >> 4; + } + + // All selectors equal - treat it as a solid block which should always be equal or better. + lr = g_bc1_match5_equals_1[avg_r].m_hi; + lg = g_bc1_match6_equals_1[avg_g].m_hi; + lb = g_bc1_match5_equals_1[avg_b].m_hi; + + hr = g_bc1_match5_equals_1[avg_r].m_lo; + hg = g_bc1_match6_equals_1[avg_g].m_lo; + hb = g_bc1_match5_equals_1[avg_b].m_lo; + + // In high/higher quality mode, let it try again in case the optimal tables have caused the sels to diverge. } else { - write_opaque_alpha_blocks(pSlice_descs[slice_index].m_num_blocks_x, pSlice_descs[slice_index].m_num_blocks_y, (uint8_t *)pOutput_blocks + 8, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, output_row_pitch_in_blocks_or_pixels); - status = true; + lr = basisu::clamp((int)((xl.c[0]) * (31.0f / 255.0f) + .5f), 0, 31); + lg = basisu::clamp((int)((xl.c[1]) * (63.0f / 255.0f) + .5f), 0, 63); + lb = basisu::clamp((int)((xl.c[2]) * (31.0f / 255.0f) + .5f), 0, 31); + + hr = basisu::clamp((int)((xh.c[0]) * (31.0f / 255.0f) + .5f), 0, 31); + hg = basisu::clamp((int)((xh.c[1]) * (63.0f / 255.0f) + .5f), 0, 63); + hb = basisu::clamp((int)((xh.c[2]) * (31.0f / 255.0f) + .5f), 0, 31); } + + bc1_find_sels(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels); + } - if (status) + uint32_t lc16 = dxt1_block::pack_unscaled_color(lr, lg, lb); + uint32_t hc16 = dxt1_block::pack_unscaled_color(hr, hg, hb); + + // Always forbid 3 color blocks + if (lc16 == hc16) + { + uint8_t mask = 0; + + // Make l > h + if (hc16 > 0) + hc16--; + else { - // Now decode the color data to R - status = transcode_slice(pData, data_size, slice_index, pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, block_format::cETC2_EAC_R11, 16, decode_flags, output_row_pitch_in_blocks_or_pixels, pState); - if (!status) + // lc16 = hc16 = 0 + assert(lc16 == hc16 && hc16 == 0); + + hc16 = 0; + lc16 = 1; + mask = 0x55; // select hc16 + } + + assert(lc16 > hc16); + pDst_block->set_low_color(static_cast<uint16_t>(lc16)); + pDst_block->set_high_color(static_cast<uint16_t>(hc16)); + + pDst_block->m_selectors[0] = mask; + pDst_block->m_selectors[1] = mask; + pDst_block->m_selectors[2] = mask; + pDst_block->m_selectors[3] = mask; + } + else + { + uint8_t invert_mask = 0; + if (lc16 < hc16) + { + std::swap(lc16, hc16); + invert_mask = 0x55; + } + + assert(lc16 > hc16); + pDst_block->set_low_color((uint16_t)lc16); + pDst_block->set_high_color((uint16_t)hc16); + + uint32_t packed_sels = 0; + static const uint8_t s_sel_trans[4] = { 0, 2, 3, 1 }; + for (uint32_t i = 0; i < 16; i++) + packed_sels |= ((uint32_t)s_sel_trans[sels[i]] << (i * 2)); + + pDst_block->m_selectors[0] = (uint8_t)packed_sels ^ invert_mask; + pDst_block->m_selectors[1] = (uint8_t)(packed_sels >> 8) ^ invert_mask; + pDst_block->m_selectors[2] = (uint8_t)(packed_sels >> 16) ^ invert_mask; + pDst_block->m_selectors[3] = (uint8_t)(packed_sels >> 24) ^ invert_mask; + } + } + + void encode_bc1_alt(void* pDst, const uint8_t* pPixels, uint32_t flags) + { + const color32* pSrc_pixels = (const color32*)pPixels; + dxt1_block* pDst_block = static_cast<dxt1_block*>(pDst); + + int avg_r = -1, avg_g = 0, avg_b = 0; + int lr = 0, lg = 0, lb = 0, hr = 0, hg = 0, hb = 0; + uint8_t sels[16]; + + const bool use_sels = (flags & cEncodeBC1UseSelectors) != 0; + if (use_sels) + { + // Caller is jamming in their own selectors for us to try. + const uint32_t s = pDst_block->m_selectors[0] | (pDst_block->m_selectors[1] << 8) | (pDst_block->m_selectors[2] << 16) | (pDst_block->m_selectors[3] << 24); + + static const uint8_t s_sel_tran[4] = { 0, 3, 1, 2 }; + + for (uint32_t i = 0; i < 16; i++) + sels[i] = s_sel_tran[(s >> (i * 2)) & 3]; + } + else + { + const uint32_t fr = pSrc_pixels[0].r, fg = pSrc_pixels[0].g, fb = pSrc_pixels[0].b; + + uint32_t j; + for (j = 1; j < 16; j++) + if ((pSrc_pixels[j].r != fr) || (pSrc_pixels[j].g != fg) || (pSrc_pixels[j].b != fb)) + break; + + if (j == 16) + { + encode_bc1_solid_block(pDst, fr, fg, fb); + return; + } + + // Select 2 colors along the principle axis. (There must be a faster/simpler way.) + int total_r = fr, total_g = fg, total_b = fb; + int max_r = fr, max_g = fg, max_b = fb; + int min_r = fr, min_g = fg, min_b = fb; + uint32_t grayscale_flag = (fr == fg) && (fr == fb); + for (uint32_t i = 1; i < 16; i++) + { + const int r = pSrc_pixels[i].r, g = pSrc_pixels[i].g, b = pSrc_pixels[i].b; + grayscale_flag &= ((r == g) && (r == b)); + max_r = basisu::maximum(max_r, r); max_g = basisu::maximum(max_g, g); max_b = basisu::maximum(max_b, b); + min_r = basisu::minimum(min_r, r); min_g = basisu::minimum(min_g, g); min_b = basisu::minimum(min_b, b); + total_r += r; total_g += g; total_b += b; + } + + if (grayscale_flag) + { + // Grayscale blocks are a common enough case to specialize. + if ((max_r - min_r) < 2) { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2_EAC_R11 R failed\n"); + lr = lb = hr = hb = to_5(fr); + lg = hg = to_6(fr); + } + else + { + lr = lb = to_5(min_r); + lg = to_6(min_r); + + hr = hb = to_5(max_r); + hg = to_6(max_r); } } else { - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: transcode_slice() to ETC2_EAC_R11 G failed\n"); + avg_r = (total_r + 8) >> 4; + avg_g = (total_g + 8) >> 4; + avg_b = (total_b + 8) >> 4; + + // Find the shortest vector from a AABB corner to the block's average color. + // This is to help avoid outliers. + + uint32_t dist[3][2]; + dist[0][0] = basisu::square(min_r - avg_r) << 3; dist[0][1] = basisu::square(max_r - avg_r) << 3; + dist[1][0] = basisu::square(min_g - avg_g) << 3; dist[1][1] = basisu::square(max_g - avg_g) << 3; + dist[2][0] = basisu::square(min_b - avg_b) << 3; dist[2][1] = basisu::square(max_b - avg_b) << 3; + + uint32_t min_d0 = (dist[0][0] + dist[1][0] + dist[2][0]); + uint32_t d4 = (dist[0][0] + dist[1][0] + dist[2][1]) | 4; + min_d0 = basisu::minimum(min_d0, d4); + + uint32_t min_d1 = (dist[0][1] + dist[1][0] + dist[2][0]) | 1; + uint32_t d5 = (dist[0][1] + dist[1][0] + dist[2][1]) | 5; + min_d1 = basisu::minimum(min_d1, d5); + + uint32_t d2 = (dist[0][0] + dist[1][1] + dist[2][0]) | 2; + min_d0 = basisu::minimum(min_d0, d2); + + uint32_t d3 = (dist[0][1] + dist[1][1] + dist[2][0]) | 3; + min_d1 = basisu::minimum(min_d1, d3); + + uint32_t d6 = (dist[0][0] + dist[1][1] + dist[2][1]) | 6; + min_d0 = basisu::minimum(min_d0, d6); + + uint32_t d7 = (dist[0][1] + dist[1][1] + dist[2][1]) | 7; + min_d1 = basisu::minimum(min_d1, d7); + + uint32_t min_d = basisu::minimum(min_d0, min_d1); + uint32_t best_i = min_d & 7; + + int delta_r = (best_i & 1) ? (max_r - avg_r) : (avg_r - min_r); + int delta_g = (best_i & 2) ? (max_g - avg_g) : (avg_g - min_g); + int delta_b = (best_i & 4) ? (max_b - avg_b) : (avg_b - min_b); + + // Note: if delta_r/g/b==0, we actually want to choose a single color, so the block average color optimization kicks in. + uint32_t low_c = 0, high_c = 0; + if ((delta_r | delta_g | delta_b) != 0) + { + // Now we have a smaller AABB going from the block's average color to a cornerpoint of the larger AABB. + // Project all pixels colors along the 4 vectors going from a smaller AABB cornerpoint to the opposite cornerpoint, find largest projection. + // One of these vectors will be a decent approximation of the block's PCA. + const int saxis0_r = delta_r, saxis0_g = delta_g, saxis0_b = delta_b; + + int low_dot0 = INT_MAX, high_dot0 = INT_MIN; + int low_dot1 = INT_MAX, high_dot1 = INT_MIN; + int low_dot2 = INT_MAX, high_dot2 = INT_MIN; + int low_dot3 = INT_MAX, high_dot3 = INT_MIN; + + //int low_c0, low_c1, low_c2, low_c3; + //int high_c0, high_c1, high_c2, high_c3; + + for (uint32_t i = 0; i < 16; i++) + { + const int dotx = pSrc_pixels[i].r * saxis0_r; + const int doty = pSrc_pixels[i].g * saxis0_g; + const int dotz = pSrc_pixels[i].b * saxis0_b; + + const int dot0 = ((dotz + dotx + doty) << 4) + i; + const int dot1 = ((dotz - dotx - doty) << 4) + i; + const int dot2 = ((dotz - dotx + doty) << 4) + i; + const int dot3 = ((dotz + dotx - doty) << 4) + i; + + if (dot0 < low_dot0) + { + low_dot0 = dot0; + //low_c0 = i; + } + if ((dot0 ^ 15) > high_dot0) + { + high_dot0 = dot0 ^ 15; + //high_c0 = i; + } + + if (dot1 < low_dot1) + { + low_dot1 = dot1; + //low_c1 = i; + } + if ((dot1 ^ 15) > high_dot1) + { + high_dot1 = dot1 ^ 15; + //high_c1 = i; + } + + if (dot2 < low_dot2) + { + low_dot2 = dot2; + //low_c2 = i; + } + if ((dot2 ^ 15) > high_dot2) + { + high_dot2 = dot2 ^ 15; + //high_c2 = i; + } + + if (dot3 < low_dot3) + { + low_dot3 = dot3; + //low_c3 = i; + } + if ((dot3 ^ 15) > high_dot3) + { + high_dot3 = dot3 ^ 15; + //high_c3 = i; + } + } + + low_c = low_dot0 & 15; + high_c = ~high_dot0 & 15; + uint32_t r = (high_dot0 & ~15) - (low_dot0 & ~15); + + uint32_t tr = (high_dot1 & ~15) - (low_dot1 & ~15); + if (tr > r) { + low_c = low_dot1 & 15; + high_c = ~high_dot1 & 15; + r = tr; + } + + tr = (high_dot2 & ~15) - (low_dot2 & ~15); + if (tr > r) { + low_c = low_dot2 & 15; + high_c = ~high_dot2 & 15; + r = tr; + } + + tr = (high_dot3 & ~15) - (low_dot3 & ~15); + if (tr > r) { + low_c = low_dot3 & 15; + high_c = ~high_dot3 & 15; + } + } + + lr = to_5(pSrc_pixels[low_c].r); + lg = to_6(pSrc_pixels[low_c].g); + lb = to_5(pSrc_pixels[low_c].b); + + hr = to_5(pSrc_pixels[high_c].r); + hg = to_6(pSrc_pixels[high_c].g); + hb = to_5(pSrc_pixels[high_c].b); } - break; + bc1_find_sels_2(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels); + } // if (use_sels) + + const uint32_t total_ls_passes = (flags & cEncodeBC1HigherQuality) ? 3 : (flags & cEncodeBC1HighQuality ? 2 : 1); + for (uint32_t ls_pass = 0; ls_pass < total_ls_passes; ls_pass++) + { + int prev_lr = lr, prev_lg = lg, prev_lb = lb, prev_hr = hr, prev_hg = hg, prev_hb = hb; + + // This is where the real magic happens. We have an array of candidate selectors, so let's use least squares to compute the optimal low/high endpoint colors. + vec3F xl, xh; + if (!compute_least_squares_endpoints_rgb(pSrc_pixels, sels, &xl, &xh)) + { + if (avg_r < 0) + { + int total_r = 0, total_g = 0, total_b = 0; + for (uint32_t i = 0; i < 16; i++) + { + total_r += pSrc_pixels[i].r; + total_g += pSrc_pixels[i].g; + total_b += pSrc_pixels[i].b; + } + + avg_r = (total_r + 8) >> 4; + avg_g = (total_g + 8) >> 4; + avg_b = (total_b + 8) >> 4; + } + + // All selectors equal - treat it as a solid block which should always be equal or better. + lr = g_bc1_match5_equals_1[avg_r].m_hi; + lg = g_bc1_match6_equals_1[avg_g].m_hi; + lb = g_bc1_match5_equals_1[avg_b].m_hi; + + hr = g_bc1_match5_equals_1[avg_r].m_lo; + hg = g_bc1_match6_equals_1[avg_g].m_lo; + hb = g_bc1_match5_equals_1[avg_b].m_lo; + + // In high/higher quality mode, let it try again in case the optimal tables have caused the sels to diverge. + } + else + { + lr = basisu::clamp((int)((xl.c[0]) * (31.0f / 255.0f) + .5f), 0, 31); + lg = basisu::clamp((int)((xl.c[1]) * (63.0f / 255.0f) + .5f), 0, 63); + lb = basisu::clamp((int)((xl.c[2]) * (31.0f / 255.0f) + .5f), 0, 31); + + hr = basisu::clamp((int)((xh.c[0]) * (31.0f / 255.0f) + .5f), 0, 31); + hg = basisu::clamp((int)((xh.c[1]) * (63.0f / 255.0f) + .5f), 0, 63); + hb = basisu::clamp((int)((xh.c[2]) * (31.0f / 255.0f) + .5f), 0, 31); + } + + if ((prev_lr == lr) && (prev_lg == lg) && (prev_lb == lb) && (prev_hr == hr) && (prev_hg == hg) && (prev_hb == hb)) + break; + + bc1_find_sels_2(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels); } - default: + + uint32_t lc16 = dxt1_block::pack_unscaled_color(lr, lg, lb); + uint32_t hc16 = dxt1_block::pack_unscaled_color(hr, hg, hb); + + // Always forbid 3 color blocks + if (lc16 == hc16) { - assert(0); - BASISU_DEVEL_ERROR("basisu_transcoder::transcode_image_level: Invalid fmt\n"); - break; + uint8_t mask = 0; + + // Make l > h + if (hc16 > 0) + hc16--; + else + { + // lc16 = hc16 = 0 + assert(lc16 == hc16 && hc16 == 0); + + hc16 = 0; + lc16 = 1; + mask = 0x55; // select hc16 + } + + assert(lc16 > hc16); + pDst_block->set_low_color(static_cast<uint16_t>(lc16)); + pDst_block->set_high_color(static_cast<uint16_t>(hc16)); + + pDst_block->m_selectors[0] = mask; + pDst_block->m_selectors[1] = mask; + pDst_block->m_selectors[2] = mask; + pDst_block->m_selectors[3] = mask; } + else + { + uint8_t invert_mask = 0; + if (lc16 < hc16) + { + std::swap(lc16, hc16); + invert_mask = 0x55; + } + + assert(lc16 > hc16); + pDst_block->set_low_color((uint16_t)lc16); + pDst_block->set_high_color((uint16_t)hc16); + + uint32_t packed_sels = 0; + static const uint8_t s_sel_trans[4] = { 0, 2, 3, 1 }; + for (uint32_t i = 0; i < 16; i++) + packed_sels |= ((uint32_t)s_sel_trans[sels[i]] << (i * 2)); + + pDst_block->m_selectors[0] = (uint8_t)packed_sels ^ invert_mask; + pDst_block->m_selectors[1] = (uint8_t)(packed_sels >> 8) ^ invert_mask; + pDst_block->m_selectors[2] = (uint8_t)(packed_sels >> 16) ^ invert_mask; + pDst_block->m_selectors[3] = (uint8_t)(packed_sels >> 24) ^ invert_mask; } + } - return status; + // Scale the UASTC first subset endpoints and first plane's weight indices directly to BC1's - fastest. + void transcode_uastc_to_bc1_hint0(const unpacked_uastc_block& unpacked_src_blk, void* pDst) + { + const uint32_t mode = unpacked_src_blk.m_mode; + const astc_block_desc& astc_blk = unpacked_src_blk.m_astc; + + dxt1_block& b = *static_cast<dxt1_block*>(pDst); + + const uint32_t endpoint_range = g_uastc_mode_endpoint_ranges[mode]; + + const uint32_t total_comps = g_uastc_mode_comps[mode]; + + if (total_comps == 2) + { + const uint32_t l = g_astc_unquant[endpoint_range][astc_blk.m_endpoints[0]].m_unquant; + const uint32_t h = g_astc_unquant[endpoint_range][astc_blk.m_endpoints[1]].m_unquant; + + b.set_low_color(dxt1_block::pack_color(color32(l, l, l, 255), true, 127)); + b.set_high_color(dxt1_block::pack_color(color32(h, h, h, 255), true, 127)); + } + else + { + b.set_low_color(dxt1_block::pack_color( + color32(g_astc_unquant[endpoint_range][astc_blk.m_endpoints[0]].m_unquant, + g_astc_unquant[endpoint_range][astc_blk.m_endpoints[2]].m_unquant, + g_astc_unquant[endpoint_range][astc_blk.m_endpoints[4]].m_unquant, + 255), true, 127) + ); + + b.set_high_color(dxt1_block::pack_color( + color32(g_astc_unquant[endpoint_range][astc_blk.m_endpoints[1]].m_unquant, + g_astc_unquant[endpoint_range][astc_blk.m_endpoints[3]].m_unquant, + g_astc_unquant[endpoint_range][astc_blk.m_endpoints[5]].m_unquant, + 255), true, 127) + ); + } + + if (b.get_low_color() == b.get_high_color()) + { + // Always forbid 3 color blocks + uint16_t lc16 = (uint16_t)b.get_low_color(); + uint16_t hc16 = (uint16_t)b.get_high_color(); + + uint8_t mask = 0; + + // Make l > h + if (hc16 > 0) + hc16--; + else + { + // lc16 = hc16 = 0 + assert(lc16 == hc16 && hc16 == 0); + + hc16 = 0; + lc16 = 1; + mask = 0x55; // select hc16 + } + + assert(lc16 > hc16); + b.set_low_color(static_cast<uint16_t>(lc16)); + b.set_high_color(static_cast<uint16_t>(hc16)); + + b.m_selectors[0] = mask; + b.m_selectors[1] = mask; + b.m_selectors[2] = mask; + b.m_selectors[3] = mask; + } + else + { + bool invert = false; + if (b.get_low_color() < b.get_high_color()) + { + std::swap(b.m_low_color[0], b.m_high_color[0]); + std::swap(b.m_low_color[1], b.m_high_color[1]); + invert = true; + } + + const uint8_t* pTran = s_uastc_to_bc1_weights[g_uastc_mode_weight_bits[mode]]; + + const uint32_t plane_shift = g_uastc_mode_planes[mode] - 1; + + uint32_t sels = 0; + for (int i = 15; i >= 0; --i) + { + uint32_t s = pTran[astc_blk.m_weights[i << plane_shift]]; + + if (invert) + s ^= 1; + + sels = (sels << 2) | s; + } + b.m_selectors[0] = sels & 0xFF; + b.m_selectors[1] = (sels >> 8) & 0xFF; + b.m_selectors[2] = (sels >> 16) & 0xFF; + b.m_selectors[3] = (sels >> 24) & 0xFF; + } } - uint32_t basis_get_bytes_per_block(transcoder_texture_format fmt) + // Scale the UASTC first plane's weight indices to BC1, use 1 or 2 least squares passes to compute endpoints - no PCA needed. + void transcode_uastc_to_bc1_hint1(const unpacked_uastc_block& unpacked_src_blk, const color32 block_pixels[4][4], void* pDst, bool high_quality) { - switch (fmt) + const uint32_t mode = unpacked_src_blk.m_mode; + + const astc_block_desc& astc_blk = unpacked_src_blk.m_astc; + + dxt1_block& b = *static_cast<dxt1_block*>(pDst); + + b.set_low_color(1); + b.set_high_color(0); + + const uint8_t* pTran = s_uastc_to_bc1_weights[g_uastc_mode_weight_bits[mode]]; + + const uint32_t plane_shift = g_uastc_mode_planes[mode] - 1; + + uint32_t sels = 0; + for (int i = 15; i >= 0; --i) { - case transcoder_texture_format::cTFETC1_RGB: - case transcoder_texture_format::cTFBC1_RGB: - case transcoder_texture_format::cTFBC4_R: - case transcoder_texture_format::cTFPVRTC1_4_RGB: - case transcoder_texture_format::cTFPVRTC1_4_RGBA: - case transcoder_texture_format::cTFATC_RGB: - case transcoder_texture_format::cTFPVRTC2_4_RGB: - case transcoder_texture_format::cTFPVRTC2_4_RGBA: - case transcoder_texture_format::cTFETC2_EAC_R11: - return 8; - case transcoder_texture_format::cTFBC7_M6_RGB: - case transcoder_texture_format::cTFBC7_M5_RGBA: - case transcoder_texture_format::cTFETC2_RGBA: - case transcoder_texture_format::cTFBC3_RGBA: - case transcoder_texture_format::cTFBC5_RG: - case transcoder_texture_format::cTFASTC_4x4_RGBA: - case transcoder_texture_format::cTFATC_RGBA: - case transcoder_texture_format::cTFFXT1_RGB: - case transcoder_texture_format::cTFETC2_EAC_RG11: - return 16; - case transcoder_texture_format::cTFRGBA32: - return sizeof(uint32_t) * 16; - case transcoder_texture_format::cTFRGB565: - case transcoder_texture_format::cTFBGR565: - case transcoder_texture_format::cTFRGBA4444: - return sizeof(uint16_t) * 16; - default: - assert(0); - BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); - break; + sels <<= 2; + sels |= pTran[astc_blk.m_weights[i << plane_shift]]; } - return 0; + + b.m_selectors[0] = sels & 0xFF; + b.m_selectors[1] = (sels >> 8) & 0xFF; + b.m_selectors[2] = (sels >> 16) & 0xFF; + b.m_selectors[3] = (sels >> 24) & 0xFF; + + encode_bc1(&b, (const uint8_t*)&block_pixels[0][0].c[0], (high_quality ? cEncodeBC1HighQuality : 0) | cEncodeBC1UseSelectors); } - const char* basis_get_format_name(transcoder_texture_format fmt) + bool transcode_uastc_to_bc1(const uastc_block& src_blk, void* pDst, bool high_quality) { - switch (fmt) + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + const uint32_t mode = unpacked_src_blk.m_mode; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) { - case transcoder_texture_format::cTFETC1_RGB: return "ETC1_RGB"; - case transcoder_texture_format::cTFBC1_RGB: return "BC1_RGB"; - case transcoder_texture_format::cTFBC4_R: return "BC4_R"; - case transcoder_texture_format::cTFPVRTC1_4_RGB: return "PVRTC1_4_RGB"; - case transcoder_texture_format::cTFPVRTC1_4_RGBA: return "PVRTC1_4_RGBA"; - case transcoder_texture_format::cTFBC7_M6_RGB: return "BC7_M6_RGB"; - case transcoder_texture_format::cTFBC7_M5_RGBA: return "BC7_M5_RGBA"; - case transcoder_texture_format::cTFETC2_RGBA: return "ETC2_RGBA"; - case transcoder_texture_format::cTFBC3_RGBA: return "BC3_RGBA"; - case transcoder_texture_format::cTFBC5_RG: return "BC5_RG"; - case transcoder_texture_format::cTFASTC_4x4_RGBA: return "ASTC_RGBA"; - case transcoder_texture_format::cTFATC_RGB: return "ATC_RGB"; - case transcoder_texture_format::cTFATC_RGBA: return "ATC_RGBA"; - case transcoder_texture_format::cTFRGBA32: return "RGBA32"; - case transcoder_texture_format::cTFRGB565: return "RGB565"; - case transcoder_texture_format::cTFBGR565: return "BGR565"; - case transcoder_texture_format::cTFRGBA4444: return "RGBA4444"; - case transcoder_texture_format::cTFFXT1_RGB: return "FXT1_RGB"; - case transcoder_texture_format::cTFPVRTC2_4_RGB: return "PVRTC2_4_RGB"; - case transcoder_texture_format::cTFPVRTC2_4_RGBA: return "PVRTC2_4_RGBA"; - case transcoder_texture_format::cTFETC2_EAC_R11: return "ETC2_EAC_R11"; - case transcoder_texture_format::cTFETC2_EAC_RG11: return "ETC2_EAC_RG11"; - default: - assert(0); - BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); - break; + encode_bc1_solid_block(pDst, unpacked_src_blk.m_solid_color.r, unpacked_src_blk.m_solid_color.g, unpacked_src_blk.m_solid_color.b); + return true; } - return ""; + + if ((!high_quality) && (unpacked_src_blk.m_bc1_hint0)) + transcode_uastc_to_bc1_hint0(unpacked_src_blk, pDst); + else + { + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + if (unpacked_src_blk.m_bc1_hint1) + transcode_uastc_to_bc1_hint1(unpacked_src_blk, block_pixels, pDst, high_quality); + else + encode_bc1(pDst, &block_pixels[0][0].r, high_quality ? cEncodeBC1HighQuality : 0); + } + + return true; } - const char* basis_get_texture_type_name(basis_texture_type tex_type) + static void write_bc4_solid_block(uint8_t* pDst, uint32_t a) { - switch (tex_type) + pDst[0] = (uint8_t)a; + pDst[1] = (uint8_t)a; + memset(pDst + 2, 0, 6); + } + + bool transcode_uastc_to_bc3(const uastc_block& src_blk, void* pDst, bool high_quality) + { + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + const uint32_t mode = unpacked_src_blk.m_mode; + + void* pBC4_block = pDst; + dxt1_block* pBC1_block = &static_cast<dxt1_block*>(pDst)[1]; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) { - case cBASISTexType2D: return "2D"; - case cBASISTexType2DArray: return "2D array"; - case cBASISTexTypeCubemapArray: return "cubemap array"; - case cBASISTexTypeVideoFrames: return "video"; - case cBASISTexTypeVolume: return "3D"; - default: - assert(0); - BASISU_DEVEL_ERROR("basis_get_texture_type_name: Invalid tex_type\n"); - break; + write_bc4_solid_block(static_cast<uint8_t*>(pBC4_block), unpacked_src_blk.m_solid_color.a); + encode_bc1_solid_block(pBC1_block, unpacked_src_blk.m_solid_color.r, unpacked_src_blk.m_solid_color.g, unpacked_src_blk.m_solid_color.b); + return true; } - return ""; + + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + basist::encode_bc4(pBC4_block, &block_pixels[0][0].a, sizeof(color32)); + + if ((!high_quality) && (unpacked_src_blk.m_bc1_hint0)) + transcode_uastc_to_bc1_hint0(unpacked_src_blk, pBC1_block); + else + { + if (unpacked_src_blk.m_bc1_hint1) + transcode_uastc_to_bc1_hint1(unpacked_src_blk, block_pixels, pBC1_block, high_quality); + else + encode_bc1(pBC1_block, &block_pixels[0][0].r, high_quality ? cEncodeBC1HighQuality : 0); + } + + return true; } - bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt) + bool transcode_uastc_to_bc4(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0) { - switch (fmt) + BASISU_NOTE_UNUSED(high_quality); + + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + const uint32_t mode = unpacked_src_blk.m_mode; + + void* pBC4_block = pDst; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) { - case transcoder_texture_format::cTFETC2_RGBA: - case transcoder_texture_format::cTFBC3_RGBA: - case transcoder_texture_format::cTFASTC_4x4_RGBA: - case transcoder_texture_format::cTFBC7_M5_RGBA: - case transcoder_texture_format::cTFPVRTC1_4_RGBA: - case transcoder_texture_format::cTFPVRTC2_4_RGBA: - case transcoder_texture_format::cTFATC_RGBA: - case transcoder_texture_format::cTFRGBA32: - case transcoder_texture_format::cTFRGBA4444: + write_bc4_solid_block(static_cast<uint8_t*>(pBC4_block), unpacked_src_blk.m_solid_color.c[chan0]); return true; - default: - break; } - return false; + + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + basist::encode_bc4(pBC4_block, &block_pixels[0][0].c[chan0], sizeof(color32)); + + return true; } - basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt) + bool transcode_uastc_to_bc5(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1) { - switch (fmt) + BASISU_NOTE_UNUSED(high_quality); + + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + const uint32_t mode = unpacked_src_blk.m_mode; + + void* pBC4_block0 = pDst; + void* pBC4_block1 = (uint8_t*)pDst + 8; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) { - case transcoder_texture_format::cTFETC1_RGB: return basisu::texture_format::cETC1; - case transcoder_texture_format::cTFBC1_RGB: return basisu::texture_format::cBC1; - case transcoder_texture_format::cTFBC4_R: return basisu::texture_format::cBC4; - case transcoder_texture_format::cTFPVRTC1_4_RGB: return basisu::texture_format::cPVRTC1_4_RGB; - case transcoder_texture_format::cTFPVRTC1_4_RGBA: return basisu::texture_format::cPVRTC1_4_RGBA; - case transcoder_texture_format::cTFBC7_M6_RGB: return basisu::texture_format::cBC7; - case transcoder_texture_format::cTFBC7_M5_RGBA: return basisu::texture_format::cBC7; - case transcoder_texture_format::cTFETC2_RGBA: return basisu::texture_format::cETC2_RGBA; - case transcoder_texture_format::cTFBC3_RGBA: return basisu::texture_format::cBC3; - case transcoder_texture_format::cTFBC5_RG: return basisu::texture_format::cBC5; - case transcoder_texture_format::cTFASTC_4x4_RGBA: return basisu::texture_format::cASTC4x4; - case transcoder_texture_format::cTFATC_RGB: return basisu::texture_format::cATC_RGB; - case transcoder_texture_format::cTFATC_RGBA: return basisu::texture_format::cATC_RGBA_INTERPOLATED_ALPHA; - case transcoder_texture_format::cTFRGBA32: return basisu::texture_format::cRGBA32; - case transcoder_texture_format::cTFRGB565: return basisu::texture_format::cRGB565; - case transcoder_texture_format::cTFBGR565: return basisu::texture_format::cBGR565; - case transcoder_texture_format::cTFRGBA4444: return basisu::texture_format::cRGBA4444; - case transcoder_texture_format::cTFFXT1_RGB: return basisu::texture_format::cFXT1_RGB; - case transcoder_texture_format::cTFPVRTC2_4_RGB: return basisu::texture_format::cPVRTC2_4_RGBA; - case transcoder_texture_format::cTFPVRTC2_4_RGBA: return basisu::texture_format::cPVRTC2_4_RGBA; - case transcoder_texture_format::cTFETC2_EAC_R11: return basisu::texture_format::cETC2_R11_EAC; - case transcoder_texture_format::cTFETC2_EAC_RG11: return basisu::texture_format::cETC2_RG11_EAC; - default: - assert(0); - BASISU_DEVEL_ERROR("basis_get_basisu_texture_format: Invalid fmt\n"); - break; + write_bc4_solid_block(static_cast<uint8_t*>(pBC4_block0), unpacked_src_blk.m_solid_color.c[chan0]); + write_bc4_solid_block(static_cast<uint8_t*>(pBC4_block1), unpacked_src_blk.m_solid_color.c[chan1]); + return true; } - return basisu::texture_format::cInvalidTextureFormat; + + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + basist::encode_bc4(pBC4_block0, &block_pixels[0][0].c[chan0], sizeof(color32)); + basist::encode_bc4(pBC4_block1, &block_pixels[0][0].c[chan1], sizeof(color32)); + + return true; } - bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type) + static const uint8_t s_etc2_eac_bit_ofs[16] = { 45, 33, 21, 9, 42, 30, 18, 6, 39, 27, 15, 3, 36, 24, 12, 0 }; + + static void pack_eac_solid_block(eac_block& blk, uint32_t a) { - switch (tex_type) + blk.m_base = static_cast<uint8_t>(a); + blk.m_table = 13; + blk.m_multiplier = 0; + + memcpy(blk.m_selectors, g_etc2_eac_a8_sel4, sizeof(g_etc2_eac_a8_sel4)); + + return; + } + + // Only checks 4 tables. + static void pack_eac(eac_block& blk, const uint8_t* pPixels, uint32_t stride) + { + uint32_t min_alpha = 255, max_alpha = 0; + for (uint32_t i = 0; i < 16; i++) { - case transcoder_texture_format::cTFRGBA32: - case transcoder_texture_format::cTFRGB565: - case transcoder_texture_format::cTFBGR565: - case transcoder_texture_format::cTFRGBA4444: + const uint32_t a = pPixels[i * stride]; + if (a < min_alpha) min_alpha = a; + if (a > max_alpha) max_alpha = a; + } + + if (min_alpha == max_alpha) + { + pack_eac_solid_block(blk, min_alpha); + return; + } + + const uint32_t alpha_range = max_alpha - min_alpha; + + const uint32_t SINGLE_TABLE_THRESH = 5; + if (alpha_range <= SINGLE_TABLE_THRESH) + { + // If alpha_range <= 5 table 13 is lossless + int base = clamp255((int)max_alpha - 2); + + blk.m_base = base; + blk.m_multiplier = 1; + blk.m_table = 13; + + base -= 3; + + uint64_t packed_sels = 0; + for (uint32_t i = 0; i < 16; i++) + { + const int a = pPixels[i * stride]; + + static const uint8_t s_sels[6] = { 2, 1, 0, 4, 5, 6 }; + + int sel = a - base; + assert(sel >= 0 && sel <= 5); + + packed_sels |= (static_cast<uint64_t>(s_sels[sel]) << s_etc2_eac_bit_ofs[i]); + } + + blk.set_selector_bits(packed_sels); + + return; + } + + const uint32_t T0 = 2, T1 = 8, T2 = 11, T3 = 13; + static const uint8_t s_tables[4] = { T0, T1, T2, T3 }; + + int base[4], mul[4]; + uint32_t mul_or = 0; + for (uint32_t i = 0; i < 4; i++) + { + const uint32_t table = s_tables[i]; + + const float range = (float)(g_eac_modifier_table[table][ETC2_EAC_MAX_VALUE_SELECTOR] - g_eac_modifier_table[table][ETC2_EAC_MIN_VALUE_SELECTOR]); + + base[i] = clamp255((int)roundf(basisu::lerp((float)min_alpha, (float)max_alpha, (float)(0 - g_eac_modifier_table[table][ETC2_EAC_MIN_VALUE_SELECTOR]) / range))); + mul[i] = clampi((int)roundf(alpha_range / range), 1, 15); + mul_or |= mul[i]; + } + + uint32_t total_err[4] = { 0, 0, 0, 0 }; + uint8_t sels[4][16]; + + for (uint32_t i = 0; i < 16; i++) + { + const int a = pPixels[i * stride]; + + uint32_t l0 = UINT32_MAX, l1 = UINT32_MAX, l2 = UINT32_MAX, l3 = UINT32_MAX; + + if ((a < 7) || (a > (255 - 7))) + { + for (uint32_t s = 0; s < 8; s++) + { + const int v0 = clamp255(mul[0] * g_eac_modifier_table[T0][s] + base[0]); + const int v1 = clamp255(mul[1] * g_eac_modifier_table[T1][s] + base[1]); + const int v2 = clamp255(mul[2] * g_eac_modifier_table[T2][s] + base[2]); + const int v3 = clamp255(mul[3] * g_eac_modifier_table[T3][s] + base[3]); + + l0 = basisu::minimum(l0, (basisu::iabs(v0 - a) << 3) | s); + l1 = basisu::minimum(l1, (basisu::iabs(v1 - a) << 3) | s); + l2 = basisu::minimum(l2, (basisu::iabs(v2 - a) << 3) | s); + l3 = basisu::minimum(l3, (basisu::iabs(v3 - a) << 3) | s); + } + } + else if (mul_or == 1) + { + const int a0 = base[0] - a, a1 = base[1] - a, a2 = base[2] - a, a3 = base[3] - a; + + for (uint32_t s = 0; s < 8; s++) + { + const int v0 = g_eac_modifier_table[T0][s] + a0; + const int v1 = g_eac_modifier_table[T1][s] + a1; + const int v2 = g_eac_modifier_table[T2][s] + a2; + const int v3 = g_eac_modifier_table[T3][s] + a3; + + l0 = basisu::minimum(l0, (basisu::iabs(v0) << 3) | s); + l1 = basisu::minimum(l1, (basisu::iabs(v1) << 3) | s); + l2 = basisu::minimum(l2, (basisu::iabs(v2) << 3) | s); + l3 = basisu::minimum(l3, (basisu::iabs(v3) << 3) | s); + } + } + else + { + const int a0 = base[0] - a, a1 = base[1] - a, a2 = base[2] - a, a3 = base[3] - a; + + for (uint32_t s = 0; s < 8; s++) + { + const int v0 = mul[0] * g_eac_modifier_table[T0][s] + a0; + const int v1 = mul[1] * g_eac_modifier_table[T1][s] + a1; + const int v2 = mul[2] * g_eac_modifier_table[T2][s] + a2; + const int v3 = mul[3] * g_eac_modifier_table[T3][s] + a3; + + l0 = basisu::minimum(l0, (basisu::iabs(v0) << 3) | s); + l1 = basisu::minimum(l1, (basisu::iabs(v1) << 3) | s); + l2 = basisu::minimum(l2, (basisu::iabs(v2) << 3) | s); + l3 = basisu::minimum(l3, (basisu::iabs(v3) << 3) | s); + } + } + + sels[0][i] = l0 & 7; + sels[1][i] = l1 & 7; + sels[2][i] = l2 & 7; + sels[3][i] = l3 & 7; + + total_err[0] += basisu::square<uint32_t>(l0 >> 3); + total_err[1] += basisu::square<uint32_t>(l1 >> 3); + total_err[2] += basisu::square<uint32_t>(l2 >> 3); + total_err[3] += basisu::square<uint32_t>(l3 >> 3); + } + + uint32_t min_err = total_err[0], min_index = 0; + for (uint32_t i = 1; i < 4; i++) + { + if (total_err[i] < min_err) + { + min_err = total_err[i]; + min_index = i; + } + } + + blk.m_base = base[min_index]; + blk.m_multiplier = mul[min_index]; + blk.m_table = s_tables[min_index]; + + uint64_t packed_sels = 0; + const uint8_t* pSels = &sels[min_index][0]; + for (uint32_t i = 0; i < 16; i++) + packed_sels |= (static_cast<uint64_t>(pSels[i]) << s_etc2_eac_bit_ofs[i]); + + blk.set_selector_bits(packed_sels); + } + + // Checks all 16 tables. Around ~2 dB better vs. pack_eac(), ~1.2 dB less than near-optimal. + static void pack_eac_high_quality(eac_block& blk, const uint8_t* pPixels, uint32_t stride) + { + uint32_t min_alpha = 255, max_alpha = 0; + for (uint32_t i = 0; i < 16; i++) + { + const uint32_t a = pPixels[i * stride]; + if (a < min_alpha) min_alpha = a; + if (a > max_alpha) max_alpha = a; + } + + if (min_alpha == max_alpha) + { + pack_eac_solid_block(blk, min_alpha); + return; + } + + const uint32_t alpha_range = max_alpha - min_alpha; + + const uint32_t SINGLE_TABLE_THRESH = 5; + if (alpha_range <= SINGLE_TABLE_THRESH) + { + // If alpha_range <= 5 table 13 is lossless + int base = clamp255((int)max_alpha - 2); + + blk.m_base = base; + blk.m_multiplier = 1; + blk.m_table = 13; + + base -= 3; + + uint64_t packed_sels = 0; + for (uint32_t i = 0; i < 16; i++) + { + const int a = pPixels[i * stride]; + + static const uint8_t s_sels[6] = { 2, 1, 0, 4, 5, 6 }; + + int sel = a - base; + assert(sel >= 0 && sel <= 5); + + packed_sels |= (static_cast<uint64_t>(s_sels[sel]) << s_etc2_eac_bit_ofs[i]); + } + + blk.set_selector_bits(packed_sels); + + return; + } + + int base[16], mul[16]; + for (uint32_t table = 0; table < 16; table++) + { + const float range = (float)(g_eac_modifier_table[table][ETC2_EAC_MAX_VALUE_SELECTOR] - g_eac_modifier_table[table][ETC2_EAC_MIN_VALUE_SELECTOR]); + + base[table] = clamp255((int)roundf(basisu::lerp((float)min_alpha, (float)max_alpha, (float)(0 - g_eac_modifier_table[table][ETC2_EAC_MIN_VALUE_SELECTOR]) / range))); + mul[table] = clampi((int)roundf(alpha_range / range), 1, 15); + } + + uint32_t total_err[16]; + memset(total_err, 0, sizeof(total_err)); + + uint8_t sels[16][16]; + + for (uint32_t table = 0; table < 16; table++) + { + const int8_t* pTable = &g_eac_modifier_table[table][0]; + const int m = mul[table], b = base[table]; + + uint32_t prev_l = 0, prev_a = UINT32_MAX; + + for (uint32_t i = 0; i < 16; i++) + { + const int a = pPixels[i * stride]; + + if ((uint32_t)a == prev_a) + { + sels[table][i] = prev_l & 7; + total_err[table] += basisu::square<uint32_t>(prev_l >> 3); + } + else + { + uint32_t l = basisu::iabs(clamp255(m * pTable[0] + b) - a) << 3; + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[1] + b) - a) << 3) | 1); + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[2] + b) - a) << 3) | 2); + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[3] + b) - a) << 3) | 3); + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[4] + b) - a) << 3) | 4); + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[5] + b) - a) << 3) | 5); + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[6] + b) - a) << 3) | 6); + l = basisu::minimum(l, (basisu::iabs(clamp255(m * pTable[7] + b) - a) << 3) | 7); + + sels[table][i] = l & 7; + total_err[table] += basisu::square<uint32_t>(l >> 3); + + prev_l = l; + prev_a = a; + } + } + } + + uint32_t min_err = total_err[0], min_index = 0; + for (uint32_t i = 1; i < 16; i++) + { + if (total_err[i] < min_err) + { + min_err = total_err[i]; + min_index = i; + } + } + + blk.m_base = base[min_index]; + blk.m_multiplier = mul[min_index]; + blk.m_table = min_index; + + uint64_t packed_sels = 0; + const uint8_t* pSels = &sels[min_index][0]; + for (uint32_t i = 0; i < 16; i++) + packed_sels |= (static_cast<uint64_t>(pSels[i]) << s_etc2_eac_bit_ofs[i]); + + blk.set_selector_bits(packed_sels); + } + + bool transcode_uastc_to_etc2_eac_r11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0) + { + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + const uint32_t mode = unpacked_src_blk.m_mode; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) + { + pack_eac_solid_block(*static_cast<eac_block*>(pDst), unpacked_src_blk.m_solid_color.c[chan0]); return true; - default: - break; } - return false; + + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + if (chan0 == 3) + transcode_uastc_to_etc2_eac_a8(unpacked_src_blk, block_pixels, pDst); + else + (high_quality ? pack_eac_high_quality : pack_eac)(*static_cast<eac_block*>(pDst), &block_pixels[0][0].c[chan0], sizeof(color32)); + + return true; } - bool basis_block_format_is_uncompressed(block_format tex_type) + bool transcode_uastc_to_etc2_eac_rg11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1) { - switch (tex_type) + unpacked_uastc_block unpacked_src_blk; + if (!unpack_uastc(src_blk, unpacked_src_blk, false)) + return false; + + const uint32_t mode = unpacked_src_blk.m_mode; + + if (mode == UASTC_MODE_INDEX_SOLID_COLOR) { - case block_format::cRGB32: - case block_format::cRGBA32: - case block_format::cA32: - case block_format::cRGB565: - case block_format::cBGR565: - case block_format::cRGBA4444_COLOR: - case block_format::cRGBA4444_ALPHA: - case block_format::cRGBA4444_COLOR_OPAQUE: + pack_eac_solid_block(static_cast<eac_block*>(pDst)[0], unpacked_src_blk.m_solid_color.c[chan0]); + pack_eac_solid_block(static_cast<eac_block*>(pDst)[1], unpacked_src_blk.m_solid_color.c[chan1]); return true; - default: - break; } - return false; + + color32 block_pixels[4][4]; + const bool unpack_srgb = false; + if (!unpack_uastc(unpacked_src_blk, &block_pixels[0][0], unpack_srgb)) + return false; + + if (chan0 == 3) + transcode_uastc_to_etc2_eac_a8(unpacked_src_blk, block_pixels, &static_cast<eac_block*>(pDst)[0]); + else + (high_quality ? pack_eac_high_quality : pack_eac)(static_cast<eac_block*>(pDst)[0], &block_pixels[0][0].c[chan0], sizeof(color32)); + + if (chan1 == 3) + transcode_uastc_to_etc2_eac_a8(unpacked_src_blk, block_pixels, &static_cast<eac_block*>(pDst)[1]); + else + (high_quality ? pack_eac_high_quality : pack_eac)(static_cast<eac_block*>(pDst)[1], &block_pixels[0][0].c[chan1], sizeof(color32)); + return true; } - - uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt) + + // PVRTC1 + static void fixup_pvrtc1_4_modulation_rgb( + const uastc_block* pSrc_blocks, + const uint32_t* pPVRTC_endpoints, + void* pDst_blocks, + uint32_t num_blocks_x, uint32_t num_blocks_y, bool from_alpha) { - switch (fmt) + const uint32_t x_mask = num_blocks_x - 1; + const uint32_t y_mask = num_blocks_y - 1; + const uint32_t x_bits = basisu::total_bits(x_mask); + const uint32_t y_bits = basisu::total_bits(y_mask); + const uint32_t min_bits = basisu::minimum(x_bits, y_bits); + //const uint32_t max_bits = basisu::maximum(x_bits, y_bits); + const uint32_t swizzle_mask = (1 << (min_bits * 2)) - 1; + + uint32_t block_index = 0; + + // really 3x3 + int e0[4][4], e1[4][4]; + + for (int y = 0; y < static_cast<int>(num_blocks_y); y++) { - case transcoder_texture_format::cTFRGBA32: - return sizeof(uint32_t); - case transcoder_texture_format::cTFRGB565: - case transcoder_texture_format::cTFBGR565: - case transcoder_texture_format::cTFRGBA4444: - return sizeof(uint16_t); - default: - break; + const uint32_t* pE_rows[3]; + + for (int ey = 0; ey < 3; ey++) + { + int by = y + ey - 1; + + const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x]; + + pE_rows[ey] = pE; + + for (int ex = 0; ex < 3; ex++) + { + int bx = 0 + ex - 1; + + const uint32_t e = pE[bx & x_mask]; + + e0[ex][ey] = (get_opaque_endpoint_l0(e) * 255) / 31; + e1[ex][ey] = (get_opaque_endpoint_l1(e) * 255) / 31; + } + } + + const uint32_t y_swizzle = (g_pvrtc_swizzle_table[y >> 8] << 16) | g_pvrtc_swizzle_table[y & 0xFF]; + + for (int x = 0; x < static_cast<int>(num_blocks_x); x++, block_index++) + { + const uastc_block& src_block = pSrc_blocks[block_index]; + + color32 block_pixels[4][4]; + unpack_uastc(src_block, &block_pixels[0][0], false); + if (from_alpha) + { + // Just set RGB to alpha to avoid adding complexity below. + for (uint32_t i = 0; i < 16; i++) + { + const uint8_t a = ((color32*)block_pixels)[i].a; + ((color32*)block_pixels)[i].set(a, a, a, 255); + } + } + + const uint32_t x_swizzle = (g_pvrtc_swizzle_table[x >> 8] << 17) | (g_pvrtc_swizzle_table[x & 0xFF] << 1); + + uint32_t swizzled = x_swizzle | y_swizzle; + if (num_blocks_x != num_blocks_y) + { + swizzled &= swizzle_mask; + + if (num_blocks_x > num_blocks_y) + swizzled |= ((x >> min_bits) << (min_bits * 2)); + else + swizzled |= ((y >> min_bits) << (min_bits * 2)); + } + + pvrtc4_block* pDst_block = static_cast<pvrtc4_block*>(pDst_blocks) + swizzled; + pDst_block->m_endpoints = pPVRTC_endpoints[block_index]; + + { + const uint32_t ex = 2; + int bx = x + ex - 1; + bx &= x_mask; + +#define DO_ROW(ey) \ + { \ + const uint32_t e = pE_rows[ey][bx]; \ + e0[ex][ey] = (get_opaque_endpoint_l0(e) * 255) / 31; \ + e1[ex][ey] = (get_opaque_endpoint_l1(e) * 255) / 31; \ + } + + DO_ROW(0); + DO_ROW(1); + DO_ROW(2); +#undef DO_ROW + } + + uint32_t mod = 0; + +#define DO_PIX(lx, ly, w0, w1, w2, w3) \ + { \ + int ca_l = a0 * w0 + a1 * w1 + a2 * w2 + a3 * w3; \ + int cb_l = b0 * w0 + b1 * w1 + b2 * w2 + b3 * w3; \ + int cl = (block_pixels[ly][lx].r + block_pixels[ly][lx].g + block_pixels[ly][lx].b) * 16; \ + int dl = cb_l - ca_l; \ + int vl = cl - ca_l; \ + int p = vl * 16; \ + if (ca_l > cb_l) { p = -p; dl = -dl; } \ + uint32_t m = 0; \ + if (p > 3 * dl) m = (uint32_t)(1 << ((ly) * 8 + (lx) * 2)); \ + if (p > 8 * dl) m = (uint32_t)(2 << ((ly) * 8 + (lx) * 2)); \ + if (p > 13 * dl) m = (uint32_t)(3 << ((ly) * 8 + (lx) * 2)); \ + mod |= m; \ + } + + { + const uint32_t ex = 0, ey = 0; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(0, 0, 4, 4, 4, 4); + DO_PIX(1, 0, 2, 6, 2, 6); + DO_PIX(0, 1, 2, 2, 6, 6); + DO_PIX(1, 1, 1, 3, 3, 9); + } + + { + const uint32_t ex = 1, ey = 0; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(2, 0, 8, 0, 8, 0); + DO_PIX(3, 0, 6, 2, 6, 2); + DO_PIX(2, 1, 4, 0, 12, 0); + DO_PIX(3, 1, 3, 1, 9, 3); + } + + { + const uint32_t ex = 0, ey = 1; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(0, 2, 8, 8, 0, 0); + DO_PIX(1, 2, 4, 12, 0, 0); + DO_PIX(0, 3, 6, 6, 2, 2); + DO_PIX(1, 3, 3, 9, 1, 3); + } + + { + const uint32_t ex = 1, ey = 1; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(2, 2, 16, 0, 0, 0); + DO_PIX(3, 2, 12, 4, 0, 0); + DO_PIX(2, 3, 12, 0, 4, 0); + DO_PIX(3, 3, 9, 3, 3, 1); + } +#undef DO_PIX + + pDst_block->m_modulation = mod; + + e0[0][0] = e0[1][0]; e0[1][0] = e0[2][0]; + e0[0][1] = e0[1][1]; e0[1][1] = e0[2][1]; + e0[0][2] = e0[1][2]; e0[1][2] = e0[2][2]; + + e1[0][0] = e1[1][0]; e1[1][0] = e1[2][0]; + e1[0][1] = e1[1][1]; e1[1][1] = e1[2][1]; + e1[0][2] = e1[1][2]; e1[1][2] = e1[2][2]; + + } // x + } // y + } + + static void fixup_pvrtc1_4_modulation_rgba( + const uastc_block* pSrc_blocks, + const uint32_t* pPVRTC_endpoints, + void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y) + { + const uint32_t x_mask = num_blocks_x - 1; + const uint32_t y_mask = num_blocks_y - 1; + const uint32_t x_bits = basisu::total_bits(x_mask); + const uint32_t y_bits = basisu::total_bits(y_mask); + const uint32_t min_bits = basisu::minimum(x_bits, y_bits); + //const uint32_t max_bits = basisu::maximum(x_bits, y_bits); + const uint32_t swizzle_mask = (1 << (min_bits * 2)) - 1; + + uint32_t block_index = 0; + + // really 3x3 + int e0[4][4], e1[4][4]; + + for (int y = 0; y < static_cast<int>(num_blocks_y); y++) + { + const uint32_t* pE_rows[3]; + + for (int ey = 0; ey < 3; ey++) + { + int by = y + ey - 1; + + const uint32_t* pE = &pPVRTC_endpoints[(by & y_mask) * num_blocks_x]; + + pE_rows[ey] = pE; + + for (int ex = 0; ex < 3; ex++) + { + int bx = 0 + ex - 1; + + const uint32_t e = pE[bx & x_mask]; + + e0[ex][ey] = get_endpoint_l8(e, 0); + e1[ex][ey] = get_endpoint_l8(e, 1); + } + } + + const uint32_t y_swizzle = (g_pvrtc_swizzle_table[y >> 8] << 16) | g_pvrtc_swizzle_table[y & 0xFF]; + + for (int x = 0; x < static_cast<int>(num_blocks_x); x++, block_index++) + { + const uastc_block& src_block = pSrc_blocks[block_index]; + + color32 block_pixels[4][4]; + unpack_uastc(src_block, &block_pixels[0][0], false); + + const uint32_t x_swizzle = (g_pvrtc_swizzle_table[x >> 8] << 17) | (g_pvrtc_swizzle_table[x & 0xFF] << 1); + + uint32_t swizzled = x_swizzle | y_swizzle; + if (num_blocks_x != num_blocks_y) + { + swizzled &= swizzle_mask; + + if (num_blocks_x > num_blocks_y) + swizzled |= ((x >> min_bits) << (min_bits * 2)); + else + swizzled |= ((y >> min_bits) << (min_bits * 2)); + } + + pvrtc4_block* pDst_block = static_cast<pvrtc4_block*>(pDst_blocks) + swizzled; + pDst_block->m_endpoints = pPVRTC_endpoints[block_index]; + + { + const uint32_t ex = 2; + int bx = x + ex - 1; + bx &= x_mask; + +#define DO_ROW(ey) \ + { \ + const uint32_t e = pE_rows[ey][bx]; \ + e0[ex][ey] = get_endpoint_l8(e, 0); \ + e1[ex][ey] = get_endpoint_l8(e, 1); \ + } + + DO_ROW(0); + DO_ROW(1); + DO_ROW(2); +#undef DO_ROW + } + + uint32_t mod = 0; + +#define DO_PIX(lx, ly, w0, w1, w2, w3) \ + { \ + int ca_l = a0 * w0 + a1 * w1 + a2 * w2 + a3 * w3; \ + int cb_l = b0 * w0 + b1 * w1 + b2 * w2 + b3 * w3; \ + int cl = 16 * (block_pixels[ly][lx].r + block_pixels[ly][lx].g + block_pixels[ly][lx].b + block_pixels[ly][lx].a); \ + int dl = cb_l - ca_l; \ + int vl = cl - ca_l; \ + int p = vl * 16; \ + if (ca_l > cb_l) { p = -p; dl = -dl; } \ + uint32_t m = 0; \ + if (p > 3 * dl) m = (uint32_t)(1 << ((ly) * 8 + (lx) * 2)); \ + if (p > 8 * dl) m = (uint32_t)(2 << ((ly) * 8 + (lx) * 2)); \ + if (p > 13 * dl) m = (uint32_t)(3 << ((ly) * 8 + (lx) * 2)); \ + mod |= m; \ + } + + { + const uint32_t ex = 0, ey = 0; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(0, 0, 4, 4, 4, 4); + DO_PIX(1, 0, 2, 6, 2, 6); + DO_PIX(0, 1, 2, 2, 6, 6); + DO_PIX(1, 1, 1, 3, 3, 9); + } + + { + const uint32_t ex = 1, ey = 0; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(2, 0, 8, 0, 8, 0); + DO_PIX(3, 0, 6, 2, 6, 2); + DO_PIX(2, 1, 4, 0, 12, 0); + DO_PIX(3, 1, 3, 1, 9, 3); + } + + { + const uint32_t ex = 0, ey = 1; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(0, 2, 8, 8, 0, 0); + DO_PIX(1, 2, 4, 12, 0, 0); + DO_PIX(0, 3, 6, 6, 2, 2); + DO_PIX(1, 3, 3, 9, 1, 3); + } + + { + const uint32_t ex = 1, ey = 1; + const int a0 = e0[ex][ey], a1 = e0[ex + 1][ey], a2 = e0[ex][ey + 1], a3 = e0[ex + 1][ey + 1]; + const int b0 = e1[ex][ey], b1 = e1[ex + 1][ey], b2 = e1[ex][ey + 1], b3 = e1[ex + 1][ey + 1]; + DO_PIX(2, 2, 16, 0, 0, 0); + DO_PIX(3, 2, 12, 4, 0, 0); + DO_PIX(2, 3, 12, 0, 4, 0); + DO_PIX(3, 3, 9, 3, 3, 1); + } +#undef DO_PIX + + pDst_block->m_modulation = mod; + + e0[0][0] = e0[1][0]; e0[1][0] = e0[2][0]; + e0[0][1] = e0[1][1]; e0[1][1] = e0[2][1]; + e0[0][2] = e0[1][2]; e0[1][2] = e0[2][2]; + + e1[0][0] = e1[1][0]; e1[1][0] = e1[2][0]; + e1[0][1] = e1[1][1]; e1[1][1] = e1[2][1]; + e1[0][2] = e1[1][2]; e1[1][2] = e1[2][2]; + + } // x + } // y + } + + bool transcode_uastc_to_pvrtc1_4_rgb(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality, bool from_alpha) + { + BASISU_NOTE_UNUSED(high_quality); + + if ((!num_blocks_x) || (!num_blocks_y)) + return false; + + const uint32_t width = num_blocks_x * 4; + const uint32_t height = num_blocks_y * 4; + if (!basisu::is_pow2(width) || !basisu::is_pow2(height)) + return false; + + basisu::vector<uint32_t> temp_endpoints(num_blocks_x * num_blocks_y); + + for (uint32_t y = 0; y < num_blocks_y; y++) + { + for (uint32_t x = 0; x < num_blocks_x; x++) + { + color32 block_pixels[16]; + if (!unpack_uastc(pSrc_blocks[x + y * num_blocks_x], block_pixels, false)) + return false; + + // Get block's RGB bounding box + color32 low_color(255, 255, 255, 255), high_color(0, 0, 0, 0); + + if (from_alpha) + { + uint32_t low_a = 255, high_a = 0; + for (uint32_t i = 0; i < 16; i++) + { + low_a = basisu::minimum<uint32_t>(low_a, block_pixels[i].a); + high_a = basisu::maximum<uint32_t>(high_a, block_pixels[i].a); + } + low_color.set(low_a, low_a, low_a, 255); + high_color.set(high_a, high_a, high_a, 255); + } + else + { + for (uint32_t i = 0; i < 16; i++) + { + low_color = color32::comp_min(low_color, block_pixels[i]); + high_color = color32::comp_max(high_color, block_pixels[i]); + } + } + + // Set PVRTC1 endpoints to floor/ceil of bounding box's coordinates. + pvrtc4_block temp; + temp.set_opaque_endpoint_floor(0, low_color); + temp.set_opaque_endpoint_ceil(1, high_color); + + temp_endpoints[x + y * num_blocks_x] = temp.m_endpoints; + } } - return 0; + + fixup_pvrtc1_4_modulation_rgb(pSrc_blocks, &temp_endpoints[0], pDst_blocks, num_blocks_x, num_blocks_y, from_alpha); + + return true; } - - uint32_t basis_get_block_width(transcoder_texture_format tex_type) + + bool transcode_uastc_to_pvrtc1_4_rgba(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality) { - switch (tex_type) + BASISU_NOTE_UNUSED(high_quality); + + if ((!num_blocks_x) || (!num_blocks_y)) + return false; + + const uint32_t width = num_blocks_x * 4; + const uint32_t height = num_blocks_y * 4; + if (!basisu::is_pow2(width) || !basisu::is_pow2(height)) + return false; + + basisu::vector<uint32_t> temp_endpoints(num_blocks_x * num_blocks_y); + + for (uint32_t y = 0; y < num_blocks_y; y++) { - case transcoder_texture_format::cTFFXT1_RGB: - return 8; - default: + for (uint32_t x = 0; x < num_blocks_x; x++) + { + color32 block_pixels[16]; + if (!unpack_uastc(pSrc_blocks[x + y * num_blocks_x], block_pixels, false)) + return false; + + // Get block's RGBA bounding box + color32 low_color(255, 255, 255, 255), high_color(0, 0, 0, 0); + + for (uint32_t i = 0; i < 16; i++) + { + low_color = color32::comp_min(low_color, block_pixels[i]); + high_color = color32::comp_max(high_color, block_pixels[i]); + } + + // Set PVRTC1 endpoints to floor/ceil of bounding box's coordinates. + pvrtc4_block temp; + temp.set_endpoint_floor(0, low_color); + temp.set_endpoint_ceil(1, high_color); + + temp_endpoints[x + y * num_blocks_x] = temp.m_endpoints; + } + } + + fixup_pvrtc1_4_modulation_rgba(pSrc_blocks, &temp_endpoints[0], pDst_blocks, num_blocks_x, num_blocks_y); + + return true; + } + + void uastc_init() + { + for (uint32_t range = 0; range < BC7ENC_TOTAL_ASTC_RANGES; range++) + { + if (!astc_is_valid_endpoint_range(range)) + continue; + + const uint32_t levels = astc_get_levels(range); + + uint32_t vals[256]; + for (uint32_t i = 0; i < levels; i++) + vals[i] = (unquant_astc_endpoint_val(i, range) << 8) | i; + + std::sort(vals, vals + levels); + + for (uint32_t i = 0; i < levels; i++) + { + const uint32_t order = vals[i] & 0xFF; + const uint32_t unq = vals[i] >> 8; + + g_astc_unquant[range][order].m_unquant = (uint8_t)unq; + g_astc_unquant[range][order].m_index = (uint8_t)i; + + } // i + } + + // TODO: Precompute? + // BC7 777.1 + for (int c = 0; c < 256; c++) + { + for (uint32_t lp = 0; lp < 2; lp++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + + for (uint32_t l = 0; l < 128; l++) + { + const uint32_t low = (l << 1) | lp; + + for (uint32_t h = 0; h < 128; h++) + { + const uint32_t high = (h << 1) | lp; + + const int k = (low * (64 - g_bc7_weights4[BC7ENC_MODE_6_OPTIMAL_INDEX]) + high * g_bc7_weights4[BC7ENC_MODE_6_OPTIMAL_INDEX] + 32) >> 6; + + const int err = (k - c) * (k - c); + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_bc7_mode_6_optimal_endpoints[c][lp] = best; + } // lp + + } // c + + // BC7 777 + for (int c = 0; c < 256; c++) + { + endpoint_err best; + best.m_error = (uint16_t)UINT16_MAX; + + for (uint32_t l = 0; l < 128; l++) + { + const uint32_t low = (l << 1) | (l >> 6); + + for (uint32_t h = 0; h < 128; h++) + { + const uint32_t high = (h << 1) | (h >> 6); + + const int k = (low * (64 - g_bc7_weights2[BC7ENC_MODE_5_OPTIMAL_INDEX]) + high * g_bc7_weights2[BC7ENC_MODE_5_OPTIMAL_INDEX] + 32) >> 6; + + const int err = (k - c) * (k - c); + if (err < best.m_error) + { + best.m_error = (uint16_t)err; + best.m_lo = (uint8_t)l; + best.m_hi = (uint8_t)h; + } + } // h + } // l + + g_bc7_mode_5_optimal_endpoints[c] = best; + + } // c + } + +#endif // #if BASISD_SUPPORT_UASTC + +// ------------------------------------------------------------------------------------------------------ +// KTX2 +// ------------------------------------------------------------------------------------------------------ + +#if BASISD_SUPPORT_KTX2 + const uint8_t g_ktx2_file_identifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; + + ktx2_transcoder::ktx2_transcoder(basist::etc1_global_selector_codebook* pGlobal_sel_codebook) : + m_etc1s_transcoder(pGlobal_sel_codebook) + { + clear(); + } + + void ktx2_transcoder::clear() + { + m_pData = nullptr; + m_data_size = 0; + + memset(&m_header, 0, sizeof(m_header)); + m_levels.clear(); + m_dfd.clear(); + m_key_values.clear(); + memset(&m_etc1s_header, 0, sizeof(m_etc1s_header)); + m_etc1s_image_descs.clear(); + + m_format = basist::basis_tex_format::cETC1S; + + m_dfd_color_model = 0; + m_dfd_color_prims = KTX2_DF_PRIMARIES_UNSPECIFIED; + m_dfd_transfer_func = 0; + m_dfd_flags = 0; + m_dfd_samples = 0; + m_dfd_chan0 = KTX2_DF_CHANNEL_UASTC_RGB; + m_dfd_chan1 = KTX2_DF_CHANNEL_UASTC_RGB; + + m_etc1s_transcoder.clear(); + + m_def_transcoder_state.clear(); + + m_has_alpha = false; + m_is_video = false; + } + + bool ktx2_transcoder::init(const void* pData, uint32_t data_size) + { + clear(); + + if (!pData) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: pData is nullptr\n"); + assert(0); + return false; + } + + if (data_size <= sizeof(ktx2_header)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: File is impossibly too small to be a valid KTX2 file\n"); + return false; + } + + if (memcmp(pData, g_ktx2_file_identifier, sizeof(g_ktx2_file_identifier)) != 0) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: KTX2 file identifier is not present\n"); + return false; + } + + m_pData = static_cast<const uint8_t *>(pData); + m_data_size = data_size; + + memcpy(&m_header, pData, sizeof(m_header)); + + // We only support UASTC and ETC1S + if (m_header.m_vk_format != KTX2_VK_FORMAT_UNDEFINED) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: KTX2 file must be in ETC1S or UASTC format\n"); + return false; + } + + // 3.3: "When format is VK_FORMAT_UNDEFINED, typeSize must equal 1." + if (m_header.m_type_size != 1) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid type_size\n"); + return false; + } + + // We only currently support 2D textures (plain, cubemapped, or texture array), which is by far the most common use case. + // The BasisU library does not support 1D or 3D textures at all. + if ((m_header.m_pixel_width < 1) || (m_header.m_pixel_height < 1) || (m_header.m_pixel_depth > 0)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Only 2D or cubemap textures are supported\n"); + return false; + } + + // Face count must be 1 or 6 + if ((m_header.m_face_count != 1) && (m_header.m_face_count != 6)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid face count, file is corrupted or invalid\n"); + return false; + } + + if (m_header.m_face_count > 1) + { + // 3.4: Make sure cubemaps are square. + if (m_header.m_pixel_width != m_header.m_pixel_height) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Cubemap is not square\n"); + return false; + } + } + + // 3.7 levelCount: "levelCount=0 is allowed, except for block-compressed formats" + if (m_header.m_level_count < 1) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid level count\n"); + return false; + } + + // Sanity check the level count. + if (m_header.m_level_count > KTX2_MAX_SUPPORTED_LEVEL_COUNT) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Too many levels or file is corrupted or invalid\n"); + return false; + } + + if (m_header.m_supercompression_scheme > KTX2_SS_ZSTANDARD) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid/unsupported supercompression or file is corrupted or invalid\n"); + return false; + } + + if (m_header.m_supercompression_scheme == KTX2_SS_BASISLZ) + { + if (m_header.m_sgd_byte_length <= sizeof(ktx2_etc1s_global_data_header)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Supercompression global data is too small\n"); + return false; + } + + if (m_header.m_sgd_byte_offset < sizeof(ktx2_header)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Supercompression global data offset is too low\n"); + return false; + } + + if (m_header.m_sgd_byte_offset + m_header.m_sgd_byte_length > m_data_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Supercompression global data offset and/or length is too high\n"); + return false; + } + } + + if (!m_levels.try_resize(m_header.m_level_count)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Out of memory\n"); + return false; + } + + const uint32_t level_index_size_in_bytes = basisu::maximum(1U, (uint32_t)m_header.m_level_count) * sizeof(ktx2_level_index); + + if ((sizeof(ktx2_header) + level_index_size_in_bytes) > m_data_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: File is too small (can't read level index array)\n"); + return false; + } + + memcpy(&m_levels[0], m_pData + sizeof(ktx2_header), level_index_size_in_bytes); + + // Sanity check the level offsets and byte sizes + for (uint32_t i = 0; i < m_levels.size(); i++) + { + if (m_levels[i].m_byte_offset < sizeof(ktx2_header)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid level offset (too low)\n"); + return false; + } + + if (!m_levels[i].m_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid level byte length\n"); + } + + if ((m_levels[i].m_byte_offset + m_levels[i].m_byte_length) > m_data_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid level offset and/or length\n"); + return false; + } + + const uint64_t MAX_SANE_LEVEL_UNCOMP_SIZE = 2048ULL * 1024ULL * 1024ULL; + + if (m_levels[i].m_uncompressed_byte_length >= MAX_SANE_LEVEL_UNCOMP_SIZE) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid level offset (too large)\n"); + return false; + } + + if (m_header.m_supercompression_scheme == KTX2_SS_BASISLZ) + { + if (m_levels[i].m_uncompressed_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid uncompressed length (0)\n"); + return false; + } + } + else if (m_header.m_supercompression_scheme >= KTX2_SS_ZSTANDARD) + { + if (!m_levels[i].m_uncompressed_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid uncompressed length (1)\n"); + return false; + } + } + } + + const uint32_t DFD_MINIMUM_SIZE = 44, DFD_MAXIMUM_SIZE = 60; + if ((m_header.m_dfd_byte_length != DFD_MINIMUM_SIZE) && (m_header.m_dfd_byte_length != DFD_MAXIMUM_SIZE)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Unsupported DFD size\n"); + return false; + } + + if (((m_header.m_dfd_byte_offset + m_header.m_dfd_byte_length) > m_data_size) || (m_header.m_dfd_byte_offset < sizeof(ktx2_header))) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid DFD offset and/or length\n"); + return false; + } + + const uint8_t* pDFD = m_pData + m_header.m_dfd_byte_offset; + + if (!m_dfd.try_resize(m_header.m_dfd_byte_length)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Out of memory\n"); + return false; + } + + memcpy(m_dfd.data(), pDFD, m_header.m_dfd_byte_length); + + // This is all hard coded for only ETC1S and UASTC. + uint32_t dfd_total_size = basisu::read_le_dword(pDFD); + + // 3.10.3: Sanity check + if (dfd_total_size != m_header.m_dfd_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: DFD size validation failed (1)\n"); + return false; + } + + // 3.10.3: More sanity checking + if (m_header.m_kvd_byte_length) + { + if (dfd_total_size != m_header.m_kvd_byte_offset - m_header.m_dfd_byte_offset) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: DFD size validation failed (2)\n"); + return false; + } + } + + const uint32_t dfd_bits = basisu::read_le_dword(pDFD + 3 * sizeof(uint32_t)); + const uint32_t sample_channel0 = basisu::read_le_dword(pDFD + 7 * sizeof(uint32_t)); + + m_dfd_color_model = dfd_bits & 255; + m_dfd_color_prims = (ktx2_df_color_primaries)((dfd_bits >> 8) & 255); + m_dfd_transfer_func = (dfd_bits >> 16) & 255; + m_dfd_flags = (dfd_bits >> 24) & 255; + + // See 3.10.1.Restrictions + if ((m_dfd_transfer_func != KTX2_KHR_DF_TRANSFER_LINEAR) && (m_dfd_transfer_func != KTX2_KHR_DF_TRANSFER_SRGB)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Invalid DFD transfer function\n"); + return false; + } + + if (m_dfd_color_model == KTX2_KDF_DF_MODEL_ETC1S) + { + m_format = basist::basis_tex_format::cETC1S; + + // 3.10.2: "Whether the image has 1 or 2 slices can be determined from the DFD’s sample count." + // If m_has_alpha is true it may be 2-channel RRRG or 4-channel RGBA, but we let the caller deal with that. + m_has_alpha = (m_header.m_dfd_byte_length == 60); + + m_dfd_samples = m_has_alpha ? 2 : 1; + m_dfd_chan0 = (ktx2_df_channel_id)((sample_channel0 >> 24) & 15); + + if (m_has_alpha) + { + const uint32_t sample_channel1 = basisu::read_le_dword(pDFD + 11 * sizeof(uint32_t)); + m_dfd_chan1 = (ktx2_df_channel_id)((sample_channel1 >> 24) & 15); + } + } + else if (m_dfd_color_model == KTX2_KDF_DF_MODEL_UASTC) + { + m_format = basist::basis_tex_format::cUASTC4x4; + + m_dfd_samples = 1; + m_dfd_chan0 = (ktx2_df_channel_id)((sample_channel0 >> 24) & 15); + + // We're assuming "DATA" means RGBA so it has alpha. + m_has_alpha = (m_dfd_chan0 == KTX2_DF_CHANNEL_UASTC_RGBA) || (m_dfd_chan0 == KTX2_DF_CHANNEL_UASTC_RRRG); + } + else + { + // Unsupported DFD color model. + BASISU_DEVEL_ERROR("ktx2_transcoder::init: Unsupported DFD color model\n"); + return false; + } + + if (!read_key_values()) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::init: read_key_values() failed\n"); + return false; + } + + // Check for a KTXanimData key + for (uint32_t i = 0; i < m_key_values.size(); i++) + { + if (strcmp(reinterpret_cast<const char*>(m_key_values[i].m_key.data()), "KTXanimData") == 0) + { + m_is_video = true; break; + } } - return 4; + + return true; } - uint32_t basis_get_block_height(transcoder_texture_format tex_type) + uint32_t ktx2_transcoder::get_etc1s_image_descs_image_flags(uint32_t level_index, uint32_t layer_index, uint32_t face_index) const { - (void)tex_type; - return 4; + const uint32_t etc1s_image_index = + (level_index * basisu::maximum<uint32_t>(m_header.m_layer_count, 1) * m_header.m_face_count) + + layer_index * m_header.m_face_count + + face_index; + + if (etc1s_image_index >= get_etc1s_image_descs().size()) + { + assert(0); + return 0; + } + + return get_etc1s_image_descs()[etc1s_image_index].m_image_flags; + } + + const basisu::uint8_vec* ktx2_transcoder::find_key(const std::string& key_name) const + { + for (uint32_t i = 0; i < m_key_values.size(); i++) + if (strcmp((const char *)m_key_values[i].m_key.data(), key_name.c_str()) == 0) + return &m_key_values[i].m_value; + + return nullptr; } - bool basis_is_format_supported(transcoder_texture_format tex_type) + bool ktx2_transcoder::start_transcoding() { - switch (tex_type) + if (!m_pData) { - // ETC1 and uncompressed are always supported. - case transcoder_texture_format::cTFETC1_RGB: - case transcoder_texture_format::cTFRGBA32: - case transcoder_texture_format::cTFRGB565: - case transcoder_texture_format::cTFBGR565: - case transcoder_texture_format::cTFRGBA4444: - return true; -#if BASISD_SUPPORT_DXT1 - case transcoder_texture_format::cTFBC1_RGB: - return true; -#endif -#if BASISD_SUPPORT_DXT5A - case transcoder_texture_format::cTFBC4_R: - case transcoder_texture_format::cTFBC5_RG: - return true; -#endif -#if BASISD_SUPPORT_DXT1 && BASISD_SUPPORT_DXT5A - case transcoder_texture_format::cTFBC3_RGBA: - return true; -#endif -#if BASISD_SUPPORT_PVRTC1 - case transcoder_texture_format::cTFPVRTC1_4_RGB: - case transcoder_texture_format::cTFPVRTC1_4_RGBA: - return true; -#endif -#if BASISD_SUPPORT_BC7_MODE6_OPAQUE_ONLY - case transcoder_texture_format::cTFBC7_M6_RGB: - return true; -#endif -#if BASISD_SUPPORT_BC7_MODE5 - case transcoder_texture_format::cTFBC7_M5_RGBA: - return true; -#endif -#if BASISD_SUPPORT_ETC2_EAC_A8 - case transcoder_texture_format::cTFETC2_RGBA: - return true; -#endif -#if BASISD_SUPPORT_ASTC - case transcoder_texture_format::cTFASTC_4x4_RGBA: - return true; -#endif -#if BASISD_SUPPORT_ATC - case transcoder_texture_format::cTFATC_RGB: - case transcoder_texture_format::cTFATC_RGBA: - return true; -#endif -#if BASISD_SUPPORT_FXT1 - case transcoder_texture_format::cTFFXT1_RGB: - return true; + BASISU_DEVEL_ERROR("ktx2_transcoder::start_transcoding: Must call init() first\n"); + return false; + } + + if (m_header.m_supercompression_scheme == KTX2_SS_BASISLZ) + { + // Check if we've already decompressed the ETC1S global data. If so don't unpack it again. + if (!m_etc1s_transcoder.get_endpoints().empty()) + return true; + + if (!decompress_etc1s_global_data()) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::start_transcoding: decompress_etc1s_global_data() failed\n"); + return false; + } + + if (!m_is_video) + { + // See if there are any P-frames. If so it must be a video, even if there wasn't a KTXanimData key. + // Video cannot be a cubemap, and it must be a texture array. + if ((m_header.m_face_count == 1) && (m_header.m_layer_count > 1)) + { + for (uint32_t i = 0; i < m_etc1s_image_descs.size(); i++) + { + if (m_etc1s_image_descs[i].m_image_flags & KTX2_IMAGE_IS_P_FRAME) + { + m_is_video = true; + break; + } + } + } + } + } + else if (m_header.m_supercompression_scheme == KTX2_SS_ZSTANDARD) + { +#if !BASISD_SUPPORT_KTX2_ZSTD + BASISU_DEVEL_ERROR("ktx2_transcoder::start_transcoding: File uses zstd supercompression, but zstd support was not enabled at compilation time (BASISD_SUPPORT_KTX2_ZSTD == 0)\n"); + return false; #endif -#if BASISD_SUPPORT_PVRTC2 - case transcoder_texture_format::cTFPVRTC2_4_RGB: - case transcoder_texture_format::cTFPVRTC2_4_RGBA: - return true; + } + + return true; + } + + bool ktx2_transcoder::get_image_level_info(ktx2_image_level_info& level_info, uint32_t level_index, uint32_t layer_index, uint32_t face_index) const + { + if (level_index >= m_levels.size()) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::get_image_level_info: level_index >= m_levels.size()\n"); + return false; + } + + if (m_header.m_face_count > 1) + { + if (face_index >= 6) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::get_image_level_info: face_index >= 6\n"); + return false; + } + } + else if (face_index != 0) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::get_image_level_info: face_index != 0\n"); + return false; + } + + if (layer_index >= basisu::maximum<uint32_t>(m_header.m_layer_count, 1)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::get_image_level_info: layer_index >= maximum<uint32_t>(m_header.m_layer_count, 1)\n"); + return false; + } + + const uint32_t level_width = basisu::maximum<uint32_t>(m_header.m_pixel_width >> level_index, 1); + const uint32_t level_height = basisu::maximum<uint32_t>(m_header.m_pixel_height >> level_index, 1); + const uint32_t num_blocks_x = (level_width + 3) >> 2; + const uint32_t num_blocks_y = (level_height + 3) >> 2; + + level_info.m_face_index = face_index; + level_info.m_layer_index = layer_index; + level_info.m_level_index = level_index; + level_info.m_orig_width = level_width; + level_info.m_orig_height = level_height; + level_info.m_width = num_blocks_x * 4; + level_info.m_height = num_blocks_y * 4; + level_info.m_num_blocks_x = num_blocks_x; + level_info.m_num_blocks_y = num_blocks_y; + level_info.m_total_blocks = num_blocks_x * num_blocks_y; + level_info.m_alpha_flag = m_has_alpha; + level_info.m_iframe_flag = false; + if (m_etc1s_image_descs.size()) + { + const uint32_t etc1s_image_index = + (level_index * basisu::maximum<uint32_t>(m_header.m_layer_count, 1) * m_header.m_face_count) + + layer_index * m_header.m_face_count + + face_index; + + level_info.m_iframe_flag = (m_etc1s_image_descs[etc1s_image_index].m_image_flags & KTX2_IMAGE_IS_P_FRAME) == 0; + } + + return true; + } + + bool ktx2_transcoder::transcode_image_level( + uint32_t level_index, uint32_t layer_index, uint32_t face_index, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + basist::transcoder_texture_format fmt, + uint32_t decode_flags, uint32_t output_row_pitch_in_blocks_or_pixels, uint32_t output_rows_in_pixels, int channel0, int channel1, + ktx2_transcoder_state* pState) + { + if (!m_pData) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: Must call init() first\n"); + return false; + } + + if (!pState) + pState = &m_def_transcoder_state; + + if (level_index >= m_levels.size()) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: level_index >= m_levels.size()\n"); + return false; + } + + if (m_header.m_face_count > 1) + { + if (face_index >= 6) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: face_index >= 6\n"); + return false; + } + } + else if (face_index != 0) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: face_index != 0\n"); + return false; + } + + if (layer_index >= basisu::maximum<uint32_t>(m_header.m_layer_count, 1)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: layer_index >= maximum<uint32_t>(m_header.m_layer_count, 1)\n"); + return false; + } + + const uint8_t* pComp_level_data = m_pData + m_levels[level_index].m_byte_offset; + uint64_t comp_level_data_size = m_levels[level_index].m_byte_length; + + const uint8_t* pUncomp_level_data = pComp_level_data; + uint64_t uncomp_level_data_size = comp_level_data_size; + + if (uncomp_level_data_size > UINT32_MAX) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: uncomp_level_data_size > UINT32_MAX\n"); + return false; + } + + if (m_header.m_supercompression_scheme == KTX2_SS_ZSTANDARD) + { + // Check if we've already decompressed this level's supercompressed data. + if ((int)level_index != pState->m_uncomp_data_level_index) + { + // Uncompress the entire level's supercompressed data. + if (!decompress_level_data(level_index, pState->m_level_uncomp_data)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: decompress_level_data() failed\n"); + return false; + } + pState->m_uncomp_data_level_index = level_index; + } + + pUncomp_level_data = pState->m_level_uncomp_data.data(); + uncomp_level_data_size = pState->m_level_uncomp_data.size(); + } + + const uint32_t level_width = basisu::maximum<uint32_t>(m_header.m_pixel_width >> level_index, 1); + const uint32_t level_height = basisu::maximum<uint32_t>(m_header.m_pixel_height >> level_index, 1); + const uint32_t num_blocks_x = (level_width + 3) >> 2; + const uint32_t num_blocks_y = (level_height + 3) >> 2; + + if (m_format == basist::basis_tex_format::cETC1S) + { + // Ensure start_transcoding() was called. + if (m_etc1s_transcoder.get_endpoints().empty()) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: must call start_transcoding() first\n"); + return false; + } + + const uint32_t etc1s_image_index = + (level_index * basisu::maximum<uint32_t>(m_header.m_layer_count, 1) * m_header.m_face_count) + + layer_index * m_header.m_face_count + + face_index; + + // Sanity check + if (etc1s_image_index >= m_etc1s_image_descs.size()) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: etc1s_image_index >= m_etc1s_image_descs.size()\n"); + assert(0); + return false; + } + + if (static_cast<uint32_t>(m_data_size) != m_data_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: File is too large\n"); + return false; + } + + const ktx2_etc1s_image_desc& image_desc = m_etc1s_image_descs[etc1s_image_index]; + + if (!m_etc1s_transcoder.transcode_image(fmt, + pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, m_pData, static_cast<uint32_t>(m_data_size), + num_blocks_x, num_blocks_y, level_width, level_height, + level_index, + m_levels[level_index].m_byte_offset + image_desc.m_rgb_slice_byte_offset, image_desc.m_rgb_slice_byte_length, + image_desc.m_alpha_slice_byte_length ? (m_levels[level_index].m_byte_offset + image_desc.m_alpha_slice_byte_offset) : 0, image_desc.m_alpha_slice_byte_length, + decode_flags, m_has_alpha, + m_is_video, output_row_pitch_in_blocks_or_pixels, &pState->m_transcoder_state, output_rows_in_pixels)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: ETC1S transcode_image() failed, this is either a bug or the file is corrupted/invalid\n"); + return false; + } + } + else if (m_format == basist::basis_tex_format::cUASTC4x4) + { + // Compute length and offset to uncompressed 2D UASTC texture data, given the face/layer indices. + assert(uncomp_level_data_size == m_levels[level_index].m_uncompressed_byte_length); + const uint32_t total_2D_image_size = num_blocks_x * num_blocks_y * KTX2_UASTC_BLOCK_SIZE; + + const uint32_t uncomp_ofs = (layer_index * m_header.m_face_count + face_index) * total_2D_image_size; + + // Sanity checks + if (uncomp_ofs >= uncomp_level_data_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: uncomp_ofs >= total_2D_image_size\n"); + return false; + } + + if ((uncomp_level_data_size - uncomp_ofs) < total_2D_image_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: (uncomp_level_data_size - uncomp_ofs) < total_2D_image_size\n"); + return false; + } + + if (!m_uastc_transcoder.transcode_image(fmt, + pOutput_blocks, output_blocks_buf_size_in_blocks_or_pixels, + (const uint8_t*)pUncomp_level_data + uncomp_ofs, (uint32_t)total_2D_image_size, num_blocks_x, num_blocks_y, level_width, level_height, level_index, + 0, (uint32_t)total_2D_image_size, + decode_flags, m_has_alpha, m_is_video, output_row_pitch_in_blocks_or_pixels, nullptr, output_rows_in_pixels, channel0, channel1)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: UASTC transcode_image() failed, this is either a bug or the file is corrupted/invalid\n"); + return false; + } + } + else + { + // Shouldn't get here. + BASISU_DEVEL_ERROR("ktx2_transcoder::transcode_image_2D: Internal error\n"); + assert(0); + return false; + } + + return true; + } + + bool ktx2_transcoder::decompress_level_data(uint32_t level_index, basisu::uint8_vec& uncomp_data) + { + const uint8_t* pComp_data = m_levels[level_index].m_byte_offset + m_pData; + const uint64_t comp_size = m_levels[level_index].m_byte_length; + + const uint64_t uncomp_size = m_levels[level_index].m_uncompressed_byte_length; + + if (((size_t)comp_size) != comp_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Compressed data too large\n"); + return false; + } + if (((size_t)uncomp_size) != uncomp_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Uncompressed data too large\n"); + return false; + } + + if (!uncomp_data.try_resize(uncomp_size)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Out of memory\n"); + return false; + } + + if (m_header.m_supercompression_scheme == KTX2_SS_ZSTANDARD) + { +#if BASISD_SUPPORT_KTX2_ZSTD + size_t actualUncompSize = ZSTD_decompress(uncomp_data.data(), (size_t)uncomp_size, pComp_data, (size_t)comp_size); + if (ZSTD_isError(actualUncompSize)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Zstd decompression failed, file is invalid or corrupted\n"); + return false; + } + if (actualUncompSize != uncomp_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: Zstd decompression returned too few bytes, file is invalid or corrupted\n"); + return false; + } +#else + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_level_data: File uses Zstd supercompression, but Zstd support was not enabled at compile time (BASISD_SUPPORT_KTX2_ZSTD is 0)\n"); + return false; #endif -#if BASISD_SUPPORT_ETC2_EAC_RG11 - case transcoder_texture_format::cTFETC2_EAC_R11: - case transcoder_texture_format::cTFETC2_EAC_RG11: + } + + return true; + } + + bool ktx2_transcoder::decompress_etc1s_global_data() + { + // Note: we don't actually support 3D textures in here yet + //uint32_t layer_pixel_depth = basisu::maximum<uint32_t>(m_header.m_pixel_depth, 1); + //for (uint32_t i = 1; i < m_header.m_level_count; i++) + // layer_pixel_depth += basisu::maximum<uint32_t>(m_header.m_pixel_depth >> i, 1); + + const uint32_t image_count = basisu::maximum<uint32_t>(m_header.m_layer_count, 1) * m_header.m_face_count * m_header.m_level_count; + assert(image_count); + + const uint8_t* pSrc = m_pData + m_header.m_sgd_byte_offset; + + memcpy(&m_etc1s_header, pSrc, sizeof(ktx2_etc1s_global_data_header)); + pSrc += sizeof(ktx2_etc1s_global_data_header); + + if ((!m_etc1s_header.m_endpoints_byte_length) || (!m_etc1s_header.m_selectors_byte_length) || (!m_etc1s_header.m_tables_byte_length)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: Invalid ETC1S global data\n"); + return false; + } + + if ((!m_etc1s_header.m_endpoint_count) || (!m_etc1s_header.m_selector_count)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: endpoint and/or selector count is 0, file is invalid or corrupted\n"); + return false; + } + + // Sanity check the ETC1S header. + if ((sizeof(ktx2_etc1s_global_data_header) + + sizeof(ktx2_etc1s_image_desc) * image_count + + m_etc1s_header.m_endpoints_byte_length + + m_etc1s_header.m_selectors_byte_length + + m_etc1s_header.m_tables_byte_length + + m_etc1s_header.m_extended_byte_length) > m_header.m_sgd_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: SGD byte length is too small, file is invalid or corrupted\n"); + return false; + } + + if (!m_etc1s_image_descs.try_resize(image_count)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: Out of memory\n"); + return false; + } + + memcpy(m_etc1s_image_descs.data(), pSrc, sizeof(ktx2_etc1s_image_desc) * image_count); + pSrc += sizeof(ktx2_etc1s_image_desc) * image_count; + + // Sanity check the ETC1S image descs + for (uint32_t i = 0; i < image_count; i++) + { + // m_etc1s_transcoder.transcode_image() will validate the slice offsets/lengths before transcoding. + + if (!m_etc1s_image_descs[i].m_rgb_slice_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: ETC1S image descs sanity check failed (1)\n"); + return false; + } + + if (m_has_alpha) + { + if (!m_etc1s_image_descs[i].m_alpha_slice_byte_length) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: ETC1S image descs sanity check failed (2)\n"); + return false; + } + } + } + + const uint8_t* pEndpoint_data = pSrc; + const uint8_t* pSelector_data = pSrc + m_etc1s_header.m_endpoints_byte_length; + const uint8_t* pTables_data = pSrc + m_etc1s_header.m_endpoints_byte_length + m_etc1s_header.m_selectors_byte_length; + + if (!m_etc1s_transcoder.decode_tables(pTables_data, m_etc1s_header.m_tables_byte_length)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: decode_tables() failed, file is invalid or corrupted\n"); + return false; + } + + if (!m_etc1s_transcoder.decode_palettes( + m_etc1s_header.m_endpoint_count, pEndpoint_data, m_etc1s_header.m_endpoints_byte_length, + m_etc1s_header.m_selector_count, pSelector_data, m_etc1s_header.m_selectors_byte_length)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::decompress_etc1s_global_data: decode_palettes() failed, file is likely corrupted\n"); + return false; + } + + return true; + } + + bool ktx2_transcoder::read_key_values() + { + if (!m_header.m_kvd_byte_length) + { + if (m_header.m_kvd_byte_offset) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Invalid KVD byte offset (it should be zero when the length is zero)\n"); + return false; + } + return true; -#endif - default: - break; } + if (m_header.m_kvd_byte_offset < sizeof(ktx2_header)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Invalid KVD byte offset\n"); + return false; + } + + if ((m_header.m_kvd_byte_offset + m_header.m_kvd_byte_length) > m_data_size) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Invalid KVD byte offset and/or length\n"); + return false; + } + + const uint8_t* pSrc = m_pData + m_header.m_kvd_byte_offset; + uint32_t src_left = m_header.m_kvd_byte_length; + + if (!m_key_values.try_reserve(8)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Out of memory\n"); + return false; + } + + while (src_left > sizeof(uint32_t)) + { + uint32_t l = basisu::read_le_dword(pSrc); + + pSrc += sizeof(uint32_t); + src_left -= sizeof(uint32_t); + + if (l < 2) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Failed reading key value fields (0)\n"); + return false; + } + + if (src_left < l) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Failed reading key value fields (1)\n"); + return false; + } + + if (!m_key_values.try_resize(m_key_values.size() + 1)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Out of memory\n"); + return false; + } + + basisu::uint8_vec& key_data = m_key_values.back().m_key; + basisu::uint8_vec& value_data = m_key_values.back().m_value; + + do + { + if (!l) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Failed reading key value fields (2)\n"); + return false; + } + + if (!key_data.try_push_back(*pSrc++)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Out of memory\n"); + return false; + } + + src_left--; + l--; + + } while (key_data.back()); + + if (!value_data.try_resize(l)) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Out of memory\n"); + return false; + } + + if (l) + { + memcpy(value_data.data(), pSrc, l); + pSrc += l; + src_left -= l; + } + + uint32_t ofs = (uint32_t)(pSrc - m_pData) & 3; + uint32_t alignment_bytes = (4 - ofs) & 3; + + if (src_left < alignment_bytes) + { + BASISU_DEVEL_ERROR("ktx2_transcoder::read_key_values: Failed reading key value fields (3)\n"); + return false; + } + + pSrc += alignment_bytes; + src_left -= alignment_bytes; + } + + return true; + } + +#endif // BASISD_SUPPORT_KTX2 + + bool basisu_transcoder_supports_ktx2() + { +#if BASISD_SUPPORT_KTX2 + return true; +#else return false; +#endif } -} // namespace basist + bool basisu_transcoder_supports_ktx2_zstd() + { +#if BASISD_SUPPORT_KTX2_ZSTD + return true; +#else + return false; +#endif + } +} // namespace basist diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.h b/thirdparty/basis_universal/transcoder/basisu_transcoder.h index 770c64122d..bf3aed3dc3 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder.h +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.h @@ -1,5 +1,5 @@ // basisu_transcoder.h -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // Important: If compiling with gcc, be sure strict aliasing is disabled: -fno-strict-aliasing // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,10 +15,25 @@ // limitations under the License. #pragma once -// Set BASISU_DEVEL_MESSAGES to 1 to enable debug printf()'s whenever an error occurs, for easier debugging during development. -//#define BASISU_DEVEL_MESSAGES 1 +// By default KTX2 support is enabled to simplify compilation. This implies the need for the Zstandard library (which we distribute as a single source file in the "zstd" directory) by default. +// Set BASISD_SUPPORT_KTX2 to 0 to completely disable KTX2 support as well as Zstd/miniz usage which is only required for UASTC supercompression in KTX2 files. +// Also see BASISD_SUPPORT_KTX2_ZSTD in basisu_transcoder.cpp, which individually disables Zstd usage. +#ifndef BASISD_SUPPORT_KTX2 + #define BASISD_SUPPORT_KTX2 1 +#endif + +// Set BASISD_SUPPORT_KTX2_ZSTD to 0 to disable Zstd usage and KTX2 UASTC Zstd supercompression support +#ifndef BASISD_SUPPORT_KTX2_ZSTD + #define BASISD_SUPPORT_KTX2_ZSTD 1 +#endif + +// Set BASISU_FORCE_DEVEL_MESSAGES to 1 to enable debug printf()'s whenever an error occurs, for easier debugging during development. +#ifndef BASISU_FORCE_DEVEL_MESSAGES + #define BASISU_FORCE_DEVEL_MESSAGES 0 +#endif #include "basisu_transcoder_internal.h" +#include "basisu_transcoder_uastc.h" #include "basisu_global_selector_palette.h" #include "basisu_file_headers.h" @@ -45,12 +60,11 @@ namespace basist cTFBC3_RGBA = 3, // Opaque+alpha, BC4 followed by a BC1 block, alpha channel will be opaque for opaque .basis files cTFBC4_R = 4, // Red only, alpha slice is transcoded to output if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified cTFBC5_RG = 5, // XY: Two BC4 blocks, X=R and Y=Alpha, .basis file should have alpha data (if not Y will be all 255's) - cTFBC7_M6_RGB = 6, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. Highest quality of all the non-ETC1 formats. - cTFBC7_M5_RGBA = 7, // Opaque+alpha, alpha channel will be opaque for opaque .basis files + cTFBC7_RGBA = 6, // RGB or RGBA, mode 5 for ETC1S, modes (1,2,3,5,6,7) for UASTC // PVRTC1 4bpp (mobile, PowerVR devices) cTFPVRTC1_4_RGB = 8, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified, nearly lowest quality of any texture format. - cTFPVRTC1_4_RGBA = 9, // Opaque+alpha, most useful for simple opacity maps. If .basis file doens't have alpha cTFPVRTC1_4_RGB will be used instead. Lowest quality of any supported texture format. + cTFPVRTC1_4_RGBA = 9, // Opaque+alpha, most useful for simple opacity maps. If .basis file doesn't have alpha cTFPVRTC1_4_RGB will be used instead. Lowest quality of any supported texture format. // ASTC (mobile, Intel devices, hopefully all desktop GPU's one day) cTFASTC_4x4_RGBA = 10, // Opaque+alpha, ASTC 4x4, alpha channel will be opaque for opaque .basis files. Transcoder uses RGB/RGBA/L/LA modes, void extent, and up to two ([0,47] and [0,255]) endpoint precisions. @@ -69,10 +83,10 @@ namespace basist cTFETC2_EAC_R11 = 20, // R only (ETC2 EAC R11 unsigned) cTFETC2_EAC_RG11 = 21, // RG only (ETC2 EAC RG11 unsigned), R=opaque.r, G=alpha - for tangent space normal maps - + // Uncompressed (raw pixel) formats cTFRGBA32 = 13, // 32bpp RGBA image stored in raster (not block) order in memory, R is first byte, A is last byte. - cTFRGB565 = 14, // 166pp RGB image stored in raster (not block) order in memory, R at bit position 11 + cTFRGB565 = 14, // 16bpp RGB image stored in raster (not block) order in memory, R at bit position 11 cTFBGR565 = 15, // 16bpp RGB image stored in raster (not block) order in memory, R at bit position 0 cTFRGBA4444 = 16, // 16bpp RGBA image stored in raster (not block) order in memory, R at bit position 12, A at bit position 0 @@ -85,27 +99,62 @@ namespace basist cTFBC3 = cTFBC3_RGBA, cTFBC4 = cTFBC4_R, cTFBC5 = cTFBC5_RG, - cTFBC7_M6_OPAQUE_ONLY = cTFBC7_M6_RGB, - cTFBC7_M5 = cTFBC7_M5_RGBA, + + // Previously, the caller had some control over which BC7 mode the transcoder output. We've simplified this due to UASTC, which supports numerous modes. + cTFBC7_M6_RGB = cTFBC7_RGBA, // Opaque only, RGB or alpha if cDecodeFlagsTranscodeAlphaDataToOpaqueFormats flag is specified. Highest quality of all the non-ETC1 formats. + cTFBC7_M5_RGBA = cTFBC7_RGBA, // Opaque+alpha, alpha channel will be opaque for opaque .basis files + cTFBC7_M6_OPAQUE_ONLY = cTFBC7_RGBA, + cTFBC7_M5 = cTFBC7_RGBA, + cTFBC7_ALT = 7, + cTFASTC_4x4 = cTFASTC_4x4_RGBA, + cTFATC_RGBA_INTERPOLATED_ALPHA = cTFATC_RGBA, }; - uint32_t basis_get_bytes_per_block(transcoder_texture_format fmt); + // For compressed texture formats, this returns the # of bytes per block. For uncompressed, it returns the # of bytes per pixel. + // NOTE: Previously, this function was called basis_get_bytes_per_block(), and it always returned 16*bytes_per_pixel for uncompressed formats which was confusing. + uint32_t basis_get_bytes_per_block_or_pixel(transcoder_texture_format fmt); + + // Returns format's name in ASCII const char* basis_get_format_name(transcoder_texture_format fmt); + + // Returns block format name in ASCII + const char* basis_get_block_format_name(block_format fmt); + + // Returns true if the format supports an alpha channel. bool basis_transcoder_format_has_alpha(transcoder_texture_format fmt); + + // Returns the basisu::texture_format corresponding to the specified transcoder_texture_format. basisu::texture_format basis_get_basisu_texture_format(transcoder_texture_format fmt); + + // Returns the texture type's name in ASCII. const char* basis_get_texture_type_name(basis_texture_type tex_type); - + + // Returns true if the transcoder texture type is an uncompressed (raw pixel) format. bool basis_transcoder_format_is_uncompressed(transcoder_texture_format tex_type); + + // Returns the # of bytes per pixel for uncompressed formats, or 0 for block texture formats. uint32_t basis_get_uncompressed_bytes_per_pixel(transcoder_texture_format fmt); - + + // Returns the block width for the specified texture format, which is currently either 4 or 8 for FXT1. uint32_t basis_get_block_width(transcoder_texture_format tex_type); + + // Returns the block height for the specified texture format, which is currently always 4. uint32_t basis_get_block_height(transcoder_texture_format tex_type); // Returns true if the specified format was enabled at compile time. - bool basis_is_format_supported(transcoder_texture_format tex_type); - + bool basis_is_format_supported(transcoder_texture_format tex_type, basis_tex_format fmt = basis_tex_format::cETC1S); + + // Validates that the output buffer is large enough to hold the entire transcoded texture. + // For uncompressed texture formats, most input parameters are in pixels, not blocks. Blocks are 4x4 pixels. + bool basis_validate_output_buffer_size(transcoder_texture_format target_format, + uint32_t output_blocks_buf_size_in_blocks_or_pixels, + uint32_t orig_width, uint32_t orig_height, + uint32_t output_row_pitch_in_blocks_or_pixels, + uint32_t output_rows_in_pixels, + uint32_t total_slice_blocks); + class basisu_transcoder; // This struct holds all state used during transcoding. For video, it needs to persist between image transcodes (it holds the previous frame). @@ -118,46 +167,161 @@ namespace basist uint8_t m_pred_bits; }; - std::vector<block_preds> m_block_endpoint_preds[2]; - + basisu::vector<block_preds> m_block_endpoint_preds[2]; + enum { cMaxPrevFrameLevels = 16 }; - std::vector<uint32_t> m_prev_frame_indices[2][cMaxPrevFrameLevels]; // [alpha_flag][level_index] + basisu::vector<uint32_t> m_prev_frame_indices[2][cMaxPrevFrameLevels]; // [alpha_flag][level_index] + + void clear() + { + for (uint32_t i = 0; i < 2; i++) + { + m_block_endpoint_preds[i].clear(); + + for (uint32_t j = 0; j < cMaxPrevFrameLevels; j++) + m_prev_frame_indices[i][j].clear(); + } + } }; - + // Low-level helper class that does the actual transcoding. - class basisu_lowlevel_transcoder + class basisu_lowlevel_etc1s_transcoder { friend class basisu_transcoder; - + public: - basisu_lowlevel_transcoder(const basist::etc1_global_selector_codebook *pGlobal_sel_codebook); + basisu_lowlevel_etc1s_transcoder(const basist::etc1_global_selector_codebook* pGlobal_sel_codebook); + + void set_global_codebooks(const basisu_lowlevel_etc1s_transcoder* pGlobal_codebook) { m_pGlobal_codebook = pGlobal_codebook; } + const basisu_lowlevel_etc1s_transcoder* get_global_codebooks() const { return m_pGlobal_codebook; } bool decode_palettes( - uint32_t num_endpoints, const uint8_t *pEndpoints_data, uint32_t endpoints_data_size, - uint32_t num_selectors, const uint8_t *pSelectors_data, uint32_t selectors_data_size); + uint32_t num_endpoints, const uint8_t* pEndpoints_data, uint32_t endpoints_data_size, + uint32_t num_selectors, const uint8_t* pSelectors_data, uint32_t selectors_data_size); + + bool decode_tables(const uint8_t* pTable_data, uint32_t table_data_size); + + bool transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const bool is_video, const bool is_alpha_slice, const uint32_t level_index, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + basisu_transcoder_state* pState = nullptr, bool astc_transcode_alpha = false, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0); + + bool transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + basisu_transcoder_state* pState = nullptr, bool astc_transcode_alpha = false, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0) + { + return transcode_slice(pDst_blocks, num_blocks_x, num_blocks_y, pImage_data, image_data_size, fmt, output_block_or_pixel_stride_in_bytes, bc1_allow_threecolor_blocks, + header.m_tex_type == cBASISTexTypeVideoFrames, (slice_desc.m_flags & cSliceDescFlagsHasAlpha) != 0, slice_desc.m_level_index, + slice_desc.m_orig_width, slice_desc.m_orig_height, output_row_pitch_in_blocks_or_pixels, pState, + astc_transcode_alpha, + pAlpha_blocks, + output_rows_in_pixels); + } + + // Container independent transcoding + bool transcode_image( + transcoder_texture_format target_format, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + const uint8_t* pCompressed_data, uint32_t compressed_data_length, + uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, + uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length, + uint32_t decode_flags = 0, + bool basis_file_has_alpha_slices = false, + bool is_video = false, + uint32_t output_row_pitch_in_blocks_or_pixels = 0, + basisu_transcoder_state* pState = nullptr, + uint32_t output_rows_in_pixels = 0); + + void clear() + { + m_local_endpoints.clear(); + m_local_selectors.clear(); + m_endpoint_pred_model.clear(); + m_delta_endpoint_model.clear(); + m_selector_model.clear(); + m_selector_history_buf_rle_model.clear(); + m_selector_history_buf_size = 0; + } - bool decode_tables(const uint8_t *pTable_data, uint32_t table_data_size); + // Low-level methods + typedef basisu::vector<endpoint> endpoint_vec; + const endpoint_vec& get_endpoints() const { return m_local_endpoints; } - bool transcode_slice(void *pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t *pImage_data, uint32_t image_data_size, block_format fmt, - uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header &header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, - basisu_transcoder_state *pState = nullptr, bool astc_transcode_alpha = false, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0); + typedef basisu::vector<selector> selector_vec; + const selector_vec& get_selectors() const { return m_local_selectors; } + + const etc1_global_selector_codebook* get_global_sel_codebook() const { return m_pGlobal_sel_codebook; } private: - typedef std::vector<endpoint> endpoint_vec; - endpoint_vec m_endpoints; + const basisu_lowlevel_etc1s_transcoder* m_pGlobal_codebook; - typedef std::vector<selector> selector_vec; - selector_vec m_selectors; + endpoint_vec m_local_endpoints; + selector_vec m_local_selectors; - const etc1_global_selector_codebook *m_pGlobal_sel_codebook; + const etc1_global_selector_codebook* m_pGlobal_sel_codebook; huffman_decoding_table m_endpoint_pred_model, m_delta_endpoint_model, m_selector_model, m_selector_history_buf_rle_model; uint32_t m_selector_history_buf_size; - + basisu_transcoder_state m_def_state; }; + enum basisu_decode_flags + { + // PVRTC1: decode non-pow2 ETC1S texture level to the next larger power of 2 (not implemented yet, but we're going to support it). Ignored if the slice's dimensions are already a power of 2. + cDecodeFlagsPVRTCDecodeToNextPow2 = 2, + + // When decoding to an opaque texture format, if the basis file has alpha, decode the alpha slice instead of the color slice to the output texture format. + // This is primarily to allow decoding of textures with alpha to multiple ETC1 textures (one for color, another for alpha). + cDecodeFlagsTranscodeAlphaDataToOpaqueFormats = 4, + + // Forbid usage of BC1 3 color blocks (we don't support BC1 punchthrough alpha yet). + // This flag is used internally when decoding to BC3. + cDecodeFlagsBC1ForbidThreeColorBlocks = 8, + + // The output buffer contains alpha endpoint/selector indices. + // Used internally when decoding formats like ASTC that require both color and alpha data to be available when transcoding to the output format. + cDecodeFlagsOutputHasAlphaIndices = 16, + + cDecodeFlagsHighQuality = 32 + }; + + class basisu_lowlevel_uastc_transcoder + { + friend class basisu_transcoder; + + public: + basisu_lowlevel_uastc_transcoder(); + + bool transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, bool has_alpha, const uint32_t orig_width, const uint32_t orig_height, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + basisu_transcoder_state* pState = nullptr, uint32_t output_rows_in_pixels = 0, int channel0 = -1, int channel1 = -1, uint32_t decode_flags = 0); + + bool transcode_slice(void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, const uint8_t* pImage_data, uint32_t image_data_size, block_format fmt, + uint32_t output_block_or_pixel_stride_in_bytes, bool bc1_allow_threecolor_blocks, const basis_file_header& header, const basis_slice_desc& slice_desc, uint32_t output_row_pitch_in_blocks_or_pixels = 0, + basisu_transcoder_state* pState = nullptr, uint32_t output_rows_in_pixels = 0, int channel0 = -1, int channel1 = -1, uint32_t decode_flags = 0) + { + return transcode_slice(pDst_blocks, num_blocks_x, num_blocks_y, pImage_data, image_data_size, fmt, + output_block_or_pixel_stride_in_bytes, bc1_allow_threecolor_blocks, (header.m_flags & cBASISHeaderFlagHasAlphaSlices) != 0, slice_desc.m_orig_width, slice_desc.m_orig_height, output_row_pitch_in_blocks_or_pixels, + pState, output_rows_in_pixels, channel0, channel1, decode_flags); + } + + // Container independent transcoding + bool transcode_image( + transcoder_texture_format target_format, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + const uint8_t* pCompressed_data, uint32_t compressed_data_length, + uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, + uint32_t slice_offset, uint32_t slice_length, + uint32_t decode_flags = 0, + bool has_alpha = false, + bool is_video = false, + uint32_t output_row_pitch_in_blocks_or_pixels = 0, + basisu_transcoder_state* pState = nullptr, + uint32_t output_rows_in_pixels = 0, + int channel0 = -1, int channel1 = -1); + }; + struct basisu_slice_info { uint32_t m_orig_width; @@ -175,19 +339,19 @@ namespace basist uint32_t m_slice_index; // the slice index in the .basis file uint32_t m_image_index; // the source image index originally provided to the encoder uint32_t m_level_index; // the mipmap level within this image - + uint32_t m_unpacked_slice_crc16; - + bool m_alpha_flag; // true if the slice has alpha data bool m_iframe_flag; // true if the slice is an I-Frame }; - typedef std::vector<basisu_slice_info> basisu_slice_info_vec; + typedef basisu::vector<basisu_slice_info> basisu_slice_info_vec; struct basisu_image_info { uint32_t m_image_index; - uint32_t m_total_levels; + uint32_t m_total_levels; uint32_t m_orig_width; uint32_t m_orig_height; @@ -199,8 +363,8 @@ namespace basist uint32_t m_num_blocks_y; uint32_t m_total_blocks; - uint32_t m_first_slice_index; - + uint32_t m_first_slice_index; + bool m_alpha_flag; // true if the image has alpha data bool m_iframe_flag; // true if the image is an I-Frame }; @@ -220,8 +384,13 @@ namespace basist uint32_t m_num_blocks_y; uint32_t m_total_blocks; - uint32_t m_first_slice_index; - + uint32_t m_first_slice_index; + + uint32_t m_rgb_file_ofs; + uint32_t m_rgb_file_len; + uint32_t m_alpha_file_ofs; + uint32_t m_alpha_file_len; + bool m_alpha_flag; // true if the image has alpha data bool m_iframe_flag; // true if the image is an I-Frame }; @@ -232,13 +401,19 @@ namespace basist uint32_t m_total_header_size; uint32_t m_total_selectors; + // will be 0 for UASTC or if the file uses global codebooks + uint32_t m_selector_codebook_ofs; uint32_t m_selector_codebook_size; uint32_t m_total_endpoints; + // will be 0 for UASTC or if the file uses global codebooks + uint32_t m_endpoint_codebook_ofs; uint32_t m_endpoint_codebook_size; + uint32_t m_tables_ofs; uint32_t m_tables_size; - uint32_t m_slices_size; + + uint32_t m_slices_size; basis_texture_type m_tex_type; uint32_t m_us_per_frame; @@ -247,14 +422,16 @@ namespace basist basisu_slice_info_vec m_slice_info; uint32_t m_total_images; // total # of images - std::vector<uint32_t> m_image_mipmap_levels; // the # of mipmap levels for each image + basisu::vector<uint32_t> m_image_mipmap_levels; // the # of mipmap levels for each image uint32_t m_userdata0; uint32_t m_userdata1; - - bool m_etc1s; // always true for basis universal + + basis_tex_format m_tex_format; // ETC1S, UASTC, etc. + bool m_y_flipped; // true if the image was Y flipped - bool m_has_alpha_slices; // true if the texture has alpha slices (even slices RGB, odd slices alpha) + bool m_etc1s; // true if the file is ETC1S + bool m_has_alpha_slices; // true if the texture has alpha slices (for ETC1S: even slices RGB, odd slices alpha) }; // High-level transcoder class which accepts .basis file data and allows the caller to query information about the file and transcode image levels to various texture formats. @@ -265,81 +442,67 @@ namespace basist basisu_transcoder& operator= (const basisu_transcoder&); public: - basisu_transcoder(const etc1_global_selector_codebook *pGlobal_sel_codebook); + basisu_transcoder(const etc1_global_selector_codebook* pGlobal_sel_codebook); // Validates the .basis file. This computes a crc16 over the entire file, so it's slow. - bool validate_file_checksums(const void *pData, uint32_t data_size, bool full_validation) const; + bool validate_file_checksums(const void* pData, uint32_t data_size, bool full_validation) const; // Quick header validation - no crc16 checks. - bool validate_header(const void *pData, uint32_t data_size) const; + bool validate_header(const void* pData, uint32_t data_size) const; + + basis_texture_type get_texture_type(const void* pData, uint32_t data_size) const; + bool get_userdata(const void* pData, uint32_t data_size, uint32_t& userdata0, uint32_t& userdata1) const; - basis_texture_type get_texture_type(const void *pData, uint32_t data_size) const; - bool get_userdata(const void *pData, uint32_t data_size, uint32_t &userdata0, uint32_t &userdata1) const; - // Returns the total number of images in the basis file (always 1 or more). // Note that the number of mipmap levels for each image may differ, and that images may have different resolutions. - uint32_t get_total_images(const void *pData, uint32_t data_size) const; + uint32_t get_total_images(const void* pData, uint32_t data_size) const; + + basis_tex_format get_tex_format(const void* pData, uint32_t data_size) const; // Returns the number of mipmap levels in an image. - uint32_t get_total_image_levels(const void *pData, uint32_t data_size, uint32_t image_index) const; - + uint32_t get_total_image_levels(const void* pData, uint32_t data_size, uint32_t image_index) const; + // Returns basic information about an image. Note that orig_width/orig_height may not be a multiple of 4. - bool get_image_level_desc(const void *pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, uint32_t &orig_width, uint32_t &orig_height, uint32_t &total_blocks) const; + bool get_image_level_desc(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, uint32_t& orig_width, uint32_t& orig_height, uint32_t& total_blocks) const; // Returns information about the specified image. - bool get_image_info(const void *pData, uint32_t data_size, basisu_image_info &image_info, uint32_t image_index) const; + bool get_image_info(const void* pData, uint32_t data_size, basisu_image_info& image_info, uint32_t image_index) const; // Returns information about the specified image's mipmap level. - bool get_image_level_info(const void *pData, uint32_t data_size, basisu_image_level_info &level_info, uint32_t image_index, uint32_t level_index) const; - + bool get_image_level_info(const void* pData, uint32_t data_size, basisu_image_level_info& level_info, uint32_t image_index, uint32_t level_index) const; + // Get a description of the basis file and low-level information about each slice. - bool get_file_info(const void *pData, uint32_t data_size, basisu_file_info &file_info) const; - + bool get_file_info(const void* pData, uint32_t data_size, basisu_file_info& file_info) const; + // start_transcoding() must be called before calling transcode_slice() or transcode_image_level(). - // This decompresses the selector/endpoint codebooks, so ideally you would only call this once per .basis file (not each image/mipmap level). - bool start_transcoding(const void *pData, uint32_t data_size) const; - + // For ETC1S files, this call decompresses the selector/endpoint codebooks, so ideally you would only call this once per .basis file (not each image/mipmap level). + bool start_transcoding(const void* pData, uint32_t data_size); + + bool stop_transcoding(); + // Returns true if start_transcoding() has been called. - bool get_ready_to_transcode() const { return m_lowlevel_decoder.m_endpoints.size() > 0; } + bool get_ready_to_transcode() const { return m_ready_to_transcode; } - enum - { - // PVRTC1: decode non-pow2 ETC1S texture level to the next larger power of 2 (not implemented yet, but we're going to support it). Ignored if the slice's dimensions are already a power of 2. - cDecodeFlagsPVRTCDecodeToNextPow2 = 2, - - // When decoding to an opaque texture format, if the basis file has alpha, decode the alpha slice instead of the color slice to the output texture format. - // This is primarily to allow decoding of textures with alpha to multiple ETC1 textures (one for color, another for alpha). - cDecodeFlagsTranscodeAlphaDataToOpaqueFormats = 4, - - // Forbid usage of BC1 3 color blocks (we don't support BC1 punchthrough alpha yet). - // This flag is used internally when decoding to BC3. - cDecodeFlagsBC1ForbidThreeColorBlocks = 8, - - // The output buffer contains alpha endpoint/selector indices. - // Used internally when decoding formats like ASTC that require both color and alpha data to be available when transcoding to the output format. - cDecodeFlagsOutputHasAlphaIndices = 16 - }; - // transcode_image_level() decodes a single mipmap level from the .basis file to any of the supported output texture formats. // It'll first find the slice(s) to transcode, then call transcode_slice() one or two times to decode both the color and alpha texture data (or RG texture data from two slices for BC5). // If the .basis file doesn't have alpha slices, the output alpha blocks will be set to fully opaque (all 255's). // Currently, to decode to PVRTC1 the basis texture's dimensions in pixels must be a power of 2, due to PVRTC1 format requirements. // output_blocks_buf_size_in_blocks_or_pixels should be at least the image level's total_blocks (num_blocks_x * num_blocks_y), or the total number of output pixels if fmt==cTFRGBA32. // output_row_pitch_in_blocks_or_pixels: Number of blocks or pixels per row. If 0, the transcoder uses the slice's num_blocks_x or orig_width (NOT num_blocks_x * 4). Ignored for PVRTC1 (due to texture swizzling). - // output_rows_in_pixels: Ignored unless fmt is cRGBA32. The total number of output rows in the output buffer. If 0, the transcoder assumes the slice's orig_height (NOT num_blocks_y * 4). + // output_rows_in_pixels: Ignored unless fmt is uncompressed (cRGBA32, etc.). The total number of output rows in the output buffer. If 0, the transcoder assumes the slice's orig_height (NOT num_blocks_y * 4). // Notes: // - basisu_transcoder_init() must have been called first to initialize the transcoder lookup tables before calling this function. // - This method assumes the output texture buffer is readable. In some cases to handle alpha, the transcoder will write temporary data to the output texture in // a first pass, which will be read in a second pass. bool transcode_image_level( - const void *pData, uint32_t data_size, - uint32_t image_index, uint32_t level_index, - void *pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + const void* pData, uint32_t data_size, + uint32_t image_index, uint32_t level_index, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, transcoder_texture_format fmt, - uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state *pState = nullptr, uint32_t output_rows_in_pixels = 0) const; + uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state* pState = nullptr, uint32_t output_rows_in_pixels = 0) const; // Finds the basis slice corresponding to the specified image/level/alpha params, or -1 if the slice can't be found. - int find_slice(const void *pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, bool alpha_data) const; + int find_slice(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index, bool alpha_data) const; // transcode_slice() decodes a single slice from the .basis file. It's a low-level API - most likely you want to use transcode_image_level(). // This is a low-level API, and will be needed to be called multiple times to decode some texture formats (like BC3, BC5, or ETC2). @@ -350,21 +513,39 @@ namespace basist // output_rows_in_pixels: Ignored unless fmt is cRGBA32. The total number of output rows in the output buffer. If 0, the transcoder assumes the slice's orig_height (NOT num_blocks_y * 4). // Notes: // - basisu_transcoder_init() must have been called first to initialize the transcoder lookup tables before calling this function. - bool transcode_slice(const void *pData, uint32_t data_size, uint32_t slice_index, - void *pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, - block_format fmt, uint32_t output_block_stride_in_bytes, uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state * pState = nullptr, void* pAlpha_blocks = nullptr, uint32_t output_rows_in_pixels = 0) const; + bool transcode_slice(const void* pData, uint32_t data_size, uint32_t slice_index, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + block_format fmt, uint32_t output_block_stride_in_bytes, uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, basisu_transcoder_state* pState = nullptr, void* pAlpha_blocks = nullptr, + uint32_t output_rows_in_pixels = 0, int channel0 = -1, int channel1 = -1) const; + + static void write_opaque_alpha_blocks( + uint32_t num_blocks_x, uint32_t num_blocks_y, + void* pOutput_blocks, block_format fmt, + uint32_t block_stride_in_bytes, uint32_t output_row_pitch_in_blocks_or_pixels); + + void set_global_codebooks(const basisu_lowlevel_etc1s_transcoder* pGlobal_codebook) { m_lowlevel_etc1s_decoder.set_global_codebooks(pGlobal_codebook); } + const basisu_lowlevel_etc1s_transcoder* get_global_codebooks() const { return m_lowlevel_etc1s_decoder.get_global_codebooks(); } + + const basisu_lowlevel_etc1s_transcoder& get_lowlevel_etc1s_decoder() const { return m_lowlevel_etc1s_decoder; } + basisu_lowlevel_etc1s_transcoder& get_lowlevel_etc1s_decoder() { return m_lowlevel_etc1s_decoder; } + + const basisu_lowlevel_uastc_transcoder& get_lowlevel_uastc_decoder() const { return m_lowlevel_uastc_decoder; } + basisu_lowlevel_uastc_transcoder& get_lowlevel_uastc_decoder() { return m_lowlevel_uastc_decoder; } private: - mutable basisu_lowlevel_transcoder m_lowlevel_decoder; + mutable basisu_lowlevel_etc1s_transcoder m_lowlevel_etc1s_decoder; + mutable basisu_lowlevel_uastc_transcoder m_lowlevel_uastc_decoder; + + bool m_ready_to_transcode; int find_first_slice_index(const void* pData, uint32_t data_size, uint32_t image_index, uint32_t level_index) const; - + bool validate_header_quick(const void* pData, uint32_t data_size) const; }; - // basisu_transcoder_init() must be called before a .basis file can be transcoded. + // basisu_transcoder_init() MUST be called before a .basis file can be transcoded. void basisu_transcoder_init(); - + enum debug_flags_t { cDebugFlagVisCRs = 1, @@ -374,4 +555,387 @@ namespace basist uint32_t get_debug_flags(); void set_debug_flags(uint32_t f); + // ------------------------------------------------------------------------------------------------------ + // Optional .KTX2 file format support + // KTX2 reading optionally requires miniz or Zstd decompressors for supercompressed UASTC files. + // ------------------------------------------------------------------------------------------------------ +#if BASISD_SUPPORT_KTX2 +#pragma pack(push) +#pragma pack(1) + struct ktx2_header + { + uint8_t m_identifier[12]; + basisu::packed_uint<4> m_vk_format; + basisu::packed_uint<4> m_type_size; + basisu::packed_uint<4> m_pixel_width; + basisu::packed_uint<4> m_pixel_height; + basisu::packed_uint<4> m_pixel_depth; + basisu::packed_uint<4> m_layer_count; + basisu::packed_uint<4> m_face_count; + basisu::packed_uint<4> m_level_count; + basisu::packed_uint<4> m_supercompression_scheme; + basisu::packed_uint<4> m_dfd_byte_offset; + basisu::packed_uint<4> m_dfd_byte_length; + basisu::packed_uint<4> m_kvd_byte_offset; + basisu::packed_uint<4> m_kvd_byte_length; + basisu::packed_uint<8> m_sgd_byte_offset; + basisu::packed_uint<8> m_sgd_byte_length; + }; + + struct ktx2_level_index + { + basisu::packed_uint<8> m_byte_offset; + basisu::packed_uint<8> m_byte_length; + basisu::packed_uint<8> m_uncompressed_byte_length; + }; + + struct ktx2_etc1s_global_data_header + { + basisu::packed_uint<2> m_endpoint_count; + basisu::packed_uint<2> m_selector_count; + basisu::packed_uint<4> m_endpoints_byte_length; + basisu::packed_uint<4> m_selectors_byte_length; + basisu::packed_uint<4> m_tables_byte_length; + basisu::packed_uint<4> m_extended_byte_length; + }; + + struct ktx2_etc1s_image_desc + { + basisu::packed_uint<4> m_image_flags; + basisu::packed_uint<4> m_rgb_slice_byte_offset; + basisu::packed_uint<4> m_rgb_slice_byte_length; + basisu::packed_uint<4> m_alpha_slice_byte_offset; + basisu::packed_uint<4> m_alpha_slice_byte_length; + }; + + struct ktx2_animdata + { + basisu::packed_uint<4> m_duration; + basisu::packed_uint<4> m_timescale; + basisu::packed_uint<4> m_loopcount; + }; +#pragma pack(pop) + + const uint32_t KTX2_VK_FORMAT_UNDEFINED = 0; + const uint32_t KTX2_KDF_DF_MODEL_UASTC = 166; + const uint32_t KTX2_KDF_DF_MODEL_ETC1S = 163; + const uint32_t KTX2_IMAGE_IS_P_FRAME = 2; + const uint32_t KTX2_UASTC_BLOCK_SIZE = 16; + const uint32_t KTX2_MAX_SUPPORTED_LEVEL_COUNT = 16; // this is an implementation specific constraint and can be increased + + // The KTX2 transfer functions supported by KTX2 + const uint32_t KTX2_KHR_DF_TRANSFER_LINEAR = 1; + const uint32_t KTX2_KHR_DF_TRANSFER_SRGB = 2; + + enum ktx2_supercompression + { + KTX2_SS_NONE = 0, + KTX2_SS_BASISLZ = 1, + KTX2_SS_ZSTANDARD = 2 + }; + + extern const uint8_t g_ktx2_file_identifier[12]; + + enum ktx2_df_channel_id + { + KTX2_DF_CHANNEL_ETC1S_RGB = 0U, + KTX2_DF_CHANNEL_ETC1S_RRR = 3U, + KTX2_DF_CHANNEL_ETC1S_GGG = 4U, + KTX2_DF_CHANNEL_ETC1S_AAA = 15U, + + KTX2_DF_CHANNEL_UASTC_DATA = 0U, + KTX2_DF_CHANNEL_UASTC_RGB = 0U, + KTX2_DF_CHANNEL_UASTC_RGBA = 3U, + KTX2_DF_CHANNEL_UASTC_RRR = 4U, + KTX2_DF_CHANNEL_UASTC_RRRG = 5U, + KTX2_DF_CHANNEL_UASTC_RG = 6U, + }; + + inline const char* ktx2_get_etc1s_df_channel_id_str(ktx2_df_channel_id id) + { + switch (id) + { + case KTX2_DF_CHANNEL_ETC1S_RGB: return "RGB"; + case KTX2_DF_CHANNEL_ETC1S_RRR: return "RRR"; + case KTX2_DF_CHANNEL_ETC1S_GGG: return "GGG"; + case KTX2_DF_CHANNEL_ETC1S_AAA: return "AAA"; + default: break; + } + return "?"; + } + + inline const char* ktx2_get_uastc_df_channel_id_str(ktx2_df_channel_id id) + { + switch (id) + { + case KTX2_DF_CHANNEL_UASTC_RGB: return "RGB"; + case KTX2_DF_CHANNEL_UASTC_RGBA: return "RGBA"; + case KTX2_DF_CHANNEL_UASTC_RRR: return "RRR"; + case KTX2_DF_CHANNEL_UASTC_RRRG: return "RRRG"; + case KTX2_DF_CHANNEL_UASTC_RG: return "RG"; + default: break; + } + return "?"; + } + + enum ktx2_df_color_primaries + { + KTX2_DF_PRIMARIES_UNSPECIFIED = 0, + KTX2_DF_PRIMARIES_BT709 = 1, + KTX2_DF_PRIMARIES_SRGB = 1, + KTX2_DF_PRIMARIES_BT601_EBU = 2, + KTX2_DF_PRIMARIES_BT601_SMPTE = 3, + KTX2_DF_PRIMARIES_BT2020 = 4, + KTX2_DF_PRIMARIES_CIEXYZ = 5, + KTX2_DF_PRIMARIES_ACES = 6, + KTX2_DF_PRIMARIES_ACESCC = 7, + KTX2_DF_PRIMARIES_NTSC1953 = 8, + KTX2_DF_PRIMARIES_PAL525 = 9, + KTX2_DF_PRIMARIES_DISPLAYP3 = 10, + KTX2_DF_PRIMARIES_ADOBERGB = 11 + }; + + inline const char* ktx2_get_df_color_primaries_str(ktx2_df_color_primaries p) + { + switch (p) + { + case KTX2_DF_PRIMARIES_UNSPECIFIED: return "UNSPECIFIED"; + case KTX2_DF_PRIMARIES_BT709: return "BT709"; + case KTX2_DF_PRIMARIES_BT601_EBU: return "EBU"; + case KTX2_DF_PRIMARIES_BT601_SMPTE: return "SMPTE"; + case KTX2_DF_PRIMARIES_BT2020: return "BT2020"; + case KTX2_DF_PRIMARIES_CIEXYZ: return "CIEXYZ"; + case KTX2_DF_PRIMARIES_ACES: return "ACES"; + case KTX2_DF_PRIMARIES_ACESCC: return "ACESCC"; + case KTX2_DF_PRIMARIES_NTSC1953: return "NTSC1953"; + case KTX2_DF_PRIMARIES_PAL525: return "PAL525"; + case KTX2_DF_PRIMARIES_DISPLAYP3: return "DISPLAYP3"; + case KTX2_DF_PRIMARIES_ADOBERGB: return "ADOBERGB"; + default: break; + } + return "?"; + } + + // Information about a single 2D texture "image" in a KTX2 file. + struct ktx2_image_level_info + { + // The mipmap level index (0=largest), texture array layer index, and cubemap face index of the image. + uint32_t m_level_index; + uint32_t m_layer_index; + uint32_t m_face_index; + + // The image's actual (or the original source image's) width/height in pixels, which may not be divisible by 4 pixels. + uint32_t m_orig_width; + uint32_t m_orig_height; + + // The image's physical width/height, which will always be divisible by 4 pixels. + uint32_t m_width; + uint32_t m_height; + + // The texture's dimensions in 4x4 texel blocks. + uint32_t m_num_blocks_x; + uint32_t m_num_blocks_y; + + // The total number of blocks + uint32_t m_total_blocks; + + // true if the image has alpha data + bool m_alpha_flag; + + // true if the image is an I-Frame. Currently, for ETC1S textures, the first frame will always be an I-Frame, and subsequent frames will always be P-Frames. + bool m_iframe_flag; + }; + + // Thread-specific ETC1S/supercompressed UASTC transcoder state. (If you're not doing multithreading transcoding you can ignore this.) + struct ktx2_transcoder_state + { + basist::basisu_transcoder_state m_transcoder_state; + basisu::uint8_vec m_level_uncomp_data; + int m_uncomp_data_level_index; + + void clear() + { + m_transcoder_state.clear(); + m_level_uncomp_data.clear(); + m_uncomp_data_level_index = -1; + } + }; + + // This class is quite similar to basisu_transcoder. It treats KTX2 files as a simple container for ETC1S/UASTC texture data. + // It does not support 1D or 3D textures. + // It only supports 2D and cubemap textures, with or without mipmaps, texture arrays of 2D/cubemap textures, and texture video files. + // It only supports raw non-supercompressed UASTC, ETC1S, UASTC+Zstd, or UASTC+zlib compressed files. + // DFD (Data Format Descriptor) parsing is purposely as simple as possible. + // If you need to know how to interpret the texture channels you'll need to parse the DFD yourself after calling get_dfd(). + class ktx2_transcoder + { + public: + ktx2_transcoder(basist::etc1_global_selector_codebook* pGlobal_sel_codebook); + + // Frees all allocations, resets object. + void clear(); + + // init() parses the KTX2 header, level index array, DFD, and key values, but nothing else. + // Importantly, it does not parse or decompress the ETC1S global supercompressed data, so some things (like which frames are I/P-Frames) won't be available until start_transcoding() is called. + // This method holds a pointer to the file data until clear() is called. + bool init(const void* pData, uint32_t data_size); + + // Returns the data/size passed to init(). + const uint8_t* get_data() const { return m_pData; } + uint32_t get_data_size() const { return m_data_size; } + + // Returns the KTX2 header. Valid after init(). + const ktx2_header& get_header() const { return m_header; } + + // Returns the KTX2 level index array. There will be one entry for each mipmap level. Valid after init(). + const basisu::vector<ktx2_level_index>& get_level_index() const { return m_levels; } + + // Returns the texture's width in texels. Always non-zero, might not be divisible by 4. Valid after init(). + uint32_t get_width() const { return m_header.m_pixel_width; } + + // Returns the texture's height in texels. Always non-zero, might not be divisible by 4. Valid after init(). + uint32_t get_height() const { return m_header.m_pixel_height; } + + // Returns the texture's number of mipmap levels. Always returns 1 or higher. Valid after init(). + uint32_t get_levels() const { return m_header.m_level_count; } + + // Returns the number of faces. Returns 1 for 2D textures and or 6 for cubemaps. Valid after init(). + uint32_t get_faces() const { return m_header.m_face_count; } + + // Returns 0 or the number of layers in the texture array or texture video. Valid after init(). + uint32_t get_layers() const { return m_header.m_layer_count; } + + // Returns cETC1S or cUASTC4x4. Valid after init(). + basist::basis_tex_format get_format() const { return m_format; } + + bool is_etc1s() const { return get_format() == basist::basis_tex_format::cETC1S; } + + bool is_uastc() const { return get_format() == basist::basis_tex_format::cUASTC4x4; } + + // Returns true if the ETC1S file has two planes (typically RGBA, or RRRG), or true if the UASTC file has alpha data. Valid after init(). + uint32_t get_has_alpha() const { return m_has_alpha; } + + // Returns the entire Data Format Descriptor (DFD) from the KTX2 file. Valid after init(). + // See https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#_the_khronos_data_format_descriptor_overview + const basisu::uint8_vec& get_dfd() const { return m_dfd; } + + // Some basic DFD accessors. Valid after init(). + uint32_t get_dfd_color_model() const { return m_dfd_color_model; } + + // Returns the DFD color primary. + // We do not validate the color primaries, so the returned value may not be in the ktx2_df_color_primaries enum. + ktx2_df_color_primaries get_dfd_color_primaries() const { return m_dfd_color_prims; } + + // Returns KTX2_KHR_DF_TRANSFER_LINEAR or KTX2_KHR_DF_TRANSFER_SRGB. + uint32_t get_dfd_transfer_func() const { return m_dfd_transfer_func; } + + uint32_t get_dfd_flags() const { return m_dfd_flags; } + + // Returns 1 (ETC1S/UASTC) or 2 (ETC1S with an internal alpha channel). + uint32_t get_dfd_total_samples() const { return m_dfd_samples; } + + // Returns the channel mapping for each DFD "sample". UASTC always has 1 sample, ETC1S can have one or two. + // Note the returned value SHOULD be one of the ktx2_df_channel_id enums, but we don't validate that. + // It's up to the caller to decide what to do if the value isn't in the enum. + ktx2_df_channel_id get_dfd_channel_id0() const { return m_dfd_chan0; } + ktx2_df_channel_id get_dfd_channel_id1() const { return m_dfd_chan1; } + + // Key value field data. + struct key_value + { + // The key field is UTF8 and always zero terminated. + basisu::uint8_vec m_key; + + // The value may be empty. It consists of raw bytes which may or may not be zero terminated. + basisu::uint8_vec m_value; + + bool operator< (const key_value& rhs) const { return strcmp((const char*)m_key.data(), (const char *)rhs.m_key.data()) < 0; } + }; + typedef basisu::vector<key_value> key_value_vec; + + // Returns the array of key-value entries. This may be empty. Valid after init(). + // The order of key values fields in this array exactly matches the order they were stored in the file. The keys are supposed to be sorted by their Unicode code points. + const key_value_vec& get_key_values() const { return m_key_values; } + + const basisu::uint8_vec *find_key(const std::string& key_name) const; + + // Low-level ETC1S specific accessors + + // Returns the ETC1S global supercompression data header, which is only valid after start_transcoding() is called. + const ktx2_etc1s_global_data_header& get_etc1s_header() const { return m_etc1s_header; } + + // Returns the array of ETC1S image descriptors, which is only valid after get_etc1s_image_descs() is called. + const basisu::vector<ktx2_etc1s_image_desc>& get_etc1s_image_descs() const { return m_etc1s_image_descs; } + + // Must have called startTranscoding() first + uint32_t get_etc1s_image_descs_image_flags(uint32_t level_index, uint32_t layer_index, uint32_t face_index) const; + + // is_video() is only valid after start_transcoding() is called. + // For ETC1S data, if this returns true you must currently transcode the file from first to last frame, in order, without skipping any frames. + bool is_video() const { return m_is_video; } + + // start_transcoding() MUST be called before calling transcode_image(). + // This method decompresses the ETC1S global endpoint/selector codebooks, which is not free, so try to avoid calling it excessively. + bool start_transcoding(); + + // get_image_level_info() be called after init(), but the m_iframe_flag's won't be valid until start_transcoding() is called. + // You can call this method before calling transcode_image_level() to retrieve basic information about the mipmap level's dimensions, etc. + bool get_image_level_info(ktx2_image_level_info& level_info, uint32_t level_index, uint32_t layer_index, uint32_t face_index) const; + + // transcode_image_level() transcodes a single 2D texture or cubemap face from the KTX2 file. + // Internally it uses the same low-level transcode API's as basisu_transcoder::transcode_image_level(). + // If the file is UASTC and is supercompressed with Zstandard, and the file is a texture array or cubemap, it's highly recommended that each mipmap level is + // completely transcoded before switching to another level. Every time the mipmap level is changed all supercompressed level data must be decompressed using Zstandard as a single unit. + // Currently ETC1S videos must always be transcoded from first to last frame (or KTX2 "layer"), in order, with no skipping of frames. + // By default this method is not thread safe unless you specify a pointer to a user allocated thread-specific transcoder_state struct. + bool transcode_image_level( + uint32_t level_index, uint32_t layer_index, uint32_t face_index, + void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, + basist::transcoder_texture_format fmt, + uint32_t decode_flags = 0, uint32_t output_row_pitch_in_blocks_or_pixels = 0, uint32_t output_rows_in_pixels = 0, int channel0 = -1, int channel1 = -1, + ktx2_transcoder_state *pState = nullptr); + + private: + const uint8_t* m_pData; + uint32_t m_data_size; + + ktx2_header m_header; + basisu::vector<ktx2_level_index> m_levels; + basisu::uint8_vec m_dfd; + key_value_vec m_key_values; + + ktx2_etc1s_global_data_header m_etc1s_header; + basisu::vector<ktx2_etc1s_image_desc> m_etc1s_image_descs; + + basist::basis_tex_format m_format; + + uint32_t m_dfd_color_model; + ktx2_df_color_primaries m_dfd_color_prims; + uint32_t m_dfd_transfer_func; + uint32_t m_dfd_flags; + uint32_t m_dfd_samples; + ktx2_df_channel_id m_dfd_chan0, m_dfd_chan1; + + basist::basisu_lowlevel_etc1s_transcoder m_etc1s_transcoder; + basist::basisu_lowlevel_uastc_transcoder m_uastc_transcoder; + + ktx2_transcoder_state m_def_transcoder_state; + + bool m_has_alpha; + bool m_is_video; + + bool decompress_level_data(uint32_t level_index, basisu::uint8_vec& uncomp_data); + bool decompress_etc1s_global_data(); + bool read_key_values(); + }; + +#endif // BASISD_SUPPORT_KTX2 + + // Returns true if the transcoder was compiled with KTX2 support. + bool basisu_transcoder_supports_ktx2(); + + // Returns true if the transcoder was compiled with Zstandard support. + bool basisu_transcoder_supports_ktx2_zstd(); + } // namespace basisu + diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h b/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h index a9c6823d92..2422d788a9 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_internal.h @@ -1,5 +1,5 @@ // basisu_transcoder_internal.h - Universal texture format transcoder library. -// Copyright (C) 2019 Binomial LLC. All Rights Reserved. +// Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved. // // Important: If compiling with gcc, be sure strict aliasing is disabled: -fno-strict-aliasing // @@ -20,8 +20,8 @@ #pragma warning (disable: 4127) // conditional expression is constant #endif -#define BASISD_LIB_VERSION 107 -#define BASISD_VERSION_STRING "01.11" +#define BASISD_LIB_VERSION 115 +#define BASISD_VERSION_STRING "01.15" #ifdef _DEBUG #define BASISD_BUILD_DEBUG @@ -45,38 +45,44 @@ namespace basist enum class block_format { cETC1, // ETC1S RGB + cETC2_RGBA, // full ETC2 EAC RGBA8 block cBC1, // DXT1 RGB + cBC3, // BC4 block followed by a four color BC1 block cBC4, // DXT5A (alpha block only) + cBC5, // two BC4 blocks cPVRTC1_4_RGB, // opaque-only PVRTC1 4bpp cPVRTC1_4_RGBA, // PVRTC1 4bpp RGBA - cBC7_M6_OPAQUE_ONLY, // RGB BC7 mode 6 + cBC7, // Full BC7 block, any mode cBC7_M5_COLOR, // RGB BC7 mode 5 color (writes an opaque mode 5 block) cBC7_M5_ALPHA, // alpha portion of BC7 mode 5 (cBC7_M5_COLOR output data must have been written to the output buffer first to set the mode/rot fields etc.) cETC2_EAC_A8, // alpha block of ETC2 EAC (first 8 bytes of the 16-bit ETC2 EAC RGBA format) cASTC_4x4, // ASTC 4x4 (either color-only or color+alpha). Note that the transcoder always currently assumes sRGB is not enabled when outputting ASTC // data. If you use a sRGB ASTC format you'll get ~1 LSB of additional error, because of the different way ASTC decoders scale 8-bit endpoints to 16-bits during unpacking. + cATC_RGB, cATC_RGBA_INTERPOLATED_ALPHA, cFXT1_RGB, // Opaque-only, has oddball 8x4 pixel block size + + cPVRTC2_4_RGB, + cPVRTC2_4_RGBA, + + cETC2_EAC_R11, + cETC2_EAC_RG11, cIndices, // Used internally: Write 16-bit endpoint and selector indices directly to output (output block must be at least 32-bits) cRGB32, // Writes RGB components to 32bpp output pixels cRGBA32, // Writes RGB255 components to 32bpp output pixels cA32, // Writes alpha component to 32bpp output pixels - + cRGB565, cBGR565, cRGBA4444_COLOR, cRGBA4444_ALPHA, cRGBA4444_COLOR_OPAQUE, - - cPVRTC2_4_RGB, - cPVRTC2_4_RGBA, - - cETC2_EAC_R11, - + cRGBA4444, + cTotalBlockFormats }; @@ -116,7 +122,7 @@ namespace basist basisu::clear_vector(m_tree); } - bool init(uint32_t total_syms, const uint8_t *pCode_sizes) + bool init(uint32_t total_syms, const uint8_t *pCode_sizes, uint32_t fast_lookup_bits = basisu::cHuffmanFastLookupBits) { if (!total_syms) { @@ -127,8 +133,10 @@ namespace basist m_code_sizes.resize(total_syms); memcpy(&m_code_sizes[0], pCode_sizes, total_syms); + const uint32_t huffman_fast_lookup_size = 1 << fast_lookup_bits; + m_lookup.resize(0); - m_lookup.resize(basisu::cHuffmanFastLookupSize); + m_lookup.resize(huffman_fast_lookup_size); m_tree.resize(0); m_tree.resize(total_syms * 2); @@ -166,10 +174,10 @@ namespace basist for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); - if (code_size <= basisu::cHuffmanFastLookupBits) + if (code_size <= fast_lookup_bits) { uint32_t k = (code_size << 16) | sym_index; - while (rev_code < basisu::cHuffmanFastLookupSize) + while (rev_code < huffman_fast_lookup_size) { if (m_lookup[rev_code] != 0) { @@ -184,9 +192,9 @@ namespace basist } int tree_cur; - if (0 == (tree_cur = m_lookup[rev_code & (basisu::cHuffmanFastLookupSize - 1)])) + if (0 == (tree_cur = m_lookup[rev_code & (huffman_fast_lookup_size - 1)])) { - const uint32_t idx = rev_code & (basisu::cHuffmanFastLookupSize - 1); + const uint32_t idx = rev_code & (huffman_fast_lookup_size - 1); if (m_lookup[idx] != 0) { // Supplied codesizes can't create a valid prefix code. @@ -204,9 +212,9 @@ namespace basist return false; } - rev_code >>= (basisu::cHuffmanFastLookupBits - 1); + rev_code >>= (fast_lookup_bits - 1); - for (int j = code_size; j > (basisu::cHuffmanFastLookupBits + 1); j--) + for (int j = code_size; j > ((int)fast_lookup_bits + 1); j--) { tree_cur -= ((rev_code >>= 1) & 1); @@ -254,6 +262,8 @@ namespace basist } const basisu::uint8_vec &get_code_sizes() const { return m_code_sizes; } + const basisu::int_vec get_lookup() const { return m_lookup; } + const basisu::int16_vec get_tree() const { return m_tree; } bool is_valid() const { return m_code_sizes.size() > 0; } @@ -430,9 +440,11 @@ namespace basist return v; } - inline uint32_t decode_huffman(const huffman_decoding_table &ct) + inline uint32_t decode_huffman(const huffman_decoding_table &ct, int fast_lookup_bits = basisu::cHuffmanFastLookupBits) { assert(ct.m_code_sizes.size()); + + const uint32_t huffman_fast_lookup_size = 1 << fast_lookup_bits; while (m_bit_buf_size < 16) { @@ -448,14 +460,14 @@ namespace basist int code_len; int sym; - if ((sym = ct.m_lookup[m_bit_buf & (basisu::cHuffmanFastLookupSize - 1)]) >= 0) + if ((sym = ct.m_lookup[m_bit_buf & (huffman_fast_lookup_size - 1)]) >= 0) { code_len = sym >> 16; sym &= 0xFFFF; } else { - code_len = basisu::cHuffmanFastLookupBits; + code_len = fast_lookup_bits; do { sym = ct.m_tree[~sym + ((m_bit_buf >> code_len++) & 1)]; // ~sym = -sym - 1 @@ -635,6 +647,11 @@ namespace basist return (uint8_t)((i & 0xFFFFFF00U) ? (~(i >> 31)) : i); } + enum eNoClamp + { + cNoClamp = 0 + }; + struct color32 { union @@ -655,21 +672,33 @@ namespace basist color32() { } color32(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { set(vr, vg, vb, va); } + color32(eNoClamp unused, uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { (void)unused; set_noclamp_rgba(vr, vg, vb, va); } void set(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { c[0] = static_cast<uint8_t>(vr); c[1] = static_cast<uint8_t>(vg); c[2] = static_cast<uint8_t>(vb); c[3] = static_cast<uint8_t>(va); } + void set_noclamp_rgb(uint32_t vr, uint32_t vg, uint32_t vb) { c[0] = static_cast<uint8_t>(vr); c[1] = static_cast<uint8_t>(vg); c[2] = static_cast<uint8_t>(vb); } + void set_noclamp_rgba(uint32_t vr, uint32_t vg, uint32_t vb, uint32_t va) { set(vr, vg, vb, va); } + void set_clamped(int vr, int vg, int vb, int va) { c[0] = clamp255(vr); c[1] = clamp255(vg); c[2] = clamp255(vb); c[3] = clamp255(va); } uint8_t operator[] (uint32_t idx) const { assert(idx < 4); return c[idx]; } uint8_t &operator[] (uint32_t idx) { assert(idx < 4); return c[idx]; } bool operator== (const color32&rhs) const { return m == rhs.m; } + + static color32 comp_min(const color32& a, const color32& b) { return color32(cNoClamp, basisu::minimum(a[0], b[0]), basisu::minimum(a[1], b[1]), basisu::minimum(a[2], b[2]), basisu::minimum(a[3], b[3])); } + static color32 comp_max(const color32& a, const color32& b) { return color32(cNoClamp, basisu::maximum(a[0], b[0]), basisu::maximum(a[1], b[1]), basisu::maximum(a[2], b[2]), basisu::maximum(a[3], b[3])); } }; struct endpoint { color32 m_color5; uint8_t m_inten5; + bool operator== (const endpoint& rhs) const + { + return (m_color5.r == rhs.m_color5.r) && (m_color5.g == rhs.m_color5.g) && (m_color5.b == rhs.m_color5.b) && (m_inten5 == rhs.m_inten5); + } + bool operator!= (const endpoint& rhs) const { return !(*this == rhs); } }; struct selector @@ -682,6 +711,17 @@ namespace basist uint8_t m_lo_selector, m_hi_selector; uint8_t m_num_unique_selectors; + bool operator== (const selector& rhs) const + { + return (m_selectors[0] == rhs.m_selectors[0]) && + (m_selectors[1] == rhs.m_selectors[1]) && + (m_selectors[2] == rhs.m_selectors[2]) && + (m_selectors[3] == rhs.m_selectors[3]); + } + bool operator!= (const selector& rhs) const + { + return !(*this == rhs); + } void init_flags() { diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc.inc index 7f38f4a863..cd634c0df5 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc.inc @@ -478,4 +478,4 @@ {31,1,10801},{47,1,12162},{14,1,6117},{14,1,6117},{8,1,50},{20,1,7322},{0,1,1241},{21,1,914},{21,1,914},{21,1,914},{7,1,274},{35,5,1513},{9,1,585},{9,1,585},{26,1,0},{27,1,1513},{26,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{0,1,0},{1,1,0},{0,1,0},{47,0,9250},{47,0,9250},{47,0,9250},{47,0,9250},{12,1,3690}, {12,1,3690},{12,1,3690},{8,1,50},{0,1,1241},{0,1,1241},{45,1,65535},{14,1,33274},{42,1,19608},{42,1,13375},{47,1,62627},{42,1,22211},{10,1,6045},{24,1,138},{36,1,39015},{0,1,1732},{35,1,1048},{5,1,766},{5,1,666},{37,1,212},{3,3,1473},{7,1,675},{23,1,410},{14,1,1},{3,3,1473},{14,1,1},{13,1,14121},{13,1,14121},{13,1,14121},{45,1,10571},{45,1,11434},{30,1,6081},{30,1,6081}, {40,1,137},{36,1,6926},{2,1,1445},{5,1,666},{5,1,666},{5,1,666},{37,1,212},{35,3,1105},{23,1,410},{23,1,410},{14,1,1},{25,1,1105},{14,1,1},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{1,1,0},{0,1,0},{1,1,0},{0,1,0},{15,0,9256},{15,0,9256},{15,0,9256},{15,0,9256},{14,1,3985},{14,1,3985},{14,1,3985},{40,1,137},{2,1,1445}, -{2,1,1445},
\ No newline at end of file +{2,1,1445}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc_0_255.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc_0_255.inc index 5e7a75396d..da4e7fee98 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc_0_255.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_astc_0_255.inc @@ -478,4 +478,4 @@ {137,255,10742},{135,255,12066},{107,255,6089},{107,255,6089},{67,255,45},{37,255,7233},{1,255,1184},{218,255,900},{218,255,900},{218,255,900},{204,255,272},{255,167,1513},{189,255,562},{189,255,562},{86,255,0},{253,213,1513},{86,255,0},{255,252,0},{255,254,0},{254,255,0},{252,255,0},{255,252,0},{255,254,0},{252,255,0},{0,255,0},{255,254,0},{0,255,0},{132,0,9248},{132,0,9248},{132,0,9248},{132,0,9248},{98,255,3656}, {98,255,3656},{98,255,3656},{67,255,45},{1,255,1184},{1,255,1184},{138,255,65535},{107,255,33448},{95,255,19729},{89,255,13446},{135,255,62717},{95,255,22307},{79,255,6021},{73,255,105},{40,255,38959},{0,254,1627},{230,255,996},{224,255,756},{221,255,653},{213,255,194},{255,204,1473},{207,255,675},{198,255,405},{110,255,0},{255,230,1473},{110,255,0},{162,255,14060},{162,255,14060},{162,255,14060},{146,255,10545},{141,255,11378},{116,255,6077},{116,255,6077}, {76,255,137},{40,255,6873},{7,255,1412},{221,255,653},{221,255,653},{221,255,653},{213,255,194},{255,180,1105},{198,255,405},{198,255,405},{110,255,0},{255,218,1105},{110,255,0},{255,252,0},{255,254,0},{254,255,0},{252,255,0},{255,252,0},{255,254,0},{252,255,0},{0,255,0},{255,254,0},{0,255,0},{140,0,9248},{140,0,9248},{140,0,9248},{140,0,9248},{107,255,3929},{107,255,3929},{107,255,3929},{76,255,137},{7,255,1412}, -{7,255,1412},
\ No newline at end of file +{7,255,1412}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_55.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_55.inc index 61f7476efc..7acedd6a6f 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_55.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_55.inc @@ -478,4 +478,4 @@ {17,31,11312},{16,31,11037},{13,31,6429},{13,31,6429},{8,31,260},{6,31,10457},{0,31,2642},{26,31,872},{26,31,872},{26,31,872},{25,31,397},{31,22,1513},{23,31,794},{23,31,794},{13,31,1},{29,27,1513},{13,31,1},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{0,31,0},{31,31,0},{0,31,0},{16,0,9248},{16,0,9248},{16,0,9248},{16,0,9248},{12,31,3074}, {12,31,3074},{12,31,3074},{8,31,260},{0,31,2642},{0,31,2642},{17,31,58848},{15,31,39619},{13,31,24975},{12,31,19007},{16,31,54474},{13,31,27057},{10,31,8569},{9,31,461},{8,31,51302},{0,31,5046},{28,31,979},{27,31,806},{27,31,637},{26,31,292},{31,26,1473},{26,31,953},{24,31,605},{16,31,0},{29,29,1473},{16,31,0},{19,31,13604},{19,31,13604},{19,31,13604},{18,31,11057},{16,31,10429},{14,31,6339},{14,31,6339}, {10,31,424},{8,31,9713},{1,31,2900},{27,31,637},{27,31,637},{27,31,637},{26,31,292},{30,25,1105},{24,31,605},{24,31,605},{16,31,0},{30,27,1105},{16,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{0,31,0},{31,31,0},{0,31,0},{17,0,9248},{17,0,9248},{17,0,9248},{17,0,9248},{12,31,3330},{12,31,3330},{12,31,3330},{10,31,424},{1,31,2900}, -{1,31,2900},
\ No newline at end of file +{1,31,2900}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_56.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_56.inc index f57a232a85..2b56c0944c 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_56.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_atc_56.inc @@ -478,4 +478,4 @@ {17,63,11312},{16,63,11037},{13,63,6429},{13,63,6429},{8,63,260},{6,63,10457},{0,63,2642},{26,63,872},{26,63,872},{26,63,872},{25,63,397},{31,45,1513},{23,63,794},{23,63,794},{13,63,1},{31,52,1513},{13,63,1},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{0,63,0},{31,63,0},{0,63,0},{16,0,9248},{16,0,9248},{16,0,9248},{16,0,9248},{12,63,3074}, {12,63,3074},{12,63,3074},{8,63,260},{0,63,2642},{0,63,2642},{17,63,58848},{15,63,39619},{13,63,24975},{12,63,19007},{16,63,54474},{13,63,27057},{10,63,8569},{9,63,461},{8,63,51302},{0,63,5046},{28,63,979},{27,63,806},{27,63,637},{26,63,292},{30,56,1473},{26,63,953},{24,63,605},{16,63,0},{30,58,1473},{16,63,0},{19,63,13604},{19,63,13604},{19,63,13604},{18,63,11057},{16,63,10429},{14,63,6339},{14,63,6339}, {10,63,424},{8,63,9713},{1,63,2900},{27,63,637},{27,63,637},{27,63,637},{26,63,292},{31,48,1105},{24,63,605},{24,63,605},{16,63,0},{31,54,1105},{16,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{31,63,0},{0,63,0},{31,63,0},{0,63,0},{17,0,9248},{17,0,9248},{17,0,9248},{17,0,9248},{12,63,3330},{12,63,3330},{12,63,3330},{10,63,424},{1,63,2900}, -{1,63,2900},
\ No newline at end of file +{1,63,2900}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc index 433b126a71..6669852923 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc @@ -46,4 +46,4 @@ {76,0,3},{255,1,27},{255,7,24},{255,1,27},{179,39,8},{255,22,16},{85,0,3},{255,2,27},{255,22,24},{255,7,27},{187,47,8},{255,47,16},{93,0,3},{255,4,27},{251,100,28},{182,0,7},{195,55,8},{255,71,16},{101,0,3},{255,4,27},{253,108,28},{191,0,7},{203,63,8},{255,95,16},{109,0,3},{255,7,27},{255,118,28},{200,0,7},{212,72,8},{255,123,16},{118,0,3},{246,0,7}, {255,129,28},{209,0,7},{220,80,8},{255,147,16},{126,0,3},{246,0,7},{255,138,28},{218,0,7},{228,88,8},{255,172,16},{134,0,3},{249,3,7},{245,91,8},{228,3,7},{236,96,8},{255,196,16},{142,6,3},{251,14,7},{250,102,8},{237,12,7},{245,105,8},{255,223,16},{151,15,3},{253,22,7},{254,112,8},{245,20,7},{253,113,8},{255,248,16},{159,23,3},{253,31,7},{255,124,8},{249,28,7}, {255,124,8},{255,0,0},{167,31,3},{254,39,7},{255,10,4},{252,37,7},{255,10,4},{255,0,0},{175,39,3},{255,48,7},{255,38,4},{254,48,7},{255,38,4},{255,0,0},{184,48,3},{255,56,7},{255,62,4},{255,56,7},{255,62,4},{255,0,0},{192,56,3},{255,65,7},{255,86,4},{255,65,7},{255,86,4},{255,0,0},{200,64,3},{255,74,7},{255,111,4},{255,77,7},{255,111,4},{255,0,0}, -{208,5,2},
\ No newline at end of file +{208,5,2}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_color.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_color.inc index 357b14b7a1..c0780988d8 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m5_color.inc @@ -478,4 +478,4 @@ {70,127,10779},{68,127,12146},{54,127,6176},{54,127,6176},{34,127,52},{14,127,7281},{2,127,1213},{109,127,937},{109,127,937},{109,127,937},{102,127,281},{127,84,1513},{93,127,565},{93,127,565},{43,127,0},{127,106,1513},{43,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{0,127,0},{127,127,0},{0,127,0},{65,0,9250},{65,0,9250},{65,0,9250},{65,0,9250},{49,127,3656}, {49,127,3656},{49,127,3656},{34,127,52},{2,127,1213},{2,127,1213},{71,127,63180},{60,127,37225},{52,127,26137},{48,127,18128},{68,127,59595},{51,127,22636},{42,127,8480},{37,127,164},{22,127,37455},{0,126,2073},{114,127,1019},{111,127,766},{111,127,666},{105,127,205},{127,102,1473},{102,127,681},{99,127,405},{56,127,0},{127,115,1473},{56,127,0},{79,127,14066},{79,127,14066},{79,127,14066},{73,127,10571},{71,127,11450},{59,127,6166},{59,127,6166}, {37,127,148},{25,127,6914},{5,127,1413},{111,127,666},{111,127,666},{111,127,666},{105,127,205},{127,90,1105},{99,127,405},{99,127,405},{56,127,0},{127,109,1105},{56,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{127,127,0},{0,127,0},{127,127,0},{0,127,0},{69,0,9250},{69,0,9250},{69,0,9250},{69,0,9250},{52,127,3940},{52,127,3940},{52,127,3940},{37,127,148},{5,127,1413}, -{5,127,1413},
\ No newline at end of file +{5,127,1413}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m6.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m6.inc deleted file mode 100644 index 6b814e6132..0000000000 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_bc7_m6.inc +++ /dev/null @@ -1,4383 +0,0 @@ -// Copyright (C) 2017-2019 Binomial LLC. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -static const uint32_t g_etc1_to_bc7_m6_table0[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x80000,0x80000,0x1,0x40000,0x40000,0x40000,0x80000,0x80000,0x1,0x80000,0x80000,0x1,0x1,0x40000,0x40000,0x40000,0x80000,0x80000,0x1,0x80000,0x80000,0x1,0x1,0x80000, -0x80000,0x1,0x1,0x1,0x40000,0x40000,0x40000,0x40000,0x40000,0x80000,0x80000,0x80000,0x40000,0x40000,0x80000,0x1,0x80000,0x100000,0x180000,0x2C0000,0x6000001,0x180000,0x2C0000,0x6000001,0x2C0000,0x6000001,0x6000001,0x180000,0x2C0000,0x6000001,0x2C0000,0x6000001, -0x6000001,0x2C0000,0x6000001,0x6000001,0x6000001,0x180000,0x2C0000,0x6000001,0x2C0000,0x6000001,0x6000001,0x2C0000,0x6000001,0x6000001,0x6000001,0x2C0000,0x6000001,0x6000001,0x6000001,0x6000001,0x140000,0x100000,0x100000,0x180000,0x240000,0x440000,0x6000001,0x6000001,0x140000,0x1C0000,0xD40000,0x6000001, -0x200000,0x4002C,0x16000004,0xA000005,0x6000005,0xE000012,0x8000005,0x6000001,0x6000012,0x400000A,0x4000012,0x8000023,0x600000D,0x6000005,0x6000016,0x400000E,0x4000016,0x4000023,0x4000013,0x400001B,0x2000023,0x4002C,0x6000011,0x6000009,0x600001A,0x4000012,0x400001A,0x2040027,0x4000017,0x200001F,0x2000024,0x8002C, -0x400001C,0x2000022,0x2000027,0x200002C,0x1600000B,0x48000012,0x78000004,0xE00000C,0xA000009,0x600000C,0x6000009,0x4000011,0x1000000F,0xA000012,0x4000013,0x200001F,0x8002C,0x80024,0x12040004,0xA040004,0x6000005,0xE000012,0x8000005,0x6000001,0x6000012,0x400000A,0x4000012,0x80023,0x600000D,0x6000005,0x6000016,0x400000E, -0x4000016,0xC0023,0x4000013,0x400001B,0x2000023,0x80023,0x600000D,0x6000005,0x6000016,0x400000E,0x4000016,0xC0023,0x4000013,0x400001B,0x2000023,0xC0023,0x4000013,0x400001B,0x2000023,0x2000023,0x1600000B,0x48000012,0x5A040004,0xE00000C,0xA000009,0x600000C,0x6000009,0x4000011,0x1000000E,0xA000011,0x4000013,0x400001B, -0xC0023,0x4,0x4,0x4,0x4,0x4000000,0x4000000,0x4000000,0x2000000,0x2000000,0x1,0x2000002,0x2000002,0x2000002,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2000003,0x2000003,0x2000003,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x3, -0x3,0x3,0x3,0x3,0x4000001,0x18000000,0x4,0x2000001,0x4000001,0x1,0x1,0x1,0x2000001,0x4000001,0x2,0x2,0x3,0x4,0x4,0x4,0x4,0x4000000,0x4000000,0x4000000,0x2000000,0x2000000,0x1,0x2000002,0x2000002,0x2000002,0x1,0x1, -0x1,0x2,0x2,0x2,0x2,0x2000002,0x2000002,0x2000002,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x4000001,0x18000000,0x4,0x2000001,0x4000001,0x1,0x1,0x1,0x2000001,0x4000001,0x2,0x2, -0x2,0x80014,0x12040000,0xA040000,0x6040001,0x20C0012,0x8000005,0x6000001,0x180012,0x400000A,0x4000012,0x20C0012,0x8000005,0x6000001,0x180012,0x400000A,0x4000012,0x180012,0x400000A,0x4000012,0x4000012,0x20C0012,0x8000005,0x6000001,0x180012,0x400000A,0x4000012,0x180012,0x400000A,0x4000012,0x4000012,0x180012, -0x400000A,0x4000012,0x4000012,0x4000012,0x1C000008,0xC080012,0x5A040000,0xA040008,0xA000005,0x6000008,0x6000005,0x600000A,0x14000008,0xC000008,0x6000005,0x4000012,0x140012,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table1[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x100000,0x100000,0x100000,0x100000,0x100000, -0x100000,0x200000,0x200000,0x200000,0x4000001,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x200000,0x200000,0x200000,0x4000001,0x200000,0x200000,0x200000,0x4000001,0x4000001,0xC0000,0xC0000,0xC0000,0x20C0000,0x40C0000,0x100000,0x100000,0x140000,0x20C0000,0x40C0000,0x180000,0x200000, -0x180000,0x140000,0x140000,0x140000,0x140000,0x1C0000,0x1C0000,0x1C0000,0x380000,0x380000,0x8000001,0x1C0000,0x1C0000,0x1C0000,0x380000,0x380000,0x8000001,0x380000,0x380000,0x8000001,0x8000001,0x1C0000,0x1C0000,0x1C0000,0x380000,0x380000,0x8000001,0x380000,0x380000,0x8000001,0x8000001,0x380000, -0x380000,0x8000001,0x8000001,0x8000001,0x180000,0x2140000,0x140000,0x2180000,0x200000,0x280000,0x2C0000,0x440000,0x180000,0x1C0000,0x280000,0x8000001,0x280000,0x200000,0x300000,0x5C0000,0xE000001,0x300000,0x5C0000,0xE000001,0x5C0000,0xE000001,0xE000001,0x300000,0x5C0000,0xE000001,0x5C0000,0xE000001, -0xE000001,0x5C0000,0xE000001,0xE000001,0xE000001,0x300000,0x5C0000,0xE000001,0x5C0000,0xE000001,0xE000001,0x5C0000,0xE000001,0xE000001,0xE000001,0x5C0000,0xE000001,0xE000001,0xE000001,0xE000001,0x280000,0x8200000,0x8200000,0x340000,0x4C0000,0x940000,0xE000001,0xE000001,0x2C0000,0x3C0000,0x1D40000,0xE000001, -0x400000,0x100088,0x220C0034,0x140C0034,0xE0C0035,0x1E080026,0x14080015,0xE080019,0x10080026,0xE040016,0xC040026,0x20000033,0x16000009,0x1004000F,0x12000012,0xE000002,0xC000016,0x10000033,0xE000011,0xA00001B,0xA000033,0x180088,0x1200003D,0xE000034,0x12000036,0xE00001B,0xC000026,0xC00004B,0xC000023,0xA00002B,0xA000043,0x2C0088, -0xA000054,0xA00004C,0x800005F,0x600008C,0x48000002,0x8C080026,0x9E0C0034,0x26000001,0x18000002,0x12000002,0x10000002,0xE000002,0x3200000E,0x1E000005,0x1000000B,0xA00002B,0x200088,0x140034,0x1E100008,0x12100009,0xE100009,0x1A0C0012,0x120C0001,0x100C0001,0x100C0012,0xE0C0005,0xC0C0012,0x200033,0x14040009,0xE080009,0x12000012,0xE000002, -0xC040012,0x3C0033,0xE000011,0xA00001B,0xA000033,0x200033,0x14040009,0xE080009,0x12000012,0xE000002,0xC040012,0x3C0033,0xE000011,0xA00001B,0xA000033,0x3C0033,0xE000011,0xA00001B,0xA000033,0xA000033,0x44040001,0x6E0C0012,0x80100008,0x20040001,0x18000002,0x12000002,0xE040002,0xE000002,0x32000005,0x1E000001,0x1000000A,0xA00001B, -0x2C0033,0xC0034,0xC0034,0xC0034,0xC0034,0x14080014,0x14080014,0x14080014,0xC080014,0xC080014,0x8040015,0x16000008,0x16000008,0x16000008,0xE000001,0xE000001,0xA000005,0xA00000A,0xA00000A,0x8000001,0x600000A,0x20C0033,0x20C0033,0x20C0033,0xC000015,0xC000015,0x8000013,0x8000019,0x8000019,0x800000A,0x600000E,0x180033, -0x180033,0x6000023,0x4000023,0x4000033,0x48000001,0x5C080014,0xC0034,0x24000001,0x18000001,0x12000001,0x10000001,0xC000001,0x24000009,0x1C000004,0xE000009,0x800000A,0x140033,0x100008,0x100008,0x100008,0x100008,0x100C0000,0x100C0000,0x100C0000,0xA0C0001,0xA0C0001,0x80C0001,0x180008,0x180008,0x180008,0xA080001,0xA080001, -0x8080001,0x2C0008,0x2C0008,0x8000001,0x600000A,0x180008,0x180008,0x180008,0xA080001,0xA080001,0x8080001,0x2C0008,0x2C0008,0x8000001,0x600000A,0x2C0008,0x2C0008,0x8000001,0x600000A,0x600000A,0x3A040000,0x3E0C0000,0x100008,0x1E040000,0x14040000,0x10040000,0xC080001,0xC040000,0x26040001,0x1C000000,0x200008,0x8000001, -0x200008,0x180014,0x1A140000,0x12140000,0xE140001,0x2240012,0x120C0001,0xE100001,0x4C0012,0xE000001,0xC000012,0x2240012,0x120C0001,0xE100001,0x4C0012,0xE000001,0xC000012,0x4C0012,0xE000001,0xC000012,0xC000012,0x2240012,0x120C0001,0xE100001,0x4C0012,0xE000001,0xC000012,0x4C0012,0xE000001,0xC000012,0xC000012,0x4C0012, -0xE000001,0xC000012,0xC000012,0xC000012,0x44040001,0x1C0012,0x62140000,0x26000000,0x18000001,0x12000001,0xE040001,0xE000002,0x36000002,0x1E000001,0x10040000,0xC000012,0x340012,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x10000000,0x10000000,0x10000000,0x10000000,0x10000000, -0x10000000,0x8000000,0x8000000,0x8000000,0x4000001,0x80012,0x80012,0x80012,0x80012,0x80012,0x80012,0x6000005,0x6000005,0x6000005,0x4000005,0xC0012,0xC0012,0xC0012,0x400000A,0x2000012,0x58000000,0x40014,0x40014,0x28000000,0x1C000000,0x14000000,0x14000000,0xE000000,0x20000005,0x16000002,0xA000001,0x6000005, -0xC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table2[] = { -0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x2C0000, -0x2C0000,0x2C0000,0x2C0000,0x6000001,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x180000,0x200000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x280000,0x280000,0x280000,0x280000,0x280000, -0x280000,0x500000,0x500000,0x500000,0xC000001,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x500000,0x500000,0x500000,0xC000001,0x500000,0x500000,0x500000,0xC000001,0xC000001,0x61C0000,0x1C0000,0x1C0000,0x200000,0x4200000,0x2240000,0x2240000,0x22C0000,0x200000,0x4200000,0x380000,0x500000, -0x380000,0x240000,0x240000,0x240000,0x240000,0x340000,0x340000,0x340000,0x680000,0x680000,0x10000001,0x340000,0x340000,0x340000,0x680000,0x680000,0x10000001,0x680000,0x680000,0x10000001,0x10000001,0x340000,0x340000,0x340000,0x680000,0x680000,0x10000001,0x680000,0x680000,0x10000001,0x10000001,0x680000, -0x680000,0x10000001,0x10000001,0x10000001,0x2280000,0xA240000,0x240000,0x300000,0x3C0000,0x4C0000,0x540000,0x800000,0x2C0000,0x340000,0x4C0000,0x10000001,0x4C0000,0x300000,0x2440000,0x8C0000,0x16000001,0x2440000,0x8C0000,0x16000001,0x8C0000,0x16000001,0x16000001,0x2440000,0x8C0000,0x16000001,0x8C0000,0x16000001, -0x16000001,0x8C0000,0x16000001,0x16000001,0x16000001,0x2440000,0x8C0000,0x16000001,0x8C0000,0x16000001,0x16000001,0x8C0000,0x16000001,0x16000001,0x16000001,0x8C0000,0x16000001,0x16000001,0x16000001,0x16000001,0x3C0000,0x340000,0x340000,0x500000,0x740000,0xE00000,0x16000001,0x16000001,0x400000,0x580000,0x9E40000,0x16000001, -0x640000,0x200088,0x2A1C0034,0x1C1C0034,0x161C0035,0x26180026,0x1C180015,0x16180019,0x18180026,0x16140016,0x14140026,0x28100033,0x1E100009,0x1814000F,0x1A100012,0x16100002,0x14100016,0x18100033,0x160C000F,0x140C001A,0x12100033,0x300088,0x22040033,0x16100034,0x1C040026,0x18080013,0x140C0024,0x1A000035,0x1604000A,0x14000013,0x12040033,0x5C0088, -0x1600003C,0x12000034,0x10000044,0xE00008C,0x50100002,0x94180026,0xA61C0034,0x2E100001,0x20100002,0x1A100002,0x18100002,0x16100002,0x4A080001,0x2A0C0001,0x180C0009,0x14000013,0x400088,0x240034,0x26200008,0x1A200009,0x16200009,0x221C0012,0x1A1C0001,0x181C0001,0x181C0012,0x161C0005,0x141C0012,0x380033,0x1C140009,0x16180009,0x1A100012,0x16100002, -0x14140012,0x700033,0x16040009,0x14000012,0x12000033,0x380033,0x1C140009,0x16180009,0x1A100012,0x16100002,0x14140012,0x700033,0x16040009,0x14000012,0x12000033,0x700033,0x16040009,0x14000012,0x12000033,0x12000033,0x4C140001,0x761C0012,0x88200008,0x28140001,0x20100002,0x1A100002,0x16140002,0x160C0002,0x4A080001,0x26100001,0x180C0008,0x14000012, -0x500033,0x1C0034,0x1C0034,0x1C0034,0x1C0034,0x1C180014,0x1C180014,0x1C180014,0x14180014,0x14180014,0x10140015,0x1E100008,0x1E100008,0x1E100008,0x16100001,0x16100001,0x12100005,0x1210000A,0x1210000A,0x10100001,0xE10000A,0x2240033,0x2240033,0x2240033,0x18080012,0x18080012,0x10100013,0x16040009,0x16040009,0x10080002,0xE08000A,0x4C0033, -0x4C0033,0x10000013,0xE00000E,0xC000033,0x50100001,0x64180014,0x1C0034,0x2C100001,0x20100001,0x1A100001,0x18100001,0x14100001,0x48080000,0x2A0C0000,0x16100009,0x10080002,0x340033,0x200008,0x200008,0x200008,0x200008,0x181C0000,0x181C0000,0x181C0000,0x121C0001,0x121C0001,0x101C0001,0x300008,0x300008,0x300008,0x12180001,0x12180001, -0x10180001,0x5C0008,0x5C0008,0x10100001,0xE00000A,0x300008,0x300008,0x300008,0x12180001,0x12180001,0x10180001,0x5C0008,0x5C0008,0x10100001,0xE00000A,0x5C0008,0x5C0008,0x10100001,0xE00000A,0xE00000A,0x42140000,0x461C0000,0x200008,0x26140000,0x1C140000,0x18140000,0x14180001,0x14140000,0x3E0C0000,0x24100000,0x400008,0x10100001, -0x400008,0x280014,0x22240000,0x1A240000,0x16240001,0x23C0012,0x1A1C0001,0x16200001,0x7C0012,0x16100001,0x14000012,0x23C0012,0x1A1C0001,0x16200001,0x7C0012,0x16100001,0x14000012,0x7C0012,0x16100001,0x14000012,0x14000012,0x23C0012,0x1A1C0001,0x16200001,0x7C0012,0x16100001,0x14000012,0x7C0012,0x16100001,0x14000012,0x14000012,0x7C0012, -0x16100001,0x14000012,0x14000012,0x14000012,0x5C0C0000,0x2C0012,0x6A240000,0x2E100000,0x20100001,0x1C0C0000,0x16140001,0x16080001,0x52040000,0x2E080000,0x18140000,0x14000012,0x580012,0x140014,0x140014,0x140014,0x140014,0x140014,0x140014,0x140014,0x140014,0x140014,0x140014,0x18100000,0x18100000,0x18100000,0x18100000,0x18100000, -0x18100000,0x10100000,0x10100000,0x10100000,0xC100001,0x200012,0x200012,0x200012,0x200012,0x200012,0x200012,0x10080001,0x10080001,0x10080001,0xC0C0001,0x3C0012,0x3C0012,0x3C0012,0xC000002,0xA000012,0x60100000,0x140014,0x140014,0x30100000,0x24100000,0x1C100000,0x1C100000,0x16100000,0x48080000,0x2A0C0000,0x12100001,0x10080001, -0x2C0012,}; -static const uint32_t g_etc1_to_bc7_m6_table3[] = { -0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x5C0000, -0x5C0000,0x5C0000,0x5C0000,0xE000001,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x8200000,0x8200000,0x8200000,0x300000,0x400000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x400000,0x400000,0x400000,0x400000,0x400000, -0x400000,0x800000,0x800000,0x800000,0x14000001,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x800000,0x800000,0x800000,0x14000001,0x800000,0x800000,0x800000,0x14000001,0x14000001,0xE2C0000,0x2C0000,0x2C0000,0x340000,0x4340000,0x3C0000,0x3C0000,0x480000,0x340000,0x4340000,0x5C0000,0x800000, -0x5C0000,0x340000,0x340000,0x340000,0x340000,0x4C0000,0x4C0000,0x4C0000,0x980000,0x980000,0x18000001,0x4C0000,0x4C0000,0x4C0000,0x980000,0x980000,0x18000001,0x980000,0x980000,0x18000001,0x18000001,0x4C0000,0x4C0000,0x4C0000,0x980000,0x980000,0x18000001,0x980000,0x980000,0x18000001,0x18000001,0x980000, -0x980000,0x18000001,0x18000001,0x18000001,0x3C0000,0x380000,0x340000,0x2440000,0x2540000,0x6C0000,0x7C0000,0xBC0000,0x400000,0x4C0000,0x6C0000,0x18000001,0x6C0000,0x400000,0x25C0000,0xBC0000,0x1E000001,0x25C0000,0xBC0000,0x1E000001,0xBC0000,0x1E000001,0x1E000001,0x25C0000,0xBC0000,0x1E000001,0xBC0000,0x1E000001, -0x1E000001,0xBC0000,0x1E000001,0x1E000001,0x1E000001,0x25C0000,0xBC0000,0x1E000001,0xBC0000,0x1E000001,0x1E000001,0xBC0000,0x1E000001,0x1E000001,0x1E000001,0xBC0000,0x1E000001,0x1E000001,0x1E000001,0x1E000001,0x500000,0x440000,0x440000,0x6C0000,0x9C0000,0x1300000,0x1E000001,0x1E000001,0x2540000,0x780000,0x11F40000,0x1E000001, -0x880000,0x300088,0x322C0034,0x242C0034,0x1E2C0035,0x2E280026,0x24280015,0x1E280019,0x20280026,0x1E240016,0x1C240026,0x30200033,0x26200009,0x2024000F,0x22200012,0x1E200002,0x1C200016,0x20200033,0x1E1C000F,0x1C1C001A,0x1A200033,0x2440088,0x2A140033,0x1E200034,0x24140026,0x20180013,0x1C1C0024,0x240C0033,0x1E14000A,0x1C100013,0x1A140033,0x8C0088, -0x1E000034,0x1C000024,0x1A000037,0x1600008C,0x58200002,0x9C280026,0xAE2C0034,0x36200001,0x28200002,0x22200002,0x20200002,0x1E200002,0x52180001,0x321C0001,0x201C0009,0x1C100013,0x640088,0x340034,0x2E300008,0x22300009,0x1E300009,0x2A2C0012,0x222C0001,0x202C0001,0x202C0012,0x1E2C0005,0x1C2C0012,0x500033,0x24240009,0x1E280009,0x22200012,0x1E200002, -0x1C240012,0xA00033,0x1E140009,0x1C100012,0x1A000033,0x500033,0x24240009,0x1E280009,0x22200012,0x1E200002,0x1C240012,0xA00033,0x1E140009,0x1C100012,0x1A000033,0xA00033,0x1E140009,0x1C100012,0x1A000033,0x1A000033,0x54240001,0x7E2C0012,0x90300008,0x30240001,0x28200002,0x22200002,0x1E240002,0x1E1C0002,0x52180001,0x2E200001,0x201C0008,0x1C100012, -0x700033,0x2C0034,0x2C0034,0x2C0034,0x2C0034,0x24280014,0x24280014,0x24280014,0x1C280014,0x1C280014,0x18240015,0x26200008,0x26200008,0x26200008,0x1E200001,0x1E200001,0x1A200005,0x1A20000A,0x1A20000A,0x18200001,0x1620000A,0x23C0033,0x23C0033,0x23C0033,0x20180012,0x20180012,0x18200013,0x1E140009,0x1E140009,0x18180002,0x1618000A,0x7C0033, -0x7C0033,0x180C0013,0x1604000A,0x14000033,0x58200001,0x6C280014,0x2C0034,0x34200001,0x28200001,0x22200001,0x20200001,0x1C200001,0x50180000,0x321C0000,0x1E200009,0x18180002,0x580033,0x300008,0x300008,0x300008,0x300008,0x202C0000,0x202C0000,0x202C0000,0x1A2C0001,0x1A2C0001,0x182C0001,0x2440008,0x2440008,0x2440008,0x1A280001,0x1A280001, -0x18280001,0x8C0008,0x8C0008,0x18200001,0x1600000A,0x2440008,0x2440008,0x2440008,0x1A280001,0x1A280001,0x18280001,0x8C0008,0x8C0008,0x18200001,0x1600000A,0x8C0008,0x8C0008,0x18200001,0x1600000A,0x1600000A,0x4A240000,0x4E2C0000,0x300008,0x2E240000,0x24240000,0x20240000,0x1C280001,0x1C240000,0x461C0000,0x2C200000,0x640008,0x18200001, -0x640008,0x380014,0x2A340000,0x22340000,0x1E340001,0x540012,0x222C0001,0x1E300001,0xAC0012,0x1E200001,0x1C000012,0x540012,0x222C0001,0x1E300001,0xAC0012,0x1E200001,0x1C000012,0xAC0012,0x1E200001,0x1C000012,0x1C000012,0x540012,0x222C0001,0x1E300001,0xAC0012,0x1E200001,0x1C000012,0xAC0012,0x1E200001,0x1C000012,0x1C000012,0xAC0012, -0x1E200001,0x1C000012,0x1C000012,0x1C000012,0x641C0000,0x63C0012,0x72340000,0x36200000,0x28200001,0x241C0000,0x1E240001,0x1E180001,0x5A140000,0x36180000,0x20240000,0x1C000012,0x780012,0x240014,0x240014,0x240014,0x240014,0x240014,0x240014,0x240014,0x240014,0x240014,0x240014,0x20200000,0x20200000,0x20200000,0x20200000,0x20200000, -0x20200000,0x18200000,0x18200000,0x18200000,0x14200001,0x380012,0x380012,0x380012,0x380012,0x380012,0x380012,0x18180001,0x18180001,0x18180001,0x141C0001,0x700012,0x700012,0x700012,0x140C0001,0x12000012,0x68200000,0x240014,0x240014,0x38200000,0x2C200000,0x24200000,0x24200000,0x1E200000,0x50180000,0x321C0000,0x1A200001,0x18180001, -0x500012,}; -static const uint32_t g_etc1_to_bc7_m6_table4[] = { -0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x940000, -0x940000,0x940000,0x940000,0x18000000,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x2340000,0x2340000,0x2340000,0x480000,0x680000,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000, -0x5C0000,0xB80000,0xB80000,0xB80000,0x1E000000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0xB80000,0xB80000,0xB80000,0x1E000000,0xB80000,0xB80000,0xB80000,0x1E000000,0x1E000000,0x8400000,0x3C0001,0x3C0001,0x480000,0x24C0000,0x540000,0x540000,0x680000,0x480000,0x24C0000,0x800000,0xB80000, -0x800000,0x440001,0x440001,0x440001,0x440001,0x680000,0x680000,0x680000,0xD00000,0xD00000,0x22000000,0x680000,0x680000,0x680000,0xD00000,0xD00000,0x22000000,0xD00000,0xD00000,0x22000000,0x22000000,0x680000,0x680000,0x680000,0xD00000,0xD00000,0x22000000,0xD00000,0xD00000,0x22000000,0x22000000,0xD00000, -0xD00000,0x22000000,0x22000000,0x22000000,0x500000,0xC480000,0x440001,0x25C0000,0x740000,0x940000,0xA80000,0x1000000,0x580000,0x680000,0x940000,0x22000000,0x940000,0x500001,0x780000,0xF40000,0x28000000,0x780000,0xF40000,0x28000000,0xF40000,0x28000000,0x28000000,0x780000,0xF40000,0x28000000,0xF40000,0x28000000, -0x28000000,0xF40000,0x28000000,0x28000000,0x28000000,0x780000,0xF40000,0x28000000,0xF40000,0x28000000,0x28000000,0xF40000,0x28000000,0x28000000,0x28000000,0xF40000,0x28000000,0x28000000,0x28000000,0x28000000,0x4640000,0x580000,0x580000,0x880000,0xC80000,0x1880000,0x28000000,0x28000000,0x700000,0x980000,0x1BE80000,0x28000000, -0xAC0000,0x40008C,0x3E3C0033,0x2E3C0033,0x283C0033,0x38380024,0x2E380013,0x2A38001A,0x2A380024,0x26380016,0x24380026,0x36340034,0x2E34000A,0x2A34000F,0x2C300013,0x28300002,0x24340016,0x28340034,0x2630000F,0x24300019,0x22300035,0x600088,0x32280033,0x28300033,0x2C280026,0x282C0012,0x24300026,0x2E1C0033,0x28200009,0x24240015,0x22280034,0xC40088, -0x280C0033,0x24140026,0x22080034,0x20000088,0x62340002,0xB4380024,0xC63C0033,0x3C340002,0x30340002,0x2A340002,0x28340002,0x28300002,0x5E280001,0x3E2C0001,0x28300009,0x24240015,0x8C0088,0x480033,0x3644000A,0x2C40000A,0x2840000A,0x30400013,0x2C3C0002,0x28400001,0x28400013,0x283C0005,0x243C0015,0x2680033,0x2E340009,0x2838000A,0x2C300012,0x28300001, -0x24380014,0xD80033,0x28200008,0x24240014,0x22000034,0x2680033,0x2E340009,0x2838000A,0x2C300012,0x28300001,0x24380014,0xD80033,0x28200008,0x24240014,0x22000034,0xD80033,0x28200008,0x24240014,0x22000034,0x22000034,0x62340001,0x78400013,0x8A44000A,0x3C340001,0x30340001,0x2A340001,0x28340001,0x28300001,0x5E280001,0x3A300001,0x28300009,0x24240014, -0x980033,0x3C0033,0x3C0033,0x3C0033,0x3C0033,0x30380012,0x30380012,0x30380012,0x26380012,0x26380012,0x22380012,0x2E340009,0x2E340009,0x2E340009,0x26340002,0x26340002,0x22340005,0x24300009,0x24300009,0x22300001,0x20300009,0x580033,0x580033,0x580033,0x282C0012,0x282C0012,0x22300012,0x26280009,0x26280009,0x22280001,0x20280009,0xB00033, -0xB00033,0x221C0012,0x20100008,0x1E000034,0x56340002,0x84380012,0x3C0033,0x3A340001,0x30340001,0x2A340001,0x28340002,0x26300002,0x5E280000,0x38300001,0x28300008,0x22280001,0x7C0033,0x40000A,0x40000A,0x40000A,0x40000A,0x28400001,0x28400001,0x28400001,0x243C0001,0x243C0001,0x223C0001,0x600008,0x600008,0x600008,0x24380001,0x24380001, -0x22380001,0xC40008,0xC40008,0x222C0000,0x20000008,0x600008,0x600008,0x600008,0x24380001,0x24380001,0x22380001,0xC40008,0xC40008,0x222C0000,0x20000008,0xC40008,0xC40008,0x222C0000,0x20000008,0x20000008,0x4A380000,0x48400001,0x40000A,0x3A340000,0x2C380000,0x28380000,0x26380000,0x24380001,0x4C300000,0x34340000,0x8C0008,0x222C0000, -0x8C0008,0x4C0012,0x32480001,0x2A480001,0x28440001,0x700012,0x2C3C0001,0x28400000,0xE40012,0x282C0000,0x24000014,0x700012,0x2C3C0001,0x28400000,0xE40012,0x282C0000,0x24000014,0xE40012,0x282C0000,0x24000014,0x24000014,0x700012,0x2C3C0001,0x28400000,0xE40012,0x282C0000,0x24000014,0xE40012,0x282C0000,0x24000014,0x24000014,0xE40012, -0x282C0000,0x24000014,0x24000014,0x24000014,0x722C0000,0x500012,0x6C480001,0x40300000,0x30340001,0x2C300000,0x28340000,0x28240000,0x66240000,0x3E2C0000,0x28380001,0x24000014,0xA00012,0x380012,0x380012,0x380012,0x380012,0x380012,0x380012,0x380012,0x380012,0x380012,0x380012,0x28340001,0x28340001,0x28340001,0x28340001,0x28340001, -0x28340001,0x20340001,0x20340001,0x20340001,0x1E300001,0x2500012,0x2500012,0x2500012,0x2500012,0x2500012,0x2500012,0x22280001,0x22280001,0x22280001,0x1E2C0000,0xA40012,0xA40012,0xA40012,0x1E180000,0x1A000014,0x62340001,0x380012,0x380012,0x3A340001,0x30340001,0x2A340001,0x2A340001,0x26340001,0x5E280000,0x402C0000,0x24300000,0x22280001, -0x740012,}; -static const uint32_t g_etc1_to_bc7_m6_table5[] = { -0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0xC40000, -0xC40000,0xC40000,0xC40000,0x20000000,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0xA440000,0xA440000,0xA440000,0x600000,0x8C0000,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x740000,0x740000,0x740000,0x740000,0x740000, -0x740000,0xE80000,0xE80000,0xE80000,0x26000000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0xE80000,0xE80000,0xE80000,0x26000000,0xE80000,0xE80000,0xE80000,0x26000000,0x26000000,0x540000,0x4C0001,0x4C0001,0x4580000,0x2600000,0x2680000,0x2680000,0x2800000,0x4580000,0x2600000,0xA40000,0xE80000, -0xA40000,0x540001,0x540001,0x540001,0x540001,0x800000,0x800000,0x800000,0x1000000,0x1000000,0x2A000000,0x800000,0x800000,0x800000,0x1000000,0x1000000,0x2A000000,0x1000000,0x1000000,0x2A000000,0x2A000000,0x800000,0x800000,0x800000,0x1000000,0x1000000,0x2A000000,0x1000000,0x1000000,0x2A000000,0x2A000000,0x1000000, -0x1000000,0x2A000000,0x2A000000,0x2A000000,0x640000,0x5C0000,0x540001,0x740000,0x900000,0xB40000,0xD00000,0x13C0000,0x6C0000,0x800000,0xB40000,0x2A000000,0xB40000,0x600001,0x900000,0x1240000,0x30000000,0x900000,0x1240000,0x30000000,0x1240000,0x30000000,0x30000000,0x900000,0x1240000,0x30000000,0x1240000,0x30000000, -0x30000000,0x1240000,0x30000000,0x30000000,0x30000000,0x900000,0x1240000,0x30000000,0x1240000,0x30000000,0x30000000,0x1240000,0x30000000,0x30000000,0x30000000,0x1240000,0x30000000,0x30000000,0x30000000,0x30000000,0x4780000,0x680000,0x680000,0xA40000,0xEC0000,0x1D80000,0x30000000,0x30000000,0x840000,0xB80000,0x23F80000,0x30000000, -0xD00000,0x50008C,0x464C0033,0x364C0033,0x304C0033,0x40480024,0x36480013,0x3248001A,0x32480024,0x2E480016,0x2C480026,0x3E440034,0x3644000A,0x3244000F,0x34400013,0x30400002,0x2C440016,0x30440034,0x2E40000F,0x2C400019,0x2A400035,0x780088,0x3A380033,0x30400033,0x34380026,0x303C0012,0x2C400026,0x362C0033,0x30300009,0x2C340015,0x2A380034,0xF40088, -0x301C0033,0x2C240026,0x2A180034,0x28000088,0x6A440002,0xBC480024,0xCE4C0033,0x44440002,0x38440002,0x32440002,0x30440002,0x30400002,0x66380001,0x463C0001,0x30400009,0x2C340015,0xAC0088,0x580033,0x3E54000A,0x3450000A,0x3050000A,0x38500013,0x344C0002,0x30500001,0x30500013,0x304C0005,0x2C4C0015,0x2800033,0x36440009,0x3048000A,0x34400012,0x30400001, -0x2C480014,0x1080033,0x30300008,0x2C340014,0x2A000034,0x2800033,0x36440009,0x3048000A,0x34400012,0x30400001,0x2C480014,0x1080033,0x30300008,0x2C340014,0x2A000034,0x1080033,0x30300008,0x2C340014,0x2A000034,0x2A000034,0x6A440001,0x80500013,0x9254000A,0x44440001,0x38440001,0x32440001,0x30440001,0x30400001,0x66380001,0x42400001,0x30400009,0x2C340014, -0xB80033,0x4C0033,0x4C0033,0x4C0033,0x4C0033,0x38480012,0x38480012,0x38480012,0x2E480012,0x2E480012,0x2A480012,0x36440009,0x36440009,0x36440009,0x2E440002,0x2E440002,0x2A440005,0x2C400009,0x2C400009,0x2A400001,0x28400009,0x700033,0x700033,0x700033,0x303C0012,0x303C0012,0x2A400012,0x2E380009,0x2E380009,0x2A380001,0x28380009,0xE40033, -0xE40033,0x2A2C0012,0x28200008,0x26000034,0x5E440002,0x8C480012,0x4C0033,0x42440001,0x38440001,0x32440001,0x30440002,0x2E400002,0x66380000,0x40400001,0x30400008,0x2A380001,0xA00033,0x50000A,0x50000A,0x50000A,0x50000A,0x30500001,0x30500001,0x30500001,0x2C4C0001,0x2C4C0001,0x2A4C0001,0x780008,0x780008,0x780008,0x2C480001,0x2C480001, -0x2A480001,0xF40008,0xF40008,0x2A3C0000,0x28000008,0x780008,0x780008,0x780008,0x2C480001,0x2C480001,0x2A480001,0xF40008,0xF40008,0x2A3C0000,0x28000008,0xF40008,0xF40008,0x2A3C0000,0x28000008,0x28000008,0x52480000,0x50500001,0x50000A,0x42440000,0x34480000,0x30480000,0x2E480000,0x2C480001,0x54400000,0x3C440000,0xAC0008,0x2A3C0000, -0xAC0008,0x5C0012,0x3A580001,0x32580001,0x30540001,0x880012,0x344C0001,0x30500000,0x1140012,0x303C0000,0x2C000014,0x880012,0x344C0001,0x30500000,0x1140012,0x303C0000,0x2C000014,0x1140012,0x303C0000,0x2C000014,0x2C000014,0x880012,0x344C0001,0x30500000,0x1140012,0x303C0000,0x2C000014,0x1140012,0x303C0000,0x2C000014,0x2C000014,0x1140012, -0x303C0000,0x2C000014,0x2C000014,0x2C000014,0x7A3C0000,0x8600012,0x74580001,0x48400000,0x38440001,0x34400000,0x30440000,0x30340000,0x6E340000,0x463C0000,0x30480001,0x2C000014,0xC00012,0x480012,0x480012,0x480012,0x480012,0x480012,0x480012,0x480012,0x480012,0x480012,0x480012,0x30440001,0x30440001,0x30440001,0x30440001,0x30440001, -0x30440001,0x28440001,0x28440001,0x28440001,0x26400001,0x2680012,0x2680012,0x2680012,0x2680012,0x2680012,0x2680012,0x2A380001,0x2A380001,0x2A380001,0x263C0000,0xD80012,0xD80012,0xD80012,0x26280000,0x22000014,0x6A440001,0x480012,0x480012,0x42440001,0x38440001,0x32440001,0x32440001,0x2E440001,0x66380000,0x483C0000,0x2C400000,0x2A380001, -0x980012,}; -static const uint32_t g_etc1_to_bc7_m6_table6[] = { -0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0xF40000, -0xF40000,0xF40000,0xF40000,0x28000000,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x580000,0x580000,0x580000,0x780000,0xAC0000,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000, -0x8C0000,0x1180000,0x1180000,0x1180000,0x2E000000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x1180000,0x1180000,0x1180000,0x2E000000,0x1180000,0x1180000,0x1180000,0x2E000000,0x2E000000,0x640000,0x5C0001,0x5C0001,0x6C0000,0x2740000,0x800000,0x800000,0x9C0000,0x6C0000,0x2740000,0xC80000,0x1180000, -0xC80000,0x640001,0x640001,0x640001,0x640001,0x980000,0x980000,0x980000,0x1300000,0x1300000,0x32000000,0x980000,0x980000,0x980000,0x1300000,0x1300000,0x32000000,0x1300000,0x1300000,0x32000000,0x32000000,0x980000,0x980000,0x980000,0x1300000,0x1300000,0x32000000,0x1300000,0x1300000,0x32000000,0x32000000,0x1300000, -0x1300000,0x32000000,0x32000000,0x32000000,0x4740000,0x6C0000,0x640001,0x2880000,0xAC0000,0xD80000,0xF80000,0x1780000,0x800000,0x980000,0xD80000,0x32000000,0xD80000,0x700001,0xA80000,0x1580000,0x38000000,0xA80000,0x1580000,0x38000000,0x1580000,0x38000000,0x38000000,0xA80000,0x1580000,0x38000000,0x1580000,0x38000000, -0x38000000,0x1580000,0x38000000,0x38000000,0x38000000,0xA80000,0x1580000,0x38000000,0x1580000,0x38000000,0x38000000,0x1580000,0x38000000,0x38000000,0x38000000,0x1580000,0x38000000,0x38000000,0x38000000,0x38000000,0x48C0000,0x4780000,0x4780000,0xC00000,0x1140000,0x7F80000,0x38000000,0x38000000,0x2980000,0xD40000,0x2DCC0000,0x38000000, -0xF00000,0x60008C,0x4E5C0033,0x3E5C0033,0x385C0033,0x48580024,0x3E580013,0x3A58001A,0x3A580024,0x36580016,0x34580026,0x46540034,0x3E54000A,0x3A54000F,0x3C500013,0x38500002,0x34540016,0x38540034,0x3650000F,0x34500019,0x32500035,0x900088,0x42480033,0x38500033,0x3C480026,0x384C0012,0x34500026,0x3E3C0033,0x38400009,0x34440015,0x32480034,0x1240088, -0x382C0033,0x34340026,0x32280034,0x30000088,0x72540002,0xC4580024,0xD65C0033,0x4C540002,0x40540002,0x3A540002,0x38540002,0x38500002,0x6E480001,0x4E4C0001,0x38500009,0x34440015,0xD00088,0x680033,0x4664000A,0x3C60000A,0x3860000A,0x40600013,0x3C5C0002,0x38600001,0x38600013,0x385C0005,0x345C0015,0x2980033,0x3E540009,0x3858000A,0x3C500012,0x38500001, -0x34580014,0x1380033,0x38400008,0x34440014,0x32000034,0x2980033,0x3E540009,0x3858000A,0x3C500012,0x38500001,0x34580014,0x1380033,0x38400008,0x34440014,0x32000034,0x1380033,0x38400008,0x34440014,0x32000034,0x32000034,0x72540001,0x88600013,0x9A64000A,0x4C540001,0x40540001,0x3A540001,0x38540001,0x38500001,0x6E480001,0x4A500001,0x38500009,0x34440014, -0xDC0033,0x5C0033,0x5C0033,0x5C0033,0x5C0033,0x40580012,0x40580012,0x40580012,0x36580012,0x36580012,0x32580012,0x3E540009,0x3E540009,0x3E540009,0x36540002,0x36540002,0x32540005,0x34500009,0x34500009,0x32500001,0x30500009,0x880033,0x880033,0x880033,0x384C0012,0x384C0012,0x32500012,0x36480009,0x36480009,0x32480001,0x30480009,0x1140033, -0x1140033,0x323C0012,0x30300008,0x2E000034,0x66540002,0x94580012,0x5C0033,0x4A540001,0x40540001,0x3A540001,0x38540002,0x36500002,0x6E480000,0x48500001,0x38500008,0x32480001,0xC00033,0x60000A,0x60000A,0x60000A,0x60000A,0x38600001,0x38600001,0x38600001,0x345C0001,0x345C0001,0x325C0001,0x900008,0x900008,0x900008,0x34580001,0x34580001, -0x32580001,0x1240008,0x1240008,0x324C0000,0x30000008,0x900008,0x900008,0x900008,0x34580001,0x34580001,0x32580001,0x1240008,0x1240008,0x324C0000,0x30000008,0x1240008,0x1240008,0x324C0000,0x30000008,0x30000008,0x5A580000,0x58600001,0x60000A,0x4A540000,0x3C580000,0x38580000,0x36580000,0x34580001,0x5C500000,0x44540000,0xD00008,0x324C0000, -0xD00008,0x6C0012,0x42680001,0x3A680001,0x38640001,0xA00012,0x3C5C0001,0x38600000,0x1440012,0x384C0000,0x34000014,0xA00012,0x3C5C0001,0x38600000,0x1440012,0x384C0000,0x34000014,0x1440012,0x384C0000,0x34000014,0x34000014,0xA00012,0x3C5C0001,0x38600000,0x1440012,0x384C0000,0x34000014,0x1440012,0x384C0000,0x34000014,0x34000014,0x1440012, -0x384C0000,0x34000014,0x34000014,0x34000014,0x824C0000,0x740012,0x7C680001,0x50500000,0x40540001,0x3C500000,0x38540000,0x38440000,0x76440000,0x4E4C0000,0x38580001,0x34000014,0xE40012,0x580012,0x580012,0x580012,0x580012,0x580012,0x580012,0x580012,0x580012,0x580012,0x580012,0x38540001,0x38540001,0x38540001,0x38540001,0x38540001, -0x38540001,0x30540001,0x30540001,0x30540001,0x2E500001,0x2800012,0x2800012,0x2800012,0x2800012,0x2800012,0x2800012,0x32480001,0x32480001,0x32480001,0x2E4C0000,0x1080012,0x1080012,0x1080012,0x2E380000,0x2A000014,0x72540001,0x580012,0x580012,0x4A540001,0x40540001,0x3A540001,0x3A540001,0x36540001,0x6E480000,0x504C0000,0x34500000,0x32480001, -0xB80012,}; -static const uint32_t g_etc1_to_bc7_m6_table7[] = { -0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x1240000, -0x1240000,0x1240000,0x1240000,0x30000000,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x680000,0x680000,0x680000,0x900000,0xD00000,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000, -0xA40000,0x14C0000,0x14C0000,0x14C0000,0x36000000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0x14C0000,0x14C0000,0x14C0000,0x36000000,0x14C0000,0x14C0000,0x14C0000,0x36000000,0x36000000,0x2740000,0x6C0001,0x6C0001,0x800000,0x2880000,0x940000,0x940000,0xB80000,0x800000,0x2880000,0xE80000,0x14C0000, -0xE80000,0x740001,0x740001,0x740001,0x740001,0xB00000,0xB00000,0xB00000,0x1640000,0x1640000,0x3A000000,0xB00000,0xB00000,0xB00000,0x1640000,0x1640000,0x3A000000,0x1640000,0x1640000,0x3A000000,0x3A000000,0xB00000,0xB00000,0xB00000,0x1640000,0x1640000,0x3A000000,0x1640000,0x1640000,0x3A000000,0x3A000000,0x1640000, -0x1640000,0x3A000000,0x3A000000,0x3A000000,0x880000,0x67C0000,0x740001,0xA00000,0xC40000,0xF80000,0x1200000,0x1B40000,0x940000,0xB00000,0xF80000,0x3A000000,0xF80000,0x800001,0xC00000,0x1880000,0x40000000,0xC00000,0x1880000,0x40000000,0x1880000,0x40000000,0x40000000,0xC00000,0x1880000,0x40000000,0x1880000,0x40000000, -0x40000000,0x1880000,0x40000000,0x40000000,0x40000000,0xC00000,0x1880000,0x40000000,0x1880000,0x40000000,0x40000000,0x1880000,0x40000000,0x40000000,0x40000000,0x1880000,0x40000000,0x40000000,0x40000000,0x40000000,0x4A00000,0xC880000,0xC880000,0xD80000,0x13C0000,0x11F80000,0x40000000,0x40000000,0xB00000,0xF40000,0x35DC0000,0x40000000, -0x1140000,0x70008C,0x566C0033,0x466C0033,0x406C0033,0x50680024,0x46680013,0x4268001A,0x42680024,0x3E680016,0x3C680026,0x4E640034,0x4664000A,0x4264000F,0x44600013,0x40600002,0x3C640016,0x40640034,0x3E60000F,0x3C600019,0x3A600035,0xA80088,0x4A580033,0x40600033,0x44580026,0x405C0012,0x3C600026,0x464C0033,0x40500009,0x3C540015,0x3A580034,0x1580088, -0x403C0033,0x3C440026,0x3A380034,0x38000088,0x7A640002,0xCC680024,0xDE6C0033,0x54640002,0x48640002,0x42640002,0x40640002,0x40600002,0x76580001,0x565C0001,0x40600009,0x3C540015,0xF00088,0x780033,0x4E74000A,0x4470000A,0x4070000A,0x48700013,0x446C0002,0x40700001,0x40700013,0x406C0005,0x3C6C0015,0x2B00033,0x46640009,0x4068000A,0x44600012,0x40600001, -0x3C680014,0x1680033,0x40500008,0x3C540014,0x3A000034,0x2B00033,0x46640009,0x4068000A,0x44600012,0x40600001,0x3C680014,0x1680033,0x40500008,0x3C540014,0x3A000034,0x1680033,0x40500008,0x3C540014,0x3A000034,0x3A000034,0x7A640001,0x90700013,0xA274000A,0x54640001,0x48640001,0x42640001,0x40640001,0x40600001,0x76580001,0x52600001,0x40600009,0x3C540014, -0xFC0033,0x6C0033,0x6C0033,0x6C0033,0x6C0033,0x48680012,0x48680012,0x48680012,0x3E680012,0x3E680012,0x3A680012,0x46640009,0x46640009,0x46640009,0x3E640002,0x3E640002,0x3A640005,0x3C600009,0x3C600009,0x3A600001,0x38600009,0xA00033,0xA00033,0xA00033,0x405C0012,0x405C0012,0x3A600012,0x3E580009,0x3E580009,0x3A580001,0x38580009,0x1440033, -0x1440033,0x3A4C0012,0x38400008,0x36000034,0x6E640002,0x9C680012,0x6C0033,0x52640001,0x48640001,0x42640001,0x40640002,0x3E600002,0x76580000,0x50600001,0x40600008,0x3A580001,0xE40033,0x70000A,0x70000A,0x70000A,0x70000A,0x40700001,0x40700001,0x40700001,0x3C6C0001,0x3C6C0001,0x3A6C0001,0xA80008,0xA80008,0xA80008,0x3C680001,0x3C680001, -0x3A680001,0x1580008,0x1580008,0x3A5C0000,0x38000008,0xA80008,0xA80008,0xA80008,0x3C680001,0x3C680001,0x3A680001,0x1580008,0x1580008,0x3A5C0000,0x38000008,0x1580008,0x1580008,0x3A5C0000,0x38000008,0x38000008,0x62680000,0x60700001,0x70000A,0x52640000,0x44680000,0x40680000,0x3E680000,0x3C680001,0x64600000,0x4C640000,0xF00008,0x3A5C0000, -0xF00008,0x7C0012,0x4A780001,0x42780001,0x40740001,0xB80012,0x446C0001,0x40700000,0x1740012,0x405C0000,0x3C000014,0xB80012,0x446C0001,0x40700000,0x1740012,0x405C0000,0x3C000014,0x1740012,0x405C0000,0x3C000014,0x3C000014,0xB80012,0x446C0001,0x40700000,0x1740012,0x405C0000,0x3C000014,0x1740012,0x405C0000,0x3C000014,0x3C000014,0x1740012, -0x405C0000,0x3C000014,0x3C000014,0x3C000014,0x8A5C0000,0x840012,0x84780001,0x58600000,0x48640001,0x44600000,0x40640000,0x40540000,0x7E540000,0x565C0000,0x40680001,0x3C000014,0x1080012,0x680012,0x680012,0x680012,0x680012,0x680012,0x680012,0x680012,0x680012,0x680012,0x680012,0x40640001,0x40640001,0x40640001,0x40640001,0x40640001, -0x40640001,0x38640001,0x38640001,0x38640001,0x36600001,0x2980012,0x2980012,0x2980012,0x2980012,0x2980012,0x2980012,0x3A580001,0x3A580001,0x3A580001,0x365C0000,0x1380012,0x1380012,0x1380012,0x36480000,0x32000014,0x7A640001,0x680012,0x680012,0x52640001,0x48640001,0x42640001,0x42640001,0x3E640001,0x76580000,0x585C0000,0x3C600000,0x3A580001, -0xDC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table8[] = { -0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0x15C0000, -0x15C0000,0x15C0000,0x15C0000,0x38000001,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x7C0000,0x7C0000,0x7C0000,0xAC0000,0xF40000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000, -0x2BC0000,0x1800000,0x1800000,0x1800000,0x3E000001,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x1800000,0x1800000,0x1800000,0x3E000001,0x1800000,0x1800000,0x1800000,0x3E000001,0x3E000001,0x880000,0x800000,0x800000,0x940000,0xA00000,0x2AC0000,0x2AC0000,0x2D40000,0x940000,0xA00000,0x1100000,0x1800000, -0x1100000,0x880000,0x880000,0x880000,0x880000,0xC80000,0xC80000,0xC80000,0x1980000,0x1980000,0x42000001,0xC80000,0xC80000,0xC80000,0x1980000,0x1980000,0x42000001,0x1980000,0x1980000,0x42000001,0x42000001,0xC80000,0xC80000,0xC80000,0x1980000,0x1980000,0x42000001,0x1980000,0x1980000,0x42000001,0x42000001,0x1980000, -0x1980000,0x42000001,0x42000001,0x42000001,0x49C0000,0x900000,0x880000,0xB80000,0xE40000,0x1200000,0x14C0000,0x1F80000,0x2A80000,0xC80000,0x1200000,0x42000001,0x1200000,0x940000,0xDC0000,0x1BC0000,0x48000001,0xDC0000,0x1BC0000,0x48000001,0x1BC0000,0x48000001,0x48000001,0xDC0000,0x1BC0000,0x48000001,0x1BC0000,0x48000001, -0x48000001,0x1BC0000,0x48000001,0x48000001,0x48000001,0xDC0000,0x1BC0000,0x48000001,0x1BC0000,0x48000001,0x48000001,0x1BC0000,0x48000001,0x48000001,0x48000001,0x1BC0000,0x48000001,0x48000001,0x48000001,0x48000001,0xB80000,0x69C0000,0x69C0000,0xF80000,0x1680000,0x1DF40000,0x48000001,0x48000001,0xC80000,0x1140000,0x3FD00000,0x48000001, -0x1380000,0x840088,0x5C800034,0x4E800034,0x48800035,0x587C0026,0x4E7C0015,0x487C0019,0x4A7C0026,0x48780016,0x46780026,0x5A740033,0x50740009,0x4A78000F,0x4C740012,0x48740002,0x46740016,0x4A740033,0x4870000F,0x4670001A,0x44740033,0xC40088,0x54680033,0x48740034,0x4E680026,0x4A6C0013,0x46700024,0x4E600033,0x4868000A,0x46640013,0x44680033,0x18C0088, -0x48540034,0x46500024,0x44440033,0x4000008C,0x82740002,0xC67C0026,0xD8800034,0x60740001,0x52740002,0x4C740002,0x4A740002,0x48740002,0x7C6C0001,0x5C700001,0x4A700009,0x46640013,0x1180088,0x880034,0x58840008,0x4C840009,0x48840009,0x54800012,0x4C800001,0x4A800001,0x4A800012,0x48800005,0x46800012,0xCC0033,0x4E780009,0x487C0009,0x4C740012,0x48740002, -0x46780012,0x1A00033,0x48680009,0x46640012,0x44000033,0xCC0033,0x4E780009,0x487C0009,0x4C740012,0x48740002,0x46780012,0x1A00033,0x48680009,0x46640012,0x44000033,0x1A00033,0x48680009,0x46640012,0x44000033,0x44000033,0x7E780001,0xA8800012,0xBA840008,0x5A780001,0x52740002,0x4C740002,0x48780002,0x48700002,0x7C6C0001,0x58740001,0x4A700008,0x46640012, -0x1240033,0x800034,0x800034,0x800034,0x800034,0x4E7C0014,0x4E7C0014,0x4E7C0014,0x467C0014,0x467C0014,0x42780015,0x50740008,0x50740008,0x50740008,0x48740001,0x48740001,0x44740005,0x4474000A,0x4474000A,0x42740001,0x4074000A,0xBC0033,0xBC0033,0xBC0033,0x4A6C0012,0x4A6C0012,0x42740013,0x48680009,0x48680009,0x426C0002,0x406C000A,0x17C0033, -0x17C0033,0x42600013,0x4058000A,0x3E000033,0x82740001,0x967C0014,0x800034,0x5E740001,0x52740001,0x4C740001,0x4A740001,0x46740001,0x7A6C0000,0x5C700000,0x48740009,0x426C0002,0x10C0033,0x840008,0x840008,0x840008,0x840008,0x4A800000,0x4A800000,0x4A800000,0x44800001,0x44800001,0x42800001,0xC40008,0xC40008,0xC40008,0x447C0001,0x447C0001, -0x427C0001,0x18C0008,0x18C0008,0x42740001,0x4000000A,0xC40008,0xC40008,0xC40008,0x447C0001,0x447C0001,0x427C0001,0x18C0008,0x18C0008,0x42740001,0x4000000A,0x18C0008,0x18C0008,0x42740001,0x4000000A,0x4000000A,0x74780000,0x78800000,0x840008,0x58780000,0x4E780000,0x4A780000,0x467C0001,0x46780000,0x70700000,0x56740000,0x1180008,0x42740001, -0x1180008,0x8C0014,0x54880000,0x4C880000,0x48880001,0x2D00012,0x4C800001,0x48840001,0x1AC0012,0x48740001,0x46000012,0x2D00012,0x4C800001,0x48840001,0x1AC0012,0x48740001,0x46000012,0x1AC0012,0x48740001,0x46000012,0x46000012,0x2D00012,0x4C800001,0x48840001,0x1AC0012,0x48740001,0x46000012,0x1AC0012,0x48740001,0x46000012,0x46000012,0x1AC0012, -0x48740001,0x46000012,0x46000012,0x46000012,0x8E700000,0x980012,0x9C880000,0x60740000,0x52740001,0x4E700000,0x48780001,0x486C0001,0x84680000,0x606C0000,0x4A780000,0x46000012,0x12C0012,0x780014,0x780014,0x780014,0x780014,0x780014,0x780014,0x780014,0x780014,0x780014,0x780014,0x4A740000,0x4A740000,0x4A740000,0x4A740000,0x4A740000, -0x4A740000,0x42740000,0x42740000,0x42740000,0x3E740001,0xB40012,0xB40012,0xB40012,0xB40012,0xB40012,0xB40012,0x426C0001,0x426C0001,0x426C0001,0x3E700001,0x1700012,0x1700012,0x1700012,0x3E600001,0x3C000012,0x92740000,0x780014,0x780014,0x62740000,0x56740000,0x4E740000,0x4E740000,0x48740000,0x7A6C0000,0x5C700000,0x44740001,0x426C0001, -0x1000012,}; -static const uint32_t g_etc1_to_bc7_m6_table9[] = { -0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0x18C0000, -0x18C0000,0x18C0000,0x18C0000,0x40000001,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x8C0000,0x8C0000,0x8C0000,0xC40000,0x1180000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000, -0xD40000,0x1B00000,0x1B00000,0x1B00000,0x46000001,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x1B00000,0x1B00000,0x1B00000,0x46000001,0x1B00000,0x1B00000,0x1B00000,0x46000001,0x46000001,0x4980000,0x900000,0x900000,0xA80000,0xB40000,0xC40000,0xC40000,0xF00000,0xA80000,0xB40000,0x1300000,0x1B00000, -0x1300000,0x980000,0x980000,0x980000,0x980000,0xE00000,0xE00000,0xE00000,0x1CC0000,0x1CC0000,0x4A000001,0xE00000,0xE00000,0xE00000,0x1CC0000,0x1CC0000,0x4A000001,0x1CC0000,0x1CC0000,0x4A000001,0x4A000001,0xE00000,0xE00000,0xE00000,0x1CC0000,0x1CC0000,0x4A000001,0x1CC0000,0x1CC0000,0x4A000001,0x4A000001,0x1CC0000, -0x1CC0000,0x4A000001,0x4A000001,0x4A000001,0xB00000,0x8A00000,0x980000,0x2CC0000,0x1000000,0x1400000,0x1740000,0xBFC0000,0x2BC0000,0xE00000,0x1400000,0x4A000001,0x1400000,0xA40000,0xF40000,0x1F00000,0x50000001,0xF40000,0x1F00000,0x50000001,0x1F00000,0x50000001,0x50000001,0xF40000,0x1F00000,0x50000001,0x1F00000,0x50000001, -0x50000001,0x1F00000,0x50000001,0x50000001,0x50000001,0xF40000,0x1F00000,0x50000001,0x1F00000,0x50000001,0x50000001,0x1F00000,0x50000001,0x50000001,0x50000001,0x1F00000,0x50000001,0x50000001,0x50000001,0x50000001,0x2CC0000,0xEAC0000,0xEAC0000,0x1140000,0x1900000,0x27F40000,0x50000001,0x50000001,0x2DC0000,0x1340000,0x47E00000,0x50000001, -0x15C0000,0x940088,0x64900034,0x56900034,0x50900035,0x608C0026,0x568C0015,0x508C0019,0x528C0026,0x50880016,0x4E880026,0x62840033,0x58840009,0x5288000F,0x54840012,0x50840002,0x4E840016,0x52840033,0x5080000F,0x4E80001A,0x4C840033,0xDC0088,0x5C780033,0x50840034,0x56780026,0x527C0013,0x4E800024,0x56700033,0x5078000A,0x4E740013,0x4C780033,0x1BC0088, -0x50640034,0x4E600024,0x4C540033,0x4800008C,0x8A840002,0xCE8C0026,0xE0900034,0x68840001,0x5A840002,0x54840002,0x52840002,0x50840002,0x847C0001,0x64800001,0x52800009,0x4E740013,0x1380088,0x980034,0x60940008,0x54940009,0x50940009,0x5C900012,0x54900001,0x52900001,0x52900012,0x50900005,0x4E900012,0xE40033,0x56880009,0x508C0009,0x54840012,0x50840002, -0x4E880012,0x1D00033,0x50780009,0x4E740012,0x4C000033,0xE40033,0x56880009,0x508C0009,0x54840012,0x50840002,0x4E880012,0x1D00033,0x50780009,0x4E740012,0x4C000033,0x1D00033,0x50780009,0x4E740012,0x4C000033,0x4C000033,0x86880001,0xB0900012,0xC2940008,0x62880001,0x5A840002,0x54840002,0x50880002,0x50800002,0x847C0001,0x60840001,0x52800008,0x4E740012, -0x1480033,0x900034,0x900034,0x900034,0x900034,0x568C0014,0x568C0014,0x568C0014,0x4E8C0014,0x4E8C0014,0x4A880015,0x58840008,0x58840008,0x58840008,0x50840001,0x50840001,0x4C840005,0x4C84000A,0x4C84000A,0x4A840001,0x4884000A,0x2D00033,0x2D00033,0x2D00033,0x527C0012,0x527C0012,0x4A840013,0x50780009,0x50780009,0x4A7C0002,0x487C000A,0x1AC0033, -0x1AC0033,0x4A700013,0x4868000A,0x46000033,0x8A840001,0x9E8C0014,0x900034,0x66840001,0x5A840001,0x54840001,0x52840001,0x4E840001,0x827C0000,0x64800000,0x50840009,0x4A7C0002,0x12C0033,0x940008,0x940008,0x940008,0x940008,0x52900000,0x52900000,0x52900000,0x4C900001,0x4C900001,0x4A900001,0xDC0008,0xDC0008,0xDC0008,0x4C8C0001,0x4C8C0001, -0x4A8C0001,0x1BC0008,0x1BC0008,0x4A840001,0x4800000A,0xDC0008,0xDC0008,0xDC0008,0x4C8C0001,0x4C8C0001,0x4A8C0001,0x1BC0008,0x1BC0008,0x4A840001,0x4800000A,0x1BC0008,0x1BC0008,0x4A840001,0x4800000A,0x4800000A,0x7C880000,0x80900000,0x940008,0x60880000,0x56880000,0x52880000,0x4E8C0001,0x4E880000,0x78800000,0x5E840000,0x1380008,0x4A840001, -0x1380008,0x9C0014,0x5C980000,0x54980000,0x50980001,0x2E80012,0x54900001,0x50940001,0x1DC0012,0x50840001,0x4E000012,0x2E80012,0x54900001,0x50940001,0x1DC0012,0x50840001,0x4E000012,0x1DC0012,0x50840001,0x4E000012,0x4E000012,0x2E80012,0x54900001,0x50940001,0x1DC0012,0x50840001,0x4E000012,0x1DC0012,0x50840001,0x4E000012,0x4E000012,0x1DC0012, -0x50840001,0x4E000012,0x4E000012,0x4E000012,0x96800000,0xA80012,0xA4980000,0x68840000,0x5A840001,0x56800000,0x50880001,0x507C0001,0x8C780000,0x687C0000,0x52880000,0x4E000012,0x1500012,0x880014,0x880014,0x880014,0x880014,0x880014,0x880014,0x880014,0x880014,0x880014,0x880014,0x52840000,0x52840000,0x52840000,0x52840000,0x52840000, -0x52840000,0x4A840000,0x4A840000,0x4A840000,0x46840001,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0x4A7C0001,0x4A7C0001,0x4A7C0001,0x46800001,0x1A00012,0x1A00012,0x1A00012,0x46700001,0x44000012,0x9A840000,0x880014,0x880014,0x6A840000,0x5E840000,0x56840000,0x56840000,0x50840000,0x827C0000,0x64800000,0x4C840001,0x4A7C0001, -0x1240012,}; -static const uint32_t g_etc1_to_bc7_m6_table10[] = { -0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0x1BC0000, -0x1BC0000,0x1BC0000,0x1BC0000,0x48000001,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x69C0000,0x69C0000,0x69C0000,0xDC0000,0x1380000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000, -0xEC0000,0x1E40000,0x1E40000,0x1E40000,0x4E000001,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0x1E40000,0x1E40000,0x1E40000,0x4E000001,0x1E40000,0x1E40000,0x1E40000,0x4E000001,0x4E000001,0xCA80000,0xA00000,0xA00000,0x4B80000,0xC80000,0xD80000,0xD80000,0x10C0000,0x4B80000,0xC80000,0x1540000,0x1E40000, -0x1540000,0xA80000,0xA80000,0xA80000,0xA80000,0xF80000,0xF80000,0xF80000,0x1FC0000,0x1FC0000,0x52000001,0xF80000,0xF80000,0xF80000,0x1FC0000,0x1FC0000,0x52000001,0x1FC0000,0x1FC0000,0x52000001,0x52000001,0xF80000,0xF80000,0xF80000,0x1FC0000,0x1FC0000,0x52000001,0x1FC0000,0x1FC0000,0x52000001,0x52000001,0x1FC0000, -0x1FC0000,0x52000001,0x52000001,0x52000001,0xC40000,0xB40000,0xA80000,0xE40000,0x1180000,0x1640000,0x19C0000,0x17F80000,0x4D00000,0xF80000,0x1640000,0x52000001,0x1640000,0xB40000,0x10C0000,0xBF80000,0x58000001,0x10C0000,0xBF80000,0x58000001,0xBF80000,0x58000001,0x58000001,0x10C0000,0xBF80000,0x58000001,0xBF80000,0x58000001, -0x58000001,0xBF80000,0x58000001,0x58000001,0x58000001,0x10C0000,0xBF80000,0x58000001,0xBF80000,0x58000001,0x58000001,0xBF80000,0x58000001,0x58000001,0x58000001,0xBF80000,0x58000001,0x58000001,0x58000001,0x58000001,0x2E00000,0xC00000,0xC00000,0x32C0000,0x1B80000,0x31F40000,0x58000001,0x58000001,0xF40000,0x1500000,0x4FF00000,0x58000001, -0x17C0000,0xA40088,0x6CA00034,0x5EA00034,0x58A00035,0x689C0026,0x5E9C0015,0x589C0019,0x5A9C0026,0x58980016,0x56980026,0x6A940033,0x60940009,0x5A98000F,0x5C940012,0x58940002,0x56940016,0x5A940033,0x5890000F,0x5690001A,0x54940033,0xF40088,0x64880033,0x58940034,0x5E880026,0x5A8C0013,0x56900024,0x5E800033,0x5888000A,0x56840013,0x54880033,0x1F00088, -0x58740034,0x56700024,0x54640033,0x5000008C,0x92940002,0xD69C0026,0xE8A00034,0x70940001,0x62940002,0x5C940002,0x5A940002,0x58940002,0x8C8C0001,0x6C900001,0x5A900009,0x56840013,0x15C0088,0xA80034,0x68A40008,0x5CA40009,0x58A40009,0x64A00012,0x5CA00001,0x5AA00001,0x5AA00012,0x58A00005,0x56A00012,0xFC0033,0x5E980009,0x589C0009,0x5C940012,0x58940002, -0x56980012,0x3F80033,0x58880009,0x56840012,0x54000033,0xFC0033,0x5E980009,0x589C0009,0x5C940012,0x58940002,0x56980012,0x3F80033,0x58880009,0x56840012,0x54000033,0x3F80033,0x58880009,0x56840012,0x54000033,0x54000033,0x8E980001,0xB8A00012,0xCAA40008,0x6A980001,0x62940002,0x5C940002,0x58980002,0x58900002,0x8C8C0001,0x68940001,0x5A900008,0x56840012, -0x1680033,0xA00034,0xA00034,0xA00034,0xA00034,0x5E9C0014,0x5E9C0014,0x5E9C0014,0x569C0014,0x569C0014,0x52980015,0x60940008,0x60940008,0x60940008,0x58940001,0x58940001,0x54940005,0x5494000A,0x5494000A,0x52940001,0x5094000A,0x2E80033,0x2E80033,0x2E80033,0x5A8C0012,0x5A8C0012,0x52940013,0x58880009,0x58880009,0x528C0002,0x508C000A,0x1DC0033, -0x1DC0033,0x52800013,0x5078000A,0x4E000033,0x92940001,0xA69C0014,0xA00034,0x6E940001,0x62940001,0x5C940001,0x5A940001,0x56940001,0x8A8C0000,0x6C900000,0x58940009,0x528C0002,0x1500033,0xA40008,0xA40008,0xA40008,0xA40008,0x5AA00000,0x5AA00000,0x5AA00000,0x54A00001,0x54A00001,0x52A00001,0xF40008,0xF40008,0xF40008,0x549C0001,0x549C0001, -0x529C0001,0x1F00008,0x1F00008,0x52940001,0x5000000A,0xF40008,0xF40008,0xF40008,0x549C0001,0x549C0001,0x529C0001,0x1F00008,0x1F00008,0x52940001,0x5000000A,0x1F00008,0x1F00008,0x52940001,0x5000000A,0x5000000A,0x84980000,0x88A00000,0xA40008,0x68980000,0x5E980000,0x5A980000,0x569C0001,0x56980000,0x80900000,0x66940000,0x15C0008,0x52940001, -0x15C0008,0xAC0014,0x64A80000,0x5CA80000,0x58A80001,0x3000012,0x5CA00001,0x58A40001,0x5FC0012,0x58940001,0x56000012,0x3000012,0x5CA00001,0x58A40001,0x5FC0012,0x58940001,0x56000012,0x5FC0012,0x58940001,0x56000012,0x56000012,0x3000012,0x5CA00001,0x58A40001,0x5FC0012,0x58940001,0x56000012,0x5FC0012,0x58940001,0x56000012,0x56000012,0x5FC0012, -0x58940001,0x56000012,0x56000012,0x56000012,0x9E900000,0x4B80012,0xACA80000,0x70940000,0x62940001,0x5E900000,0x58980001,0x588C0001,0x94880000,0x708C0000,0x5A980000,0x56000012,0x1700012,0x980014,0x980014,0x980014,0x980014,0x980014,0x980014,0x980014,0x980014,0x980014,0x980014,0x5A940000,0x5A940000,0x5A940000,0x5A940000,0x5A940000, -0x5A940000,0x52940000,0x52940000,0x52940000,0x4E940001,0xE40012,0xE40012,0xE40012,0xE40012,0xE40012,0xE40012,0x528C0001,0x528C0001,0x528C0001,0x4E900001,0x1D00012,0x1D00012,0x1D00012,0x4E800001,0x4C000012,0xA2940000,0x980014,0x980014,0x72940000,0x66940000,0x5E940000,0x5E940000,0x58940000,0x8A8C0000,0x6C900000,0x54940001,0x528C0001, -0x1480012,}; -static const uint32_t g_etc1_to_bc7_m6_table11[] = { -0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0x1F00000, -0x1F00000,0x1F00000,0x1F00000,0x50000001,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xEAC0000,0xEAC0000,0xEAC0000,0xF40000,0x15C0000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000, -0x1040000,0x7FC0000,0x7FC0000,0x7FC0000,0x56000001,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x7FC0000,0x7FC0000,0x7FC0000,0x56000001,0x7FC0000,0x7FC0000,0x7FC0000,0x56000001,0x56000001,0xBC0000,0xB00000,0xB00000,0xCC0000,0xDC0000,0xF00000,0xF00000,0x1280000,0xCC0000,0xDC0000,0x1740000,0x7FC0000, -0x1740000,0xB80000,0xB80000,0xB80000,0xB80000,0x1100000,0x1100000,0x1100000,0xDFC0000,0xDFC0000,0x5A000001,0x1100000,0x1100000,0x1100000,0xDFC0000,0xDFC0000,0x5A000001,0xDFC0000,0xDFC0000,0x5A000001,0x5A000001,0x1100000,0x1100000,0x1100000,0xDFC0000,0xDFC0000,0x5A000001,0xDFC0000,0xDFC0000,0x5A000001,0x5A000001,0xDFC0000, -0xDFC0000,0x5A000001,0x5A000001,0x5A000001,0x2D40000,0xC40000,0xB80000,0x2F80000,0x1340000,0x1880000,0x1C00000,0x21FC0000,0x4E40000,0x1100000,0x1880000,0x5A000001,0x1880000,0xC40000,0x1240000,0x17F80000,0x60000001,0x1240000,0x17F80000,0x60000001,0x17F80000,0x60000001,0x60000001,0x1240000,0x17F80000,0x60000001,0x17F80000,0x60000001, -0x60000001,0x17F80000,0x60000001,0x60000001,0x60000001,0x1240000,0x17F80000,0x60000001,0x17F80000,0x60000001,0x60000001,0x17F80000,0x60000001,0x60000001,0x60000001,0x17F80000,0x60000001,0x60000001,0x60000001,0x60000001,0x2F40000,0xD00000,0xD00000,0x1480000,0x1E00000,0x3BF40000,0x60000001,0x60000001,0x3080000,0x1700000,0x59C40000,0x60000001, -0x1A00000,0xB40088,0x74B00034,0x66B00034,0x60B00035,0x70AC0026,0x66AC0015,0x60AC0019,0x62AC0026,0x60A80016,0x5EA80026,0x72A40033,0x68A40009,0x62A8000F,0x64A40012,0x60A40002,0x5EA40016,0x62A40033,0x60A0000F,0x5EA0001A,0x5CA40033,0x10C0088,0x6C980033,0x60A40034,0x66980026,0x629C0013,0x5EA00024,0x66900033,0x6098000A,0x5E940013,0x5C980033,0xBF80088, -0x60840034,0x5E800024,0x5C740033,0x5800008C,0x9AA40002,0xDEAC0026,0xF0B00034,0x78A40001,0x6AA40002,0x64A40002,0x62A40002,0x60A40002,0x949C0001,0x74A00001,0x62A00009,0x5E940013,0x17C0088,0xB80034,0x70B40008,0x64B40009,0x60B40009,0x6CB00012,0x64B00001,0x62B00001,0x62B00012,0x60B00005,0x5EB00012,0x1140033,0x66A80009,0x60AC0009,0x64A40012,0x60A40002, -0x5EA80012,0xFF80033,0x60980009,0x5E940012,0x5C000033,0x1140033,0x66A80009,0x60AC0009,0x64A40012,0x60A40002,0x5EA80012,0xFF80033,0x60980009,0x5E940012,0x5C000033,0xFF80033,0x60980009,0x5E940012,0x5C000033,0x5C000033,0x96A80001,0xC0B00012,0xD2B40008,0x72A80001,0x6AA40002,0x64A40002,0x60A80002,0x60A00002,0x949C0001,0x70A40001,0x62A00008,0x5E940012, -0x18C0033,0xB00034,0xB00034,0xB00034,0xB00034,0x66AC0014,0x66AC0014,0x66AC0014,0x5EAC0014,0x5EAC0014,0x5AA80015,0x68A40008,0x68A40008,0x68A40008,0x60A40001,0x60A40001,0x5CA40005,0x5CA4000A,0x5CA4000A,0x5AA40001,0x58A4000A,0x3000033,0x3000033,0x3000033,0x629C0012,0x629C0012,0x5AA40013,0x60980009,0x60980009,0x5A9C0002,0x589C000A,0x5FC0033, -0x5FC0033,0x5A900013,0x5888000A,0x56000033,0x9AA40001,0xAEAC0014,0xB00034,0x76A40001,0x6AA40001,0x64A40001,0x62A40001,0x5EA40001,0x929C0000,0x74A00000,0x60A40009,0x5A9C0002,0x1700033,0xB40008,0xB40008,0xB40008,0xB40008,0x62B00000,0x62B00000,0x62B00000,0x5CB00001,0x5CB00001,0x5AB00001,0x10C0008,0x10C0008,0x10C0008,0x5CAC0001,0x5CAC0001, -0x5AAC0001,0xBF80008,0xBF80008,0x5AA40001,0x5800000A,0x10C0008,0x10C0008,0x10C0008,0x5CAC0001,0x5CAC0001,0x5AAC0001,0xBF80008,0xBF80008,0x5AA40001,0x5800000A,0xBF80008,0xBF80008,0x5AA40001,0x5800000A,0x5800000A,0x8CA80000,0x90B00000,0xB40008,0x70A80000,0x66A80000,0x62A80000,0x5EAC0001,0x5EA80000,0x88A00000,0x6EA40000,0x17C0008,0x5AA40001, -0x17C0008,0xBC0014,0x6CB80000,0x64B80000,0x60B80001,0x3180012,0x64B00001,0x60B40001,0x11FC0012,0x60A40001,0x5E000012,0x3180012,0x64B00001,0x60B40001,0x11FC0012,0x60A40001,0x5E000012,0x11FC0012,0x60A40001,0x5E000012,0x5E000012,0x3180012,0x64B00001,0x60B40001,0x11FC0012,0x60A40001,0x5E000012,0x11FC0012,0x60A40001,0x5E000012,0x5E000012,0x11FC0012, -0x60A40001,0x5E000012,0x5E000012,0x5E000012,0xA6A00000,0xCC80012,0xB4B80000,0x78A40000,0x6AA40001,0x66A00000,0x60A80001,0x609C0001,0x9C980000,0x789C0000,0x62A80000,0x5E000012,0x1940012,0xA80014,0xA80014,0xA80014,0xA80014,0xA80014,0xA80014,0xA80014,0xA80014,0xA80014,0xA80014,0x62A40000,0x62A40000,0x62A40000,0x62A40000,0x62A40000, -0x62A40000,0x5AA40000,0x5AA40000,0x5AA40000,0x56A40001,0xFC0012,0xFC0012,0xFC0012,0xFC0012,0xFC0012,0xFC0012,0x5A9C0001,0x5A9C0001,0x5A9C0001,0x56A00001,0x3F80012,0x3F80012,0x3F80012,0x56900001,0x54000012,0xAAA40000,0xA80014,0xA80014,0x7AA40000,0x6EA40000,0x66A40000,0x66A40000,0x60A40000,0x929C0000,0x74A00000,0x5CA40001,0x5A9C0001, -0x1680012,}; -static const uint32_t g_etc1_to_bc7_m6_table12[] = { -0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0xBFC0000, -0xBFC0000,0xBFC0000,0xBFC0000,0x5A000000,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0x8C00000,0x8C00000,0x8C00000,0x30C0000,0x1800000,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000, -0x1200000,0x15F80000,0x15F80000,0x15F80000,0x60000000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x15F80000,0x15F80000,0x15F80000,0x60000000,0x15F80000,0x15F80000,0x15F80000,0x60000000,0x60000000,0xECC0000,0xC00001,0xC00001,0x2E00000,0xF40000,0x1080000,0x1080000,0x1440000,0x2E00000,0xF40000,0x19C0000,0x15F80000, -0x19C0000,0xC80001,0xC80001,0xC80001,0xC80001,0x12C0000,0x12C0000,0x12C0000,0x1BF80000,0x1BF80000,0x64000000,0x12C0000,0x12C0000,0x12C0000,0x1BF80000,0x1BF80000,0x64000000,0x1BF80000,0x1BF80000,0x64000000,0x64000000,0x12C0000,0x12C0000,0x12C0000,0x1BF80000,0x1BF80000,0x64000000,0x1BF80000,0x1BF80000,0x64000000,0x64000000,0x1BF80000, -0x1BF80000,0x64000000,0x64000000,0x64000000,0x6E80000,0xD80000,0xC80001,0x3100000,0x1540000,0x1AC0000,0x1EC0000,0x2DFC0000,0xFC0000,0x12C0000,0x1AC0000,0x64000000,0x1AC0000,0xD40001,0x33C0000,0x23FC0000,0x6A000000,0x33C0000,0x23FC0000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x33C0000,0x23FC0000,0x6A000000,0x23FC0000,0x6A000000, -0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0x33C0000,0x23FC0000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0x6A000000,0x10C0000,0xE40000,0xE40000,0x1680000,0x7F80000,0x45FC0000,0x6A000000,0x6A000000,0x1240000,0x1900000,0x61F40000,0x6A000000, -0x1C80000,0xC4008C,0x80C00033,0x70C00033,0x6AC00033,0x7ABC0024,0x70BC0013,0x6CBC001A,0x6CBC0024,0x68BC0016,0x66BC0026,0x78B80034,0x70B8000A,0x6CB8000F,0x6EB40013,0x6AB40002,0x66B80016,0x6AB80034,0x68B4000F,0x66B40019,0x64B40035,0x3240088,0x74AC0033,0x6AB40033,0x6EAC0026,0x6AB00012,0x66B40026,0x70A00033,0x6AA40009,0x66A80015,0x64AC0034,0x17FC0088, -0x6A900033,0x66980026,0x648C0034,0x62000088,0xA4B80002,0xF6BC0024,0xF8C00034,0x7EB80002,0x72B80002,0x6CB80002,0x6AB80002,0x6AB40002,0xA0AC0001,0x80B00001,0x6AB40009,0x66A80015,0x1A40088,0xCC0033,0x78C8000A,0x6EC4000A,0x6AC4000A,0x72C40013,0x6EC00002,0x6AC40001,0x6AC40013,0x6AC00005,0x66C00015,0x1300033,0x70B80009,0x6ABC000A,0x6EB40012,0x6AB40001, -0x66BC0014,0x1DF40033,0x6AA40008,0x66A80014,0x64000034,0x1300033,0x70B80009,0x6ABC000A,0x6EB40012,0x6AB40001,0x66BC0014,0x1DF40033,0x6AA40008,0x66A80014,0x64000034,0x1DF40033,0x6AA40008,0x66A80014,0x64000034,0x64000034,0xA4B80001,0xBAC40013,0xCCC8000A,0x7EB80001,0x72B80001,0x6CB80001,0x6AB80001,0x6AB40001,0xA0AC0001,0x7CB40001,0x6AB40009,0x66A80014, -0x1B00033,0xC00033,0xC00033,0xC00033,0xC00033,0x72BC0012,0x72BC0012,0x72BC0012,0x68BC0012,0x68BC0012,0x64BC0012,0x70B80009,0x70B80009,0x70B80009,0x68B80002,0x68B80002,0x64B80005,0x66B40009,0x66B40009,0x64B40001,0x62B40009,0x11C0033,0x11C0033,0x11C0033,0x6AB00012,0x6AB00012,0x64B40012,0x68AC0009,0x68AC0009,0x64AC0001,0x62AC0009,0x13FC0033, -0x13FC0033,0x64A00012,0x62940008,0x60000034,0x98B80002,0xC6BC0012,0xC00033,0x7CB80001,0x72B80001,0x6CB80001,0x6AB80002,0x68B40002,0xA0AC0000,0x7AB40001,0x6AB40008,0x64AC0001,0x1980033,0xC4000A,0xC4000A,0xC4000A,0xC4000A,0x6AC40001,0x6AC40001,0x6AC40001,0x66C00001,0x66C00001,0x64C00001,0x3240008,0x3240008,0x3240008,0x66BC0001,0x66BC0001, -0x64BC0001,0x17FC0008,0x17FC0008,0x64B00000,0x62000008,0x3240008,0x3240008,0x3240008,0x66BC0001,0x66BC0001,0x64BC0001,0x17FC0008,0x17FC0008,0x64B00000,0x62000008,0x17FC0008,0x17FC0008,0x64B00000,0x62000008,0x62000008,0x8CBC0000,0x8AC40001,0xC4000A,0x7CB80000,0x6EBC0000,0x6ABC0000,0x68BC0000,0x66BC0001,0x8EB40000,0x76B80000,0x1A40008,0x64B00000, -0x1A40008,0xD00012,0x74CC0001,0x6CCC0001,0x6AC80001,0x1340012,0x6EC00001,0x6AC40000,0x1FF80012,0x6AB00000,0x66000014,0x1340012,0x6EC00001,0x6AC40000,0x1FF80012,0x6AB00000,0x66000014,0x1FF80012,0x6AB00000,0x66000014,0x66000014,0x1340012,0x6EC00001,0x6AC40000,0x1FF80012,0x6AB00000,0x66000014,0x1FF80012,0x6AB00000,0x66000014,0x66000014,0x1FF80012, -0x6AB00000,0x66000014,0x66000014,0x66000014,0xB4B00000,0x6DC0012,0xAECC0001,0x82B40000,0x72B80001,0x6EB40000,0x6AB80000,0x6AA80000,0xA8A80000,0x80B00000,0x6ABC0001,0x66000014,0x1B80012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0xBC0012,0x6AB80001,0x6AB80001,0x6AB80001,0x6AB80001,0x6AB80001, -0x6AB80001,0x62B80001,0x62B80001,0x62B80001,0x60B40001,0x1180012,0x1180012,0x1180012,0x1180012,0x1180012,0x1180012,0x64AC0001,0x64AC0001,0x64AC0001,0x60B00000,0x11F80012,0x11F80012,0x11F80012,0x609C0000,0x5C000014,0xA4B80001,0xBC0012,0xBC0012,0x7CB80001,0x72B80001,0x6CB80001,0x6CB80001,0x68B80001,0xA0AC0000,0x82B00000,0x66B40000,0x64AC0001, -0x1900012,}; -static const uint32_t g_etc1_to_bc7_m6_table13[] = { -0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x17FC0000, -0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xD40000,0xD40000,0xD40000,0x3240000,0x1A40000,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000, -0x1380000,0x21F80000,0x21F80000,0x21F80000,0x68000000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x21F80000,0x21F80000,0x21F80000,0x68000000,0x21F80000,0x21F80000,0x21F80000,0x68000000,0x68000000,0xE00000,0xD00001,0xD00001,0xF40000,0x1080000,0x11C0000,0x11C0000,0x1600000,0xF40000,0x1080000,0x1BC0000,0x21F80000, -0x1BC0000,0xD80001,0xD80001,0xD80001,0xD80001,0x1440000,0x1440000,0x1440000,0x27F80000,0x27F80000,0x6C000000,0x1440000,0x1440000,0x1440000,0x27F80000,0x27F80000,0x6C000000,0x27F80000,0x27F80000,0x6C000000,0x6C000000,0x1440000,0x1440000,0x1440000,0x27F80000,0x27F80000,0x6C000000,0x27F80000,0x27F80000,0x6C000000,0x6C000000,0x27F80000, -0x27F80000,0x6C000000,0x6C000000,0x6C000000,0x2FC0000,0xE80000,0xD80001,0x1280000,0x36C0000,0x1D00000,0x9FC0000,0x39F80000,0x1100000,0x1440000,0x1D00000,0x6C000000,0x1D00000,0xE40001,0x1540000,0x2FFC0000,0x72000000,0x1540000,0x2FFC0000,0x72000000,0x2FFC0000,0x72000000,0x72000000,0x1540000,0x2FFC0000,0x72000000,0x2FFC0000,0x72000000, -0x72000000,0x2FFC0000,0x72000000,0x72000000,0x72000000,0x1540000,0x2FFC0000,0x72000000,0x2FFC0000,0x72000000,0x72000000,0x2FFC0000,0x72000000,0x72000000,0x72000000,0x2FFC0000,0x72000000,0x72000000,0x72000000,0x72000000,0x1200000,0x2F40000,0x2F40000,0x3800000,0x15F80000,0x4FFC0000,0x72000000,0x72000000,0x1380000,0x1B00000,0x6BC80000,0x72000000, -0x1E80000,0xD4008C,0x88D00033,0x78D00033,0x72D00033,0x82CC0024,0x78CC0013,0x74CC001A,0x74CC0024,0x70CC0016,0x6ECC0026,0x80C80034,0x78C8000A,0x74C8000F,0x76C40013,0x72C40002,0x6EC80016,0x72C80034,0x70C4000F,0x6EC40019,0x6CC40035,0x33C0088,0x7CBC0033,0x72C40033,0x76BC0026,0x72C00012,0x6EC40026,0x78B00033,0x72B40009,0x6EB80015,0x6CBC0034,0x23FC0088, -0x72A00033,0x6EA80026,0x6C9C0034,0x6A000088,0xACC80002,0xFECC0024,0xF0D00037,0x86C80002,0x7AC80002,0x74C80002,0x72C80002,0x72C40002,0xA8BC0001,0x88C00001,0x72C40009,0x6EB80015,0x1C80088,0xDC0033,0x80D8000A,0x76D4000A,0x72D4000A,0x7AD40013,0x76D00002,0x72D40001,0x72D40013,0x72D00005,0x6ED00015,0x3440033,0x78C80009,0x72CC000A,0x76C40012,0x72C40001, -0x6ECC0014,0x27FC0033,0x72B40008,0x6EB80014,0x6C000034,0x3440033,0x78C80009,0x72CC000A,0x76C40012,0x72C40001,0x6ECC0014,0x27FC0033,0x72B40008,0x6EB80014,0x6C000034,0x27FC0033,0x72B40008,0x6EB80014,0x6C000034,0x6C000034,0xACC80001,0xC2D40013,0xD4D8000A,0x86C80001,0x7AC80001,0x74C80001,0x72C80001,0x72C40001,0xA8BC0001,0x84C40001,0x72C40009,0x6EB80014, -0x1D40033,0xD00033,0xD00033,0xD00033,0xD00033,0x7ACC0012,0x7ACC0012,0x7ACC0012,0x70CC0012,0x70CC0012,0x6CCC0012,0x78C80009,0x78C80009,0x78C80009,0x70C80002,0x70C80002,0x6CC80005,0x6EC40009,0x6EC40009,0x6CC40001,0x6AC40009,0x1340033,0x1340033,0x1340033,0x72C00012,0x72C00012,0x6CC40012,0x70BC0009,0x70BC0009,0x6CBC0001,0x6ABC0009,0x1FF80033, -0x1FF80033,0x6CB00012,0x6AA40008,0x68000034,0xA0C80002,0xCECC0012,0xD00033,0x84C80001,0x7AC80001,0x74C80001,0x72C80002,0x70C40002,0xA8BC0000,0x82C40001,0x72C40008,0x6CBC0001,0x1B80033,0xD4000A,0xD4000A,0xD4000A,0xD4000A,0x72D40001,0x72D40001,0x72D40001,0x6ED00001,0x6ED00001,0x6CD00001,0x33C0008,0x33C0008,0x33C0008,0x6ECC0001,0x6ECC0001, -0x6CCC0001,0x23FC0008,0x23FC0008,0x6CC00000,0x6A000008,0x33C0008,0x33C0008,0x33C0008,0x6ECC0001,0x6ECC0001,0x6CCC0001,0x23FC0008,0x23FC0008,0x6CC00000,0x6A000008,0x23FC0008,0x23FC0008,0x6CC00000,0x6A000008,0x6A000008,0x94CC0000,0x92D40001,0xD4000A,0x84C80000,0x76CC0000,0x72CC0000,0x70CC0000,0x6ECC0001,0x96C40000,0x7EC80000,0x1C80008,0x6CC00000, -0x1C80008,0xE00012,0x7CDC0001,0x74DC0001,0x72D80001,0x14C0012,0x76D00001,0x72D40000,0x2BF80012,0x72C00000,0x6E000014,0x14C0012,0x76D00001,0x72D40000,0x2BF80012,0x72C00000,0x6E000014,0x2BF80012,0x72C00000,0x6E000014,0x6E000014,0x14C0012,0x76D00001,0x72D40000,0x2BF80012,0x72C00000,0x6E000014,0x2BF80012,0x72C00000,0x6E000014,0x6E000014,0x2BF80012, -0x72C00000,0x6E000014,0x6E000014,0x6E000014,0xBCC00000,0xEEC0012,0xB6DC0001,0x8AC40000,0x7AC80001,0x76C40000,0x72C80000,0x72B80000,0xB0B80000,0x88C00000,0x72CC0001,0x6E000014,0x1DC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0xCC0012,0x72C80001,0x72C80001,0x72C80001,0x72C80001,0x72C80001, -0x72C80001,0x6AC80001,0x6AC80001,0x6AC80001,0x68C40001,0x1300012,0x1300012,0x1300012,0x1300012,0x1300012,0x1300012,0x6CBC0001,0x6CBC0001,0x6CBC0001,0x68C00000,0x1DF40012,0x1DF40012,0x1DF40012,0x68AC0000,0x64000014,0xACC80001,0xCC0012,0xCC0012,0x84C80001,0x7AC80001,0x74C80001,0x74C80001,0x70C80001,0xA8BC0000,0x8AC00000,0x6EC40000,0x6CBC0001, -0x1B00012,}; -static const uint32_t g_etc1_to_bc7_m6_table14[] = { -0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x23FC0000, -0x23FC0000,0x23FC0000,0x23FC0000,0x6A000000,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xE40000,0xE40000,0xE40000,0x33C0000,0x1C80000,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000, -0x1500000,0x2DF80000,0x2DF80000,0x2DF80000,0x70000000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x2DF80000,0x2DF80000,0x2DF80000,0x70000000,0x2DF80000,0x2DF80000,0x2DF80000,0x70000000,0x70000000,0xF00000,0xE00001,0xE00001,0x7040000,0x11C0000,0x1340000,0x1340000,0x17C0000,0x7040000,0x11C0000,0x1E00000,0x2DF80000, -0x1E00000,0xE80001,0xE80001,0xE80001,0xE80001,0x15C0000,0x15C0000,0x15C0000,0x33F80000,0x33F80000,0x74000000,0x15C0000,0x15C0000,0x15C0000,0x33F80000,0x33F80000,0x74000000,0x33F80000,0x33F80000,0x74000000,0x74000000,0x15C0000,0x15C0000,0x15C0000,0x33F80000,0x33F80000,0x74000000,0x33F80000,0x33F80000,0x74000000,0x74000000,0x33F80000, -0x33F80000,0x74000000,0x74000000,0x74000000,0x1100000,0x4F80000,0xE80001,0x33C0000,0x1880000,0x1F00000,0x17FC0000,0x43FC0000,0x1240000,0x15C0000,0x1F00000,0x74000000,0x1F00000,0xF40001,0x16C0000,0x3BFC0000,0x7A000000,0x16C0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x7A000000,0x7A000000,0x16C0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x7A000000, -0x7A000000,0x3BFC0000,0x7A000000,0x7A000000,0x7A000000,0x16C0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x7A000000,0x7A000000,0x3BFC0000,0x7A000000,0x7A000000,0x7A000000,0x3BFC0000,0x7A000000,0x7A000000,0x7A000000,0x7A000000,0x1340000,0xB040000,0xB040000,0x19C0000,0x21FC0000,0x59FC0000,0x7A000000,0x7A000000,0x34C0000,0x1CC0000,0x73D80000,0x7A000000, -0x7FC0000,0xE4008C,0x90E00033,0x80E00033,0x7AE00033,0x8ADC0024,0x80DC0013,0x7CDC001A,0x7CDC0024,0x78DC0016,0x76DC0026,0x88D80034,0x80D8000A,0x7CD8000F,0x7ED40013,0x7AD40002,0x76D80016,0x7AD80034,0x78D4000F,0x76D40019,0x74D40035,0x1540088,0x84CC0033,0x7AD40033,0x7ECC0026,0x7AD00012,0x76D40026,0x80C00033,0x7AC40009,0x76C80015,0x74CC0034,0x2FFC0088, -0x7AB00033,0x76B80026,0x74AC0034,0x72000088,0xB4D80002,0xF6DC0026,0xF8E00037,0x8ED80002,0x82D80002,0x7CD80002,0x7AD80002,0x7AD40002,0xB0CC0001,0x90D00001,0x7AD40009,0x76C80015,0x1E80088,0xEC0033,0x88E8000A,0x7EE4000A,0x7AE4000A,0x82E40013,0x7EE00002,0x7AE40001,0x7AE40013,0x7AE00005,0x76E00015,0x35C0033,0x80D80009,0x7ADC000A,0x7ED40012,0x7AD40001, -0x76DC0014,0x33FC0033,0x7AC40008,0x76C80014,0x74000034,0x35C0033,0x80D80009,0x7ADC000A,0x7ED40012,0x7AD40001,0x76DC0014,0x33FC0033,0x7AC40008,0x76C80014,0x74000034,0x33FC0033,0x7AC40008,0x76C80014,0x74000034,0x74000034,0xB4D80001,0xCAE40013,0xDCE8000A,0x8ED80001,0x82D80001,0x7CD80001,0x7AD80001,0x7AD40001,0xB0CC0001,0x8CD40001,0x7AD40009,0x76C80014, -0x1F40033,0xE00033,0xE00033,0xE00033,0xE00033,0x82DC0012,0x82DC0012,0x82DC0012,0x78DC0012,0x78DC0012,0x74DC0012,0x80D80009,0x80D80009,0x80D80009,0x78D80002,0x78D80002,0x74D80005,0x76D40009,0x76D40009,0x74D40001,0x72D40009,0x14C0033,0x14C0033,0x14C0033,0x7AD00012,0x7AD00012,0x74D40012,0x78CC0009,0x78CC0009,0x74CC0001,0x72CC0009,0x2BF80033, -0x2BF80033,0x74C00012,0x72B40008,0x70000034,0xA8D80002,0xD6DC0012,0xE00033,0x8CD80001,0x82D80001,0x7CD80001,0x7AD80002,0x78D40002,0xB0CC0000,0x8AD40001,0x7AD40008,0x74CC0001,0x1DC0033,0xE4000A,0xE4000A,0xE4000A,0xE4000A,0x7AE40001,0x7AE40001,0x7AE40001,0x76E00001,0x76E00001,0x74E00001,0x1540008,0x1540008,0x1540008,0x76DC0001,0x76DC0001, -0x74DC0001,0x2FFC0008,0x2FFC0008,0x74D00000,0x72000008,0x1540008,0x1540008,0x1540008,0x76DC0001,0x76DC0001,0x74DC0001,0x2FFC0008,0x2FFC0008,0x74D00000,0x72000008,0x2FFC0008,0x2FFC0008,0x74D00000,0x72000008,0x72000008,0x9CDC0000,0x9AE40001,0xE4000A,0x8CD80000,0x7EDC0000,0x7ADC0000,0x78DC0000,0x76DC0001,0x9ED40000,0x86D80000,0x1E80008,0x74D00000, -0x1E80008,0xF00012,0x84EC0001,0x7CEC0001,0x7AE80001,0x1640012,0x7EE00001,0x7AE40000,0x37F80012,0x7AD00000,0x76000014,0x1640012,0x7EE00001,0x7AE40000,0x37F80012,0x7AD00000,0x76000014,0x37F80012,0x7AD00000,0x76000014,0x76000014,0x1640012,0x7EE00001,0x7AE40000,0x37F80012,0x7AD00000,0x76000014,0x37F80012,0x7AD00000,0x76000014,0x76000014,0x37F80012, -0x7AD00000,0x76000014,0x76000014,0x76000014,0xC4D00000,0x1000012,0xBEEC0001,0x92D40000,0x82D80001,0x7ED40000,0x7AD80000,0x7AC80000,0xB8C80000,0x90D00000,0x7ADC0001,0x76000014,0x1FC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0xDC0012,0x7AD80001,0x7AD80001,0x7AD80001,0x7AD80001,0x7AD80001, -0x7AD80001,0x72D80001,0x72D80001,0x72D80001,0x70D40001,0x3440012,0x3440012,0x3440012,0x3440012,0x3440012,0x3440012,0x74CC0001,0x74CC0001,0x74CC0001,0x70D00000,0x27FC0012,0x27FC0012,0x27FC0012,0x70BC0000,0x6C000014,0xB4D80001,0xDC0012,0xDC0012,0x8CD80001,0x82D80001,0x7CD80001,0x7CD80001,0x78D80001,0xB0CC0000,0x92D00000,0x76D40000,0x74CC0001, -0x1D40012,}; -static const uint32_t g_etc1_to_bc7_m6_table15[] = { -0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x2FFC0000, -0x2FFC0000,0x2FFC0000,0x2FFC0000,0x72000000,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0x2F40000,0x2F40000,0x2F40000,0x1540000,0x1E80000,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000, -0x1680000,0x39F80000,0x39F80000,0x39F80000,0x78000000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x39F80000,0x39F80000,0x39F80000,0x78000000,0x39F80000,0x39F80000,0x39F80000,0x78000000,0x78000000,0x9000000,0xF00001,0xF00001,0x3180000,0x1300000,0x1480000,0x1480000,0x3940000,0x3180000,0x1300000,0x3FC0000,0x39F80000, -0x3FC0000,0xF80001,0xF80001,0xF80001,0xF80001,0x1740000,0x1740000,0x1740000,0x3FF80000,0x3FF80000,0x7C000000,0x1740000,0x1740000,0x1740000,0x3FF80000,0x3FF80000,0x7C000000,0x3FF80000,0x3FF80000,0x7C000000,0x7C000000,0x1740000,0x1740000,0x1740000,0x3FF80000,0x3FF80000,0x7C000000,0x3FF80000,0x3FF80000,0x7C000000,0x7C000000,0x3FF80000, -0x3FF80000,0x7C000000,0x7C000000,0x7C000000,0x7200000,0xD080000,0xF80001,0x1540000,0x1A40000,0xBFC0000,0x25FC0000,0x4FF80000,0x1380000,0x1740000,0xBFC0000,0x7C000000,0xBFC0000,0x1040001,0x1840000,0x47FC0000,0x82000000,0x1840000,0x47FC0000,0x82000000,0x47FC0000,0x82000000,0x82000000,0x1840000,0x47FC0000,0x82000000,0x47FC0000,0x82000000, -0x82000000,0x47FC0000,0x82000000,0x82000000,0x82000000,0x1840000,0x47FC0000,0x82000000,0x47FC0000,0x82000000,0x82000000,0x47FC0000,0x82000000,0x82000000,0x82000000,0x47FC0000,0x82000000,0x82000000,0x82000000,0x82000000,0x1480000,0x1180000,0x1180000,0x1B80000,0x2FFC0000,0x65F00000,0x82000000,0x82000000,0x1640000,0x1EC0000,0x7BE80000,0x82000000, -0x17FC0000,0xF4008C,0x98F00033,0x88F00033,0x82F00033,0x92EC0024,0x88EC0013,0x84EC001A,0x84EC0024,0x80EC0016,0x7EEC0026,0x90E80034,0x88E8000A,0x84E8000F,0x86E40013,0x82E40002,0x7EE80016,0x82E80034,0x80E4000F,0x7EE40019,0x7CE40035,0x16C0088,0x8CDC0033,0x82E40033,0x86DC0026,0x82E00012,0x7EE40026,0x88D00033,0x82D40009,0x7ED80015,0x7CDC0034,0x3BFC0088, -0x82C00033,0x7EC80026,0x7CBC0034,0x7A000088,0xBCE80002,0xFEEC0026,0xF0F0003C,0x96E80002,0x8AE80002,0x84E80002,0x82E80002,0x82E40002,0xB8DC0001,0x98E00001,0x82E40009,0x7ED80015,0x7FC0088,0xFC0033,0x90F8000A,0x86F4000A,0x82F4000A,0x8AF40013,0x86F00002,0x82F40001,0x82F40013,0x82F00005,0x7EF00015,0x3740033,0x88E80009,0x82EC000A,0x86E40012,0x82E40001, -0x7EEC0014,0x3FFC0033,0x82D40008,0x7ED80014,0x7C000034,0x3740033,0x88E80009,0x82EC000A,0x86E40012,0x82E40001,0x7EEC0014,0x3FFC0033,0x82D40008,0x7ED80014,0x7C000034,0x3FFC0033,0x82D40008,0x7ED80014,0x7C000034,0x7C000034,0xBCE80001,0xD2F40013,0xE4F8000A,0x96E80001,0x8AE80001,0x84E80001,0x82E80001,0x82E40001,0xB8DC0001,0x94E40001,0x82E40009,0x7ED80014, -0xDFC0033,0xF00033,0xF00033,0xF00033,0xF00033,0x8AEC0012,0x8AEC0012,0x8AEC0012,0x80EC0012,0x80EC0012,0x7CEC0012,0x88E80009,0x88E80009,0x88E80009,0x80E80002,0x80E80002,0x7CE80005,0x7EE40009,0x7EE40009,0x7CE40001,0x7AE40009,0x1640033,0x1640033,0x1640033,0x82E00012,0x82E00012,0x7CE40012,0x80DC0009,0x80DC0009,0x7CDC0001,0x7ADC0009,0x37F80033, -0x37F80033,0x7CD00012,0x7AC40008,0x78000034,0xB0E80002,0xDEEC0012,0xF00033,0x94E80001,0x8AE80001,0x84E80001,0x82E80002,0x80E40002,0xB8DC0000,0x92E40001,0x82E40008,0x7CDC0001,0x1FC0033,0xF4000A,0xF4000A,0xF4000A,0xF4000A,0x82F40001,0x82F40001,0x82F40001,0x7EF00001,0x7EF00001,0x7CF00001,0x16C0008,0x16C0008,0x16C0008,0x7EEC0001,0x7EEC0001, -0x7CEC0001,0x3BFC0008,0x3BFC0008,0x7CE00000,0x7A000008,0x16C0008,0x16C0008,0x16C0008,0x7EEC0001,0x7EEC0001,0x7CEC0001,0x3BFC0008,0x3BFC0008,0x7CE00000,0x7A000008,0x3BFC0008,0x3BFC0008,0x7CE00000,0x7A000008,0x7A000008,0xA4EC0000,0xA2F40001,0xF4000A,0x94E80000,0x86EC0000,0x82EC0000,0x80EC0000,0x7EEC0001,0xA6E40000,0x8EE80000,0x7FC0008,0x7CE00000, -0x7FC0008,0x1000012,0x8CFC0001,0x84FC0001,0x82F80001,0x17C0012,0x86F00001,0x82F40000,0x43F80012,0x82E00000,0x7E000014,0x17C0012,0x86F00001,0x82F40000,0x43F80012,0x82E00000,0x7E000014,0x43F80012,0x82E00000,0x7E000014,0x7E000014,0x17C0012,0x86F00001,0x82F40000,0x43F80012,0x82E00000,0x7E000014,0x43F80012,0x82E00000,0x7E000014,0x7E000014,0x43F80012, -0x82E00000,0x7E000014,0x7E000014,0x7E000014,0xCCE00000,0x1100012,0xC6FC0001,0x9AE40000,0x8AE80001,0x86E40000,0x82E80000,0x82D80000,0xC0D80000,0x98E00000,0x82EC0001,0x7E000014,0x11FC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0xEC0012,0x82E80001,0x82E80001,0x82E80001,0x82E80001,0x82E80001, -0x82E80001,0x7AE80001,0x7AE80001,0x7AE80001,0x78E40001,0x35C0012,0x35C0012,0x35C0012,0x35C0012,0x35C0012,0x35C0012,0x7CDC0001,0x7CDC0001,0x7CDC0001,0x78E00000,0x33FC0012,0x33FC0012,0x33FC0012,0x78CC0000,0x74000014,0xBCE80001,0xEC0012,0xEC0012,0x94E80001,0x8AE80001,0x84E80001,0x84E80001,0x80E80001,0xB8DC0000,0x9AE00000,0x7EE40000,0x7CDC0001, -0x1F40012,}; -static const uint32_t g_etc1_to_bc7_m6_table16[] = { -0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x3DF80000, -0x3DF80000,0x3DF80000,0x3DF80000,0x7A000001,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0x1080000,0x1080000,0x1080000,0x1700000,0x9FC0000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x3800000,0x3800000,0x3800000,0x3800000,0x3800000, -0x3800000,0x45FC0000,0x45FC0000,0x45FC0000,0x80000001,0x3800000,0x3800000,0x3800000,0x3800000,0x3800000,0x3800000,0x45FC0000,0x45FC0000,0x45FC0000,0x80000001,0x45FC0000,0x45FC0000,0x45FC0000,0x80000001,0x80000001,0x3140000,0x1040000,0x1040000,0x52C0000,0x3440000,0x1600000,0x1600000,0x1B40000,0x52C0000,0x3440000,0x15FC0000,0x45FC0000, -0x15FC0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x38C0000,0x38C0000,0x38C0000,0x4BFC0000,0x4BFC0000,0x84000001,0x38C0000,0x38C0000,0x38C0000,0x4BFC0000,0x4BFC0000,0x84000001,0x4BFC0000,0x4BFC0000,0x84000001,0x84000001,0x38C0000,0x38C0000,0x38C0000,0x4BFC0000,0x4BFC0000,0x84000001,0x4BFC0000,0x4BFC0000,0x84000001,0x84000001,0x4BFC0000, -0x4BFC0000,0x84000001,0x84000001,0x84000001,0x1380000,0x71C0000,0x10C0000,0x16C0000,0x3C00000,0x1DF80000,0x35F80000,0x5BF80000,0x1500000,0x38C0000,0x1DF80000,0x84000001,0x1DF80000,0x1180000,0x1A00000,0x55F80000,0x8A000001,0x1A00000,0x55F80000,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x1A00000,0x55F80000,0x8A000001,0x55F80000,0x8A000001, -0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x1A00000,0x55F80000,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x8A000001,0x1600000,0xD280000,0xD280000,0x3D40000,0x3FF80000,0x6FF80000,0x8A000001,0x8A000001,0x17C0000,0xBFC0000,0x85DC0000,0x8A000001, -0x27FC0000,0x1080088,0x9F040034,0x91040034,0x8B040035,0x9B000026,0x91000015,0x8B000019,0x8D000026,0x8AFC0016,0x88FC0026,0x9CF80033,0x92F80009,0x8CFC000F,0x8EF80012,0x8AF80002,0x88F80016,0x8CF80033,0x8AF4000F,0x88F4001A,0x86F80033,0x1880088,0x96EC0033,0x8AF80034,0x90EC0026,0x8CF00013,0x88F40024,0x90E40033,0x8AEC000A,0x88E80013,0x86EC0033,0x49F80088, -0x8AD80034,0x88D40024,0x86C80033,0x8200008C,0xC4F80002,0xF9000028,0xFB040038,0xA2F80001,0x94F80002,0x8EF80002,0x8CF80002,0x8AF80002,0xBEF00001,0x9EF40001,0x8CF40009,0x88E80013,0x19FC0088,0x10C0034,0x9B080008,0x8F080009,0x8B080009,0x97040012,0x8F040001,0x8D040001,0x8D040012,0x8B040005,0x89040012,0x1900033,0x90FC0009,0x8B000009,0x8EF80012,0x8AF80002, -0x88FC0012,0x4DFC0033,0x8AEC0009,0x88E80012,0x86000033,0x1900033,0x90FC0009,0x8B000009,0x8EF80012,0x8AF80002,0x88FC0012,0x4DFC0033,0x8AEC0009,0x88E80012,0x86000033,0x4DFC0033,0x8AEC0009,0x88E80012,0x86000033,0x86000033,0xC0FC0001,0xEB040012,0xFD080008,0x9CFC0001,0x94F80002,0x8EF80002,0x8AFC0002,0x8AF40002,0xBEF00001,0x9AF80001,0x8CF40008,0x88E80012, -0x1FF80033,0x1040034,0x1040034,0x1040034,0x1040034,0x91000014,0x91000014,0x91000014,0x89000014,0x89000014,0x84FC0015,0x92F80008,0x92F80008,0x92F80008,0x8AF80001,0x8AF80001,0x86F80005,0x86F8000A,0x86F8000A,0x84F80001,0x82F8000A,0x1800033,0x1800033,0x1800033,0x8CF00012,0x8CF00012,0x84F80013,0x8AEC0009,0x8AEC0009,0x84F00002,0x82F0000A,0x45F80033, -0x45F80033,0x84E40013,0x82DC000A,0x80000033,0xC4F80001,0xD9000014,0x1040034,0xA0F80001,0x94F80001,0x8EF80001,0x8CF80001,0x88F80001,0xBCF00000,0x9EF40000,0x8AF80009,0x84F00002,0x13FC0033,0x1080008,0x1080008,0x1080008,0x1080008,0x8D040000,0x8D040000,0x8D040000,0x87040001,0x87040001,0x85040001,0x1880008,0x1880008,0x1880008,0x87000001,0x87000001, -0x85000001,0x49F80008,0x49F80008,0x84F80001,0x8200000A,0x1880008,0x1880008,0x1880008,0x87000001,0x87000001,0x85000001,0x49F80008,0x49F80008,0x84F80001,0x8200000A,0x49F80008,0x49F80008,0x84F80001,0x8200000A,0x8200000A,0xB6FC0000,0xBB040000,0x1080008,0x9AFC0000,0x90FC0000,0x8CFC0000,0x89000001,0x88FC0000,0xB2F40000,0x98F80000,0x19FC0008,0x84F80001, -0x19FC0008,0x1100014,0x970C0000,0x8F0C0000,0x8B0C0001,0x1980012,0x8F040001,0x8B080001,0x51F80012,0x8AF80001,0x88000012,0x1980012,0x8F040001,0x8B080001,0x51F80012,0x8AF80001,0x88000012,0x51F80012,0x8AF80001,0x88000012,0x88000012,0x1980012,0x8F040001,0x8B080001,0x51F80012,0x8AF80001,0x88000012,0x51F80012,0x8AF80001,0x88000012,0x88000012,0x51F80012, -0x8AF80001,0x88000012,0x88000012,0x88000012,0xD0F40000,0x1240012,0xDF0C0000,0xA2F80000,0x94F80001,0x90F40000,0x8AFC0001,0x8AF00001,0xC6EC0000,0xA2F00000,0x8CFC0000,0x88000012,0x21FC0012,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0xFC0014,0x8CF80000,0x8CF80000,0x8CF80000,0x8CF80000,0x8CF80000, -0x8CF80000,0x84F80000,0x84F80000,0x84F80000,0x80F80001,0x1780012,0x1780012,0x1780012,0x1780012,0x1780012,0x1780012,0x84F00001,0x84F00001,0x84F00001,0x80F40001,0x41FC0012,0x41FC0012,0x41FC0012,0x80E40001,0x7E000012,0xD4F80000,0xFC0014,0xFC0014,0xA4F80000,0x98F80000,0x90F80000,0x90F80000,0x8AF80000,0xBCF00000,0x9EF40000,0x86F80001,0x84F00001, -0xFFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table17[] = { -0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x49F80000, -0x49F80000,0x49F80000,0x49F80000,0x82000001,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x5180000,0x5180000,0x5180000,0x1880000,0x19FC0000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000, -0x3980000,0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x88000001,0xB240000,0x1140000,0x1140000,0x1400000,0x3580000,0x1780000,0x1780000,0x1D00000,0x1400000,0x3580000,0x23FC0000,0x51FC0000, -0x23FC0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x3A40000,0x3A40000,0x3A40000,0x57FC0000,0x57FC0000,0x8C000001,0x3A40000,0x3A40000,0x3A40000,0x57FC0000,0x57FC0000,0x8C000001,0x57FC0000,0x57FC0000,0x8C000001,0x8C000001,0x3A40000,0x3A40000,0x3A40000,0x57FC0000,0x57FC0000,0x8C000001,0x57FC0000,0x57FC0000,0x8C000001,0x8C000001,0x57FC0000, -0x57FC0000,0x8C000001,0x8C000001,0x8C000001,0x5480000,0xF2C0000,0x11C0000,0x3800000,0x1DC0000,0x2BFC0000,0x41FC0000,0x65FC0000,0x1640000,0x3A40000,0x2BFC0000,0x8C000001,0x2BFC0000,0x1280000,0x1B80000,0x61F80000,0x92000001,0x1B80000,0x61F80000,0x92000001,0x61F80000,0x92000001,0x92000001,0x1B80000,0x61F80000,0x92000001,0x61F80000,0x92000001, -0x92000001,0x61F80000,0x92000001,0x92000001,0x92000001,0x1B80000,0x61F80000,0x92000001,0x61F80000,0x92000001,0x92000001,0x61F80000,0x92000001,0x92000001,0x92000001,0x61F80000,0x92000001,0x92000001,0x92000001,0x92000001,0x1740000,0x13C0000,0x13C0000,0x1F00000,0x4BFC0000,0x79F80000,0x92000001,0x92000001,0x3900000,0x1BFC0000,0x8DEC0000,0x92000001, -0x37FC0000,0x1180088,0xA7140034,0x99140034,0x93140035,0xA3100026,0x99100015,0x93100019,0x95100026,0x930C0016,0x910C0026,0xA5080033,0x9B080009,0x950C000F,0x97080012,0x93080002,0x91080016,0x95080033,0x9304000F,0x9104001A,0x8F080033,0x1A00088,0x9EFC0033,0x93080034,0x98FC0026,0x95000013,0x91040024,0x98F40033,0x92FC000A,0x90F80013,0x8EFC0033,0x55F80088, -0x92E80034,0x90E40024,0x8ED80033,0x8A00008C,0xCD080002,0xF110002E,0xF314003D,0xAB080001,0x9D080002,0x97080002,0x95080002,0x93080002,0xC7000001,0xA7040001,0x95040009,0x90F80013,0x27FC0088,0x11C0034,0xA3180008,0x97180009,0x93180009,0x9F140012,0x97140001,0x95140001,0x95140012,0x93140005,0x91140012,0x1A80033,0x990C0009,0x93100009,0x97080012,0x93080002, -0x910C0012,0x59FC0033,0x92FC0009,0x90F80012,0x8E000033,0x1A80033,0x990C0009,0x93100009,0x97080012,0x93080002,0x910C0012,0x59FC0033,0x92FC0009,0x90F80012,0x8E000033,0x59FC0033,0x92FC0009,0x90F80012,0x8E000033,0x8E000033,0xC90C0001,0xF3140012,0xF5180009,0xA50C0001,0x9D080002,0x97080002,0x930C0002,0x93040002,0xC7000001,0xA3080001,0x95040008,0x90F80012, -0x2DFC0033,0x1140034,0x1140034,0x1140034,0x1140034,0x99100014,0x99100014,0x99100014,0x91100014,0x91100014,0x8D0C0015,0x9B080008,0x9B080008,0x9B080008,0x93080001,0x93080001,0x8F080005,0x8F08000A,0x8F08000A,0x8D080001,0x8B08000A,0x1980033,0x1980033,0x1980033,0x95000012,0x95000012,0x8D080013,0x92FC0009,0x92FC0009,0x8D000002,0x8B00000A,0x51F80033, -0x51F80033,0x8CF40013,0x8AEC000A,0x88000033,0xCD080001,0xE1100014,0x1140034,0xA9080001,0x9D080001,0x97080001,0x95080001,0x91080001,0xC5000000,0xA7040000,0x93080009,0x8D000002,0x21FC0033,0x1180008,0x1180008,0x1180008,0x1180008,0x95140000,0x95140000,0x95140000,0x8F140001,0x8F140001,0x8D140001,0x1A00008,0x1A00008,0x1A00008,0x8F100001,0x8F100001, -0x8D100001,0x55F80008,0x55F80008,0x8D080001,0x8A00000A,0x1A00008,0x1A00008,0x1A00008,0x8F100001,0x8F100001,0x8D100001,0x55F80008,0x55F80008,0x8D080001,0x8A00000A,0x55F80008,0x55F80008,0x8D080001,0x8A00000A,0x8A00000A,0xBF0C0000,0xC3140000,0x1180008,0xA30C0000,0x990C0000,0x950C0000,0x91100001,0x910C0000,0xBB040000,0xA1080000,0x27FC0008,0x8D080001, -0x27FC0008,0x1200014,0x9F1C0000,0x971C0000,0x931C0001,0x1B00012,0x97140001,0x93180001,0x5DF40012,0x93080001,0x90000012,0x1B00012,0x97140001,0x93180001,0x5DF40012,0x93080001,0x90000012,0x5DF40012,0x93080001,0x90000012,0x90000012,0x1B00012,0x97140001,0x93180001,0x5DF40012,0x93080001,0x90000012,0x5DF40012,0x93080001,0x90000012,0x90000012,0x5DF40012, -0x93080001,0x90000012,0x90000012,0x90000012,0xD9040000,0x3340012,0xE71C0000,0xAB080000,0x9D080001,0x99040000,0x930C0001,0x93000001,0xCEFC0000,0xAB000000,0x950C0000,0x90000012,0x31FC0012,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x10C0014,0x95080000,0x95080000,0x95080000,0x95080000,0x95080000, -0x95080000,0x8D080000,0x8D080000,0x8D080000,0x89080001,0x1900012,0x1900012,0x1900012,0x1900012,0x1900012,0x1900012,0x8D000001,0x8D000001,0x8D000001,0x89040001,0x4DFC0012,0x4DFC0012,0x4DFC0012,0x88F40001,0x86000012,0xDD080000,0x10C0014,0x10C0014,0xAD080000,0xA1080000,0x99080000,0x99080000,0x93080000,0xC5000000,0xA7040000,0x8F080001,0x8D000001, -0x1FF80012,}; -static const uint32_t g_etc1_to_bc7_m6_table18[] = { -0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x55F80000, -0x55F80000,0x55F80000,0x55F80000,0x8A000001,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0xD280000,0xD280000,0xD280000,0x1A00000,0x27FC0000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000, -0x3B00000,0x5DFC0000,0x5DFC0000,0x5DFC0000,0x90000001,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x5DFC0000,0x5DFC0000,0x5DFC0000,0x90000001,0x5DFC0000,0x5DFC0000,0x5DFC0000,0x90000001,0x90000001,0x1380000,0x1240000,0x1240000,0x1540000,0x36C0000,0x18C0000,0x18C0000,0x1EC0000,0x1540000,0x36C0000,0x33FC0000,0x5DFC0000, -0x33FC0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x3BC0000,0x3BC0000,0x3BC0000,0x63FC0000,0x63FC0000,0x94000001,0x3BC0000,0x3BC0000,0x3BC0000,0x63FC0000,0x63FC0000,0x94000001,0x63FC0000,0x63FC0000,0x94000001,0x94000001,0x3BC0000,0x3BC0000,0x3BC0000,0x63FC0000,0x63FC0000,0x94000001,0x63FC0000,0x63FC0000,0x94000001,0x94000001,0x63FC0000, -0x63FC0000,0x94000001,0x94000001,0x94000001,0x15C0000,0x1400000,0x12C0000,0x1980000,0x1F80000,0x3BFC0000,0x4FFC0000,0x71F80000,0x1780000,0x3BC0000,0x3BFC0000,0x94000001,0x3BFC0000,0x1380000,0x1D00000,0x6DF80000,0x9A000001,0x1D00000,0x6DF80000,0x9A000001,0x6DF80000,0x9A000001,0x9A000001,0x1D00000,0x6DF80000,0x9A000001,0x6DF80000,0x9A000001, -0x9A000001,0x6DF80000,0x9A000001,0x9A000001,0x9A000001,0x1D00000,0x6DF80000,0x9A000001,0x6DF80000,0x9A000001,0x9A000001,0x6DF80000,0x9A000001,0x9A000001,0x9A000001,0x6DF80000,0x9A000001,0x9A000001,0x9A000001,0x9A000001,0x1880000,0x14C0000,0x14C0000,0xDFC0000,0x59FC0000,0x83F80000,0x9A000001,0x9A000001,0x1A80000,0x2DFC0000,0x95FC0000,0x9A000001, -0x45FC0000,0x1280088,0xAF240034,0xA1240034,0x9B240035,0xAB200026,0xA1200015,0x9B200019,0x9D200026,0x9B1C0016,0x991C0026,0xAD180033,0xA3180009,0x9D1C000F,0x9F180012,0x9B180002,0x99180016,0x9D180033,0x9B14000F,0x9914001A,0x97180033,0x1B80088,0xA70C0033,0x9B180034,0xA10C0026,0x9D100013,0x99140024,0xA1040033,0x9B0C000A,0x99080013,0x970C0033,0x61F80088, -0x9AF80034,0x98F40024,0x96E80033,0x9200008C,0xD5180002,0xF920002E,0xFB24003D,0xB3180001,0xA5180002,0x9F180002,0x9D180002,0x9B180002,0xCF100001,0xAF140001,0x9D140009,0x99080013,0x37FC0088,0x12C0034,0xAB280008,0x9F280009,0x9B280009,0xA7240012,0x9F240001,0x9D240001,0x9D240012,0x9B240005,0x99240012,0x1C00033,0xA11C0009,0x9B200009,0x9F180012,0x9B180002, -0x991C0012,0x65F80033,0x9B0C0009,0x99080012,0x96000033,0x1C00033,0xA11C0009,0x9B200009,0x9F180012,0x9B180002,0x991C0012,0x65F80033,0x9B0C0009,0x99080012,0x96000033,0x65F80033,0x9B0C0009,0x99080012,0x96000033,0x96000033,0xD11C0001,0xFB240012,0xFD280009,0xAD1C0001,0xA5180002,0x9F180002,0x9B1C0002,0x9B140002,0xCF100001,0xAB180001,0x9D140008,0x99080012, -0x3DF80033,0x1240034,0x1240034,0x1240034,0x1240034,0xA1200014,0xA1200014,0xA1200014,0x99200014,0x99200014,0x951C0015,0xA3180008,0xA3180008,0xA3180008,0x9B180001,0x9B180001,0x97180005,0x9718000A,0x9718000A,0x95180001,0x9318000A,0x1B00033,0x1B00033,0x1B00033,0x9D100012,0x9D100012,0x95180013,0x9B0C0009,0x9B0C0009,0x95100002,0x9310000A,0x5DF40033, -0x5DF40033,0x95040013,0x92FC000A,0x90000033,0xD5180001,0xE9200014,0x1240034,0xB1180001,0xA5180001,0x9F180001,0x9D180001,0x99180001,0xCD100000,0xAF140000,0x9B180009,0x95100002,0x31FC0033,0x1280008,0x1280008,0x1280008,0x1280008,0x9D240000,0x9D240000,0x9D240000,0x97240001,0x97240001,0x95240001,0x1B80008,0x1B80008,0x1B80008,0x97200001,0x97200001, -0x95200001,0x61F80008,0x61F80008,0x95180001,0x9200000A,0x1B80008,0x1B80008,0x1B80008,0x97200001,0x97200001,0x95200001,0x61F80008,0x61F80008,0x95180001,0x9200000A,0x61F80008,0x61F80008,0x95180001,0x9200000A,0x9200000A,0xC71C0000,0xCB240000,0x1280008,0xAB1C0000,0xA11C0000,0x9D1C0000,0x99200001,0x991C0000,0xC3140000,0xA9180000,0x37FC0008,0x95180001, -0x37FC0008,0x1300014,0xA72C0000,0x9F2C0000,0x9B2C0001,0x3C40012,0x9F240001,0x9B280001,0x67FC0012,0x9B180001,0x98000012,0x3C40012,0x9F240001,0x9B280001,0x67FC0012,0x9B180001,0x98000012,0x67FC0012,0x9B180001,0x98000012,0x98000012,0x3C40012,0x9F240001,0x9B280001,0x67FC0012,0x9B180001,0x98000012,0x67FC0012,0x9B180001,0x98000012,0x98000012,0x67FC0012, -0x9B180001,0x98000012,0x98000012,0x98000012,0xE1140000,0xB440012,0xEF2C0000,0xB3180000,0xA5180001,0xA1140000,0x9B1C0001,0x9B100001,0xD70C0000,0xB3100000,0x9D1C0000,0x98000012,0x3FFC0012,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x11C0014,0x9D180000,0x9D180000,0x9D180000,0x9D180000,0x9D180000, -0x9D180000,0x95180000,0x95180000,0x95180000,0x91180001,0x1A80012,0x1A80012,0x1A80012,0x1A80012,0x1A80012,0x1A80012,0x95100001,0x95100001,0x95100001,0x91140001,0x59FC0012,0x59FC0012,0x59FC0012,0x91040001,0x8E000012,0xE5180000,0x11C0014,0x11C0014,0xB5180000,0xA9180000,0xA1180000,0xA1180000,0x9B180000,0xCD100000,0xAF140000,0x97180001,0x95100001, -0x2DFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table19[] = { -0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x61F80000, -0x61F80000,0x61F80000,0x61F80000,0x92000001,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x13C0000,0x13C0000,0x13C0000,0x1B80000,0x37FC0000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000, -0x1C80000,0x69FC0000,0x69FC0000,0x69FC0000,0x98000001,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x69FC0000,0x69FC0000,0x69FC0000,0x98000001,0x69FC0000,0x69FC0000,0x69FC0000,0x98000001,0x98000001,0x1480000,0x1340000,0x1340000,0x5640000,0x3800000,0x1A40000,0x1A40000,0x7FC0000,0x5640000,0x3800000,0x41FC0000,0x69FC0000, -0x41FC0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x1D40000,0x1D40000,0x1D40000,0x6FFC0000,0x6FFC0000,0x9C000001,0x1D40000,0x1D40000,0x1D40000,0x6FFC0000,0x6FFC0000,0x9C000001,0x6FFC0000,0x6FFC0000,0x9C000001,0x9C000001,0x1D40000,0x1D40000,0x1D40000,0x6FFC0000,0x6FFC0000,0x9C000001,0x6FFC0000,0x6FFC0000,0x9C000001,0x9C000001,0x6FFC0000, -0x6FFC0000,0x9C000001,0x9C000001,0x9C000001,0x1700000,0x1500000,0x13C0000,0x3AC0000,0x11FC0000,0x49FC0000,0x5DF80000,0x7BFC0000,0x18C0000,0x1D40000,0x49FC0000,0x9C000001,0x49FC0000,0x1480000,0x1E80000,0x79F80000,0xA2000001,0x1E80000,0x79F80000,0xA2000001,0x79F80000,0xA2000001,0xA2000001,0x1E80000,0x79F80000,0xA2000001,0x79F80000,0xA2000001, -0xA2000001,0x79F80000,0xA2000001,0xA2000001,0xA2000001,0x1E80000,0x79F80000,0xA2000001,0x79F80000,0xA2000001,0xA2000001,0x79F80000,0xA2000001,0xA2000001,0xA2000001,0x79F80000,0xA2000001,0xA2000001,0xA2000001,0xA2000001,0x19C0000,0x75C0000,0x75C0000,0x21FC0000,0x67F80000,0x8DF80000,0xA2000001,0xA2000001,0x3BC0000,0x3DFC0000,0x9FD00000,0xA2000001, -0x55FC0000,0x1380088,0xB7340034,0xA9340034,0xA3340035,0xB3300026,0xA9300015,0xA3300019,0xA5300026,0xA32C0016,0xA12C0026,0xB5280033,0xAB280009,0xA52C000F,0xA7280012,0xA3280002,0xA1280016,0xA5280033,0xA324000F,0xA124001A,0x9F280033,0x1D00088,0xAF1C0033,0xA3280034,0xA91C0026,0xA5200013,0xA1240024,0xA9140033,0xA31C000A,0xA1180013,0x9F1C0033,0x6DF80088, -0xA3080034,0xA1040024,0x9EF80033,0x9A00008C,0xDD280002,0xF1300038,0xF3340044,0xBB280001,0xAD280002,0xA7280002,0xA5280002,0xA3280002,0xD7200001,0xB7240001,0xA5240009,0xA1180013,0x45FC0088,0x13C0034,0xB3380008,0xA7380009,0xA3380009,0xAF340012,0xA7340001,0xA5340001,0xA5340012,0xA3340005,0xA1340012,0x1D80033,0xA92C0009,0xA3300009,0xA7280012,0xA3280002, -0xA12C0012,0x71F80033,0xA31C0009,0xA1180012,0x9E000033,0x1D80033,0xA92C0009,0xA3300009,0xA7280012,0xA3280002,0xA12C0012,0x71F80033,0xA31C0009,0xA1180012,0x9E000033,0x71F80033,0xA31C0009,0xA1180012,0x9E000033,0x9E000033,0xD92C0001,0xF3340014,0xF538000C,0xB52C0001,0xAD280002,0xA7280002,0xA32C0002,0xA3240002,0xD7200001,0xB3280001,0xA5240008,0xA1180012, -0x4BFC0033,0x1340034,0x1340034,0x1340034,0x1340034,0xA9300014,0xA9300014,0xA9300014,0xA1300014,0xA1300014,0x9D2C0015,0xAB280008,0xAB280008,0xAB280008,0xA3280001,0xA3280001,0x9F280005,0x9F28000A,0x9F28000A,0x9D280001,0x9B28000A,0x3C40033,0x3C40033,0x3C40033,0xA5200012,0xA5200012,0x9D280013,0xA31C0009,0xA31C0009,0x9D200002,0x9B20000A,0x67FC0033, -0x67FC0033,0x9D140013,0x9B0C000A,0x98000033,0xDD280001,0xF1300014,0x1340034,0xB9280001,0xAD280001,0xA7280001,0xA5280001,0xA1280001,0xD5200000,0xB7240000,0xA3280009,0x9D200002,0x3FFC0033,0x1380008,0x1380008,0x1380008,0x1380008,0xA5340000,0xA5340000,0xA5340000,0x9F340001,0x9F340001,0x9D340001,0x1D00008,0x1D00008,0x1D00008,0x9F300001,0x9F300001, -0x9D300001,0x6DF80008,0x6DF80008,0x9D280001,0x9A00000A,0x1D00008,0x1D00008,0x1D00008,0x9F300001,0x9F300001,0x9D300001,0x6DF80008,0x6DF80008,0x9D280001,0x9A00000A,0x6DF80008,0x6DF80008,0x9D280001,0x9A00000A,0x9A00000A,0xCF2C0000,0xD3340000,0x1380008,0xB32C0000,0xA92C0000,0xA52C0000,0xA1300001,0xA12C0000,0xCB240000,0xB1280000,0x45FC0008,0x9D280001, -0x45FC0008,0x1400014,0xAF3C0000,0xA73C0000,0xA33C0001,0x3DC0012,0xA7340001,0xA3380001,0x73FC0012,0xA3280001,0xA0000012,0x3DC0012,0xA7340001,0xA3380001,0x73FC0012,0xA3280001,0xA0000012,0x73FC0012,0xA3280001,0xA0000012,0xA0000012,0x3DC0012,0xA7340001,0xA3380001,0x73FC0012,0xA3280001,0xA0000012,0x73FC0012,0xA3280001,0xA0000012,0xA0000012,0x73FC0012, -0xA3280001,0xA0000012,0xA0000012,0xA0000012,0xE9240000,0x1580012,0xF73C0000,0xBB280000,0xAD280001,0xA9240000,0xA32C0001,0xA3200001,0xDF1C0000,0xBB200000,0xA52C0000,0xA0000012,0x4FFC0012,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0x12C0014,0xA5280000,0xA5280000,0xA5280000,0xA5280000,0xA5280000, -0xA5280000,0x9D280000,0x9D280000,0x9D280000,0x99280001,0x1C00012,0x1C00012,0x1C00012,0x1C00012,0x1C00012,0x1C00012,0x9D200001,0x9D200001,0x9D200001,0x99240001,0x65F80012,0x65F80012,0x65F80012,0x99140001,0x96000012,0xED280000,0x12C0014,0x12C0014,0xBD280000,0xB1280000,0xA9280000,0xA9280000,0xA3280000,0xD5200000,0xB7240000,0x9F280001,0x9D200001, -0x3DF80012,}; -static const uint32_t g_etc1_to_bc7_m6_table20[] = { -0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x6DFC0000, -0x6DFC0000,0x6DFC0000,0x6DFC0000,0x9C000000,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0xF4C0000,0xF4C0000,0xF4C0000,0x3D00000,0x47FC0000,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000, -0x1E40000,0x77F80000,0x77F80000,0x77F80000,0xA2000000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x77F80000,0x77F80000,0x77F80000,0xA2000000,0x77F80000,0x77F80000,0x77F80000,0xA2000000,0xA2000000,0x15C0000,0x1440001,0x1440001,0x17C0000,0x1980000,0x1BC0000,0x1BC0000,0x1DFC0000,0x17C0000,0x1980000,0x53FC0000,0x77F80000, -0x53FC0000,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x1F00000,0x1F00000,0x1F00000,0x7DF80000,0x7DF80000,0xA6000000,0x1F00000,0x1F00000,0x1F00000,0x7DF80000,0x7DF80000,0xA6000000,0x7DF80000,0x7DF80000,0xA6000000,0xA6000000,0x1F00000,0x1F00000,0x1F00000,0x7DF80000,0x7DF80000,0xA6000000,0x7DF80000,0x7DF80000,0xA6000000,0xA6000000,0x7DF80000, -0x7DF80000,0xA6000000,0xA6000000,0xA6000000,0x1840000,0x1640000,0x14C0001,0x3C40000,0x27FC0000,0x5BFC0000,0x6BFC0000,0x87FC0000,0x5A00000,0x1F00000,0x5BFC0000,0xA6000000,0x5BFC0000,0x1580001,0x7FC0000,0x85FC0000,0xAC000000,0x7FC0000,0x85FC0000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0x7FC0000,0x85FC0000,0xAC000000,0x85FC0000,0xAC000000, -0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0x7FC0000,0x85FC0000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0xAC000000,0x3B00000,0x1700000,0x1700000,0x37FC0000,0x75FC0000,0x99F40000,0xAC000000,0xAC000000,0x3D40000,0x51FC0000,0xA9C40000,0xAC000000, -0x65FC0000,0x148008C,0xC3440033,0xB3440033,0xAD440033,0xBD400024,0xB3400013,0xAF40001A,0xAF400024,0xAB400016,0xA9400026,0xBB3C0034,0xB33C000A,0xAF3C000F,0xB1380013,0xAD380002,0xA93C0016,0xAD3C0034,0xAB38000F,0xA9380019,0xA7380035,0x3E80088,0xB7300033,0xAD380033,0xB1300026,0xAD340012,0xA9380026,0xB3240033,0xAD280009,0xA92C0015,0xA7300034,0x79FC0088, -0xAD140033,0xA91C0026,0xA7100034,0xA4000088,0xE73C0002,0xFB440034,0xFD480044,0xC13C0002,0xB53C0002,0xAF3C0002,0xAD3C0002,0xAD380002,0xE3300001,0xC3340001,0xAD380009,0xA92C0015,0x57FC0088,0x1500033,0xBB4C000A,0xB148000A,0xAD48000A,0xB5480013,0xB1440002,0xAD480001,0xAD480013,0xAD440005,0xA9440015,0x1F40033,0xB33C0009,0xAD40000A,0xB1380012,0xAD380001, -0xA9400014,0x7FF80033,0xAD280008,0xA92C0014,0xA6000034,0x1F40033,0xB33C0009,0xAD40000A,0xB1380012,0xAD380001,0xA9400014,0x7FF80033,0xAD280008,0xA92C0014,0xA6000034,0x7FF80033,0xAD280008,0xA92C0014,0xA6000034,0xA6000034,0xE73C0001,0xFD480013,0xFF4C000B,0xC13C0001,0xB53C0001,0xAF3C0001,0xAD3C0001,0xAD380001,0xE3300001,0xBF380001,0xAD380009,0xA92C0014, -0x5DF80033,0x1440033,0x1440033,0x1440033,0x1440033,0xB5400012,0xB5400012,0xB5400012,0xAB400012,0xAB400012,0xA7400012,0xB33C0009,0xB33C0009,0xB33C0009,0xAB3C0002,0xAB3C0002,0xA73C0005,0xA9380009,0xA9380009,0xA7380001,0xA5380009,0x1E00033,0x1E00033,0x1E00033,0xAD340012,0xAD340012,0xA7380012,0xAB300009,0xAB300009,0xA7300001,0xA5300009,0x75FC0033, -0x75FC0033,0xA7240012,0xA5180008,0xA2000034,0xDB3C0002,0xF9400013,0x1440033,0xBF3C0001,0xB53C0001,0xAF3C0001,0xAD3C0002,0xAB380002,0xE3300000,0xBD380001,0xAD380008,0xA7300001,0x51FC0033,0x148000A,0x148000A,0x148000A,0x148000A,0xAD480001,0xAD480001,0xAD480001,0xA9440001,0xA9440001,0xA7440001,0x3E80008,0x3E80008,0x3E80008,0xA9400001,0xA9400001, -0xA7400001,0x79FC0008,0x79FC0008,0xA7340000,0xA4000008,0x3E80008,0x3E80008,0x3E80008,0xA9400001,0xA9400001,0xA7400001,0x79FC0008,0x79FC0008,0xA7340000,0xA4000008,0x79FC0008,0x79FC0008,0xA7340000,0xA4000008,0xA4000008,0xCF400000,0xCD480001,0x148000A,0xBF3C0000,0xB1400000,0xAD400000,0xAB400000,0xA9400001,0xD1380000,0xB93C0000,0x57FC0008,0xA7340000, -0x57FC0008,0x1540012,0xB7500001,0xAF500001,0xAD4C0001,0x1F80012,0xB1440001,0xAD480000,0x81FC0012,0xAD340000,0xA8000014,0x1F80012,0xB1440001,0xAD480000,0x81FC0012,0xAD340000,0xA8000014,0x81FC0012,0xAD340000,0xA8000014,0xA8000014,0x1F80012,0xB1440001,0xAD480000,0x81FC0012,0xAD340000,0xA8000014,0x81FC0012,0xAD340000,0xA8000014,0xA8000014,0x81FC0012, -0xAD340000,0xA8000014,0xA8000014,0xA8000014,0xF7340000,0xD680012,0xF1500001,0xC5380000,0xB53C0001,0xB1380000,0xAD3C0000,0xAD2C0000,0xEB2C0000,0xC3340000,0xAD400001,0xA8000014,0x5FFC0012,0x1400012,0x1400012,0x1400012,0x1400012,0x1400012,0x1400012,0x1400012,0x1400012,0x1400012,0x1400012,0xAD3C0001,0xAD3C0001,0xAD3C0001,0xAD3C0001,0xAD3C0001, -0xAD3C0001,0xA53C0001,0xA53C0001,0xA53C0001,0xA3380001,0x1DC0012,0x1DC0012,0x1DC0012,0x1DC0012,0x1DC0012,0x1DC0012,0xA7300001,0xA7300001,0xA7300001,0xA3340000,0x73F80012,0x73F80012,0x73F80012,0xA3200000,0x9E000014,0xE73C0001,0x1400012,0x1400012,0xBF3C0001,0xB53C0001,0xAF3C0001,0xAF3C0001,0xAB3C0001,0xE3300000,0xC5340000,0xA9380000,0xA7300001, -0x4DFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table21[] = { -0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000, -0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1600000,0x1600000,0x1600000,0x3E80000,0x57FC0000,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000, -0x1FC0000,0x83F80000,0x83F80000,0x83F80000,0xAA000000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x83F80000,0x83F80000,0x83F80000,0xAA000000,0x83F80000,0x83F80000,0x83F80000,0xAA000000,0xAA000000,0x16C0000,0x1540001,0x1540001,0x38C0000,0x1AC0000,0x1D00000,0x1D00000,0x31FC0000,0x38C0000,0x1AC0000,0x61FC0000,0x83F80000, -0x61FC0000,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0xDFC0000,0xDFC0000,0xDFC0000,0x89F80000,0x89F80000,0xAE000000,0xDFC0000,0xDFC0000,0xDFC0000,0x89F80000,0x89F80000,0xAE000000,0x89F80000,0x89F80000,0xAE000000,0xAE000000,0xDFC0000,0xDFC0000,0xDFC0000,0x89F80000,0x89F80000,0xAE000000,0x89F80000,0x89F80000,0xAE000000,0xAE000000,0x89F80000, -0x89F80000,0xAE000000,0xAE000000,0xAE000000,0x1980000,0x3740000,0x15C0001,0x1DC0000,0x3BFC0000,0x69FC0000,0x79FC0000,0x93F80000,0x5B40000,0xDFC0000,0x69FC0000,0xAE000000,0x69FC0000,0x1680001,0x1FFC0000,0x91FC0000,0xB4000000,0x1FFC0000,0x91FC0000,0xB4000000,0x91FC0000,0xB4000000,0xB4000000,0x1FFC0000,0x91FC0000,0xB4000000,0x91FC0000,0xB4000000, -0xB4000000,0x91FC0000,0xB4000000,0xB4000000,0xB4000000,0x1FFC0000,0x91FC0000,0xB4000000,0x91FC0000,0xB4000000,0xB4000000,0x91FC0000,0xB4000000,0xB4000000,0xB4000000,0x91FC0000,0xB4000000,0xB4000000,0xB4000000,0xB4000000,0x3C40000,0x9800000,0x9800000,0x4BFC0000,0x83FC0000,0xA3F40000,0xB4000000,0xB4000000,0x1EC0000,0x63FC0000,0xB1D40000,0xB4000000, -0x75FC0000,0x158008C,0xCB540033,0xBB540033,0xB5540033,0xC5500024,0xBB500013,0xB750001A,0xB7500024,0xB3500016,0xB1500026,0xC34C0034,0xBB4C000A,0xB74C000F,0xB9480013,0xB5480002,0xB14C0016,0xB54C0034,0xB348000F,0xB1480019,0xAF480035,0x7FC0088,0xBF400033,0xB5480033,0xB9400026,0xB5440012,0xB1480026,0xBB340033,0xB5380009,0xB13C0015,0xAF400034,0x85FC0088, -0xB5240033,0xB12C0026,0xAF200034,0xAC000088,0xEF4C0002,0xF354003E,0xF558004B,0xC94C0002,0xBD4C0002,0xB74C0002,0xB54C0002,0xB5480002,0xEB400001,0xCB440001,0xB5480009,0xB13C0015,0x65FC0088,0x1600033,0xC35C000A,0xB958000A,0xB558000A,0xBD580013,0xB9540002,0xB5580001,0xB5580013,0xB5540005,0xB1540015,0xFFC0033,0xBB4C0009,0xB550000A,0xB9480012,0xB5480001, -0xB1500014,0x8BF80033,0xB5380008,0xB13C0014,0xAE000034,0xFFC0033,0xBB4C0009,0xB550000A,0xB9480012,0xB5480001,0xB1500014,0x8BF80033,0xB5380008,0xB13C0014,0xAE000034,0x8BF80033,0xB5380008,0xB13C0014,0xAE000034,0xAE000034,0xEF4C0001,0xF5580015,0xF75C000E,0xC94C0001,0xBD4C0001,0xB74C0001,0xB54C0001,0xB5480001,0xEB400001,0xC7480001,0xB5480009,0xB13C0014, -0x6BFC0033,0x1540033,0x1540033,0x1540033,0x1540033,0xBD500012,0xBD500012,0xBD500012,0xB3500012,0xB3500012,0xAF500012,0xBB4C0009,0xBB4C0009,0xBB4C0009,0xB34C0002,0xB34C0002,0xAF4C0005,0xB1480009,0xB1480009,0xAF480001,0xAD480009,0x1F80033,0x1F80033,0x1F80033,0xB5440012,0xB5440012,0xAF480012,0xB3400009,0xB3400009,0xAF400001,0xAD400009,0x81FC0033, -0x81FC0033,0xAF340012,0xAD280008,0xAA000034,0xE34C0002,0xF1500016,0x1540033,0xC74C0001,0xBD4C0001,0xB74C0001,0xB54C0002,0xB3480002,0xEB400000,0xC5480001,0xB5480008,0xAF400001,0x5FFC0033,0x158000A,0x158000A,0x158000A,0x158000A,0xB5580001,0xB5580001,0xB5580001,0xB1540001,0xB1540001,0xAF540001,0x7FC0008,0x7FC0008,0x7FC0008,0xB1500001,0xB1500001, -0xAF500001,0x85FC0008,0x85FC0008,0xAF440000,0xAC000008,0x7FC0008,0x7FC0008,0x7FC0008,0xB1500001,0xB1500001,0xAF500001,0x85FC0008,0x85FC0008,0xAF440000,0xAC000008,0x85FC0008,0x85FC0008,0xAF440000,0xAC000008,0xAC000008,0xD7500000,0xD5580001,0x158000A,0xC74C0000,0xB9500000,0xB5500000,0xB3500000,0xB1500001,0xD9480000,0xC14C0000,0x65FC0008,0xAF440000, -0x65FC0008,0x1640012,0xBF600001,0xB7600001,0xB55C0001,0x15FC0012,0xB9540001,0xB5580000,0x8DFC0012,0xB5440000,0xB0000014,0x15FC0012,0xB9540001,0xB5580000,0x8DFC0012,0xB5440000,0xB0000014,0x8DFC0012,0xB5440000,0xB0000014,0xB0000014,0x15FC0012,0xB9540001,0xB5580000,0x8DFC0012,0xB5440000,0xB0000014,0x8DFC0012,0xB5440000,0xB0000014,0xB0000014,0x8DFC0012, -0xB5440000,0xB0000014,0xB0000014,0xB0000014,0xFF440000,0x17C0012,0xF9600001,0xCD480000,0xBD4C0001,0xB9480000,0xB54C0000,0xB53C0000,0xF33C0000,0xCB440000,0xB5500001,0xB0000014,0x6FFC0012,0x1500012,0x1500012,0x1500012,0x1500012,0x1500012,0x1500012,0x1500012,0x1500012,0x1500012,0x1500012,0xB54C0001,0xB54C0001,0xB54C0001,0xB54C0001,0xB54C0001, -0xB54C0001,0xAD4C0001,0xAD4C0001,0xAD4C0001,0xAB480001,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0xAF400001,0xAF400001,0xAF400001,0xAB440000,0x7FF80012,0x7FF80012,0x7FF80012,0xAB300000,0xA6000014,0xEF4C0001,0x1500012,0x1500012,0xC74C0001,0xBD4C0001,0xB74C0001,0xB74C0001,0xB34C0001,0xEB400000,0xCD440000,0xB1480000,0xAF400001, -0x5DF80012,}; -static const uint32_t g_etc1_to_bc7_m6_table22[] = { -0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x85FC0000, -0x85FC0000,0x85FC0000,0x85FC0000,0xAC000000,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1700000,0x1700000,0x1700000,0x7FC0000,0x65FC0000,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000, -0x19FC0000,0x8FF80000,0x8FF80000,0x8FF80000,0xB2000000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x8FF80000,0x8FF80000,0x8FF80000,0xB2000000,0x8FF80000,0x8FF80000,0x8FF80000,0xB2000000,0xB2000000,0x77C0000,0x1640001,0x1640001,0x1A00000,0x1C00000,0x1E80000,0x1E80000,0x45FC0000,0x1A00000,0x1C00000,0x71FC0000,0x8FF80000, -0x71FC0000,0x16C0001,0x16C0001,0x16C0001,0x16C0001,0x25FC0000,0x25FC0000,0x25FC0000,0x95F80000,0x95F80000,0xB6000000,0x25FC0000,0x25FC0000,0x25FC0000,0x95F80000,0x95F80000,0xB6000000,0x95F80000,0x95F80000,0xB6000000,0xB6000000,0x25FC0000,0x25FC0000,0x25FC0000,0x95F80000,0x95F80000,0xB6000000,0x95F80000,0x95F80000,0xB6000000,0xB6000000,0x95F80000, -0x95F80000,0xB6000000,0xB6000000,0xB6000000,0x3A80000,0xB840000,0x16C0001,0x3F00000,0x4FFC0000,0x79FC0000,0x87F80000,0x9DFC0000,0x1CC0000,0x25FC0000,0x79FC0000,0xB6000000,0x79FC0000,0x1780001,0x37FC0000,0x9DFC0000,0xBC000000,0x37FC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0xBC000000,0xBC000000,0x37FC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0xBC000000, -0xBC000000,0x9DFC0000,0xBC000000,0xBC000000,0xBC000000,0x37FC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0xBC000000,0xBC000000,0x9DFC0000,0xBC000000,0xBC000000,0xBC000000,0x9DFC0000,0xBC000000,0xBC000000,0xBC000000,0xBC000000,0x3D80000,0x1940000,0x1940000,0x5DFC0000,0x91FC0000,0xADF40000,0xBC000000,0xBC000000,0x9FC0000,0x73FC0000,0xB9E40000,0xBC000000, -0x83FC0000,0x168008C,0xD3640033,0xC3640033,0xBD640033,0xCD600024,0xC3600013,0xBF60001A,0xBF600024,0xBB600016,0xB9600026,0xCB5C0034,0xC35C000A,0xBF5C000F,0xC1580013,0xBD580002,0xB95C0016,0xBD5C0034,0xBB58000F,0xB9580019,0xB7580035,0x1FFC0088,0xC7500033,0xBD580033,0xC1500026,0xBD540012,0xB9580026,0xC3440033,0xBD480009,0xB94C0015,0xB7500034,0x91FC0088, -0xBD340033,0xB93C0026,0xB7300034,0xB4000088,0xF75C0002,0xFB64003E,0xFD68004B,0xD15C0002,0xC55C0002,0xBF5C0002,0xBD5C0002,0xBD580002,0xF3500001,0xD3540001,0xBD580009,0xB94C0015,0x75FC0088,0x1700033,0xCB6C000A,0xC168000A,0xBD68000A,0xC5680013,0xC1640002,0xBD680001,0xBD680013,0xBD640005,0xB9640015,0x29FC0033,0xC35C0009,0xBD60000A,0xC1580012,0xBD580001, -0xB9600014,0x97F80033,0xBD480008,0xB94C0014,0xB6000034,0x29FC0033,0xC35C0009,0xBD60000A,0xC1580012,0xBD580001,0xB9600014,0x97F80033,0xBD480008,0xB94C0014,0xB6000034,0x97F80033,0xBD480008,0xB94C0014,0xB6000034,0xB6000034,0xF75C0001,0xFD680015,0xFF6C000E,0xD15C0001,0xC55C0001,0xBF5C0001,0xBD5C0001,0xBD580001,0xF3500001,0xCF580001,0xBD580009,0xB94C0014, -0x7BFC0033,0x1640033,0x1640033,0x1640033,0x1640033,0xC5600012,0xC5600012,0xC5600012,0xBB600012,0xBB600012,0xB7600012,0xC35C0009,0xC35C0009,0xC35C0009,0xBB5C0002,0xBB5C0002,0xB75C0005,0xB9580009,0xB9580009,0xB7580001,0xB5580009,0x15FC0033,0x15FC0033,0x15FC0033,0xBD540012,0xBD540012,0xB7580012,0xBB500009,0xBB500009,0xB7500001,0xB5500009,0x8DFC0033, -0x8DFC0033,0xB7440012,0xB5380008,0xB2000034,0xEB5C0002,0xF9600016,0x1640033,0xCF5C0001,0xC55C0001,0xBF5C0001,0xBD5C0002,0xBB580002,0xF3500000,0xCD580001,0xBD580008,0xB7500001,0x6FFC0033,0x168000A,0x168000A,0x168000A,0x168000A,0xBD680001,0xBD680001,0xBD680001,0xB9640001,0xB9640001,0xB7640001,0x1FFC0008,0x1FFC0008,0x1FFC0008,0xB9600001,0xB9600001, -0xB7600001,0x91FC0008,0x91FC0008,0xB7540000,0xB4000008,0x1FFC0008,0x1FFC0008,0x1FFC0008,0xB9600001,0xB9600001,0xB7600001,0x91FC0008,0x91FC0008,0xB7540000,0xB4000008,0x91FC0008,0x91FC0008,0xB7540000,0xB4000008,0xB4000008,0xDF600000,0xDD680001,0x168000A,0xCF5C0000,0xC1600000,0xBD600000,0xBB600000,0xB9600001,0xE1580000,0xC95C0000,0x75FC0008,0xB7540000, -0x75FC0008,0x1740012,0xC7700001,0xBF700001,0xBD6C0001,0x2FFC0012,0xC1640001,0xBD680000,0x99FC0012,0xBD540000,0xB8000014,0x2FFC0012,0xC1640001,0xBD680000,0x99FC0012,0xBD540000,0xB8000014,0x99FC0012,0xBD540000,0xB8000014,0xB8000014,0x2FFC0012,0xC1640001,0xBD680000,0x99FC0012,0xBD540000,0xB8000014,0x99FC0012,0xBD540000,0xB8000014,0xB8000014,0x99FC0012, -0xBD540000,0xB8000014,0xB8000014,0xB8000014,0xF15C0001,0x18C0012,0xF1700002,0xD5580000,0xC55C0001,0xC1580000,0xBD5C0000,0xBD4C0000,0xFB4C0000,0xD3540000,0xBD600001,0xB8000014,0x7FF80012,0x1600012,0x1600012,0x1600012,0x1600012,0x1600012,0x1600012,0x1600012,0x1600012,0x1600012,0x1600012,0xBD5C0001,0xBD5C0001,0xBD5C0001,0xBD5C0001,0xBD5C0001, -0xBD5C0001,0xB55C0001,0xB55C0001,0xB55C0001,0xB3580001,0xFFC0012,0xFFC0012,0xFFC0012,0xFFC0012,0xFFC0012,0xFFC0012,0xB7500001,0xB7500001,0xB7500001,0xB3540000,0x8BF80012,0x8BF80012,0x8BF80012,0xB3400000,0xAE000014,0xF75C0001,0x1600012,0x1600012,0xCF5C0001,0xC55C0001,0xBF5C0001,0xBF5C0001,0xBB5C0001,0xF3500000,0xD5540000,0xB9580000,0xB7500001, -0x6BFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table23[] = { -0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x91FC0000, -0x91FC0000,0x91FC0000,0x91FC0000,0xB4000000,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x9800000,0x9800000,0x9800000,0x1FFC0000,0x75FC0000,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000, -0x31FC0000,0x9BF80000,0x9BF80000,0x9BF80000,0xBA000000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x9BF80000,0x9BF80000,0x9BF80000,0xBA000000,0x9BF80000,0x9BF80000,0x9BF80000,0xBA000000,0xBA000000,0xF8C0000,0x1740001,0x1740001,0x1B40000,0x1D40000,0x1FC0000,0x1FC0000,0x59FC0000,0x1B40000,0x1D40000,0x7FFC0000,0x9BF80000, -0x7FFC0000,0x17C0001,0x17C0001,0x17C0001,0x17C0001,0x3DFC0000,0x3DFC0000,0x3DFC0000,0xA1F80000,0xA1F80000,0xBE000000,0x3DFC0000,0x3DFC0000,0x3DFC0000,0xA1F80000,0xA1F80000,0xBE000000,0xA1F80000,0xA1F80000,0xBE000000,0xBE000000,0x3DFC0000,0x3DFC0000,0x3DFC0000,0xA1F80000,0xA1F80000,0xBE000000,0xA1F80000,0xA1F80000,0xBE000000,0xBE000000,0xA1F80000, -0xA1F80000,0xBE000000,0xBE000000,0xBE000000,0x1BC0000,0x1980000,0x17C0001,0xFFC0000,0x63FC0000,0x87FC0000,0x95F80000,0xA9F40000,0x1E00000,0x3DFC0000,0x87FC0000,0xBE000000,0x87FC0000,0x1880001,0x4FFC0000,0xA9FC0000,0xC4000000,0x4FFC0000,0xA9FC0000,0xC4000000,0xA9FC0000,0xC4000000,0xC4000000,0x4FFC0000,0xA9FC0000,0xC4000000,0xA9FC0000,0xC4000000, -0xC4000000,0xA9FC0000,0xC4000000,0xC4000000,0xC4000000,0x4FFC0000,0xA9FC0000,0xC4000000,0xA9FC0000,0xC4000000,0xC4000000,0xA9FC0000,0xC4000000,0xC4000000,0xC4000000,0xA9FC0000,0xC4000000,0xC4000000,0xC4000000,0xC4000000,0x3EC0000,0x1A40000,0x1A40000,0x71FC0000,0x9FF80000,0xB7F40000,0xC4000000,0xC4000000,0x27FC0000,0x85FC0000,0xC1F40000,0xC4000000, -0x93FC0000,0x178008C,0xDB740033,0xCB740033,0xC5740033,0xD5700024,0xCB700013,0xC770001A,0xC7700024,0xC3700016,0xC1700026,0xD36C0034,0xCB6C000A,0xC76C000F,0xC9680013,0xC5680002,0xC16C0016,0xC56C0034,0xC368000F,0xC1680019,0xBF680035,0x37FC0088,0xCF600033,0xC5680033,0xC9600026,0xC5640012,0xC1680026,0xCB540033,0xC5580009,0xC15C0015,0xBF600034,0x9DFC0088, -0xC5440033,0xC14C0026,0xBF400034,0xBC000088,0xFF6C0002,0xF374004C,0xF5780054,0xD96C0002,0xCD6C0002,0xC76C0002,0xC56C0002,0xC5680002,0xFB600001,0xDB640001,0xC5680009,0xC15C0015,0x83FC0088,0x1800033,0xD37C000A,0xC978000A,0xC578000A,0xCD780013,0xC9740002,0xC5780001,0xC5780013,0xC5740005,0xC1740015,0x41FC0033,0xCB6C0009,0xC570000A,0xC9680012,0xC5680001, -0xC1700014,0xA1FC0033,0xC5580008,0xC15C0014,0xBE000034,0x41FC0033,0xCB6C0009,0xC570000A,0xC9680012,0xC5680001,0xC1700014,0xA1FC0033,0xC5580008,0xC15C0014,0xBE000034,0xA1FC0033,0xC5580008,0xC15C0014,0xBE000034,0xBE000034,0xFF6C0001,0xF578001B,0xF77C0013,0xD96C0001,0xCD6C0001,0xC76C0001,0xC56C0001,0xC5680001,0xFB600001,0xD7680001,0xC5680009,0xC15C0014, -0x89FC0033,0x1740033,0x1740033,0x1740033,0x1740033,0xCD700012,0xCD700012,0xCD700012,0xC3700012,0xC3700012,0xBF700012,0xCB6C0009,0xCB6C0009,0xCB6C0009,0xC36C0002,0xC36C0002,0xBF6C0005,0xC1680009,0xC1680009,0xBF680001,0xBD680009,0x2FFC0033,0x2FFC0033,0x2FFC0033,0xC5640012,0xC5640012,0xBF680012,0xC3600009,0xC3600009,0xBF600001,0xBD600009,0x99FC0033, -0x99FC0033,0xBF540012,0xBD480008,0xBA000034,0xF36C0002,0xF170001B,0x1740033,0xD76C0001,0xCD6C0001,0xC76C0001,0xC56C0002,0xC3680002,0xFB600000,0xD5680001,0xC5680008,0xBF600001,0x7FF80033,0x178000A,0x178000A,0x178000A,0x178000A,0xC5780001,0xC5780001,0xC5780001,0xC1740001,0xC1740001,0xBF740001,0x37FC0008,0x37FC0008,0x37FC0008,0xC1700001,0xC1700001, -0xBF700001,0x9DFC0008,0x9DFC0008,0xBF640000,0xBC000008,0x37FC0008,0x37FC0008,0x37FC0008,0xC1700001,0xC1700001,0xBF700001,0x9DFC0008,0x9DFC0008,0xBF640000,0xBC000008,0x9DFC0008,0x9DFC0008,0xBF640000,0xBC000008,0xBC000008,0xE7700000,0xE5780001,0x178000A,0xD76C0000,0xC9700000,0xC5700000,0xC3700000,0xC1700001,0xE9680000,0xD16C0000,0x83FC0008,0xBF640000, -0x83FC0008,0x1840012,0xCF800001,0xC7800001,0xC57C0001,0x47FC0012,0xC9740001,0xC5780000,0xA5F80012,0xC5640000,0xC0000014,0x47FC0012,0xC9740001,0xC5780000,0xA5F80012,0xC5640000,0xC0000014,0xA5F80012,0xC5640000,0xC0000014,0xC0000014,0x47FC0012,0xC9740001,0xC5780000,0xA5F80012,0xC5640000,0xC0000014,0xA5F80012,0xC5640000,0xC0000014,0xC0000014,0xA5F80012, -0xC5640000,0xC0000014,0xC0000014,0xC0000014,0xF96C0001,0x79C0012,0xF9800002,0xDD680000,0xCD6C0001,0xC9680000,0xC56C0000,0xC55C0000,0xF9640001,0xDB640000,0xC5700001,0xC0000014,0x8DFC0012,0x1700012,0x1700012,0x1700012,0x1700012,0x1700012,0x1700012,0x1700012,0x1700012,0x1700012,0x1700012,0xC56C0001,0xC56C0001,0xC56C0001,0xC56C0001,0xC56C0001, -0xC56C0001,0xBD6C0001,0xBD6C0001,0xBD6C0001,0xBB680001,0x29FC0012,0x29FC0012,0x29FC0012,0x29FC0012,0x29FC0012,0x29FC0012,0xBF600001,0xBF600001,0xBF600001,0xBB640000,0x97F80012,0x97F80012,0x97F80012,0xBB500000,0xB6000014,0xFF6C0001,0x1700012,0x1700012,0xD76C0001,0xCD6C0001,0xC76C0001,0xC76C0001,0xC36C0001,0xFB600000,0xDD640000,0xC1680000,0xBF600001, -0x7BFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table24[] = { -0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x9FF80000, -0x9FF80000,0x9FF80000,0x9FF80000,0xBC000001,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x3940000,0x3940000,0x3940000,0x3BFC0000,0x85FC0000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000, -0x4DFC0000,0xA7FC0000,0xA7FC0000,0xA7FC0000,0xC2000001,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0xA7FC0000,0xA7FC0000,0xA7FC0000,0xC2000001,0xA7FC0000,0xA7FC0000,0xA7FC0000,0xC2000001,0xC2000001,0x9A00000,0x1880000,0x1880000,0x1C80000,0x1EC0000,0x23FC0000,0x23FC0000,0x6FFC0000,0x1C80000,0x1EC0000,0x91FC0000,0xA7FC0000, -0x91FC0000,0x1900000,0x1900000,0x1900000,0x1900000,0x59FC0000,0x59FC0000,0x59FC0000,0xADFC0000,0xADFC0000,0xC6000001,0x59FC0000,0x59FC0000,0x59FC0000,0xADFC0000,0xADFC0000,0xC6000001,0xADFC0000,0xADFC0000,0xC6000001,0xC6000001,0x59FC0000,0x59FC0000,0x59FC0000,0xADFC0000,0xADFC0000,0xC6000001,0xADFC0000,0xADFC0000,0xC6000001,0xC6000001,0xADFC0000, -0xADFC0000,0xC6000001,0xC6000001,0xC6000001,0x1D00000,0xDA80000,0x1900000,0x31FC0000,0x79FC0000,0x99FC0000,0xA3FC0000,0xB5F80000,0x3F40000,0x59FC0000,0x99FC0000,0xC6000001,0x99FC0000,0x19C0000,0x6BFC0000,0xB7F80000,0xCC000001,0x6BFC0000,0xB7F80000,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0x6BFC0000,0xB7F80000,0xCC000001,0xB7F80000,0xCC000001, -0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0x6BFC0000,0xB7F80000,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0xCC000001,0x11FC0000,0x1B80000,0x1B80000,0x87FC0000,0xADFC0000,0xC3F00000,0xCC000001,0xCC000001,0x49FC0000,0x97FC0000,0xCBE80000,0xCC000001, -0xA3FC0000,0x18C0088,0xE1880034,0xD3880034,0xCD880035,0xDD840026,0xD3840015,0xCD840019,0xCF840026,0xCD800016,0xCB800026,0xDF7C0033,0xD57C0009,0xCF80000F,0xD17C0012,0xCD7C0002,0xCB7C0016,0xCF7C0033,0xCD78000F,0xCB78001A,0xC97C0033,0x53FC0088,0xD9700033,0xCD7C0034,0xD3700026,0xCF740013,0xCB780024,0xD3680033,0xCD70000A,0xCB6C0013,0xC9700033,0xABF80088, -0xCD5C0034,0xCB580024,0xC94C0033,0xC400008C,0xFF800006,0xFD880048,0xFD880058,0xE57C0001,0xD77C0002,0xD17C0002,0xCF7C0002,0xCD7C0002,0xFF740004,0xE1780001,0xCF780009,0xCB6C0013,0x95FC0088,0x1900034,0xDD8C0008,0xD18C0009,0xCD8C0009,0xD9880012,0xD1880001,0xCF880001,0xCF880012,0xCD880005,0xCB880012,0x5BFC0033,0xD3800009,0xCD840009,0xD17C0012,0xCD7C0002, -0xCB800012,0xAFFC0033,0xCD700009,0xCB6C0012,0xC8000033,0x5BFC0033,0xD3800009,0xCD840009,0xD17C0012,0xCD7C0002,0xCB800012,0xAFFC0033,0xCD700009,0xCB6C0012,0xC8000033,0xAFFC0033,0xCD700009,0xCB6C0012,0xC8000033,0xC8000033,0xFF800002,0xFF8C0018,0xFF8C0018,0xDF800001,0xD77C0002,0xD17C0002,0xCD800002,0xCD780002,0xFB780003,0xDD7C0001,0xCF780008,0xCB6C0012, -0x9BFC0033,0x1880034,0x1880034,0x1880034,0x1880034,0xD3840014,0xD3840014,0xD3840014,0xCB840014,0xCB840014,0xC7800015,0xD57C0008,0xD57C0008,0xD57C0008,0xCD7C0001,0xCD7C0001,0xC97C0005,0xC97C000A,0xC97C000A,0xC77C0001,0xC57C000A,0x49FC0033,0x49FC0033,0x49FC0033,0xCF740012,0xCF740012,0xC77C0013,0xCD700009,0xCD700009,0xC7740002,0xC574000A,0xA7F80033, -0xA7F80033,0xC7680013,0xC560000A,0xC2000033,0xF9800004,0xFB840018,0x1880034,0xE37C0001,0xD77C0001,0xD17C0001,0xCF7C0001,0xCB7C0001,0xFF740000,0xE1780000,0xCD7C0009,0xC7740002,0x8FFC0033,0x18C0008,0x18C0008,0x18C0008,0x18C0008,0xCF880000,0xCF880000,0xCF880000,0xC9880001,0xC9880001,0xC7880001,0x53FC0008,0x53FC0008,0x53FC0008,0xC9840001,0xC9840001, -0xC7840001,0xABF80008,0xABF80008,0xC77C0001,0xC400000A,0x53FC0008,0x53FC0008,0x53FC0008,0xC9840001,0xC9840001,0xC7840001,0xABF80008,0xABF80008,0xC77C0001,0xC400000A,0xABF80008,0xABF80008,0xC77C0001,0xC400000A,0xC400000A,0xF9800000,0xFD880000,0x18C0008,0xDD800000,0xD3800000,0xCF800000,0xCB840001,0xCB800000,0xF5780000,0xDB7C0000,0x95FC0008,0xC77C0001, -0x95FC0008,0x1940014,0xD9900000,0xD1900000,0xCD900001,0x63FC0012,0xD1880001,0xCD8C0001,0xB3F80012,0xCD7C0001,0xCA000012,0x63FC0012,0xD1880001,0xCD8C0001,0xB3F80012,0xCD7C0001,0xCA000012,0xB3F80012,0xCD7C0001,0xCA000012,0xCA000012,0x63FC0012,0xD1880001,0xCD8C0001,0xB3F80012,0xCD7C0001,0xCA000012,0xB3F80012,0xCD7C0001,0xCA000012,0xCA000012,0xB3F80012, -0xCD7C0001,0xCA000012,0xCA000012,0xCA000012,0xF7840002,0x1B00012,0xF3940005,0xE57C0000,0xD77C0001,0xD3780000,0xCD800001,0xCD740001,0xF57C0002,0xE5740000,0xCF800000,0xCA000012,0x9FF80012,0x1800014,0x1800014,0x1800014,0x1800014,0x1800014,0x1800014,0x1800014,0x1800014,0x1800014,0x1800014,0xCF7C0000,0xCF7C0000,0xCF7C0000,0xCF7C0000,0xCF7C0000, -0xCF7C0000,0xC77C0000,0xC77C0000,0xC77C0000,0xC37C0001,0x43FC0012,0x43FC0012,0x43FC0012,0x43FC0012,0x43FC0012,0x43FC0012,0xC7740001,0xC7740001,0xC7740001,0xC3780001,0xA3FC0012,0xA3FC0012,0xA3FC0012,0xC3680001,0xC0000012,0xF77C0004,0x1800014,0x1800014,0xE77C0000,0xDB7C0000,0xD37C0000,0xD37C0000,0xCD7C0000,0xFF740000,0xE1780000,0xC97C0001,0xC7740001, -0x8BFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table25[] = { -0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000, -0xABF80000,0xABF80000,0xABF80000,0xC4000001,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0xBA40000,0xBA40000,0xBA40000,0x53FC0000,0x95FC0000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000, -0x65FC0000,0xB3FC0000,0xB3FC0000,0xB3FC0000,0xCA000001,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0xB3FC0000,0xB3FC0000,0xB3FC0000,0xCA000001,0xB3FC0000,0xB3FC0000,0xB3FC0000,0xCA000001,0xCA000001,0x1B40000,0x1980000,0x1980000,0x5D80000,0x7FC0000,0x41FC0000,0x41FC0000,0x83FC0000,0x5D80000,0x7FC0000,0x9FFC0000,0xB3FC0000, -0x9FFC0000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x71FC0000,0x71FC0000,0x71FC0000,0xB9FC0000,0xB9FC0000,0xCE000001,0x71FC0000,0x71FC0000,0x71FC0000,0xB9FC0000,0xB9FC0000,0xCE000001,0xB9FC0000,0xB9FC0000,0xCE000001,0xCE000001,0x71FC0000,0x71FC0000,0x71FC0000,0xB9FC0000,0xB9FC0000,0xCE000001,0xB9FC0000,0xB9FC0000,0xCE000001,0xCE000001,0xB9FC0000, -0xB9FC0000,0xCE000001,0xCE000001,0xCE000001,0x1E40000,0x1BC0000,0x1A00000,0x4FFC0000,0x8DFC0000,0xA7FC0000,0xB1FC0000,0xBFFC0000,0x1BFC0000,0x71FC0000,0xA7FC0000,0xCE000001,0xA7FC0000,0x1AC0000,0x83FC0000,0xC3F80000,0xD4000001,0x83FC0000,0xC3F80000,0xD4000001,0xC3F80000,0xD4000001,0xD4000001,0x83FC0000,0xC3F80000,0xD4000001,0xC3F80000,0xD4000001, -0xD4000001,0xC3F80000,0xD4000001,0xD4000001,0xD4000001,0x83FC0000,0xC3F80000,0xD4000001,0xC3F80000,0xD4000001,0xD4000001,0xC3F80000,0xD4000001,0xD4000001,0xD4000001,0xC3F80000,0xD4000001,0xD4000001,0xD4000001,0xD4000001,0x37FC0000,0x1C80000,0x1C80000,0x9BFC0000,0xBBFC0000,0xCDF00000,0xD4000001,0xD4000001,0x67FC0000,0xA9FC0000,0xD3F80000,0xD4000001, -0xB3FC0000,0x19C0088,0xE9980034,0xDB980034,0xD5980035,0xE5940026,0xDB940015,0xD5940019,0xD7940026,0xD5900016,0xD3900026,0xE78C0033,0xDD8C0009,0xD790000F,0xD98C0012,0xD58C0002,0xD38C0016,0xD78C0033,0xD588000F,0xD388001A,0xD18C0033,0x6BFC0088,0xE1800033,0xD58C0034,0xDB800026,0xD7840013,0xD3880024,0xDB780033,0xD580000A,0xD37C0013,0xD1800033,0xB7F80088, -0xD56C0034,0xD3680024,0xD15C0033,0xCC00008C,0xFF90000E,0xF5980056,0xF79C0061,0xED8C0001,0xDF8C0002,0xD98C0002,0xD78C0002,0xD58C0002,0xFF880008,0xE9880001,0xD7880009,0xD37C0013,0xA3FC0088,0x1A00034,0xE59C0008,0xD99C0009,0xD59C0009,0xE1980012,0xD9980001,0xD7980001,0xD7980012,0xD5980005,0xD3980012,0x75FC0033,0xDB900009,0xD5940009,0xD98C0012,0xD58C0002, -0xD3900012,0xBBFC0033,0xD5800009,0xD37C0012,0xD0000033,0x75FC0033,0xDB900009,0xD5940009,0xD98C0012,0xD58C0002,0xD3900012,0xBBFC0033,0xD5800009,0xD37C0012,0xD0000033,0xBBFC0033,0xD5800009,0xD37C0012,0xD0000033,0xD0000033,0xFF940003,0xF79C001E,0xF9A00019,0xE7900001,0xDF8C0002,0xD98C0002,0xD5900002,0xD5880002,0xFF880004,0xE58C0001,0xD7880008,0xD37C0012, -0xA9FC0033,0x1980034,0x1980034,0x1980034,0x1980034,0xDB940014,0xDB940014,0xDB940014,0xD3940014,0xD3940014,0xCF900015,0xDD8C0008,0xDD8C0008,0xDD8C0008,0xD58C0001,0xD58C0001,0xD18C0005,0xD18C000A,0xD18C000A,0xCF8C0001,0xCD8C000A,0x63FC0033,0x63FC0033,0x63FC0033,0xD7840012,0xD7840012,0xCF8C0013,0xD5800009,0xD5800009,0xCF840002,0xCD84000A,0xB3F80033, -0xB3F80033,0xCF780013,0xCD70000A,0xCA000033,0xFF900005,0xF394001D,0x1980034,0xEB8C0001,0xDF8C0001,0xD98C0001,0xD78C0001,0xD38C0001,0xFB880002,0xE9880000,0xD58C0009,0xCF840002,0x9FF80033,0x19C0008,0x19C0008,0x19C0008,0x19C0008,0xD7980000,0xD7980000,0xD7980000,0xD1980001,0xD1980001,0xCF980001,0x6BFC0008,0x6BFC0008,0x6BFC0008,0xD1940001,0xD1940001, -0xCF940001,0xB7F80008,0xB7F80008,0xCF8C0001,0xCC00000A,0x6BFC0008,0x6BFC0008,0x6BFC0008,0xD1940001,0xD1940001,0xCF940001,0xB7F80008,0xB7F80008,0xCF8C0001,0xCC00000A,0xB7F80008,0xB7F80008,0xCF8C0001,0xCC00000A,0xCC00000A,0xEB940001,0xF5980001,0x19C0008,0xE5900000,0xDB900000,0xD7900000,0xD3940001,0xD3900000,0xFD880000,0xE38C0000,0xA3FC0008,0xCF8C0001, -0xA3FC0008,0x1A40014,0xE1A00000,0xD9A00000,0xD5A00001,0x7BFC0012,0xD9980001,0xD59C0001,0xBFF80012,0xD58C0001,0xD2000012,0x7BFC0012,0xD9980001,0xD59C0001,0xBFF80012,0xD58C0001,0xD2000012,0xBFF80012,0xD58C0001,0xD2000012,0xD2000012,0x7BFC0012,0xD9980001,0xD59C0001,0xBFF80012,0xD58C0001,0xD2000012,0xBFF80012,0xD58C0001,0xD2000012,0xD2000012,0xBFF80012, -0xD58C0001,0xD2000012,0xD2000012,0xD2000012,0xFF940002,0x9C00012,0xFBA40005,0xED8C0000,0xDF8C0001,0xDB880000,0xD5900001,0xD5840001,0xFD8C0002,0xED840000,0xD7900000,0xD2000012,0xADFC0012,0x1900014,0x1900014,0x1900014,0x1900014,0x1900014,0x1900014,0x1900014,0x1900014,0x1900014,0x1900014,0xD78C0000,0xD78C0000,0xD78C0000,0xD78C0000,0xD78C0000, -0xD78C0000,0xCF8C0000,0xCF8C0000,0xCF8C0000,0xCB8C0001,0x5BFC0012,0x5BFC0012,0x5BFC0012,0x5BFC0012,0x5BFC0012,0x5BFC0012,0xCF840001,0xCF840001,0xCF840001,0xCB880001,0xAFFC0012,0xAFFC0012,0xAFFC0012,0xCB780001,0xC8000012,0xFF8C0004,0x1900014,0x1900014,0xEF8C0000,0xE38C0000,0xDB8C0000,0xDB8C0000,0xD58C0000,0xFB880001,0xE9880000,0xD18C0001,0xCF840001, -0x9BFC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table26[] = { -0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0xB7F80000, -0xB7F80000,0xB7F80000,0xB7F80000,0xCC000001,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x1B80000,0x1B80000,0x1B80000,0x6BFC0000,0xA3FC0000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x7DFC0000,0x7DFC0000,0x7DFC0000,0x7DFC0000,0x7DFC0000, -0x7DFC0000,0xBFFC0000,0xBFFC0000,0xBFFC0000,0xD2000001,0x7DFC0000,0x7DFC0000,0x7DFC0000,0x7DFC0000,0x7DFC0000,0x7DFC0000,0xBFFC0000,0xBFFC0000,0xBFFC0000,0xD2000001,0xBFFC0000,0xBFFC0000,0xBFFC0000,0xD2000001,0xD2000001,0x1C40000,0x1A80000,0x1A80000,0x1EC0000,0x2DFC0000,0x5FFC0000,0x5FFC0000,0x97FC0000,0x1EC0000,0x2DFC0000,0xAFFC0000,0xBFFC0000, -0xAFFC0000,0x1B00000,0x1B00000,0x1B00000,0x1B00000,0x89FC0000,0x89FC0000,0x89FC0000,0xC5FC0000,0xC5FC0000,0xD6000001,0x89FC0000,0x89FC0000,0x89FC0000,0xC5FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xC5FC0000,0xD6000001,0xD6000001,0x89FC0000,0x89FC0000,0x89FC0000,0xC5FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xC5FC0000,0xD6000001,0xD6000001,0xC5FC0000, -0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0x5F40000,0x1CC0000,0x1B00000,0x6FFC0000,0xA1FC0000,0xB7FC0000,0xBFF80000,0xCBF80000,0x41FC0000,0x89FC0000,0xB7FC0000,0xD6000001,0xB7FC0000,0x1BC0000,0x9BFC0000,0xCFF80000,0xDC000001,0x9BFC0000,0xCFF80000,0xDC000001,0xCFF80000,0xDC000001,0xDC000001,0x9BFC0000,0xCFF80000,0xDC000001,0xCFF80000,0xDC000001, -0xDC000001,0xCFF80000,0xDC000001,0xDC000001,0xDC000001,0x9BFC0000,0xCFF80000,0xDC000001,0xCFF80000,0xDC000001,0xDC000001,0xCFF80000,0xDC000001,0xDC000001,0xDC000001,0xCFF80000,0xDC000001,0xDC000001,0xDC000001,0xDC000001,0x5FFC0000,0x5D80000,0x5D80000,0xAFFC0000,0xC9F80000,0xD7F00000,0xDC000001,0xDC000001,0x85FC0000,0xB9FC0000,0xDDCC0000,0xDC000001, -0xC1FC0000,0x1AC0088,0xF1A80034,0xE3A80034,0xDDA80035,0xEDA40026,0xE3A40015,0xDDA40019,0xDFA40026,0xDDA00016,0xDBA00026,0xEF9C0033,0xE59C0009,0xDFA0000F,0xE19C0012,0xDD9C0002,0xDB9C0016,0xDF9C0033,0xDD98000F,0xDB98001A,0xD99C0033,0x83FC0088,0xE9900033,0xDD9C0034,0xE3900026,0xDF940013,0xDB980024,0xE3880033,0xDD90000A,0xDB8C0013,0xD9900033,0xC3F80088, -0xDD7C0034,0xDB780024,0xD96C0033,0xD400008C,0xFFA00016,0xFDA80056,0xFFAC0061,0xF59C0001,0xE79C0002,0xE19C0002,0xDF9C0002,0xDD9C0002,0xFF9C0013,0xF1980001,0xDF980009,0xDB8C0013,0xB3FC0088,0x1B00034,0xEDAC0008,0xE1AC0009,0xDDAC0009,0xE9A80012,0xE1A80001,0xDFA80001,0xDFA80012,0xDDA80005,0xDBA80012,0x8DFC0033,0xE3A00009,0xDDA40009,0xE19C0012,0xDD9C0002, -0xDBA00012,0xC7FC0033,0xDD900009,0xDB8C0012,0xD8000033,0x8DFC0033,0xE3A00009,0xDDA40009,0xE19C0012,0xDD9C0002,0xDBA00012,0xC7FC0033,0xDD900009,0xDB8C0012,0xD8000033,0xC7FC0033,0xDD900009,0xDB8C0012,0xD8000033,0xD8000033,0xF9A80009,0xFFAC001E,0xF1B00020,0xEFA00001,0xE79C0002,0xE19C0002,0xDDA00002,0xDD980002,0xFDA00009,0xED9C0001,0xDF980008,0xDB8C0012, -0xB9FC0033,0x1A80034,0x1A80034,0x1A80034,0x1A80034,0xE3A40014,0xE3A40014,0xE3A40014,0xDBA40014,0xDBA40014,0xD7A00015,0xE59C0008,0xE59C0008,0xE59C0008,0xDD9C0001,0xDD9C0001,0xD99C0005,0xD99C000A,0xD99C000A,0xD79C0001,0xD59C000A,0x7BFC0033,0x7BFC0033,0x7BFC0033,0xDF940012,0xDF940012,0xD79C0013,0xDD900009,0xDD900009,0xD7940002,0xD594000A,0xBFF80033, -0xBFF80033,0xD7880013,0xD580000A,0xD2000033,0xFFA00006,0xFBA4001D,0x1A80034,0xF39C0001,0xE79C0001,0xE19C0001,0xDF9C0001,0xDB9C0001,0xFB980006,0xF1980000,0xDD9C0009,0xD7940002,0xADFC0033,0x1AC0008,0x1AC0008,0x1AC0008,0x1AC0008,0xDFA80000,0xDFA80000,0xDFA80000,0xD9A80001,0xD9A80001,0xD7A80001,0x83FC0008,0x83FC0008,0x83FC0008,0xD9A40001,0xD9A40001, -0xD7A40001,0xC3F80008,0xC3F80008,0xD79C0001,0xD400000A,0x83FC0008,0x83FC0008,0x83FC0008,0xD9A40001,0xD9A40001,0xD7A40001,0xC3F80008,0xC3F80008,0xD79C0001,0xD400000A,0xC3F80008,0xC3F80008,0xD79C0001,0xD400000A,0xD400000A,0xF3A40001,0xFDA80001,0x1AC0008,0xEDA00000,0xE3A00000,0xDFA00000,0xDBA40001,0xDBA00000,0xF5A00001,0xEB9C0000,0xB3FC0008,0xD79C0001, -0xB3FC0008,0x1B40014,0xE9B00000,0xE1B00000,0xDDB00001,0x93FC0012,0xE1A80001,0xDDAC0001,0xCBF80012,0xDD9C0001,0xDA000012,0x93FC0012,0xE1A80001,0xDDAC0001,0xCBF80012,0xDD9C0001,0xDA000012,0xCBF80012,0xDD9C0001,0xDA000012,0xDA000012,0x93FC0012,0xE1A80001,0xDDAC0001,0xCBF80012,0xDD9C0001,0xDA000012,0xCBF80012,0xDD9C0001,0xDA000012,0xDA000012,0xCBF80012, -0xDD9C0001,0xDA000012,0xDA000012,0xDA000012,0xF9A80005,0x1D40012,0xF3B40008,0xF59C0000,0xE79C0001,0xE3980000,0xDDA00001,0xDD940001,0xFBA40005,0xF5940000,0xDFA00000,0xDA000012,0xBDF80012,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0x1A00014,0xDF9C0000,0xDF9C0000,0xDF9C0000,0xDF9C0000,0xDF9C0000, -0xDF9C0000,0xD79C0000,0xD79C0000,0xD79C0000,0xD39C0001,0x75FC0012,0x75FC0012,0x75FC0012,0x75FC0012,0x75FC0012,0x75FC0012,0xD7940001,0xD7940001,0xD7940001,0xD3980001,0xBBFC0012,0xBBFC0012,0xBBFC0012,0xD3880001,0xD0000012,0xF9A00005,0x1A00014,0x1A00014,0xF79C0000,0xEB9C0000,0xE39C0000,0xE39C0000,0xDD9C0000,0xFB980002,0xF1980000,0xD99C0001,0xD7940001, -0xA9FC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table27[] = { -0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0xC3F80000, -0xC3F80000,0xC3F80000,0xC3F80000,0xD4000001,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1C80000,0x1C80000,0x1C80000,0x83FC0000,0xB3FC0000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x95FC0000,0x95FC0000,0x95FC0000,0x95FC0000,0x95FC0000, -0x95FC0000,0xCBFC0000,0xCBFC0000,0xCBFC0000,0xDA000001,0x95FC0000,0x95FC0000,0x95FC0000,0x95FC0000,0x95FC0000,0x95FC0000,0xCBFC0000,0xCBFC0000,0xCBFC0000,0xDA000001,0xCBFC0000,0xCBFC0000,0xCBFC0000,0xDA000001,0xDA000001,0x3D40000,0x1B80000,0x1B80000,0x9FC0000,0x55FC0000,0x7DFC0000,0x7DFC0000,0xABFC0000,0x9FC0000,0x55FC0000,0xBFF80000,0xCBFC0000, -0xBFF80000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xD1FC0000,0xD1FC0000,0xDE000001,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xD1FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xD1FC0000,0xDE000001,0xDE000001,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xD1FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xD1FC0000,0xDE000001,0xDE000001,0xD1FC0000, -0xD1FC0000,0xDE000001,0xDE000001,0xDE000001,0x27FC0000,0x7DC0000,0x1C00000,0x8DFC0000,0xB3FC0000,0xC5FC0000,0xCBFC0000,0xD5FC0000,0x69FC0000,0xA3FC0000,0xC5FC0000,0xDE000001,0xC5FC0000,0x1CC0000,0xB5FC0000,0xDBF80000,0xE4000001,0xB5FC0000,0xDBF80000,0xE4000001,0xDBF80000,0xE4000001,0xE4000001,0xB5FC0000,0xDBF80000,0xE4000001,0xDBF80000,0xE4000001, -0xE4000001,0xDBF80000,0xE4000001,0xE4000001,0xE4000001,0xB5FC0000,0xDBF80000,0xE4000001,0xDBF80000,0xE4000001,0xE4000001,0xDBF80000,0xE4000001,0xE4000001,0xE4000001,0xDBF80000,0xE4000001,0xE4000001,0xE4000001,0xE4000001,0x87FC0000,0xDE80000,0xDE80000,0xC3FC0000,0xD5FC0000,0xE1F00000,0xE4000001,0xE4000001,0xA3FC0000,0xCBFC0000,0xE5DC0000,0xE4000001, -0xD1FC0000,0x1BC0088,0xF9B80034,0xEBB80034,0xE5B80035,0xF5B40026,0xEBB40015,0xE5B40019,0xE7B40026,0xE5B00016,0xE3B00026,0xF7AC0033,0xEDAC0009,0xE7B0000F,0xE9AC0012,0xE5AC0002,0xE3AC0016,0xE7AC0033,0xE5A8000F,0xE3A8001A,0xE1AC0033,0x9BFC0088,0xF1A00033,0xE5AC0034,0xEBA00026,0xE7A40013,0xE3A80024,0xEB980033,0xE5A0000A,0xE39C0013,0xE1A00033,0xCFF80088, -0xE58C0034,0xE3880024,0xE17C0033,0xDC00008C,0xFFB40021,0xF5B80068,0xF7BC006C,0xFDAC0001,0xEFAC0002,0xE9AC0002,0xE7AC0002,0xE5AC0002,0xFDB00021,0xF9A80001,0xE7A80009,0xE39C0013,0xC1FC0088,0x1C00034,0xF5BC0008,0xE9BC0009,0xE5BC0009,0xF1B80012,0xE9B80001,0xE7B80001,0xE7B80012,0xE5B80005,0xE3B80012,0xA5FC0033,0xEBB00009,0xE5B40009,0xE9AC0012,0xE5AC0002, -0xE3B00012,0xD3FC0033,0xE5A00009,0xE39C0012,0xE0000033,0xA5FC0033,0xEBB00009,0xE5B40009,0xE9AC0012,0xE5AC0002,0xE3B00012,0xD3FC0033,0xE5A00009,0xE39C0012,0xE0000033,0xD3FC0033,0xE5A00009,0xE39C0012,0xE0000033,0xE0000033,0xFDB8000E,0xF9C00024,0xF9C00020,0xF7B00001,0xEFAC0002,0xE9AC0002,0xE5B00002,0xE5A80002,0xFDB00011,0xF5AC0001,0xE7A80008,0xE39C0012, -0xC7FC0033,0x1B80034,0x1B80034,0x1B80034,0x1B80034,0xEBB40014,0xEBB40014,0xEBB40014,0xE3B40014,0xE3B40014,0xDFB00015,0xEDAC0008,0xEDAC0008,0xEDAC0008,0xE5AC0001,0xE5AC0001,0xE1AC0005,0xE1AC000A,0xE1AC000A,0xDFAC0001,0xDDAC000A,0x93FC0033,0x93FC0033,0x93FC0033,0xE7A40012,0xE7A40012,0xDFAC0013,0xE5A00009,0xE5A00009,0xDFA40002,0xDDA4000A,0xCBF80033, -0xCBF80033,0xDF980013,0xDD90000A,0xDA000033,0xF9B00011,0xF3B40024,0x1B80034,0xFBAC0001,0xEFAC0001,0xE9AC0001,0xE7AC0001,0xE3AC0001,0xFBAC0009,0xF9A80000,0xE5AC0009,0xDFA40002,0xBDF80033,0x1BC0008,0x1BC0008,0x1BC0008,0x1BC0008,0xE7B80000,0xE7B80000,0xE7B80000,0xE1B80001,0xE1B80001,0xDFB80001,0x9BFC0008,0x9BFC0008,0x9BFC0008,0xE1B40001,0xE1B40001, -0xDFB40001,0xCFF80008,0xCFF80008,0xDFAC0001,0xDC00000A,0x9BFC0008,0x9BFC0008,0x9BFC0008,0xE1B40001,0xE1B40001,0xDFB40001,0xCFF80008,0xCFF80008,0xDFAC0001,0xDC00000A,0xCFF80008,0xCFF80008,0xDFAC0001,0xDC00000A,0xDC00000A,0xFBB40001,0xF5B80004,0x1BC0008,0xF5B00000,0xEBB00000,0xE7B00000,0xE3B40001,0xE3B00000,0xFDB00001,0xF3AC0000,0xC1FC0008,0xDFAC0001, -0xC1FC0008,0x1C40014,0xF1C00000,0xE9C00000,0xE5C00001,0xABFC0012,0xE9B80001,0xE5BC0001,0xD7F80012,0xE5AC0001,0xE2000012,0xABFC0012,0xE9B80001,0xE5BC0001,0xD7F80012,0xE5AC0001,0xE2000012,0xD7F80012,0xE5AC0001,0xE2000012,0xE2000012,0xABFC0012,0xE9B80001,0xE5BC0001,0xD7F80012,0xE5AC0001,0xE2000012,0xD7F80012,0xE5AC0001,0xE2000012,0xE2000012,0xD7F80012, -0xE5AC0001,0xE2000012,0xE2000012,0xE2000012,0xFBBC0008,0x1E40012,0xFBC40008,0xFDAC0000,0xEFAC0001,0xEBA80000,0xE5B00001,0xE5A40001,0xF3BC0008,0xFDA40000,0xE7B00000,0xE2000012,0xCBFC0012,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0x1B00014,0xE7AC0000,0xE7AC0000,0xE7AC0000,0xE7AC0000,0xE7AC0000, -0xE7AC0000,0xDFAC0000,0xDFAC0000,0xDFAC0000,0xDBAC0001,0x8DFC0012,0x8DFC0012,0x8DFC0012,0x8DFC0012,0x8DFC0012,0x8DFC0012,0xDFA40001,0xDFA40001,0xDFA40001,0xDBA80001,0xC7FC0012,0xC7FC0012,0xC7FC0012,0xDB980001,0xD8000012,0xF1B00008,0x1B00014,0x1B00014,0xFFAC0000,0xF3AC0000,0xEBAC0000,0xEBAC0000,0xE5AC0000,0xF7AC0005,0xF9A80000,0xE1AC0001,0xDFA40001, -0xB9FC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table28[] = { -0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0xD1F80000, -0xD1F80000,0xD1F80000,0xD1F80000,0xDE000000,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1DC0000,0x1DC0000,0x1DC0000,0x9FFC0000,0xC3FC0000,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000, -0xB1FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xE4000000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xE4000000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xE4000000,0xE4000000,0x1E80000,0x1C80001,0x1C80001,0x49FC0000,0x81FC0000,0x9FFC0000,0x9FFC0000,0xC1FC0000,0x49FC0000,0x81FC0000,0xCFFC0000,0xD9FC0000, -0xCFFC0000,0x1D00001,0x1D00001,0x1D00001,0x1D00001,0xBDFC0000,0xBDFC0000,0xBDFC0000,0xDFF80000,0xDFF80000,0xE8000000,0xBDFC0000,0xBDFC0000,0xBDFC0000,0xDFF80000,0xDFF80000,0xE8000000,0xDFF80000,0xDFF80000,0xE8000000,0xE8000000,0xBDFC0000,0xBDFC0000,0xBDFC0000,0xDFF80000,0xDFF80000,0xE8000000,0xDFF80000,0xDFF80000,0xE8000000,0xE8000000,0xDFF80000, -0xDFF80000,0xE8000000,0xE8000000,0xE8000000,0x67FC0000,0x1F00000,0x1D00001,0xAFFC0000,0xCBFC0000,0xD7FC0000,0xDBFC0000,0xE1FC0000,0x95FC0000,0xBDFC0000,0xD7FC0000,0xE8000000,0xD7FC0000,0x1DC0001,0xCFFC0000,0xE7FC0000,0xEE000000,0xCFFC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xCFFC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xEE000000, -0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0xCFFC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0xEE000000,0xB3FC0000,0x7FC0000,0x7FC0000,0xD9FC0000,0xE5FC0000,0xEBFC0000,0xEE000000,0xEE000000,0xC5FC0000,0xDDFC0000,0xEFD00000,0xEE000000, -0xE1FC0000,0x1CC008C,0xFFC80037,0xF5C80033,0xEFC80033,0xFFC40024,0xF5C40013,0xF1C4001A,0xF1C40024,0xEDC40016,0xEBC40026,0xFDC00034,0xF5C0000A,0xF1C0000F,0xF3BC0013,0xEFBC0002,0xEBC00016,0xEFC00034,0xEDBC000F,0xEBBC0019,0xE9BC0035,0xB7FC0088,0xF9B40033,0xEFBC0033,0xF3B40026,0xEFB80012,0xEBBC0026,0xF5A80033,0xEFAC0009,0xEBB00015,0xE9B40034,0xDDF40088, -0xEF980033,0xEBA00026,0xE9940034,0xE6000088,0xFDC8003F,0xFFCC0064,0xFFCC006C,0xFFC00007,0xF7C00002,0xF1C00002,0xEFC00002,0xEFBC0002,0xFFC40034,0xFFBC0005,0xEFBC0009,0xEBB00015,0xD3FC0088,0x1D40033,0xFDD0000A,0xF3CC000A,0xEFCC000A,0xF7CC0013,0xF3C80002,0xEFCC0001,0xEFCC0013,0xEFC80005,0xEBC80015,0xC1FC0033,0xF5C00009,0xEFC4000A,0xF3BC0012,0xEFBC0001, -0xEBC40014,0xE1F80033,0xEFAC0008,0xEBB00014,0xE8000034,0xC1FC0033,0xF5C00009,0xEFC4000A,0xF3BC0012,0xEFBC0001,0xEBC40014,0xE1F80033,0xEFAC0008,0xEBB00014,0xE8000034,0xE1F80033,0xEFAC0008,0xEBB00014,0xE8000034,0xE8000034,0xFDCC0014,0xF1D0002D,0xF3D4002A,0xFFC40003,0xF7C00001,0xF1C00001,0xEFC00001,0xEFBC0001,0xF7CC0019,0xFFC00002,0xEFBC0009,0xEBB00014, -0xD9FC0033,0x1C80033,0x1C80033,0x1C80033,0x1C80033,0xF7C40012,0xF7C40012,0xF7C40012,0xEDC40012,0xEDC40012,0xE9C40012,0xF5C00009,0xF5C00009,0xF5C00009,0xEDC00002,0xEDC00002,0xE9C00005,0xEBBC0009,0xEBBC0009,0xE9BC0001,0xE7BC0009,0xAFFC0033,0xAFFC0033,0xAFFC0033,0xEFB80012,0xEFB80012,0xE9BC0012,0xEDB40009,0xEDB40009,0xE9B40001,0xE7B40009,0xD7FC0033, -0xD7FC0033,0xE9A80012,0xE79C0008,0xE4000034,0xFBC40013,0xFDC80023,0x1C80033,0xFDC00003,0xF7C00001,0xF1C00001,0xEFC00002,0xEDBC0002,0xFDC00013,0xFFBC0001,0xEFBC0008,0xE9B40001,0xCDFC0033,0x1CC000A,0x1CC000A,0x1CC000A,0x1CC000A,0xEFCC0001,0xEFCC0001,0xEFCC0001,0xEBC80001,0xEBC80001,0xE9C80001,0xB7FC0008,0xB7FC0008,0xB7FC0008,0xEBC40001,0xEBC40001, -0xE9C40001,0xDDF40008,0xDDF40008,0xE9B80000,0xE6000008,0xB7FC0008,0xB7FC0008,0xB7FC0008,0xEBC40001,0xEBC40001,0xE9C40001,0xDDF40008,0xDDF40008,0xE9B80000,0xE6000008,0xDDF40008,0xDDF40008,0xE9B80000,0xE6000008,0xE6000008,0xFDC80002,0xFFCC0002,0x1CC000A,0xF5C80001,0xF3C40000,0xEFC40000,0xEDC40000,0xEBC40001,0xFFC40002,0xFBC00000,0xD3FC0008,0xE9B80000, -0xD3FC0008,0x1D80012,0xF9D40001,0xF1D40001,0xEFD00001,0xC7FC0012,0xF3C80001,0xEFCC0000,0xE3FC0012,0xEFB80000,0xEA000014,0xC7FC0012,0xF3C80001,0xEFCC0000,0xE3FC0012,0xEFB80000,0xEA000014,0xE3FC0012,0xEFB80000,0xEA000014,0xEA000014,0xC7FC0012,0xF3C80001,0xEFCC0000,0xE3FC0012,0xEFB80000,0xEA000014,0xE3FC0012,0xEFB80000,0xEA000014,0xEA000014,0xE3FC0012, -0xEFB80000,0xEA000014,0xEA000014,0xEA000014,0xFFD00008,0x1F80012,0xF5D8000D,0xFFC40002,0xF7C00001,0xF3BC0000,0xEFC00000,0xEFB00000,0xF9D00008,0xFFC00001,0xEFC40001,0xEA000014,0xDDF80012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0x1C40012,0xEFC00001,0xEFC00001,0xEFC00001,0xEFC00001,0xEFC00001, -0xEFC00001,0xE7C00001,0xE7C00001,0xE7C00001,0xE5BC0001,0xA9FC0012,0xA9FC0012,0xA9FC0012,0xA9FC0012,0xA9FC0012,0xA9FC0012,0xE9B40001,0xE9B40001,0xE9B40001,0xE5B80000,0xD5F80012,0xD5F80012,0xD5F80012,0xE5A40000,0xE0000014,0xF9C0000A,0x1C40012,0x1C40012,0xF9C00002,0xF7C00001,0xF1C00001,0xF1C00001,0xEDC00001,0xFFBC0005,0xFFBC0001,0xEBBC0000,0xE9B40001, -0xC9FC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table29[] = { -0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000, -0xDDF40000,0xDDF40000,0xDDF40000,0xE6000000,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1EC0000,0x1EC0000,0x1EC0000,0xB7FC0000,0xD3FC0000,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000, -0xC9FC0000,0xE5F80000,0xE5F80000,0xE5F80000,0xEC000000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xE5F80000,0xE5F80000,0xE5F80000,0xEC000000,0xE5F80000,0xE5F80000,0xE5F80000,0xEC000000,0xEC000000,0x5F80000,0x1D80001,0x1D80001,0x83FC0000,0xA9FC0000,0xBDFC0000,0xBDFC0000,0xD3FC0000,0x83FC0000,0xA9FC0000,0xDFF80000,0xE5F80000, -0xDFF80000,0x1E00001,0x1E00001,0x1E00001,0x1E00001,0xD5FC0000,0xD5FC0000,0xD5FC0000,0xEBF80000,0xEBF80000,0xF0000000,0xD5FC0000,0xD5FC0000,0xD5FC0000,0xEBF80000,0xEBF80000,0xF0000000,0xEBF80000,0xEBF80000,0xF0000000,0xF0000000,0xD5FC0000,0xD5FC0000,0xD5FC0000,0xEBF80000,0xEBF80000,0xF0000000,0xEBF80000,0xEBF80000,0xF0000000,0xF0000000,0xEBF80000, -0xEBF80000,0xF0000000,0xF0000000,0xF0000000,0x9FFC0000,0x27FC0000,0x1E00001,0xCDFC0000,0xDDFC0000,0xE5FC0000,0xE9F80000,0xEDF80000,0xBDFC0000,0xD5FC0000,0xE5FC0000,0xF0000000,0xE5FC0000,0x1EC0001,0xE9FC0000,0xF3FC0000,0xF6000000,0xE9FC0000,0xF3FC0000,0xF6000000,0xF3FC0000,0xF6000000,0xF6000000,0xE9FC0000,0xF3FC0000,0xF6000000,0xF3FC0000,0xF6000000, -0xF6000000,0xF3FC0000,0xF6000000,0xF6000000,0xF6000000,0xE9FC0000,0xF3FC0000,0xF6000000,0xF3FC0000,0xF6000000,0xF6000000,0xF3FC0000,0xF6000000,0xF6000000,0xF6000000,0xF3FC0000,0xF6000000,0xF6000000,0xF6000000,0xF6000000,0xDBFC0000,0x87FC0000,0x87FC0000,0xEDFC0000,0xF3F80000,0xF5FC0000,0xF6000000,0xF6000000,0xE3FC0000,0xEFFC0000,0xF7E00000,0xF6000000, -0xF1FC0000,0x1DC008C,0xFFDC0044,0xFDD80033,0xF7D80033,0xFDD80034,0xFDD40013,0xF9D4001A,0xF9D40024,0xF5D40016,0xF3D40026,0xFFD0003C,0xFDD0000A,0xF9D0000F,0xFBCC0013,0xF7CC0002,0xF3D00016,0xF7D00034,0xF5CC000F,0xF3CC0019,0xF1CC0035,0xCFFC0088,0xFFC80035,0xF7CC0033,0xFBC40026,0xF7C80012,0xF3CC0026,0xFDB80033,0xF7BC0009,0xF3C00015,0xF1C40034,0xE7FC0088, -0xF7A80033,0xF3B00026,0xF1A40034,0xEE000088,0xFFD8004E,0xF7DC0076,0xF7DC007B,0xFFD4001A,0xFFD00002,0xF9D00002,0xF7D00002,0xF7CC0002,0xFFD4004A,0xFFD00015,0xF7CC0009,0xF3C00015,0xE1FC0088,0x1E40033,0xFFE0000E,0xFBDC000A,0xF7DC000A,0xFFDC0013,0xFBD80002,0xF7DC0001,0xF7DC0013,0xF7D80005,0xF3D80015,0xD9FC0033,0xFDD00009,0xF7D4000A,0xFBCC0012,0xF7CC0001, -0xF3D40014,0xEDF80033,0xF7BC0008,0xF3C00014,0xF0000034,0xD9FC0033,0xFDD00009,0xF7D4000A,0xFBCC0012,0xF7CC0001,0xF3D40014,0xEDF80033,0xF7BC0008,0xF3C00014,0xF0000034,0xEDF80033,0xF7BC0008,0xF3C00014,0xF0000034,0xF0000034,0xFDE00021,0xF9E0002D,0xFBE4002A,0xFFD8000D,0xFFD00001,0xF9D00001,0xF7D00001,0xF7CC0001,0xFFDC0019,0xFFD4000A,0xF7CC0009,0xF3C00014, -0xE7FC0033,0x1D80033,0x1D80033,0x1D80033,0x1D80033,0xFFD40012,0xFFD40012,0xFFD40012,0xF5D40012,0xF5D40012,0xF1D40012,0xFDD00009,0xFDD00009,0xFDD00009,0xF5D00002,0xF5D00002,0xF1D00005,0xF3CC0009,0xF3CC0009,0xF1CC0001,0xEFCC0009,0xC7FC0033,0xC7FC0033,0xC7FC0033,0xF7C80012,0xF7C80012,0xF1CC0012,0xF5C40009,0xF5C40009,0xF1C40001,0xEFC40009,0xE3FC0033, -0xE3FC0033,0xF1B80012,0xEFAC0008,0xEC000034,0xFDD4001D,0xF5D8002A,0x1D80033,0xFFD4000A,0xFFD00001,0xF9D00001,0xF7D00002,0xF5CC0002,0xFFD00018,0xFFD00005,0xF7CC0008,0xF1C40001,0xDDF80033,0x1DC000A,0x1DC000A,0x1DC000A,0x1DC000A,0xF7DC0001,0xF7DC0001,0xF7DC0001,0xF3D80001,0xF3D80001,0xF1D80001,0xCFFC0008,0xCFFC0008,0xCFFC0008,0xF3D40001,0xF3D40001, -0xF1D40001,0xE7FC0008,0xE7FC0008,0xF1C80000,0xEE000008,0xCFFC0008,0xCFFC0008,0xCFFC0008,0xF3D40001,0xF3D40001,0xF1D40001,0xE7FC0008,0xE7FC0008,0xF1C80000,0xEE000008,0xE7FC0008,0xE7FC0008,0xF1C80000,0xEE000008,0xEE000008,0xFFD80004,0xF7DC0005,0x1DC000A,0xFDD80001,0xFBD40000,0xF7D40000,0xF5D40000,0xF3D40001,0xF1DC0005,0xFBD40001,0xE1FC0008,0xF1C80000, -0xE1FC0008,0x1E80012,0xFDE40002,0xF9E40001,0xF7E00001,0xDFFC0012,0xFBD80001,0xF7DC0000,0xEFFC0012,0xF7C80000,0xF2000014,0xDFFC0012,0xFBD80001,0xF7DC0000,0xEFFC0012,0xF7C80000,0xF2000014,0xEFFC0012,0xF7C80000,0xF2000014,0xF2000014,0xDFFC0012,0xFBD80001,0xF7DC0000,0xEFFC0012,0xF7C80000,0xF2000014,0xEFFC0012,0xF7C80000,0xF2000014,0xF2000014,0xEFFC0012, -0xF7C80000,0xF2000014,0xF2000014,0xF2000014,0xF7E8000D,0x57FC0012,0xFDE8000D,0xFDE00008,0xFFD00001,0xFBCC0000,0xF7D00000,0xF7C00000,0xF9E4000D,0xFFD80005,0xF7D40001,0xF2000014,0xEBFC0012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0x1D40012,0xF7D00001,0xF7D00001,0xF7D00001,0xF7D00001,0xF7D00001, -0xF7D00001,0xEFD00001,0xEFD00001,0xEFD00001,0xEDCC0001,0xC1FC0012,0xC1FC0012,0xC1FC0012,0xC1FC0012,0xC1FC0012,0xC1FC0012,0xF1C40001,0xF1C40001,0xF1C40001,0xEDC80000,0xE1F80012,0xE1F80012,0xE1F80012,0xEDB40000,0xE8000014,0xF3D4000D,0x1D40012,0x1D40012,0xFBD00005,0xFFD00001,0xF9D00001,0xF9D00001,0xF5D00001,0xFBD00008,0xFDCC0004,0xF3CC0000,0xF1C40001, -0xD9FC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table30[] = { -0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xE7FC0000, -0xE7FC0000,0xE7FC0000,0xE7FC0000,0xEE000000,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0x7FC0000,0x7FC0000,0x7FC0000,0xCFFC0000,0xE1FC0000,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xE3FC0000, -0xE3FC0000,0xF1F80000,0xF1F80000,0xF1F80000,0xF4000000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xF1F80000,0xF1F80000,0xF1F80000,0xF4000000,0xF1F80000,0xF1F80000,0xF1F80000,0xF4000000,0xF4000000,0x67FC0000,0x1E80001,0x1E80001,0xBBFC0000,0xD1FC0000,0xDBFC0000,0xDBFC0000,0xE7FC0000,0xBBFC0000,0xD1FC0000,0xEDFC0000,0xF1F80000, -0xEDFC0000,0x1F00001,0x1F00001,0x1F00001,0x1F00001,0xEFFC0000,0xEFFC0000,0xEFFC0000,0xF7F80000,0xF7F80000,0xF8000000,0xEFFC0000,0xEFFC0000,0xEFFC0000,0xF7F80000,0xF7F80000,0xF8000000,0xF7F80000,0xF7F80000,0xF8000000,0xF8000000,0xEFFC0000,0xEFFC0000,0xEFFC0000,0xF7F80000,0xF7F80000,0xF8000000,0xF7F80000,0xF7F80000,0xF8000000,0xF8000000,0xF7F80000, -0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xD7FC0000,0xA7FC0000,0x1F00001,0xEBFC0000,0xF1FC0000,0xF5FC0000,0xF5FC0000,0xF7FC0000,0xE3FC0000,0xEFFC0000,0xF5FC0000,0xF8000000,0xF5FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1EC008C,0xFFEC005F,0xFFE80043,0xFFE80033,0xFFE8004C,0xFFE4002B,0xFFE4001B,0xFFE40026,0xFDE40016,0xFBE40026,0xFFE80054,0xFFE40023,0xFFE00011,0xFFE0001B,0xFFDC0002,0xFBE00016,0xFFE00034,0xFDDC000F,0xFBDC0019,0xF9DC0035,0xE9FC0088,0xFFE4004B,0xFFDC0033,0xFFD80036,0xFFD80012,0xFBDC0026,0xFFD8003D,0xFFCC0009,0xFBD00015,0xF9D40034,0xF3FC0088, -0xFFB80033,0xFBC00026,0xF9B40034,0xF6000088,0xFFEC006A,0xFFEC0076,0xFFEC007B,0xFFE8004F,0xFFE40026,0xFFE0000C,0xFFE00002,0xFFDC0002,0xFDEC006A,0xFFE4004A,0xFFDC0009,0xFBD00015,0xF1FC0088,0x1F40033,0xFDF00023,0xFFF0000E,0xFFEC000A,0xFDF00023,0xFFEC000A,0xFFEC0001,0xFFEC0013,0xFFE80005,0xFBE80015,0xF1FC0033,0xFFEC0019,0xFFE4000A,0xFFE40015,0xFFDC0001, -0xFBE40014,0xF9F80033,0xFFCC0008,0xFBD00014,0xF8000034,0xF1FC0033,0xFFEC0019,0xFFE4000A,0xFFE40015,0xFFDC0001,0xFBE40014,0xF9F80033,0xFFCC0008,0xFBD00014,0xF8000034,0xF9F80033,0xFFCC0008,0xFBD00014,0xF8000034,0xF8000034,0xFDF4002A,0xF3F40033,0xF3F40033,0xFFEC001E,0xFFE80012,0xFFE40009,0xFFE00001,0xFFDC0001,0xFFF00029,0xFFF00021,0xFFDC0009,0xFBD00014, -0xF7FC0033,0x1E80033,0x1E80033,0x1E80033,0x1E80033,0xFDE4001B,0xFDE4001B,0xFDE4001B,0xFDE40012,0xFDE40012,0xF9E40012,0xFFE00011,0xFFE00011,0xFFE00011,0xFDE00002,0xFDE00002,0xF9E00005,0xFBDC0009,0xFBDC0009,0xF9DC0001,0xF7DC0009,0xDFFC0033,0xDFFC0033,0xDFFC0033,0xFFD80012,0xFFD80012,0xF9DC0012,0xFDD40009,0xFDD40009,0xF9D40001,0xF7D40009,0xEFFC0033, -0xEFFC0033,0xF9C80012,0xF7BC0008,0xF4000034,0xFFE80022,0xFDE8002A,0x1E80033,0xFDE4001A,0xFFE4000D,0xFFE00003,0xFFE00002,0xFDDC0002,0xFFE40021,0xFFE00018,0xFFDC0008,0xF9D40001,0xEBFC0033,0x1EC000A,0x1EC000A,0x1EC000A,0x1EC000A,0xFFEC0001,0xFFEC0001,0xFFEC0001,0xFBE80001,0xFBE80001,0xF9E80001,0xE9FC0008,0xE9FC0008,0xE9FC0008,0xFBE40001,0xFBE40001, -0xF9E40001,0xF3FC0008,0xF3FC0008,0xF9D80000,0xF6000008,0xE9FC0008,0xE9FC0008,0xE9FC0008,0xFBE40001,0xFBE40001,0xF9E40001,0xF3FC0008,0xF3FC0008,0xF9D80000,0xF6000008,0xF3FC0008,0xF3FC0008,0xF9D80000,0xF6000008,0xF6000008,0xFBEC0005,0xFFEC0005,0x1EC000A,0xF9EC0005,0xFDE80002,0xFFE40000,0xFDE40000,0xFBE40001,0xF9EC0005,0xFFE80002,0xF1FC0008,0xF9D80000, -0xF1FC0008,0x1F80012,0xFFF4000A,0xFFF00005,0xFFF00001,0xF7FC0012,0xFFF00005,0xFFEC0000,0xFBFC0012,0xFFD80000,0xFA000014,0xF7FC0012,0xFFF00005,0xFFEC0000,0xFBFC0012,0xFFD80000,0xFA000014,0xFBFC0012,0xFFD80000,0xFA000014,0xFA000014,0xF7FC0012,0xFFF00005,0xFFEC0000,0xFBFC0012,0xFFD80000,0xFA000014,0xFBFC0012,0xFFD80000,0xFA000014,0xFA000014,0xFBFC0012, -0xFFD80000,0xFA000014,0xFA000014,0xFA000014,0xFFF8000D,0xD7FC0012,0xF5F80012,0xFFF4000D,0xFDF4000D,0xFFE80005,0xFFE00000,0xFFD00000,0xF5FC0012,0xFFF00011,0xFFE40001,0xFA000014,0xFBFC0012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0x1E40012,0xFFE00001,0xFFE00001,0xFFE00001,0xFFE00001,0xFFE00001, -0xFFE00001,0xF7E00001,0xF7E00001,0xF7E00001,0xF5DC0001,0xD9FC0012,0xD9FC0012,0xD9FC0012,0xD9FC0012,0xD9FC0012,0xD9FC0012,0xF9D40001,0xF9D40001,0xF9D40001,0xF5D80000,0xEDF80012,0xEDF80012,0xEDF80012,0xF5C40000,0xF0000014,0xFBE4000D,0x1E40012,0x1E40012,0xFBE0000A,0xFDE00005,0xFFE00002,0xFFE00002,0xFDE00001,0xF7E4000D,0xFDE00008,0xFBDC0000,0xF9D40001, -0xE7FC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table31[] = { -0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xF3FC0000, -0xF3FC0000,0xF3FC0000,0xF3FC0000,0xF6000000,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0x87FC0000,0x87FC0000,0x87FC0000,0xE9FC0000,0xF1FC0000,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000, -0xFBFC0000,0xFDF80000,0xFDF80000,0xFDF80000,0xFC000000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFDF80000,0xFDF80000,0xFDF80000,0xFC000000,0xFDF80000,0xFDF80000,0xFDF80000,0xFC000000,0xFC000000,0xE7FC0000,0x1F80001,0x1F80001,0xF5FC0000,0xF7FC0000,0xF9FC0000,0xF9FC0000,0xFBFC0000,0xF5FC0000,0xF7FC0000,0xFDF80000,0xFDF80000, -0xFDF80000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1F8002C,0xFFF80027,0xFFF80024,0xFFF80023,0xFFF80022,0xFFF4001F,0xFFF4001B,0xFFF4001A,0xFFF40016,0xFFF40012,0xFFF4001C,0xFFF40017,0xFFF40013,0xFFF00012,0xFFF0000E,0xFFF0000A,0xFFF00009,0xFFF00005,0xFFF00001,0xFFEC0005,0xF7FC002C,0xFDF80027,0xFFF40023,0xFFF0001A,0xFFF00016,0xFFF00012,0xFFF00011,0xFFF0000D,0xFFE40005,0xFFE40005,0xFBFC002C, -0xFFEC0023,0xFFE00012,0xFFCC0004,0xFC00002C,0xFFF80027,0xF5F8002C,0xF5F8002C,0xFFF80022,0xFFF4001A,0xFFF40012,0xFFF40011,0xFFF00009,0xFFF80022,0xFFF4001F,0xFFF0000B,0xFFE40005,0xFBFC002C,0x1FC0003,0xFDFC0003,0xFFFC0002,0xFFFC0002,0xFDFC0003,0xFFFC0002,0xFFFC0002,0xFFFC0001,0xFFFC0001,0xFFF80001,0xFDFC0003,0xFFFC0002,0xFFFC0002,0xFFFC0001,0xFFF80001, -0xFFF80000,0xFFF80003,0xFFF80002,0xFFF00000,0xFE000004,0xFDFC0003,0xFFFC0002,0xFFFC0002,0xFFFC0001,0xFFF80001,0xFFF80000,0xFFF80003,0xFFF80002,0xFFF00000,0xFE000004,0xFFF80003,0xFFF80002,0xFFF00000,0xFE000004,0xFE000004,0xFDFC0003,0xF7FC0003,0xF7FC0003,0xFDFC0003,0xFFFC0002,0xFFFC0001,0xFFF80001,0xFFF80001,0xFDFC0003,0xFDFC0003,0xFFF80002,0xFFF00000, -0xFFF80003,0x1F80023,0x1F80023,0x1F80023,0x1F80023,0xFFF4001B,0xFFF4001B,0xFFF4001B,0xFFF40016,0xFFF40016,0xFFF40012,0xFFF40013,0xFFF40013,0xFFF40013,0xFFF0000E,0xFFF0000E,0xFFF0000A,0xFFF00005,0xFFF00005,0xFFF00001,0xFDEC0005,0xF7FC0023,0xF7FC0023,0xF7FC0023,0xFFF00016,0xFFF00016,0xFFF00012,0xFFF0000D,0xFFF0000D,0xFFE40005,0xFDE80004,0xFBFC0023, -0xFBFC0023,0xFFE00012,0xFDD40004,0xFA000024,0xFFF40022,0xF5F80023,0x1F80023,0xFFF4001D,0xFFF40016,0xFFF40011,0xFFF40011,0xFFF00009,0xFFF4001D,0xFFF40016,0xFFF0000B,0xFFE40005,0xFBFC0023,0x1FC0002,0x1FC0002,0x1FC0002,0x1FC0002,0xFDFC0002,0xFDFC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFF80001,0xFDFC0002,0xFDFC0002,0xFDFC0002,0xFFF80001,0xFFF80001, -0xFFF80000,0xFFF80002,0xFFF80002,0xFFF00000,0xFC000004,0xFDFC0002,0xFDFC0002,0xFDFC0002,0xFFF80001,0xFFF80001,0xFFF80000,0xFFF80002,0xFFF80002,0xFFF00000,0xFC000004,0xFFF80002,0xFFF80002,0xFFF00000,0xFC000004,0xFC000004,0xFBFC0002,0xF7FC0002,0x1FC0002,0xFDFC0002,0xFDFC0002,0xFFF80001,0xFFF80001,0xFFF80001,0xFDFC0002,0xFDFC0002,0xFFF80002,0xFFF00000, -0xFFF80002,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0x1F40012,0xFDF0000A,0xFDF0000A,0xFDF0000A,0xFDF0000A,0xFDF0000A, -0xFDF0000A,0xFFF00001,0xFFF00001,0xFFF00001,0xFDEC0001,0xF1FC0012,0xF1FC0012,0xF1FC0012,0xF1FC0012,0xF1FC0012,0xF1FC0012,0xFDEC0005,0xFDEC0005,0xFDEC0005,0xFDE80000,0xF9F80012,0xF9F80012,0xF9F80012,0xFDD40000,0xF8000014,0xF3F40012,0x1F40012,0x1F40012,0xFFF4000D,0xFDF4000D,0xFFF0000A,0xFFF0000A,0xFFF00005,0xFFF4000D,0xFDF4000D,0xFFF00002,0xFDEC0005, -0xF7FC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table32[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x80001,0x80001,0x80001,0x80001,0x20C0000,0x20C0000,0x20C0000,0x180000,0x180000,0x4000000,0x20C0000,0x20C0000,0x20C0000,0x180000,0x180000,0x4000000,0x180000,0x180000,0x4000000,0x4000000,0x20C0000,0x20C0000,0x20C0000,0x180000,0x180000,0x4000000,0x180000,0x180000,0x4000000,0x4000000,0x180000, -0x180000,0x4000000,0x4000000,0x4000000,0xC0000,0xC080000,0x80001,0xC0000,0x100000,0x140000,0x140000,0x200000,0xC0000,0x20C0000,0x140000,0x4000000,0x140000,0x200001,0x2300000,0x640000,0x10000000,0x2300000,0x640000,0x10000000,0x640000,0x10000000,0x10000000,0x2300000,0x640000,0x10000000,0x640000,0x10000000, -0x10000000,0x640000,0x10000000,0x10000000,0x10000000,0x2300000,0x640000,0x10000000,0x640000,0x10000000,0x10000000,0x640000,0x10000000,0x10000000,0x10000000,0x640000,0x10000000,0x10000000,0x10000000,0x10000000,0x2280000,0x240000,0x240000,0x380000,0x500000,0x9C0000,0x10000000,0x10000000,0x22C0000,0x400000,0x1F40000,0x10000000, -0x480000,0xC00C2,0x2E040011,0x18040011,0x10040011,0x20000048,0x18000009,0x10000001,0x10000048,0xE00001D,0xA000048,0x14000099,0x12000035,0xE00001D,0xC000060,0xC000030,0xA000058,0xA000099,0xA000059,0x8000074,0x6000099,0x1000C2,0x12000059,0xC000031,0xC000070,0xC000040,0x8000062,0x80000A7,0xA000069,0x800007D,0x600009D,0x1800C2, -0x8000089,0x8000098,0x40000B2,0x40000C2,0x42000029,0xA8000048,0xEA040011,0x1E000029,0x16000032,0xE000032,0xC000022,0xA00003D,0x2C000056,0x1A00003D,0xC00004F,0x800007D,0x1400C2,0x10009A,0x2E04000D,0x1804000D,0x1004000D,0x20000048,0x18000009,0x10000001,0x10000048,0xE00001D,0xA000048,0x140099,0x12000035,0xE00001D,0xC000060,0xC000030, -0xA000058,0x240099,0xA000059,0x8000074,0x6000099,0x140099,0x12000035,0xE00001D,0xC000060,0xC000030,0xA000058,0x240099,0xA000059,0x8000074,0x6000099,0x240099,0xA000059,0x8000074,0x6000099,0x6000099,0x42000029,0xA8000048,0xEA04000D,0x1E000029,0x16000032,0xE000032,0xC000022,0xA00003D,0x2C00004D,0x1A000039,0xC00004E,0x8000074, -0x1C0099,0x40011,0x40011,0x40011,0x40011,0xE000000,0xE000000,0xE000000,0x6000000,0x6000000,0x4000000,0x400000D,0x400000D,0x400000D,0x6000004,0x6000004,0x4000004,0x200000D,0x200000D,0x2000008,0x200000D,0x40011,0x40011,0x40011,0x6000008,0x6000008,0x2000006,0x200000E,0x200000E,0x2000009,0x200000E,0x80011, -0x80011,0x200000C,0x2000011,0x12,0x20000004,0x48000000,0x40011,0x10000004,0x6000005,0x8000004,0x8000004,0x4000005,0xC000009,0xA000006,0x200000D,0x2000009,0x80011,0x4000D,0x4000D,0x4000D,0x4000D,0xE000000,0xE000000,0xE000000,0x6000000,0x6000000,0x4000000,0x4000D,0x4000D,0x4000D,0x6000004,0x6000004, -0x4000004,0x8000D,0x8000D,0x2000008,0x200000D,0x4000D,0x4000D,0x4000D,0x6000004,0x6000004,0x4000004,0x8000D,0x8000D,0x2000008,0x200000D,0x8000D,0x8000D,0x2000008,0x200000D,0x200000D,0x20000004,0x48000000,0x4000D,0x10000004,0x6000005,0x8000004,0x8000004,0x4000005,0x4040008,0xA000005,0x8000D,0x2000008, -0x8000D,0x14004A,0x260C0001,0x16080001,0x10080001,0x200048,0x18000009,0x10000001,0x3C0048,0xE00001D,0xA000048,0x200048,0x18000009,0x10000001,0x3C0048,0xE00001D,0xA000048,0x3C0048,0xE00001D,0xA000048,0xA000048,0x200048,0x18000009,0x10000001,0x3C0048,0xE00001D,0xA000048,0x3C0048,0xE00001D,0xA000048,0xA000048,0x3C0048, -0xE00001D,0xA000048,0xA000048,0xA000048,0x42000019,0x180048,0xAE0C0001,0x1E000019,0x16000019,0x10000019,0xE000014,0xE000028,0x32000022,0x1E00001D,0x10000011,0xA000048,0x2C0048,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table33[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x80000,0x80000,0x80000,0x80000,0x80000, -0x80000,0xC0000,0xC0000,0xC0000,0x2000000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0xC0000,0xC0000,0xC0000,0x2000000,0xC0000,0xC0000,0xC0000,0x2000000,0x2000000,0xA040000,0x40001,0x40001,0x6040000,0x80000,0x80000,0x80000,0x80000,0x6040000,0x80000,0xC0000,0xC0000, -0xC0000,0x180001,0x180001,0x180001,0x180001,0x2240000,0x2240000,0x2240000,0x4C0000,0x4C0000,0xC000000,0x2240000,0x2240000,0x2240000,0x4C0000,0x4C0000,0xC000000,0x4C0000,0x4C0000,0xC000000,0xC000000,0x2240000,0x2240000,0x2240000,0x4C0000,0x4C0000,0xC000000,0x4C0000,0x4C0000,0xC000000,0xC000000,0x4C0000, -0x4C0000,0xC000000,0xC000000,0xC000000,0x41C0000,0x1C0000,0x180001,0x240000,0x2C0000,0x340000,0x3C0000,0x5C0000,0x200000,0x2240000,0x340000,0xC000000,0x340000,0x300001,0x480000,0x940000,0x18000000,0x480000,0x940000,0x18000000,0x940000,0x18000000,0x18000000,0x480000,0x940000,0x18000000,0x940000,0x18000000, -0x18000000,0x940000,0x18000000,0x18000000,0x18000000,0x480000,0x940000,0x18000000,0x940000,0x18000000,0x18000000,0x940000,0x18000000,0x18000000,0x18000000,0x940000,0x18000000,0x18000000,0x18000000,0x18000000,0x23C0000,0x2340000,0x2340000,0x540000,0x780000,0xEC0000,0x18000000,0x18000000,0x440000,0x5C0000,0xBC80000,0x18000000, -0x680000,0x14017F,0x3E0C005E,0x220C005E,0x180C005E,0x3404004D,0x22040006,0x1804000E,0x1A04004D,0x16000011,0x1204004D,0x2A0000F3,0x22000045,0x18000032,0x18000069,0x14000021,0x12000051,0x140000F3,0x10000084,0x10000090,0xC0000F4,0x1C017F,0x1E0000AE,0x18000072,0x180000A9,0x12000051,0x12000075,0x12000118,0x100000A8,0xE0000B2,0xC000104,0x38017F, -0x100000FD,0xE0000FD,0xA000139,0xA000181,0x6400001A,0xFA04004F,0xFE0C0067,0x3400001A,0x22000021,0x1A00001A,0x1600000E,0x14000038,0x42000066,0x2C000041,0x1600005C,0xE0000B2,0x28017F,0x1C00F3,0x3A100032,0x20100032,0x18100032,0x30080049,0x22040002,0x18080005,0x1A040049,0x1604000E,0x12040049,0x2800F3,0x22000045,0x18000032,0x18000069,0x14000021, -0x12000051,0x5000F3,0x10000084,0x10000090,0xC0000F4,0x2800F3,0x22000045,0x18000032,0x18000069,0x14000021,0x12000051,0x5000F3,0x10000084,0x10000090,0xC0000F4,0x5000F3,0x10000084,0x10000090,0xC0000F4,0xC0000F4,0x6400001A,0xEC080049,0xF0100036,0x3400001A,0x22000021,0x1A00001A,0x1600000E,0x14000038,0x50000052,0x2C000038,0x1600005B,0x10000090, -0x3800F3,0xC005E,0xC005E,0xC005E,0xC005E,0x22040005,0x22040005,0x22040005,0x12040005,0x12040005,0xC040005,0x16000032,0x16000032,0x16000032,0x12000009,0x12000009,0xC000001,0xA000034,0xA000034,0xA000014,0x6000034,0x20C005D,0x20C005D,0x20C005D,0xC000021,0xC000021,0xC000011,0x8000043,0x8000043,0x8000022,0x6000038,0x18005D, -0x18005D,0x800003D,0x400004D,0x400005D,0x52000005,0xAA040005,0xC005E,0x2C00000A,0x1A000008,0x1600000A,0x12000008,0xC00000D,0x3400001D,0x1C000016,0xE000033,0x8000022,0x14005D,0x100032,0x100032,0x100032,0x100032,0x1E080001,0x1E080001,0x1E080001,0x10080001,0x10080001,0xC040001,0x180032,0x180032,0x180032,0x12000009,0x12000009, -0xC000001,0x2C0032,0x2C0032,0xA000014,0x6000034,0x180032,0x180032,0x180032,0x12000009,0x12000009,0xC000001,0x2C0032,0x2C0032,0xA000014,0x6000034,0x2C0032,0x2C0032,0xA000014,0x6000034,0x6000034,0x52000005,0x8C080001,0x100032,0x2C00000A,0x1A000008,0x1600000A,0x12000008,0xC00000D,0x34000014,0x1C000012,0x200032,0xA000014, -0x200032,0x24004A,0x2E1C0001,0x1E180001,0x18180001,0x380048,0x22040001,0x180C0001,0x700048,0x16000008,0x12000048,0x380048,0x22040001,0x180C0001,0x700048,0x16000008,0x12000048,0x700048,0x16000008,0x12000048,0x12000048,0x380048,0x22040001,0x180C0001,0x700048,0x16000008,0x12000048,0x700048,0x16000008,0x12000048,0x12000048,0x700048, -0x16000008,0x12000048,0x12000048,0x12000048,0x7400000A,0x280048,0xB61C0001,0x38000008,0x2204000D,0x1C000008,0x18000004,0x14000014,0x50000012,0x2E00000D,0x1A000001,0x12000048,0x500048,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x8000000,0x8000000,0x8000000,0x8000000,0x8000000, -0x8000000,0x4000000,0x4000000,0x4000000,0x2000000,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x2000002,0x2000002,0x2000002,0x2000001,0x5,0x5,0x5,0x2000004,0x5,0x28000000,0x40005,0x40005,0x12000000,0xC000000,0xA000000,0xA000000,0x6000000,0x12000001,0xC000001,0x4000000,0x2000002, -0x5,}; -static const uint32_t g_etc1_to_bc7_m6_table34[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x200000,0x200000,0x200000,0x200000,0x200000, -0x200000,0x3C0000,0x3C0000,0x3C0000,0xA000000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x3C0000,0x3C0000,0x3C0000,0xA000000,0x3C0000,0x3C0000,0x3C0000,0xA000000,0xA000000,0x180000,0x140001,0x140001,0x2180000,0x1C0000,0x1C0000,0x1C0000,0x240000,0x2180000,0x1C0000,0x2C0000,0x3C0000, -0x2C0000,0x280001,0x280001,0x280001,0x280001,0x23C0000,0x23C0000,0x23C0000,0x7C0000,0x7C0000,0x14000000,0x23C0000,0x23C0000,0x23C0000,0x7C0000,0x7C0000,0x14000000,0x7C0000,0x7C0000,0x14000000,0x14000000,0x23C0000,0x23C0000,0x23C0000,0x7C0000,0x7C0000,0x14000000,0x7C0000,0x7C0000,0x14000000,0x14000000,0x7C0000, -0x7C0000,0x14000000,0x14000000,0x14000000,0x300000,0x2C0000,0x280001,0x380000,0x440000,0x580000,0x640000,0x980000,0x340000,0x23C0000,0x580000,0x14000000,0x580000,0x400001,0x600000,0xC40000,0x20000000,0x600000,0xC40000,0x20000000,0xC40000,0x20000000,0x20000000,0x600000,0xC40000,0x20000000,0xC40000,0x20000000, -0x20000000,0xC40000,0x20000000,0x20000000,0x20000000,0x600000,0xC40000,0x20000000,0xC40000,0x20000000,0x20000000,0xC40000,0x20000000,0x20000000,0x20000000,0xC40000,0x20000000,0x20000000,0x20000000,0x20000000,0x4500000,0xA440000,0xA440000,0x26C0000,0xA00000,0x13C0000,0x20000000,0x20000000,0x580000,0x7C0000,0x13D80000,0x20000000, -0x8C0000,0x200253,0x4E1400DE,0x2A1400DF,0x201400DE,0x440C0085,0x2C0C0042,0x220C005A,0x240C0085,0x1E0C0045,0x1A0C0085,0x420000F3,0x30000032,0x2008004A,0x2600004E,0x20000001,0x1A00004C,0x200000F3,0x1C000054,0x18000074,0x140000F4,0x300253,0x28000106,0x200000DD,0x220000D3,0x1E000069,0x18000099,0x1E000158,0x1A0000AF,0x180000B4,0x14000125,0x5C0253, -0x16000179,0x16000159,0x100001AD,0x10000255,0x9C000003,0xF01000B1,0xF4180106,0x4E000001,0x36000001,0x28000001,0x20000005,0x1E00000C,0x64000051,0x3E00001D,0x20000042,0x180000B4,0x400253,0x2C00F3,0x42200032,0x28200032,0x20200032,0x38180049,0x2A140002,0x20180005,0x22140049,0x1E14000E,0x1A140049,0x4000F3,0x30000032,0x20100032,0x2404004E,0x20000001, -0x1A040049,0x8000F3,0x1C000054,0x18000074,0x140000F4,0x4000F3,0x30000032,0x20100032,0x2404004E,0x20000001,0x1A040049,0x8000F3,0x1C000054,0x18000074,0x140000F4,0x8000F3,0x1C000054,0x18000074,0x140000F4,0x140000F4,0x9C000003,0xF4180049,0xF8200036,0x4E000001,0x36000001,0x28000001,0x20080001,0x1E00000C,0x6C000021,0x3E00000D,0x2000003E,0x18000074, -0x5C00F3,0x1400DE,0x1400DE,0x1400DE,0x1400DE,0x320C003D,0x320C003D,0x320C003D,0x1C0C003D,0x1C0C003D,0x140C003D,0x30000032,0x30000032,0x30000032,0x1E000001,0x1E000001,0x1604000C,0x16000034,0x16000034,0x12000008,0xE000034,0x2000DD,0x2000DD,0x2000DD,0x18000059,0x18000059,0x12000041,0x12000068,0x12000068,0x1200002C,0xE00004D,0x3C00DD, -0x3C00DD,0xE000089,0xA000095,0xA0000DD,0x98000002,0xEE0C003D,0x1400DE,0x4E000000,0x32000001,0x26000001,0x24000002,0x1A000001,0x56000023,0x36000012,0x1E000036,0x1200002C,0x2C00DD,0x200032,0x200032,0x200032,0x200032,0x26180001,0x26180001,0x26180001,0x18180001,0x18180001,0x14140001,0x300032,0x300032,0x300032,0x1C040001,0x1C040001, -0x140C0000,0x5C0032,0x5C0032,0x12000008,0xE000034,0x300032,0x300032,0x300032,0x1C040001,0x1C040001,0x140C0000,0x5C0032,0x5C0032,0x12000008,0xE000034,0x5C0032,0x5C0032,0x12000008,0xE000034,0xE000034,0x7A080000,0x94180001,0x200032,0x4E000000,0x2C080001,0x24040000,0x1E080001,0x1A000001,0x5C000008,0x3C000002,0x400032,0x12000008, -0x400032,0x34004A,0x362C0001,0x26280001,0x20280001,0x500048,0x2A140001,0x201C0001,0xA00048,0x20000001,0x1A000048,0x500048,0x2A140001,0x201C0001,0xA00048,0x20000001,0x1A000048,0xA00048,0x20000001,0x1A000048,0x1A000048,0x500048,0x2A140001,0x201C0001,0xA00048,0x20000001,0x1A000048,0xA00048,0x20000001,0x1A000048,0x1A000048,0xA00048, -0x20000001,0x1A000048,0x1A000048,0x1A000048,0x9C000002,0x4380048,0xBE2C0001,0x4A040001,0x36000001,0x28000001,0x20080000,0x1E000008,0x72000008,0x46000004,0x220C0000,0x1A000048,0x700048,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0x20000000,0x20000000,0x20000000,0x20000000,0x20000000, -0x20000000,0x10000000,0x10000000,0x10000000,0xA000000,0x10003D,0x10003D,0x10003D,0x10003D,0x10003D,0x10003D,0xC000014,0xC000014,0xC000014,0x800000D,0x18003D,0x18003D,0x18003D,0x8000028,0x400003D,0xA8000000,0xC003D,0xC003D,0x4A000000,0x34000000,0x28000000,0x28000000,0x1A000000,0x44000011,0x34000009,0x14000001,0xC000014, -0x14003D,}; -static const uint32_t g_etc1_to_bc7_m6_table35[] = { -0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x240000, -0x240000,0x240000,0x240000,0x6000000,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xE0C0000,0xE0C0000,0xE0C0000,0x140000,0x1C0000,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x380000,0x380000,0x380000,0x380000,0x380000, -0x380000,0x700000,0x700000,0x700000,0x12000000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x700000,0x700000,0x700000,0x12000000,0x700000,0x700000,0x700000,0x12000000,0x12000000,0x280000,0x240001,0x240001,0x2C0000,0x300000,0x340000,0x340000,0x400000,0x2C0000,0x300000,0x500000,0x700000, -0x500000,0x380001,0x380001,0x380001,0x380001,0x540000,0x540000,0x540000,0xAC0000,0xAC0000,0x1C000000,0x540000,0x540000,0x540000,0xAC0000,0xAC0000,0x1C000000,0xAC0000,0xAC0000,0x1C000000,0x1C000000,0x540000,0x540000,0x540000,0xAC0000,0xAC0000,0x1C000000,0xAC0000,0xAC0000,0x1C000000,0x1C000000,0xAC0000, -0xAC0000,0x1C000000,0x1C000000,0x1C000000,0x440000,0x63C0000,0x380001,0x24C0000,0x600000,0x780000,0x8C0000,0xD40000,0x480000,0x540000,0x780000,0x1C000000,0x780000,0x500001,0x780000,0xF40000,0x28000000,0x780000,0xF40000,0x28000000,0xF40000,0x28000000,0x28000000,0x780000,0xF40000,0x28000000,0xF40000,0x28000000, -0x28000000,0xF40000,0x28000000,0x28000000,0x28000000,0x780000,0xF40000,0x28000000,0xF40000,0x28000000,0x28000000,0xF40000,0x28000000,0x28000000,0x28000000,0xF40000,0x28000000,0x28000000,0x28000000,0x28000000,0x4640000,0x580000,0x580000,0x880000,0xC80000,0x1880000,0x28000000,0x28000000,0x700000,0x980000,0x1BE80000,0x28000000, -0xAC0000,0x300274,0x562400F3,0x322400F4,0x282400F3,0x4C1C0092,0x341C004F,0x2A1C0067,0x2C1C0092,0x2818004E,0x22180092,0x4A1000F4,0x38100033,0x2A140051,0x300C004A,0x28100002,0x2210004D,0x280C00F4,0x24080053,0x20080069,0x1C0C00F5,0x2440274,0x3A0000F5,0x281000F4,0x2E0000AA,0x28000049,0x22040090,0x2800011F,0x2400005D,0x20000069,0x1C0000FD,0x8C0274, -0x2000015B,0x1C000120,0x1A000181,0x16000278,0xA4100004,0xF82000C2,0xFC28011F,0x56100002,0x3E100002,0x30100002,0x28100006,0x260C0006,0x90000009,0x54040000,0x2A080035,0x20000069,0x640274,0x3C00F3,0x4A300032,0x30300032,0x28300032,0x40280049,0x32240002,0x28280005,0x2A240049,0x2624000E,0x22240049,0x5800F3,0x38100032,0x28200032,0x300C0049,0x28100001, -0x22140049,0xB000F3,0x2600003E,0x20000059,0x1C0000F4,0x5800F3,0x38100032,0x28200032,0x300C0049,0x28100001,0x22140049,0xB000F3,0x2600003E,0x20000059,0x1C0000F4,0xB000F3,0x2600003E,0x20000059,0x1C0000F4,0x1C0000F4,0xA4100003,0xFC280049,0xF030003B,0x56100001,0x3E100001,0x30100001,0x28180001,0x28080004,0x90000005,0x54040000,0x2A040033,0x20000059, -0x7C00F3,0x2400F3,0x2400F3,0x2400F3,0x2400F3,0x3A1C004A,0x3A1C004A,0x3A1C004A,0x2418004A,0x2418004A,0x1C18004A,0x38100033,0x38100033,0x38100033,0x26100002,0x26100002,0x1E10000E,0x200C0033,0x200C0033,0x1C0C0005,0x160C0035,0x3400F3,0x3400F3,0x3400F3,0x28000049,0x28000049,0x1C08004A,0x22000042,0x22000042,0x1A000009,0x16000035,0x6800F3, -0x6800F3,0x16000074,0x16000074,0x120000F4,0xA0100003,0xF61C004A,0x2400F3,0x56100001,0x3A100002,0x2E100002,0x2C100003,0x240C0001,0x84000005,0x54040000,0x260C0033,0x1A000009,0x4C00F3,0x300032,0x300032,0x300032,0x300032,0x2E280001,0x2E280001,0x2E280001,0x20280001,0x20280001,0x1C240001,0x2440032,0x2440032,0x2440032,0x24140001,0x24140001, -0x1C1C0000,0x8C0032,0x8C0032,0x1C000000,0x16000034,0x2440032,0x2440032,0x2440032,0x24140001,0x24140001,0x1C1C0000,0x8C0032,0x8C0032,0x1C000000,0x16000034,0x8C0032,0x8C0032,0x1C000000,0x16000034,0x16000034,0x82180000,0x9C280001,0x300032,0x56100000,0x34180001,0x2C140000,0x26180001,0x240C0000,0x84040001,0x4E080000,0x640032,0x1C000000, -0x640032,0x44004A,0x3E3C0001,0x2E380001,0x28380001,0x680048,0x32240001,0x282C0001,0xD00048,0x28080000,0x22000048,0x680048,0x32240001,0x282C0001,0xD00048,0x28080000,0x22000048,0xD00048,0x28080000,0x22000048,0x22000048,0x680048,0x32240001,0x282C0001,0xD00048,0x28080000,0x22000048,0xD00048,0x28080000,0x22000048,0x22000048,0xD00048, -0x28080000,0x22000048,0x22000048,0x22000048,0xB8080000,0xC480048,0xC63C0001,0x5A0C0000,0x3E0C0001,0x32080000,0x28180000,0x28000001,0x94000002,0x54040000,0x2A1C0000,0x22000048,0x940048,0x18004A,0x18004A,0x18004A,0x18004A,0x18004A,0x18004A,0x18004A,0x18004A,0x18004A,0x18004A,0x28100001,0x28100001,0x28100001,0x28100001,0x28100001, -0x28100001,0x180C0001,0x180C0001,0x180C0001,0x120C0001,0x2240048,0x2240048,0x2240048,0x2240048,0x2240048,0x2240048,0x18000005,0x18000005,0x18000005,0x12000001,0x4C0048,0x4C0048,0x4C0048,0x10000014,0xC000048,0xB0100001,0x18004A,0x18004A,0x52100001,0x3C100001,0x30100001,0x30100001,0x22100001,0x84000001,0x54040000,0x1C0C0001,0x18000005, -0x340048,}; -static const uint32_t g_etc1_to_bc7_m6_table36[] = { -0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x5C0000, -0x5C0000,0x5C0000,0x5C0000,0xE000001,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x8200000,0x8200000,0x8200000,0x300000,0x400000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000, -0x2500000,0xA40000,0xA40000,0xA40000,0x1A000001,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0xA40000,0xA40000,0xA40000,0x1A000001,0xA40000,0xA40000,0xA40000,0x1A000001,0x1A000001,0x3C0000,0x380000,0x380000,0x400000,0x2440000,0x4C0000,0x4C0000,0x5C0000,0x400000,0x2440000,0x740000,0xA40000, -0x740000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x700000,0x700000,0x700000,0xE40000,0xE40000,0x24000001,0x700000,0x700000,0x700000,0xE40000,0xE40000,0x24000001,0xE40000,0xE40000,0x24000001,0x24000001,0x700000,0x700000,0x700000,0xE40000,0xE40000,0x24000001,0xE40000,0xE40000,0x24000001,0x24000001,0xE40000, -0xE40000,0x24000001,0x24000001,0x24000001,0x580000,0x500000,0x4C0000,0x680000,0x800000,0xA00000,0xB80000,0x1180000,0x600000,0x700000,0xA00000,0x24000001,0xA00000,0x640000,0x940000,0x12C0000,0x30000001,0x940000,0x12C0000,0x30000001,0x12C0000,0x30000001,0x30000001,0x940000,0x12C0000,0x30000001,0x12C0000,0x30000001, -0x30000001,0x12C0000,0x30000001,0x30000001,0x30000001,0x940000,0x12C0000,0x30000001,0x12C0000,0x30000001,0x30000001,0x12C0000,0x30000001,0x30000001,0x30000001,0x12C0000,0x30000001,0x30000001,0x30000001,0x30000001,0x7C0000,0xC680000,0xC680000,0xA80000,0xF40000,0x1E00000,0x30000001,0x30000001,0x880000,0xBC0000,0x25DC0000,0x30000001, -0xD40000,0x400278,0x5E3800F4,0x3C3800F4,0x303800F5,0x582C0090,0x402C004D,0x34300069,0x362C0090,0x302C004D,0x2A2C0092,0x542000F3,0x42200032,0x34280053,0x38200049,0x30200002,0x2C20004E,0x302000F4,0x2E1C0051,0x2A1C0067,0x262000F3,0x600274,0x460C00F3,0x302000F4,0x3E040092,0x3210004A,0x2A180092,0x360400FD,0x30000033,0x2A00004F,0x260800F4,0xC40274, -0x2C000121,0x260000E2,0x2400014C,0x20000274,0xB4200005,0xF23400D0,0xF63C012C,0x62200000,0x48200001,0x38200002,0x32240006,0x30200006,0xAC080002,0x5A180002,0x321C0035,0x2A00004F,0x8C0274,0x4C00F4,0x52440034,0x3A400034,0x30400035,0x4C380048,0x3A380001,0x32380005,0x3238004A,0x3034000E,0x2A38004A,0x7400F3,0x40240032,0x32300033,0x38200049,0x30200002, -0x2A28004A,0xE800F3,0x30000033,0x2A00004B,0x260000F3,0x7400F3,0x40240032,0x32300033,0x38200049,0x30200002,0x2A28004A,0xE800F3,0x30000033,0x2A00004B,0x260000F3,0xE800F3,0x30000033,0x2A00004B,0x260000F3,0x260000F3,0xA8240003,0xF63C004C,0xFA440038,0x62200000,0x48200001,0x38200002,0x32280001,0x30180003,0xAC080001,0x5A180001,0x34140032,0x2A00004B, -0xA400F3,0x3800F4,0x3800F4,0x3800F4,0x3800F4,0x462C0048,0x462C0048,0x462C0048,0x2C2C0049,0x2C2C0049,0x242C0049,0x42200032,0x42200032,0x42200032,0x30200001,0x30200001,0x2624000E,0x28200032,0x28200032,0x24200005,0x20200032,0x5000F3,0x5000F3,0x5000F3,0x32100049,0x32100049,0x241C0049,0x30000032,0x30000032,0x240C0002,0x20100032,0xA000F3, -0xA000F3,0x22000059,0x1E000053,0x1A0000F3,0xA8200004,0xFE2C0049,0x3800F4,0x62200000,0x44200001,0x38200001,0x34200004,0x2C200001,0xA20C0000,0x5A180001,0x301C0032,0x240C0002,0x7000F3,0x400034,0x400034,0x400034,0x400034,0x38380000,0x38380000,0x38380000,0x2A380000,0x2A380000,0x24380001,0x600032,0x600032,0x600032,0x2C280001,0x2C280001, -0x24300001,0xC40032,0xC40032,0x24140001,0x20000032,0x600032,0x600032,0x600032,0x2C280001,0x2C280001,0x24300001,0xC40032,0xC40032,0x24140001,0x20000032,0xC40032,0xC40032,0x24140001,0x20000032,0x20000032,0x90280000,0xB4380000,0x400034,0x62200000,0x42240000,0x36240000,0x32280000,0x2C200001,0xA20C0000,0x5A180000,0x8C0032,0x24140001, -0x8C0032,0x580048,0x4A4C0000,0x364C0001,0x304C0001,0x2800048,0x3A380001,0x30400001,0x1080048,0x301C0001,0x2A00004A,0x2800048,0x3A380001,0x30400001,0x1080048,0x301C0001,0x2A00004A,0x1080048,0x301C0001,0x2A00004A,0x2A00004A,0x2800048,0x3A380001,0x30400001,0x1080048,0x301C0001,0x2A00004A,0x1080048,0x301C0001,0x2A00004A,0x2A00004A,0x1080048, -0x301C0001,0x2A00004A,0x2A00004A,0x2A00004A,0xC4180000,0x65C0048,0xDE4C0000,0x62200000,0x46200001,0x3A1C0000,0x302C0001,0x300C0001,0xB4040000,0x5E140000,0x32300001,0x2A00004A,0xB80048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x2C0048,0x34200000,0x34200000,0x34200000,0x34200000,0x34200000, -0x34200000,0x20200001,0x20200001,0x20200001,0x1A200001,0x400048,0x400048,0x400048,0x400048,0x400048,0x400048,0x240C0001,0x240C0001,0x240C0001,0x1A140001,0x800048,0x800048,0x800048,0x1A000005,0x1400004A,0xC8200000,0x2C0048,0x2C0048,0x62200000,0x48200000,0x3C200000,0x3C200000,0x2C200000,0x9E0C0000,0x62140000,0x281C0000,0x240C0001, -0x5C0048,}; -static const uint32_t g_etc1_to_bc7_m6_table37[] = { -0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x8C0000, -0x8C0000,0x8C0000,0x8C0000,0x16000001,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x340000,0x340000,0x340000,0x2440000,0x640000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x2680000,0x2680000,0x2680000,0x2680000,0x2680000, -0x2680000,0xD80000,0xD80000,0xD80000,0x22000001,0x2680000,0x2680000,0x2680000,0x2680000,0x2680000,0x2680000,0xD80000,0xD80000,0xD80000,0x22000001,0xD80000,0xD80000,0xD80000,0x22000001,0x22000001,0x4C0000,0x480000,0x480000,0x540000,0x2580000,0x600000,0x600000,0x780000,0x540000,0x2580000,0x980000,0xD80000, -0x980000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x880000,0x880000,0x880000,0x1140000,0x1140000,0x2C000001,0x880000,0x880000,0x880000,0x1140000,0x1140000,0x2C000001,0x1140000,0x1140000,0x2C000001,0x2C000001,0x880000,0x880000,0x880000,0x1140000,0x1140000,0x2C000001,0x1140000,0x1140000,0x2C000001,0x2C000001,0x1140000, -0x1140000,0x2C000001,0x2C000001,0x2C000001,0x6680000,0x8600000,0x5C0000,0x7C0000,0x980000,0xC00000,0xE00000,0x1540000,0x740000,0x880000,0xC00000,0x2C000001,0xC00000,0x740000,0xAC0000,0x15C0000,0x38000001,0xAC0000,0x15C0000,0x38000001,0x15C0000,0x38000001,0x38000001,0xAC0000,0x15C0000,0x38000001,0x15C0000,0x38000001, -0x38000001,0x15C0000,0x38000001,0x38000001,0x38000001,0xAC0000,0x15C0000,0x38000001,0x15C0000,0x38000001,0x38000001,0x15C0000,0x38000001,0x38000001,0x38000001,0x15C0000,0x38000001,0x38000001,0x38000001,0x38000001,0x900000,0x7C0000,0x7C0000,0x2C00000,0x11C0000,0x9F00000,0x38000001,0x38000001,0x9C0000,0xD80000,0x2DEC0000,0x38000001, -0xF40000,0x500278,0x664800F4,0x444800F4,0x384800F5,0x603C0090,0x483C004D,0x3C400069,0x3E3C0090,0x383C004D,0x323C0092,0x5C3000F3,0x4A300032,0x3C380053,0x40300049,0x38300002,0x3430004E,0x383000F4,0x362C0051,0x322C0067,0x2E3000F3,0x780274,0x4E1C00F3,0x383000F4,0x46140092,0x3A20004A,0x32280092,0x440400F3,0x38100033,0x3210004F,0x2E1800F4,0xF40274, -0x36000104,0x320000B2,0x2C00011F,0x28000274,0xBC300005,0xFA4400D0,0xFE4C012C,0x6A300000,0x50300001,0x40300002,0x3A340006,0x38300006,0xB4180002,0x62280002,0x3A2C0035,0x3210004F,0xAC0274,0x5C00F4,0x5A540034,0x42500034,0x38500035,0x54480048,0x42480001,0x3A480005,0x3A48004A,0x3844000E,0x3248004A,0x8C00F3,0x48340032,0x3A400033,0x40300049,0x38300002, -0x3238004A,0x11800F3,0x38100033,0x3208004A,0x2E0000F3,0x8C00F3,0x48340032,0x3A400033,0x40300049,0x38300002,0x3238004A,0x11800F3,0x38100033,0x3208004A,0x2E0000F3,0x11800F3,0x38100033,0x3208004A,0x2E0000F3,0x2E0000F3,0xB0340003,0xFE4C004C,0xF254003D,0x6A300000,0x50300001,0x40300002,0x3A380001,0x38280003,0xB4180001,0x62280001,0x3C240032,0x3208004A, -0xC800F3,0x4800F4,0x4800F4,0x4800F4,0x4800F4,0x4E3C0048,0x4E3C0048,0x4E3C0048,0x343C0049,0x343C0049,0x2C3C0049,0x4A300032,0x4A300032,0x4A300032,0x38300001,0x38300001,0x2E34000E,0x30300032,0x30300032,0x2C300005,0x28300032,0x6800F3,0x6800F3,0x6800F3,0x3A200049,0x3A200049,0x2C2C0049,0x38100032,0x38100032,0x2C1C0002,0x28200032,0xD000F3, -0xD000F3,0x2C000049,0x2600003E,0x220000F3,0xB0300004,0xF63C004C,0x4800F4,0x6A300000,0x4C300001,0x40300001,0x3C300004,0x34300001,0xAA1C0000,0x62280001,0x382C0032,0x2C1C0002,0x9400F3,0x500034,0x500034,0x500034,0x500034,0x40480000,0x40480000,0x40480000,0x32480000,0x32480000,0x2C480001,0x780032,0x780032,0x780032,0x34380001,0x34380001, -0x2C400001,0xF40032,0xF40032,0x2C240001,0x28000032,0x780032,0x780032,0x780032,0x34380001,0x34380001,0x2C400001,0xF40032,0xF40032,0x2C240001,0x28000032,0xF40032,0xF40032,0x2C240001,0x28000032,0x28000032,0x98380000,0xBC480000,0x500034,0x6A300000,0x4A340000,0x3E340000,0x3A380000,0x34300001,0xAA1C0000,0x62280000,0xAC0032,0x2C240001, -0xAC0032,0x680048,0x525C0000,0x3E5C0001,0x385C0001,0x2980048,0x42480001,0x38500001,0x1380048,0x382C0001,0x3200004A,0x2980048,0x42480001,0x38500001,0x1380048,0x382C0001,0x3200004A,0x1380048,0x382C0001,0x3200004A,0x3200004A,0x2980048,0x42480001,0x38500001,0x1380048,0x382C0001,0x3200004A,0x1380048,0x382C0001,0x3200004A,0x3200004A,0x1380048, -0x382C0001,0x3200004A,0x3200004A,0x3200004A,0xCC280000,0xE6C0048,0xE65C0000,0x6A300000,0x4E300001,0x422C0000,0x383C0001,0x381C0001,0xBC140000,0x66240000,0x3A400001,0x3200004A,0xDC0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C0048,0x3C300000,0x3C300000,0x3C300000,0x3C300000,0x3C300000, -0x3C300000,0x28300001,0x28300001,0x28300001,0x22300001,0x580048,0x580048,0x580048,0x580048,0x580048,0x580048,0x2C1C0001,0x2C1C0001,0x2C1C0001,0x22240001,0xB00048,0xB00048,0xB00048,0x22000001,0x1C00004A,0xD0300000,0x3C0048,0x3C0048,0x6A300000,0x50300000,0x44300000,0x44300000,0x34300000,0xA61C0000,0x6A240000,0x302C0000,0x2C1C0001, -0x7C0048,}; -static const uint32_t g_etc1_to_bc7_m6_table38[] = { -0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0xBC0000, -0xBC0000,0xBC0000,0xBC0000,0x1E000001,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x440000,0x440000,0x440000,0x25C0000,0x880000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x2800000,0x2800000,0x2800000,0x2800000,0x2800000, -0x2800000,0x1080000,0x1080000,0x1080000,0x2A000001,0x2800000,0x2800000,0x2800000,0x2800000,0x2800000,0x2800000,0x1080000,0x1080000,0x1080000,0x2A000001,0x1080000,0x1080000,0x1080000,0x2A000001,0x2A000001,0x65C0000,0x580000,0x580000,0x4640000,0x26C0000,0x780000,0x780000,0x940000,0x4640000,0x26C0000,0xB80000,0x1080000, -0xB80000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0xA00000,0xA00000,0xA00000,0x1440000,0x1440000,0x34000001,0xA00000,0xA00000,0xA00000,0x1440000,0x1440000,0x34000001,0x1440000,0x1440000,0x34000001,0x34000001,0xA00000,0xA00000,0xA00000,0x1440000,0x1440000,0x34000001,0x1440000,0x1440000,0x34000001,0x34000001,0x1440000, -0x1440000,0x34000001,0x34000001,0x34000001,0x27C0000,0x740000,0x6C0000,0x2900000,0xB40000,0xE40000,0x1080000,0x1900000,0x880000,0xA00000,0xE40000,0x34000001,0xE40000,0x840000,0xC40000,0x18C0000,0x40000001,0xC40000,0x18C0000,0x40000001,0x18C0000,0x40000001,0x40000001,0xC40000,0x18C0000,0x40000001,0x18C0000,0x40000001, -0x40000001,0x18C0000,0x40000001,0x40000001,0x40000001,0xC40000,0x18C0000,0x40000001,0x18C0000,0x40000001,0x40000001,0x18C0000,0x40000001,0x40000001,0x40000001,0x18C0000,0x40000001,0x40000001,0x40000001,0x40000001,0xA40000,0x8C0000,0x8C0000,0xDC0000,0x1400000,0x13F00000,0x40000001,0x40000001,0xB40000,0xF80000,0x35FC0000,0x40000001, -0x1180000,0x600278,0x6E5800F4,0x4C5800F4,0x405800F5,0x684C0090,0x504C004D,0x44500069,0x464C0090,0x404C004D,0x3A4C0092,0x644000F3,0x52400032,0x44480053,0x48400049,0x40400002,0x3C40004E,0x404000F4,0x3E3C0051,0x3A3C0067,0x364000F3,0x900274,0x562C00F3,0x404000F4,0x4E240092,0x4230004A,0x3A380092,0x4C1400F3,0x40200033,0x3A20004F,0x362800F4,0x1240274, -0x400000F5,0x3A00009A,0x3400010B,0x30000274,0xC4400005,0xF25400E2,0xF65C0139,0x72400000,0x58400001,0x48400002,0x42440006,0x40400006,0xBC280002,0x6A380002,0x423C0035,0x3A20004F,0xD00274,0x6C00F4,0x62640034,0x4A600034,0x40600035,0x5C580048,0x4A580001,0x42580005,0x4258004A,0x4054000E,0x3A58004A,0xA400F3,0x50440032,0x42500033,0x48400049,0x40400002, -0x3A48004A,0x14C00F3,0x40200033,0x3A18004A,0x360000F3,0xA400F3,0x50440032,0x42500033,0x48400049,0x40400002,0x3A48004A,0x14C00F3,0x40200033,0x3A18004A,0x360000F3,0x14C00F3,0x40200033,0x3A18004A,0x360000F3,0x360000F3,0xB8440003,0xF65C004E,0xFA64003D,0x72400000,0x58400001,0x48400002,0x42480001,0x40380003,0xBC280001,0x6A380001,0x44340032,0x3A18004A, -0xE800F3,0x5800F4,0x5800F4,0x5800F4,0x5800F4,0x564C0048,0x564C0048,0x564C0048,0x3C4C0049,0x3C4C0049,0x344C0049,0x52400032,0x52400032,0x52400032,0x40400001,0x40400001,0x3644000E,0x38400032,0x38400032,0x34400005,0x30400032,0x8000F3,0x8000F3,0x8000F3,0x42300049,0x42300049,0x343C0049,0x40200032,0x40200032,0x342C0002,0x30300032,0x10000F3, -0x10000F3,0x340C0049,0x30000033,0x2A0000F3,0xB8400004,0xFE4C004C,0x5800F4,0x72400000,0x54400001,0x48400001,0x44400004,0x3C400001,0xB22C0000,0x6A380001,0x403C0032,0x342C0002,0xB400F3,0x600034,0x600034,0x600034,0x600034,0x48580000,0x48580000,0x48580000,0x3A580000,0x3A580000,0x34580001,0x900032,0x900032,0x900032,0x3C480001,0x3C480001, -0x34500001,0x1240032,0x1240032,0x34340001,0x30000032,0x900032,0x900032,0x900032,0x3C480001,0x3C480001,0x34500001,0x1240032,0x1240032,0x34340001,0x30000032,0x1240032,0x1240032,0x34340001,0x30000032,0x30000032,0xA0480000,0xC4580000,0x600034,0x72400000,0x52440000,0x46440000,0x42480000,0x3C400001,0xB22C0000,0x6A380000,0xD00032,0x34340001, -0xD00032,0x780048,0x5A6C0000,0x466C0001,0x406C0001,0x2B00048,0x4A580001,0x40600001,0x1680048,0x403C0001,0x3A00004A,0x2B00048,0x4A580001,0x40600001,0x1680048,0x403C0001,0x3A00004A,0x1680048,0x403C0001,0x3A00004A,0x3A00004A,0x2B00048,0x4A580001,0x40600001,0x1680048,0x403C0001,0x3A00004A,0x1680048,0x403C0001,0x3A00004A,0x3A00004A,0x1680048, -0x403C0001,0x3A00004A,0x3A00004A,0x3A00004A,0xD4380000,0x800048,0xEE6C0000,0x72400000,0x56400001,0x4A3C0000,0x404C0001,0x402C0001,0xC4240000,0x6E340000,0x42500001,0x3A00004A,0xFC0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x4C0048,0x44400000,0x44400000,0x44400000,0x44400000,0x44400000, -0x44400000,0x30400001,0x30400001,0x30400001,0x2A400001,0x700048,0x700048,0x700048,0x700048,0x700048,0x700048,0x342C0001,0x342C0001,0x342C0001,0x2A340001,0xE40048,0xE40048,0xE40048,0x2A100001,0x2400004A,0xD8400000,0x4C0048,0x4C0048,0x72400000,0x58400000,0x4C400000,0x4C400000,0x3C400000,0xAE2C0000,0x72340000,0x383C0000,0x342C0001, -0xA00048,}; -static const uint32_t g_etc1_to_bc7_m6_table39[] = { -0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0xF00000, -0xF00000,0xF00000,0xF00000,0x26000001,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x2540000,0x2540000,0x2540000,0x2740000,0xA80000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000, -0x2980000,0x1380000,0x1380000,0x1380000,0x32000001,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x1380000,0x1380000,0x1380000,0x32000001,0x1380000,0x1380000,0x1380000,0x32000001,0x32000001,0xE6C0000,0x680000,0x680000,0x780000,0x2800000,0x8C0000,0x8C0000,0x2AC0000,0x780000,0x2800000,0xDC0000,0x1380000, -0xDC0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0xB80000,0xB80000,0xB80000,0x1740000,0x1740000,0x3C000001,0xB80000,0xB80000,0xB80000,0x1740000,0x1740000,0x3C000001,0x1740000,0x1740000,0x3C000001,0x3C000001,0xB80000,0xB80000,0xB80000,0x1740000,0x1740000,0x3C000001,0x1740000,0x1740000,0x3C000001,0x3C000001,0x1740000, -0x1740000,0x3C000001,0x3C000001,0x3C000001,0x900000,0x840000,0x7C0000,0xA80000,0xD00000,0x1080000,0x12C0000,0x1CC0000,0x9C0000,0xB80000,0x1080000,0x3C000001,0x1080000,0x940000,0xDC0000,0x1BC0000,0x48000001,0xDC0000,0x1BC0000,0x48000001,0x1BC0000,0x48000001,0x48000001,0xDC0000,0x1BC0000,0x48000001,0x1BC0000,0x48000001, -0x48000001,0x1BC0000,0x48000001,0x48000001,0x48000001,0xDC0000,0x1BC0000,0x48000001,0x1BC0000,0x48000001,0x48000001,0x1BC0000,0x48000001,0x48000001,0x48000001,0x1BC0000,0x48000001,0x48000001,0x48000001,0x48000001,0xB80000,0x69C0000,0x69C0000,0xF80000,0x1680000,0x1DF40000,0x48000001,0x48000001,0xC80000,0x1140000,0x3FD00000,0x48000001, -0x1380000,0x700278,0x766800F4,0x546800F4,0x486800F5,0x705C0090,0x585C004D,0x4C600069,0x4E5C0090,0x485C004D,0x425C0092,0x6C5000F3,0x5A500032,0x4C580053,0x50500049,0x48500002,0x4450004E,0x485000F4,0x464C0051,0x424C0067,0x3E5000F3,0xA80274,0x5E3C00F3,0x485000F4,0x56340092,0x4A40004A,0x42480092,0x542400F3,0x48300033,0x4230004F,0x3E3800F4,0x1580274, -0x480C00F4,0x42040092,0x3E0000F7,0x38000274,0xCC500005,0xFA6400E2,0xFE6C0139,0x7A500000,0x60500001,0x50500002,0x4A540006,0x48500006,0xC4380002,0x72480002,0x4A4C0035,0x4230004F,0xF00274,0x7C00F4,0x6A740034,0x52700034,0x48700035,0x64680048,0x52680001,0x4A680005,0x4A68004A,0x4864000E,0x4268004A,0xBC00F3,0x58540032,0x4A600033,0x50500049,0x48500002, -0x4258004A,0x17C00F3,0x48300033,0x4228004A,0x3E0000F3,0xBC00F3,0x58540032,0x4A600033,0x50500049,0x48500002,0x4258004A,0x17C00F3,0x48300033,0x4228004A,0x3E0000F3,0x17C00F3,0x48300033,0x4228004A,0x3E0000F3,0x3E0000F3,0xC0540003,0xFE6C004E,0xF2740044,0x7A500000,0x60500001,0x50500002,0x4A580001,0x48480003,0xC4380001,0x72480001,0x4C440032,0x4228004A, -0x10C00F3,0x6800F4,0x6800F4,0x6800F4,0x6800F4,0x5E5C0048,0x5E5C0048,0x5E5C0048,0x445C0049,0x445C0049,0x3C5C0049,0x5A500032,0x5A500032,0x5A500032,0x48500001,0x48500001,0x3E54000E,0x40500032,0x40500032,0x3C500005,0x38500032,0x9800F3,0x9800F3,0x9800F3,0x4A400049,0x4A400049,0x3C4C0049,0x48300032,0x48300032,0x3C3C0002,0x38400032,0x13000F3, -0x13000F3,0x3C1C0049,0x38080032,0x320000F3,0xC0500004,0xF65C0051,0x6800F4,0x7A500000,0x5C500001,0x50500001,0x4C500004,0x44500001,0xBA3C0000,0x72480001,0x484C0032,0x3C3C0002,0xD800F3,0x700034,0x700034,0x700034,0x700034,0x50680000,0x50680000,0x50680000,0x42680000,0x42680000,0x3C680001,0xA80032,0xA80032,0xA80032,0x44580001,0x44580001, -0x3C600001,0x1580032,0x1580032,0x3C440001,0x38000032,0xA80032,0xA80032,0xA80032,0x44580001,0x44580001,0x3C600001,0x1580032,0x1580032,0x3C440001,0x38000032,0x1580032,0x1580032,0x3C440001,0x38000032,0x38000032,0xA8580000,0xCC680000,0x700034,0x7A500000,0x5A540000,0x4E540000,0x4A580000,0x44500001,0xBA3C0000,0x72480000,0xF00032,0x3C440001, -0xF00032,0x880048,0x627C0000,0x4E7C0001,0x487C0001,0xC80048,0x52680001,0x48700001,0x1980048,0x484C0001,0x4200004A,0xC80048,0x52680001,0x48700001,0x1980048,0x484C0001,0x4200004A,0x1980048,0x484C0001,0x4200004A,0x4200004A,0xC80048,0x52680001,0x48700001,0x1980048,0x484C0001,0x4200004A,0x1980048,0x484C0001,0x4200004A,0x4200004A,0x1980048, -0x484C0001,0x4200004A,0x4200004A,0x4200004A,0xDC480000,0x900048,0xF67C0000,0x7A500000,0x5E500001,0x524C0000,0x485C0001,0x483C0001,0xCC340000,0x76440000,0x4A600001,0x4200004A,0x1200048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x5C0048,0x4C500000,0x4C500000,0x4C500000,0x4C500000,0x4C500000, -0x4C500000,0x38500001,0x38500001,0x38500001,0x32500001,0x880048,0x880048,0x880048,0x880048,0x880048,0x880048,0x3C3C0001,0x3C3C0001,0x3C3C0001,0x32440001,0x1140048,0x1140048,0x1140048,0x32200001,0x2C00004A,0xE0500000,0x5C0048,0x5C0048,0x7A500000,0x60500000,0x54500000,0x54500000,0x44500000,0xB63C0000,0x7A440000,0x404C0000,0x3C3C0001, -0xC00048,}; -static const uint32_t g_etc1_to_bc7_m6_table40[] = { -0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x1240000, -0x1240000,0x1240000,0x1240000,0x30000000,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x680000,0x680000,0x680000,0x900000,0xD00000,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000, -0xB40000,0x1700000,0x1700000,0x1700000,0x3C000000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x1700000,0x1700000,0x1700000,0x3C000000,0x1700000,0x1700000,0x1700000,0x3C000000,0x3C000000,0x8800000,0x780001,0x780001,0x28C0000,0x980000,0x2A40000,0x2A40000,0xCC0000,0x28C0000,0x980000,0x1000000,0x1700000, -0x1000000,0x8C0001,0x8C0001,0x8C0001,0x8C0001,0x2D00000,0x2D00000,0x2D00000,0x1AC0000,0x1AC0000,0x46000000,0x2D00000,0x2D00000,0x2D00000,0x1AC0000,0x1AC0000,0x46000000,0x1AC0000,0x1AC0000,0x46000000,0x46000000,0x2D00000,0x2D00000,0x2D00000,0x1AC0000,0x1AC0000,0x46000000,0x1AC0000,0x1AC0000,0x46000000,0x46000000,0x1AC0000, -0x1AC0000,0x46000000,0x46000000,0x46000000,0xA40000,0x980000,0x8C0001,0xC00000,0x2EC0000,0x12C0000,0x15C0000,0x5F80000,0x2B00000,0x2D00000,0x12C0000,0x46000000,0x12C0000,0xA40001,0x2F40000,0x1F40000,0x52000000,0x2F40000,0x1F40000,0x52000000,0x1F40000,0x52000000,0x52000000,0x2F40000,0x1F40000,0x52000000,0x1F40000,0x52000000, -0x52000000,0x1F40000,0x52000000,0x52000000,0x52000000,0x2F40000,0x1F40000,0x52000000,0x1F40000,0x52000000,0x52000000,0x1F40000,0x52000000,0x52000000,0x52000000,0x1F40000,0x52000000,0x52000000,0x52000000,0x52000000,0xD00000,0xB00000,0xB00000,0x3140000,0x1940000,0x27FC0000,0x52000000,0x52000000,0xE00000,0x1380000,0x49C40000,0x52000000, -0x1600000,0x840274,0x807800F3,0x5C7800F4,0x527800F3,0x76700092,0x5E70004F,0x54700067,0x56700092,0x526C004E,0x4C6C0092,0x746400F4,0x62640033,0x54680051,0x5A60004A,0x52640002,0x4C64004D,0x526000F4,0x4E5C0053,0x4A5C0069,0x466000F5,0xC40274,0x684C00F3,0x526400F4,0x5E480092,0x52540049,0x4C580090,0x5C3800F3,0x52400032,0x4C40004D,0x464C00F4,0x18C0274, -0x521800F3,0x4C140090,0x460800F4,0x40000278,0xCE640004,0xF47800F4,0xF67C014C,0x80640002,0x68640002,0x5A640002,0x52640006,0x50600006,0xCE4C0002,0x7E580000,0x545C0035,0x4C40004D,0x1180274,0x9000F3,0x74840032,0x5A840032,0x52840032,0x6A7C0049,0x5C780002,0x527C0005,0x54780049,0x5078000E,0x4C780049,0xD400F3,0x62640032,0x52740032,0x5A600049,0x52640001, -0x4C680049,0x1B000F3,0x523C0032,0x4C380048,0x460000F4,0xD400F3,0x62640032,0x52740032,0x5A600049,0x52640001,0x4C680049,0x1B000F3,0x523C0032,0x4C380048,0x460000F4,0x1B000F3,0x523C0032,0x4C380048,0x460000F4,0x460000F4,0xCE640003,0xF8800053,0xFC880043,0x80640001,0x68640001,0x5A640001,0x526C0001,0x525C0004,0xD4480001,0x7E580000,0x54580033,0x4C380048, -0x13000F3,0x7800F3,0x7800F3,0x7800F3,0x7800F3,0x6470004A,0x6470004A,0x6470004A,0x4E6C004A,0x4E6C004A,0x466C004A,0x62640033,0x62640033,0x62640033,0x50640002,0x50640002,0x4864000E,0x4A600033,0x4A600033,0x46600005,0x40600035,0x2B000F3,0x2B000F3,0x2B000F3,0x52540049,0x52540049,0x465C004A,0x50440032,0x50440032,0x464C0001,0x42500034,0x16800F3, -0x16800F3,0x462C0048,0x40200034,0x3C0000F4,0xCA640003,0xF0700053,0x7800F3,0x80640001,0x64640002,0x58640002,0x56640003,0x4E600001,0xBE500000,0x7E580000,0x50600033,0x464C0001,0xFC00F3,0x840032,0x840032,0x840032,0x840032,0x587C0001,0x587C0001,0x587C0001,0x4A7C0001,0x4A7C0001,0x46780001,0xC40032,0xC40032,0xC40032,0x4E680001,0x4E680001, -0x46700000,0x18C0032,0x18C0032,0x46500000,0x40000034,0xC40032,0xC40032,0xC40032,0x4E680001,0x4E680001,0x46700000,0x18C0032,0x18C0032,0x46500000,0x40000034,0x18C0032,0x18C0032,0x46500000,0x40000034,0x40000034,0xAC6C0000,0xC67C0001,0x840032,0x80640000,0x5E6C0001,0x56680000,0x506C0001,0x4E600000,0xBE500000,0x785C0000,0x1180032,0x46500000, -0x1180032,0x98004A,0x68900001,0x588C0001,0x528C0001,0xE40048,0x5C780001,0x52800001,0x1D00048,0x525C0000,0x4C000048,0xE40048,0x5C780001,0x52800001,0x1D00048,0x525C0000,0x4C000048,0x1D00048,0x525C0000,0x4C000048,0x4C000048,0xE40048,0x5C780001,0x52800001,0x1D00048,0x525C0000,0x4C000048,0x1D00048,0x525C0000,0x4C000048,0x4C000048,0x1D00048, -0x525C0000,0x4C000048,0x4C000048,0x4C000048,0xE25C0000,0xA40048,0xF0900001,0x84600000,0x68600001,0x5C5C0000,0x526C0000,0x52480000,0xD8440000,0x7E580000,0x54700000,0x4C000048,0x1480048,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x6C004A,0x52640001,0x52640001,0x52640001,0x52640001,0x52640001, -0x52640001,0x42600001,0x42600001,0x42600001,0x3C600001,0xA40048,0xA40048,0xA40048,0xA40048,0xA40048,0xA40048,0x464C0001,0x464C0001,0x464C0001,0x3C540001,0x14C0048,0x14C0048,0x14C0048,0x3C300000,0x36000048,0xDA640001,0x6C004A,0x6C004A,0x7C640001,0x66640001,0x5A640001,0x5A640001,0x4C640001,0xBA500000,0x7E580000,0x46600001,0x464C0001, -0xE80048,}; -static const uint32_t g_etc1_to_bc7_m6_table41[] = { -0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0x1580000, -0x1580000,0x1580000,0x1580000,0x38000000,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x4780000,0x4780000,0x4780000,0xA80000,0xF00000,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000, -0xCC0000,0x1A00000,0x1A00000,0x1A00000,0x44000000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0x1A00000,0x1A00000,0x1A00000,0x44000000,0x1A00000,0x1A00000,0x1A00000,0x44000000,0x44000000,0x940000,0x880001,0x880001,0xA00000,0xAC0000,0xBC0000,0xBC0000,0xE80000,0xA00000,0xAC0000,0x1240000,0x1A00000, -0x1240000,0x9C0001,0x9C0001,0x9C0001,0x9C0001,0x2E80000,0x2E80000,0x2E80000,0x1DC0000,0x1DC0000,0x4E000000,0x2E80000,0x2E80000,0x2E80000,0x1DC0000,0x1DC0000,0x4E000000,0x1DC0000,0x1DC0000,0x4E000000,0x4E000000,0x2E80000,0x2E80000,0x2E80000,0x1DC0000,0x1DC0000,0x4E000000,0x1DC0000,0x1DC0000,0x4E000000,0x4E000000,0x1DC0000, -0x1DC0000,0x4E000000,0x4E000000,0x4E000000,0xB80000,0xA80000,0x9C0001,0x2D40000,0x1080000,0x1500000,0x1800000,0x11F40000,0x2C40000,0x2E80000,0x1500000,0x4E000000,0x1500000,0xB40001,0x30C0000,0xBFC0000,0x5A000000,0x30C0000,0xBFC0000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x30C0000,0xBFC0000,0x5A000000,0xBFC0000,0x5A000000, -0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0x30C0000,0xBFC0000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0x5A000000,0xE40000,0x8C00000,0x8C00000,0x1300000,0x1BC0000,0x31FC0000,0x5A000000,0x5A000000,0xF80000,0x1540000,0x51D40000,0x5A000000, -0x1800000,0x940274,0x888800F3,0x648800F4,0x5A8800F3,0x7E800092,0x6680004F,0x5C800067,0x5E800092,0x5A7C004E,0x547C0092,0x7C7400F4,0x6A740033,0x5C780051,0x6270004A,0x5A740002,0x5474004D,0x5A7000F4,0x566C0053,0x526C0069,0x4E7000F5,0xDC0274,0x705C00F3,0x5A7400F4,0x66580092,0x5A640049,0x54680090,0x644800F3,0x5A500032,0x5450004D,0x4E5C00F4,0x1BC0274, -0x5A2800F3,0x54240090,0x4E1800F4,0x48000278,0xD6740004,0xFC8800F4,0xFE8C014C,0x88740002,0x70740002,0x62740002,0x5A740006,0x58700006,0xD65C0002,0x86680000,0x5C6C0035,0x5450004D,0x1380274,0xA000F3,0x7C940032,0x62940032,0x5A940032,0x728C0049,0x64880002,0x5A8C0005,0x5C880049,0x5888000E,0x54880049,0xEC00F3,0x6A740032,0x5A840032,0x62700049,0x5A740001, -0x54780049,0x1E400F3,0x5A4C0032,0x54480048,0x4E0000F4,0xEC00F3,0x6A740032,0x5A840032,0x62700049,0x5A740001,0x54780049,0x1E400F3,0x5A4C0032,0x54480048,0x4E0000F4,0x1E400F3,0x5A4C0032,0x54480048,0x4E0000F4,0x4E0000F4,0xD6740003,0xF0900059,0xF498004A,0x88740001,0x70740001,0x62740001,0x5A7C0001,0x5A6C0004,0xDC580001,0x86680000,0x5C680033,0x54480048, -0x15400F3,0x8800F3,0x8800F3,0x8800F3,0x8800F3,0x6C80004A,0x6C80004A,0x6C80004A,0x567C004A,0x567C004A,0x4E7C004A,0x6A740033,0x6A740033,0x6A740033,0x58740002,0x58740002,0x5074000E,0x52700033,0x52700033,0x4E700005,0x48700035,0xC800F3,0xC800F3,0xC800F3,0x5A640049,0x5A640049,0x4E6C004A,0x58540032,0x58540032,0x4E5C0001,0x4A600034,0x19800F3, -0x19800F3,0x4E3C0048,0x48300034,0x440000F4,0xD2740003,0xF8800053,0x8800F3,0x88740001,0x6C740002,0x60740002,0x5E740003,0x56700001,0xC6600000,0x86680000,0x58700033,0x4E5C0001,0x12000F3,0x940032,0x940032,0x940032,0x940032,0x608C0001,0x608C0001,0x608C0001,0x528C0001,0x528C0001,0x4E880001,0xDC0032,0xDC0032,0xDC0032,0x56780001,0x56780001, -0x4E800000,0x1BC0032,0x1BC0032,0x4E600000,0x48000034,0xDC0032,0xDC0032,0xDC0032,0x56780001,0x56780001,0x4E800000,0x1BC0032,0x1BC0032,0x4E600000,0x48000034,0x1BC0032,0x1BC0032,0x4E600000,0x48000034,0x48000034,0xB47C0000,0xCE8C0001,0x940032,0x88740000,0x667C0001,0x5E780000,0x587C0001,0x56700000,0xC6600000,0x806C0000,0x1380032,0x4E600000, -0x1380032,0xA8004A,0x70A00001,0x609C0001,0x5A9C0001,0xFC0048,0x64880001,0x5A900001,0x3F80048,0x5A6C0000,0x54000048,0xFC0048,0x64880001,0x5A900001,0x3F80048,0x5A6C0000,0x54000048,0x3F80048,0x5A6C0000,0x54000048,0x54000048,0xFC0048,0x64880001,0x5A900001,0x3F80048,0x5A6C0000,0x54000048,0x3F80048,0x5A6C0000,0x54000048,0x54000048,0x3F80048, -0x5A6C0000,0x54000048,0x54000048,0x54000048,0xEA6C0000,0x2B40048,0xF8A00001,0x8C700000,0x70700001,0x646C0000,0x5A7C0000,0x5A580000,0xE0540000,0x86680000,0x5C800000,0x54000048,0x1680048,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x7C004A,0x5A740001,0x5A740001,0x5A740001,0x5A740001,0x5A740001, -0x5A740001,0x4A700001,0x4A700001,0x4A700001,0x44700001,0xBC0048,0xBC0048,0xBC0048,0xBC0048,0xBC0048,0xBC0048,0x4E5C0001,0x4E5C0001,0x4E5C0001,0x44640001,0x17C0048,0x17C0048,0x17C0048,0x44400000,0x3E000048,0xE2740001,0x7C004A,0x7C004A,0x84740001,0x6E740001,0x62740001,0x62740001,0x54740001,0xC2600000,0x86680000,0x4E700001,0x4E5C0001, -0x10C0048,}; -static const uint32_t g_etc1_to_bc7_m6_table42[] = { -0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0x1880000, -0x1880000,0x1880000,0x1880000,0x40000000,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0xC880000,0xC880000,0xC880000,0xC00000,0x1140000,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000, -0xE40000,0x1D00000,0x1D00000,0x1D00000,0x4C000000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0x1D00000,0x1D00000,0x1D00000,0x4C000000,0x1D00000,0x1D00000,0x1D00000,0x4C000000,0x4C000000,0xA40000,0x980001,0x980001,0xB40000,0xC00000,0xD00000,0xD00000,0x3000000,0xB40000,0xC00000,0x1480000,0x1D00000, -0x1480000,0xAC0001,0xAC0001,0xAC0001,0xAC0001,0x3000000,0x3000000,0x3000000,0x5FC0000,0x5FC0000,0x56000000,0x3000000,0x3000000,0x3000000,0x5FC0000,0x5FC0000,0x56000000,0x5FC0000,0x5FC0000,0x56000000,0x56000000,0x3000000,0x3000000,0x3000000,0x5FC0000,0x5FC0000,0x56000000,0x5FC0000,0x5FC0000,0x56000000,0x56000000,0x5FC0000, -0x5FC0000,0x56000000,0x56000000,0x56000000,0x4C80000,0x4B80000,0xAC0001,0xEC0000,0x1240000,0x1700000,0x1A80000,0x1BF80000,0x2D80000,0x3000000,0x1700000,0x56000000,0x1700000,0xC40001,0x3240000,0x17FC0000,0x62000000,0x3240000,0x17FC0000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x3240000,0x17FC0000,0x62000000,0x17FC0000,0x62000000, -0x62000000,0x17FC0000,0x62000000,0x62000000,0x62000000,0x3240000,0x17FC0000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x62000000,0x62000000,0xF80000,0xD40000,0xD40000,0x14C0000,0x1E40000,0x3BFC0000,0x62000000,0x62000000,0x10C0000,0x1740000,0x59E40000,0x62000000, -0x1A40000,0xA40274,0x909800F3,0x6C9800F4,0x629800F3,0x86900092,0x6E90004F,0x64900067,0x66900092,0x628C004E,0x5C8C0092,0x848400F4,0x72840033,0x64880051,0x6A80004A,0x62840002,0x5C84004D,0x628000F4,0x5E7C0053,0x5A7C0069,0x568000F5,0xF40274,0x786C00F3,0x628400F4,0x6E680092,0x62740049,0x5C780090,0x6C5800F3,0x62600032,0x5C60004D,0x566C00F4,0x1F00274, -0x623800F3,0x5C340090,0x562800F4,0x50000278,0xDE840004,0xF498010A,0xF8A0015B,0x90840002,0x78840002,0x6A840002,0x62840006,0x60800006,0xDE6C0002,0x8E780000,0x647C0035,0x5C60004D,0x15C0274,0xB000F3,0x84A40032,0x6AA40032,0x62A40032,0x7A9C0049,0x6C980002,0x629C0005,0x64980049,0x6098000E,0x5C980049,0x10400F3,0x72840032,0x62940032,0x6A800049,0x62840001, -0x5C880049,0x7FC00F3,0x625C0032,0x5C580048,0x560000F4,0x10400F3,0x72840032,0x62940032,0x6A800049,0x62840001,0x5C880049,0x7FC00F3,0x625C0032,0x5C580048,0x560000F4,0x7FC00F3,0x625C0032,0x5C580048,0x560000F4,0x560000F4,0xDE840003,0xF8A00059,0xFCA8004A,0x90840001,0x78840001,0x6A840001,0x628C0001,0x627C0004,0xE4680001,0x8E780000,0x64780033,0x5C580048, -0x17400F3,0x9800F3,0x9800F3,0x9800F3,0x9800F3,0x7490004A,0x7490004A,0x7490004A,0x5E8C004A,0x5E8C004A,0x568C004A,0x72840033,0x72840033,0x72840033,0x60840002,0x60840002,0x5884000E,0x5A800033,0x5A800033,0x56800005,0x50800035,0xE000F3,0xE000F3,0xE000F3,0x62740049,0x62740049,0x567C004A,0x60640032,0x60640032,0x566C0001,0x52700034,0x1CC00F3, -0x1CC00F3,0x564C0048,0x50400034,0x4C0000F4,0xDA840003,0xF090005A,0x9800F3,0x90840001,0x74840002,0x68840002,0x66840003,0x5E800001,0xCE700000,0x8E780000,0x60800033,0x566C0001,0x14000F3,0xA40032,0xA40032,0xA40032,0xA40032,0x689C0001,0x689C0001,0x689C0001,0x5A9C0001,0x5A9C0001,0x56980001,0xF40032,0xF40032,0xF40032,0x5E880001,0x5E880001, -0x56900000,0x1F00032,0x1F00032,0x56700000,0x50000034,0xF40032,0xF40032,0xF40032,0x5E880001,0x5E880001,0x56900000,0x1F00032,0x1F00032,0x56700000,0x50000034,0x1F00032,0x1F00032,0x56700000,0x50000034,0x50000034,0xBC8C0000,0xD69C0001,0xA40032,0x90840000,0x6E8C0001,0x66880000,0x608C0001,0x5E800000,0xCE700000,0x887C0000,0x15C0032,0x56700000, -0x15C0032,0xB8004A,0x78B00001,0x68AC0001,0x62AC0001,0x1140048,0x6C980001,0x62A00001,0xFF80048,0x627C0000,0x5C000048,0x1140048,0x6C980001,0x62A00001,0xFF80048,0x627C0000,0x5C000048,0xFF80048,0x627C0000,0x5C000048,0x5C000048,0x1140048,0x6C980001,0x62A00001,0xFF80048,0x627C0000,0x5C000048,0xFF80048,0x627C0000,0x5C000048,0x5C000048,0xFF80048, -0x627C0000,0x5C000048,0x5C000048,0x5C000048,0xF27C0000,0xAC40048,0xF0B00002,0x94800000,0x78800001,0x6C7C0000,0x628C0000,0x62680000,0xE8640000,0x8E780000,0x64900000,0x5C000048,0x18C0048,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x8C004A,0x62840001,0x62840001,0x62840001,0x62840001,0x62840001, -0x62840001,0x52800001,0x52800001,0x52800001,0x4C800001,0x2D00048,0x2D00048,0x2D00048,0x2D00048,0x2D00048,0x2D00048,0x566C0001,0x566C0001,0x566C0001,0x4C740001,0x1AC0048,0x1AC0048,0x1AC0048,0x4C500000,0x46000048,0xEA840001,0x8C004A,0x8C004A,0x8C840001,0x76840001,0x6A840001,0x6A840001,0x5C840001,0xCA700000,0x8E780000,0x56800001,0x566C0001, -0x12C0048,}; -static const uint32_t g_etc1_to_bc7_m6_table43[] = { -0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0x1B80000, -0x1B80000,0x1B80000,0x1B80000,0x48000000,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x9C0000,0x9C0000,0x9C0000,0xD80000,0x1340000,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000, -0xFC0000,0x3F80000,0x3F80000,0x3F80000,0x54000000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0x3F80000,0x3F80000,0x3F80000,0x54000000,0x3F80000,0x3F80000,0x3F80000,0x54000000,0x54000000,0x2B40000,0xA80001,0xA80001,0x2C40000,0xD40000,0xE80000,0xE80000,0x11C0000,0x2C40000,0xD40000,0x1680000,0x3F80000, -0x1680000,0xBC0001,0xBC0001,0xBC0001,0xBC0001,0x3180000,0x3180000,0x3180000,0x11FC0000,0x11FC0000,0x5E000000,0x3180000,0x3180000,0x3180000,0x11FC0000,0x11FC0000,0x5E000000,0x11FC0000,0x11FC0000,0x5E000000,0x5E000000,0x3180000,0x3180000,0x3180000,0x11FC0000,0x11FC0000,0x5E000000,0x11FC0000,0x11FC0000,0x5E000000,0x5E000000,0x11FC0000, -0x11FC0000,0x5E000000,0x5E000000,0x5E000000,0xDC0000,0xCC80000,0xBC0001,0x3000000,0x1400000,0x1940000,0x1D00000,0x25FC0000,0x2EC0000,0x3180000,0x1940000,0x5E000000,0x1940000,0xD40001,0x33C0000,0x23FC0000,0x6A000000,0x33C0000,0x23FC0000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x33C0000,0x23FC0000,0x6A000000,0x23FC0000,0x6A000000, -0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0x33C0000,0x23FC0000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0x6A000000,0x10C0000,0xE40000,0xE40000,0x1680000,0x7F80000,0x45FC0000,0x6A000000,0x6A000000,0x1240000,0x1900000,0x61F40000,0x6A000000, -0x1C80000,0xB40274,0x98A800F3,0x74A800F4,0x6AA800F3,0x8EA00092,0x76A0004F,0x6CA00067,0x6EA00092,0x6A9C004E,0x649C0092,0x8C9400F4,0x7A940033,0x6C980051,0x7290004A,0x6A940002,0x6494004D,0x6A9000F4,0x668C0053,0x628C0069,0x5E9000F5,0x10C0274,0x807C00F3,0x6A9400F4,0x76780092,0x6A840049,0x64880090,0x746800F3,0x6A700032,0x6470004D,0x5E7C00F4,0xBF80274, -0x6A4800F3,0x64440090,0x5E3800F4,0x58000278,0xE6940004,0xFCA8010A,0xFEAC015F,0x98940002,0x80940002,0x72940002,0x6A940006,0x68900006,0xE67C0002,0x96880000,0x6C8C0035,0x6470004D,0x17C0274,0xC000F3,0x8CB40032,0x72B40032,0x6AB40032,0x82AC0049,0x74A80002,0x6AAC0005,0x6CA80049,0x68A8000E,0x64A80049,0x11C00F3,0x7A940032,0x6AA40032,0x72900049,0x6A940001, -0x64980049,0x13FC00F3,0x6A6C0032,0x64680048,0x5E0000F4,0x11C00F3,0x7A940032,0x6AA40032,0x72900049,0x6A940001,0x64980049,0x13FC00F3,0x6A6C0032,0x64680048,0x5E0000F4,0x13FC00F3,0x6A6C0032,0x64680048,0x5E0000F4,0x5E0000F4,0xE6940003,0xF0B00063,0xF4B80053,0x98940001,0x80940001,0x72940001,0x6A9C0001,0x6A8C0004,0xEC780001,0x96880000,0x6C880033,0x64680048, -0x19800F3,0xA800F3,0xA800F3,0xA800F3,0xA800F3,0x7CA0004A,0x7CA0004A,0x7CA0004A,0x669C004A,0x669C004A,0x5E9C004A,0x7A940033,0x7A940033,0x7A940033,0x68940002,0x68940002,0x6094000E,0x62900033,0x62900033,0x5E900005,0x58900035,0xF800F3,0xF800F3,0xF800F3,0x6A840049,0x6A840049,0x5E8C004A,0x68740032,0x68740032,0x5E7C0001,0x5A800034,0x1FC00F3, -0x1FC00F3,0x5E5C0048,0x58500034,0x540000F4,0xE2940003,0xF8A0005A,0xA800F3,0x98940001,0x7C940002,0x70940002,0x6E940003,0x66900001,0xD6800000,0x96880000,0x68900033,0x5E7C0001,0x16400F3,0xB40032,0xB40032,0xB40032,0xB40032,0x70AC0001,0x70AC0001,0x70AC0001,0x62AC0001,0x62AC0001,0x5EA80001,0x10C0032,0x10C0032,0x10C0032,0x66980001,0x66980001, -0x5EA00000,0xBF80032,0xBF80032,0x5E800000,0x58000034,0x10C0032,0x10C0032,0x10C0032,0x66980001,0x66980001,0x5EA00000,0xBF80032,0xBF80032,0x5E800000,0x58000034,0xBF80032,0xBF80032,0x5E800000,0x58000034,0x58000034,0xC49C0000,0xDEAC0001,0xB40032,0x98940000,0x769C0001,0x6E980000,0x689C0001,0x66900000,0xD6800000,0x908C0000,0x17C0032,0x5E800000, -0x17C0032,0xC8004A,0x80C00001,0x70BC0001,0x6ABC0001,0x12C0048,0x74A80001,0x6AB00001,0x1BF80048,0x6A8C0000,0x64000048,0x12C0048,0x74A80001,0x6AB00001,0x1BF80048,0x6A8C0000,0x64000048,0x1BF80048,0x6A8C0000,0x64000048,0x64000048,0x12C0048,0x74A80001,0x6AB00001,0x1BF80048,0x6A8C0000,0x64000048,0x1BF80048,0x6A8C0000,0x64000048,0x64000048,0x1BF80048, -0x6A8C0000,0x64000048,0x64000048,0x64000048,0xFA8C0000,0xD80048,0xF8C00002,0x9C900000,0x80900001,0x748C0000,0x6A9C0000,0x6A780000,0xF0740000,0x96880000,0x6CA00000,0x64000048,0x1AC0048,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x9C004A,0x6A940001,0x6A940001,0x6A940001,0x6A940001,0x6A940001, -0x6A940001,0x5A900001,0x5A900001,0x5A900001,0x54900001,0x2E80048,0x2E80048,0x2E80048,0x2E80048,0x2E80048,0x2E80048,0x5E7C0001,0x5E7C0001,0x5E7C0001,0x54840001,0x1DC0048,0x1DC0048,0x1DC0048,0x54600000,0x4E000048,0xF2940001,0x9C004A,0x9C004A,0x94940001,0x7E940001,0x72940001,0x72940001,0x64940001,0xD2800000,0x96880000,0x5E900001,0x5E7C0001, -0x1500048,}; -static const uint32_t g_etc1_to_bc7_m6_table44[] = { -0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0x1F00000, -0x1F00000,0x1F00000,0x1F00000,0x50000001,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xEAC0000,0xEAC0000,0xEAC0000,0xF40000,0x15C0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000, -0x1180000,0x11F80000,0x11F80000,0x11F80000,0x5C000001,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x11F80000,0x11F80000,0x11F80000,0x5C000001,0x11F80000,0x11F80000,0x11F80000,0x5C000001,0x5C000001,0xC80000,0xBC0000,0xBC0000,0x4D80000,0xEC0000,0x1000000,0x1000000,0x13C0000,0x4D80000,0xEC0000,0x1900000,0x11F80000, -0x1900000,0xD00000,0xD00000,0xD00000,0xD00000,0x1340000,0x1340000,0x1340000,0x1FF80000,0x1FF80000,0x66000001,0x1340000,0x1340000,0x1340000,0x1FF80000,0x1FF80000,0x66000001,0x1FF80000,0x1FF80000,0x66000001,0x66000001,0x1340000,0x1340000,0x1340000,0x1FF80000,0x1FF80000,0x66000001,0x1FF80000,0x1FF80000,0x66000001,0x66000001,0x1FF80000, -0x1FF80000,0x66000001,0x66000001,0x66000001,0x2F00000,0x6DC0000,0xD00000,0x3180000,0x15C0000,0x1B80000,0x1FC0000,0x33F40000,0x1040000,0x1340000,0x1B80000,0x66000001,0x1B80000,0xE80000,0x1580000,0x31F80000,0x72000001,0x1580000,0x31F80000,0x72000001,0x31F80000,0x72000001,0x72000001,0x1580000,0x31F80000,0x72000001,0x31F80000,0x72000001, -0x72000001,0x31F80000,0x72000001,0x72000001,0x72000001,0x1580000,0x31F80000,0x72000001,0x31F80000,0x72000001,0x72000001,0x31F80000,0x72000001,0x72000001,0x72000001,0x31F80000,0x72000001,0x72000001,0x72000001,0x72000001,0x5200000,0xF80000,0xF80000,0x1840000,0x15FC0000,0x51F80000,0x72000001,0x72000001,0x13C0000,0x1B40000,0x6BE80000,0x72000001, -0x1EC0000,0xC40278,0xA0BC00F4,0x7EBC00F4,0x72BC00F5,0x9AB00090,0x82B0004D,0x76B40069,0x78B00090,0x72B0004D,0x6CB00092,0x96A400F3,0x84A40032,0x76AC0053,0x7AA40049,0x72A40002,0x6EA4004E,0x72A400F4,0x70A00051,0x6CA00067,0x68A400F3,0x3240274,0x889000F3,0x72A400F4,0x80880092,0x7494004A,0x6C9C0092,0x7E7800F3,0x72840033,0x6C84004F,0x688C00F4,0x17FC0274, -0x726000F4,0x6C580092,0x684400F3,0x62000274,0xF6A40005,0xF6BC0120,0xF8C0016C,0xA4A40000,0x8AA40001,0x7AA40002,0x74A80006,0x72A40006,0xEE8C0002,0x9C9C0002,0x74A00035,0x6C84004F,0x1A40274,0xD000F4,0x94C80034,0x7CC40034,0x72C40035,0x8EBC0048,0x7CBC0001,0x74BC0005,0x74BC004A,0x72B8000E,0x6CBC004A,0x13800F3,0x82A80032,0x74B40033,0x7AA40049,0x72A40002, -0x6CAC004A,0x21F800F3,0x72840033,0x6C7C004A,0x680000F3,0x13800F3,0x82A80032,0x74B40033,0x7AA40049,0x72A40002,0x6CAC004A,0x21F800F3,0x72840033,0x6C7C004A,0x680000F3,0x21F800F3,0x72840033,0x6C7C004A,0x680000F3,0x680000F3,0xEAA80003,0xFAC40060,0xFECC0054,0xA4A40000,0x8AA40001,0x7AA40002,0x74AC0001,0x729C0003,0xEE8C0001,0x9C9C0001,0x76980032,0x6C7C004A, -0x1BC00F3,0xBC00F4,0xBC00F4,0xBC00F4,0xBC00F4,0x88B00048,0x88B00048,0x88B00048,0x6EB00049,0x6EB00049,0x66B00049,0x84A40032,0x84A40032,0x84A40032,0x72A40001,0x72A40001,0x68A8000E,0x6AA40032,0x6AA40032,0x66A40005,0x62A40032,0x11400F3,0x11400F3,0x11400F3,0x74940049,0x74940049,0x66A00049,0x72840032,0x72840032,0x66900002,0x62940032,0xFF800F3, -0xFF800F3,0x66700049,0x625C0032,0x5C0000F3,0xEAA40004,0xF2B40060,0xBC00F4,0xA4A40000,0x86A40001,0x7AA40001,0x76A40004,0x6EA40001,0xE4900000,0x9C9C0001,0x72A00032,0x66900002,0x18C00F3,0xC40034,0xC40034,0xC40034,0xC40034,0x7ABC0000,0x7ABC0000,0x7ABC0000,0x6CBC0000,0x6CBC0000,0x66BC0001,0x3240032,0x3240032,0x3240032,0x6EAC0001,0x6EAC0001, -0x66B40001,0x17FC0032,0x17FC0032,0x66980001,0x62000032,0x3240032,0x3240032,0x3240032,0x6EAC0001,0x6EAC0001,0x66B40001,0x17FC0032,0x17FC0032,0x66980001,0x62000032,0x17FC0032,0x17FC0032,0x66980001,0x62000032,0x62000032,0xD2AC0000,0xF6BC0000,0xC40034,0xA4A40000,0x84A80000,0x78A80000,0x74AC0000,0x6EA40001,0xE4900000,0x9C9C0000,0x1A40032,0x66980001, -0x1A40032,0xDC0048,0x8CD00000,0x78D00001,0x72D00001,0x3440048,0x7CBC0001,0x72C40001,0x27FC0048,0x72A00001,0x6C00004A,0x3440048,0x7CBC0001,0x72C40001,0x27FC0048,0x72A00001,0x6C00004A,0x27FC0048,0x72A00001,0x6C00004A,0x6C00004A,0x3440048,0x7CBC0001,0x72C40001,0x27FC0048,0x72A00001,0x6C00004A,0x27FC0048,0x72A00001,0x6C00004A,0x6C00004A,0x27FC0048, -0x72A00001,0x6C00004A,0x6C00004A,0x6C00004A,0xF6A40001,0xCE80048,0xF2D40005,0xA4A40000,0x88A40001,0x7CA00000,0x72B00001,0x72900001,0xF6880000,0xA0980000,0x74B40001,0x6C00004A,0x1D40048,0xB00048,0xB00048,0xB00048,0xB00048,0xB00048,0xB00048,0xB00048,0xB00048,0xB00048,0xB00048,0x76A40000,0x76A40000,0x76A40000,0x76A40000,0x76A40000, -0x76A40000,0x62A40001,0x62A40001,0x62A40001,0x5CA40001,0x1040048,0x1040048,0x1040048,0x1040048,0x1040048,0x1040048,0x66900001,0x66900001,0x66900001,0x5C980001,0x7FC0048,0x7FC0048,0x7FC0048,0x5C740001,0x5600004A,0xFAA40001,0xB00048,0xB00048,0xA4A40000,0x8AA40000,0x7EA40000,0x7EA40000,0x6EA40000,0xE0900000,0xA4980000,0x6AA00000,0x66900001, -0x1740048,}; -static const uint32_t g_etc1_to_bc7_m6_table45[] = { -0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0xBF80000, -0xBF80000,0xBF80000,0xBF80000,0x58000001,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xC00000,0xC00000,0xC00000,0x10C0000,0x17C0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000, -0x1300000,0x1DF40000,0x1DF40000,0x1DF40000,0x64000001,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1DF40000,0x1DF40000,0x1DF40000,0x64000001,0x1DF40000,0x1DF40000,0x1DF40000,0x64000001,0x64000001,0x4D80000,0xCC0000,0xCC0000,0xEC0000,0x1000000,0x1140000,0x1140000,0x3540000,0xEC0000,0x1000000,0x1B00000,0x1DF40000, -0x1B00000,0xE00000,0xE00000,0xE00000,0xE00000,0x14C0000,0x14C0000,0x14C0000,0x2BF80000,0x2BF80000,0x6E000001,0x14C0000,0x14C0000,0x14C0000,0x2BF80000,0x2BF80000,0x6E000001,0x2BF80000,0x2BF80000,0x6E000001,0x6E000001,0x14C0000,0x14C0000,0x14C0000,0x2BF80000,0x2BF80000,0x6E000001,0x2BF80000,0x2BF80000,0x6E000001,0x6E000001,0x2BF80000, -0x2BF80000,0x6E000001,0x6E000001,0x6E000001,0x1040000,0xEEC0000,0xE00000,0x1300000,0x1780000,0x1DC0000,0xFFC0000,0x3DF80000,0x1180000,0x14C0000,0x1DC0000,0x6E000001,0x1DC0000,0xF80000,0x1700000,0x3DF80000,0x7A000001,0x1700000,0x3DF80000,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x1700000,0x3DF80000,0x7A000001,0x3DF80000,0x7A000001, -0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x1700000,0x3DF80000,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x7A000001,0x5340000,0x1080000,0x1080000,0x1A00000,0x23FC0000,0x5BF80000,0x7A000001,0x7A000001,0x1500000,0x1D00000,0x73F80000,0x7A000001, -0x9FC0000,0xD40278,0xA8CC00F4,0x86CC00F4,0x7ACC00F5,0xA2C00090,0x8AC0004D,0x7EC40069,0x80C00090,0x7AC0004D,0x74C00092,0x9EB400F3,0x8CB40032,0x7EBC0053,0x82B40049,0x7AB40002,0x76B4004E,0x7AB400F4,0x78B00051,0x74B00067,0x70B400F3,0x33C0274,0x90A000F3,0x7AB400F4,0x88980092,0x7CA4004A,0x74AC0092,0x868800F3,0x7A940033,0x7494004F,0x709C00F4,0x23FC0274, -0x7A7000F4,0x74680092,0x705400F3,0x6A000274,0xFEB40005,0xFECC0120,0xF0D00181,0xACB40000,0x92B40001,0x82B40002,0x7CB80006,0x7AB40006,0xF69C0002,0xA4AC0002,0x7CB00035,0x7494004F,0x1C80274,0xE000F4,0x9CD80034,0x84D40034,0x7AD40035,0x96CC0048,0x84CC0001,0x7CCC0005,0x7CCC004A,0x7AC8000E,0x74CC004A,0x15000F3,0x8AB80032,0x7CC40033,0x82B40049,0x7AB40002, -0x74BC004A,0x2DF800F3,0x7A940033,0x748C004A,0x700000F3,0x15000F3,0x8AB80032,0x7CC40033,0x82B40049,0x7AB40002,0x74BC004A,0x2DF800F3,0x7A940033,0x748C004A,0x700000F3,0x2DF800F3,0x7A940033,0x748C004A,0x700000F3,0x700000F3,0xF2B80003,0xF2D4006A,0xF6DC005D,0xACB40000,0x92B40001,0x82B40002,0x7CBC0001,0x7AAC0003,0xF69C0001,0xA4AC0001,0x7EA80032,0x748C004A, -0x1E000F3,0xCC00F4,0xCC00F4,0xCC00F4,0xCC00F4,0x90C00048,0x90C00048,0x90C00048,0x76C00049,0x76C00049,0x6EC00049,0x8CB40032,0x8CB40032,0x8CB40032,0x7AB40001,0x7AB40001,0x70B8000E,0x72B40032,0x72B40032,0x6EB40005,0x6AB40032,0x12C00F3,0x12C00F3,0x12C00F3,0x7CA40049,0x7CA40049,0x6EB00049,0x7A940032,0x7A940032,0x6EA00002,0x6AA40032,0x1BF800F3, -0x1BF800F3,0x6E800049,0x6A6C0032,0x640000F3,0xF2B40004,0xFAC40060,0xCC00F4,0xACB40000,0x8EB40001,0x82B40001,0x7EB40004,0x76B40001,0xECA00000,0xA4AC0001,0x7AB00032,0x6EA00002,0x1AC00F3,0xD40034,0xD40034,0xD40034,0xD40034,0x82CC0000,0x82CC0000,0x82CC0000,0x74CC0000,0x74CC0000,0x6ECC0001,0x33C0032,0x33C0032,0x33C0032,0x76BC0001,0x76BC0001, -0x6EC40001,0x23FC0032,0x23FC0032,0x6EA80001,0x6A000032,0x33C0032,0x33C0032,0x33C0032,0x76BC0001,0x76BC0001,0x6EC40001,0x23FC0032,0x23FC0032,0x6EA80001,0x6A000032,0x23FC0032,0x23FC0032,0x6EA80001,0x6A000032,0x6A000032,0xDABC0000,0xFECC0000,0xD40034,0xACB40000,0x8CB80000,0x80B80000,0x7CBC0000,0x76B40001,0xECA00000,0xA4AC0000,0x1C80032,0x6EA80001, -0x1C80032,0xEC0048,0x94E00000,0x80E00001,0x7AE00001,0x35C0048,0x84CC0001,0x7AD40001,0x33FC0048,0x7AB00001,0x7400004A,0x35C0048,0x84CC0001,0x7AD40001,0x33FC0048,0x7AB00001,0x7400004A,0x33FC0048,0x7AB00001,0x7400004A,0x7400004A,0x35C0048,0x84CC0001,0x7AD40001,0x33FC0048,0x7AB00001,0x7400004A,0x33FC0048,0x7AB00001,0x7400004A,0x7400004A,0x33FC0048, -0x7AB00001,0x7400004A,0x7400004A,0x7400004A,0xFEB40001,0xFC0048,0xFAE40005,0xACB40000,0x90B40001,0x84B00000,0x7AC00001,0x7AA00001,0xFE980000,0xA8A80000,0x7CC40001,0x7400004A,0x1F40048,0xC00048,0xC00048,0xC00048,0xC00048,0xC00048,0xC00048,0xC00048,0xC00048,0xC00048,0xC00048,0x7EB40000,0x7EB40000,0x7EB40000,0x7EB40000,0x7EB40000, -0x7EB40000,0x6AB40001,0x6AB40001,0x6AB40001,0x64B40001,0x11C0048,0x11C0048,0x11C0048,0x11C0048,0x11C0048,0x11C0048,0x6EA00001,0x6EA00001,0x6EA00001,0x64A80001,0x13FC0048,0x13FC0048,0x13FC0048,0x64840001,0x5E00004A,0xF2B40004,0xC00048,0xC00048,0xACB40000,0x92B40000,0x86B40000,0x86B40000,0x76B40000,0xE8A00000,0xACA80000,0x72B00000,0x6EA00001, -0x1980048,}; -static const uint32_t g_etc1_to_bc7_m6_table46[] = { -0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x17F80000, -0x17F80000,0x17F80000,0x17F80000,0x60000001,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xD00000,0xD00000,0xD00000,0x1240000,0x1A00000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0x3440000,0x3440000,0x3440000,0x3440000,0x3440000, -0x3440000,0x27FC0000,0x27FC0000,0x27FC0000,0x6C000001,0x3440000,0x3440000,0x3440000,0x3440000,0x3440000,0x3440000,0x27FC0000,0x27FC0000,0x27FC0000,0x6C000001,0x27FC0000,0x27FC0000,0x27FC0000,0x6C000001,0x6C000001,0xCE80000,0xDC0000,0xDC0000,0x1000000,0x1140000,0x12C0000,0x12C0000,0x1700000,0x1000000,0x1140000,0x1D40000,0x27FC0000, -0x1D40000,0xF00000,0xF00000,0xF00000,0xF00000,0x1640000,0x1640000,0x1640000,0x37F80000,0x37F80000,0x76000001,0x1640000,0x1640000,0x1640000,0x37F80000,0x37F80000,0x76000001,0x37F80000,0x37F80000,0x76000001,0x76000001,0x1640000,0x1640000,0x1640000,0x37F80000,0x37F80000,0x76000001,0x37F80000,0x37F80000,0x76000001,0x76000001,0x37F80000, -0x37F80000,0x76000001,0x76000001,0x76000001,0x1180000,0x1000000,0xF00000,0x3440000,0x1940000,0x1FC0000,0x1DF80000,0x47FC0000,0x12C0000,0x1640000,0x1FC0000,0x76000001,0x1FC0000,0x1080000,0x1880000,0x49F80000,0x82000001,0x1880000,0x49F80000,0x82000001,0x49F80000,0x82000001,0x82000001,0x1880000,0x49F80000,0x82000001,0x49F80000,0x82000001, -0x82000001,0x49F80000,0x82000001,0x82000001,0x82000001,0x1880000,0x49F80000,0x82000001,0x49F80000,0x82000001,0x82000001,0x49F80000,0x82000001,0x82000001,0x82000001,0x49F80000,0x82000001,0x82000001,0x82000001,0x82000001,0x14C0000,0x5180000,0x5180000,0x1BC0000,0x31FC0000,0x65F80000,0x82000001,0x82000001,0x1680000,0x1F00000,0x7DCC0000,0x82000001, -0x19FC0000,0xE40278,0xB0DC00F4,0x8EDC00F4,0x82DC00F5,0xAAD00090,0x92D0004D,0x86D40069,0x88D00090,0x82D0004D,0x7CD00092,0xA6C400F3,0x94C40032,0x86CC0053,0x8AC40049,0x82C40002,0x7EC4004E,0x82C400F4,0x80C00051,0x7CC00067,0x78C400F3,0x1540274,0x98B000F3,0x82C400F4,0x90A80092,0x84B4004A,0x7CBC0092,0x8E9800F3,0x82A40033,0x7CA4004F,0x78AC00F4,0x2FFC0274, -0x828000F4,0x7C780092,0x786400F3,0x72000274,0xFAC80007,0xF6DC013A,0xF8E00181,0xB4C40000,0x9AC40001,0x8AC40002,0x84C80006,0x82C40006,0xFEAC0002,0xACBC0002,0x84C00035,0x7CA4004F,0x1E80274,0xF000F4,0xA4E80034,0x8CE40034,0x82E40035,0x9EDC0048,0x8CDC0001,0x84DC0005,0x84DC004A,0x82D8000E,0x7CDC004A,0x16800F3,0x92C80032,0x84D40033,0x8AC40049,0x82C40002, -0x7CCC004A,0x39F800F3,0x82A40033,0x7C9C004A,0x780000F3,0x16800F3,0x92C80032,0x84D40033,0x8AC40049,0x82C40002,0x7CCC004A,0x39F800F3,0x82A40033,0x7C9C004A,0x780000F3,0x39F800F3,0x82A40033,0x7C9C004A,0x780000F3,0x780000F3,0xFAC80003,0xFAE4006A,0xFEEC005D,0xB4C40000,0x9AC40001,0x8AC40002,0x84CC0001,0x82BC0003,0xFEAC0001,0xACBC0001,0x86B80032,0x7C9C004A, -0x3FC00F3,0xDC00F4,0xDC00F4,0xDC00F4,0xDC00F4,0x98D00048,0x98D00048,0x98D00048,0x7ED00049,0x7ED00049,0x76D00049,0x94C40032,0x94C40032,0x94C40032,0x82C40001,0x82C40001,0x78C8000E,0x7AC40032,0x7AC40032,0x76C40005,0x72C40032,0x14400F3,0x14400F3,0x14400F3,0x84B40049,0x84B40049,0x76C00049,0x82A40032,0x82A40032,0x76B00002,0x72B40032,0x27F800F3, -0x27F800F3,0x76900049,0x727C0032,0x6C0000F3,0xFAC40004,0xF2D40069,0xDC00F4,0xB4C40000,0x96C40001,0x8AC40001,0x86C40004,0x7EC40001,0xF4B00000,0xACBC0001,0x82C00032,0x76B00002,0x1D000F3,0xE40034,0xE40034,0xE40034,0xE40034,0x8ADC0000,0x8ADC0000,0x8ADC0000,0x7CDC0000,0x7CDC0000,0x76DC0001,0x1540032,0x1540032,0x1540032,0x7ECC0001,0x7ECC0001, -0x76D40001,0x2FFC0032,0x2FFC0032,0x76B80001,0x72000032,0x1540032,0x1540032,0x1540032,0x7ECC0001,0x7ECC0001,0x76D40001,0x2FFC0032,0x2FFC0032,0x76B80001,0x72000032,0x2FFC0032,0x2FFC0032,0x76B80001,0x72000032,0x72000032,0xE2CC0000,0xF6DC0001,0xE40034,0xB4C40000,0x94C80000,0x88C80000,0x84CC0000,0x7EC40001,0xF4B00000,0xACBC0000,0x1E80032,0x76B80001, -0x1E80032,0xFC0048,0x9CF00000,0x88F00001,0x82F00001,0x3740048,0x8CDC0001,0x82E40001,0x3FFC0048,0x82C00001,0x7C00004A,0x3740048,0x8CDC0001,0x82E40001,0x3FFC0048,0x82C00001,0x7C00004A,0x3FFC0048,0x82C00001,0x7C00004A,0x7C00004A,0x3740048,0x8CDC0001,0x82E40001,0x3FFC0048,0x82C00001,0x7C00004A,0x3FFC0048,0x82C00001,0x7C00004A,0x7C00004A,0x3FFC0048, -0x82C00001,0x7C00004A,0x7C00004A,0x7C00004A,0xFAC80002,0x10C0048,0xF2F40008,0xB4C40000,0x98C40001,0x8CC00000,0x82D00001,0x82B00001,0xFEAC0001,0xB0B80000,0x84D40001,0x7C00004A,0xDFC0048,0xD00048,0xD00048,0xD00048,0xD00048,0xD00048,0xD00048,0xD00048,0xD00048,0xD00048,0xD00048,0x86C40000,0x86C40000,0x86C40000,0x86C40000,0x86C40000, -0x86C40000,0x72C40001,0x72C40001,0x72C40001,0x6CC40001,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x76B00001,0x76B00001,0x76B00001,0x6CB80001,0x1FF80048,0x1FF80048,0x1FF80048,0x6C940001,0x6600004A,0xFAC40004,0xD00048,0xD00048,0xB4C40000,0x9AC40000,0x8EC40000,0x8EC40000,0x7EC40000,0xF0B00000,0xB4B80000,0x7AC00000,0x76B00001, -0x1B80048,}; -static const uint32_t g_etc1_to_bc7_m6_table47[] = { -0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x21FC0000, -0x21FC0000,0x21FC0000,0x21FC0000,0x68000001,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x8E00000,0x8E00000,0x8E00000,0x13C0000,0x1C00000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000, -0x35C0000,0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0x74000001,0xFC0000,0xEC0000,0xEC0000,0x5100000,0x1280000,0x1400000,0x1400000,0x18C0000,0x5100000,0x1280000,0x1F40000,0x33FC0000, -0x1F40000,0x1000000,0x1000000,0x1000000,0x1000000,0x17C0000,0x17C0000,0x17C0000,0x43F80000,0x43F80000,0x7E000001,0x17C0000,0x17C0000,0x17C0000,0x43F80000,0x43F80000,0x7E000001,0x43F80000,0x43F80000,0x7E000001,0x7E000001,0x17C0000,0x17C0000,0x17C0000,0x43F80000,0x43F80000,0x7E000001,0x43F80000,0x43F80000,0x7E000001,0x7E000001,0x43F80000, -0x43F80000,0x7E000001,0x7E000001,0x7E000001,0x3280000,0x1100000,0x1000000,0x15C0000,0x3AC0000,0x11FC0000,0x29FC0000,0x53F80000,0x1400000,0x17C0000,0x11FC0000,0x7E000001,0x11FC0000,0x1180000,0x1A00000,0x55F80000,0x8A000001,0x1A00000,0x55F80000,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x1A00000,0x55F80000,0x8A000001,0x55F80000,0x8A000001, -0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x1A00000,0x55F80000,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x8A000001,0x1600000,0xD280000,0xD280000,0x3D40000,0x3FF80000,0x6FF80000,0x8A000001,0x8A000001,0x17C0000,0xBFC0000,0x85DC0000,0x8A000001, -0x27FC0000,0xF40278,0xB8EC00F4,0x96EC00F4,0x8AEC00F5,0xB2E00090,0x9AE0004D,0x8EE40069,0x90E00090,0x8AE0004D,0x84E00092,0xAED400F3,0x9CD40032,0x8EDC0053,0x92D40049,0x8AD40002,0x86D4004E,0x8AD400F4,0x88D00051,0x84D00067,0x80D400F3,0x16C0274,0xA0C000F3,0x8AD400F4,0x98B80092,0x8CC4004A,0x84CC0092,0x96A800F3,0x8AB40033,0x84B4004F,0x80BC00F4,0x3BFC0274, -0x8A9000F4,0x84880092,0x807400F3,0x7A000274,0xFED8000A,0xFEEC013A,0xF0F00198,0xBCD40000,0xA2D40001,0x92D40002,0x8CD80006,0x8AD40006,0xFCC00004,0xB4CC0002,0x8CD00035,0x84B4004F,0x7FC0274,0x10000F4,0xACF80034,0x94F40034,0x8AF40035,0xA6EC0048,0x94EC0001,0x8CEC0005,0x8CEC004A,0x8AE8000E,0x84EC004A,0x18000F3,0x9AD80032,0x8CE40033,0x92D40049,0x8AD40002, -0x84DC004A,0x45F800F3,0x8AB40033,0x84AC004A,0x800000F3,0x18000F3,0x9AD80032,0x8CE40033,0x92D40049,0x8AD40002,0x84DC004A,0x45F800F3,0x8AB40033,0x84AC004A,0x800000F3,0x45F800F3,0x8AB40033,0x84AC004A,0x800000F3,0x800000F3,0xF6DC0006,0xF4F80074,0xF6FC0068,0xBCD40000,0xA2D40001,0x92D40002,0x8CDC0001,0x8ACC0003,0xFCC00004,0xB4CC0001,0x8EC80032,0x84AC004A, -0x13FC00F3,0xEC00F4,0xEC00F4,0xEC00F4,0xEC00F4,0xA0E00048,0xA0E00048,0xA0E00048,0x86E00049,0x86E00049,0x7EE00049,0x9CD40032,0x9CD40032,0x9CD40032,0x8AD40001,0x8AD40001,0x80D8000E,0x82D40032,0x82D40032,0x7ED40005,0x7AD40032,0x15C00F3,0x15C00F3,0x15C00F3,0x8CC40049,0x8CC40049,0x7ED00049,0x8AB40032,0x8AB40032,0x7EC00002,0x7AC40032,0x33F800F3, -0x33F800F3,0x7EA00049,0x7A8C0032,0x740000F3,0xF6D80005,0xFAE40069,0xEC00F4,0xBCD40000,0x9ED40001,0x92D40001,0x8ED40004,0x86D40001,0xFCC00000,0xB4CC0001,0x8AD00032,0x7EC00002,0x1F000F3,0xF40034,0xF40034,0xF40034,0xF40034,0x92EC0000,0x92EC0000,0x92EC0000,0x84EC0000,0x84EC0000,0x7EEC0001,0x16C0032,0x16C0032,0x16C0032,0x86DC0001,0x86DC0001, -0x7EE40001,0x3BFC0032,0x3BFC0032,0x7EC80001,0x7A000032,0x16C0032,0x16C0032,0x16C0032,0x86DC0001,0x86DC0001,0x7EE40001,0x3BFC0032,0x3BFC0032,0x7EC80001,0x7A000032,0x3BFC0032,0x3BFC0032,0x7EC80001,0x7A000032,0x7A000032,0xEADC0000,0xFEEC0001,0xF40034,0xBCD40000,0x9CD80000,0x90D80000,0x8CDC0000,0x86D40001,0xFCC00000,0xB4CC0000,0x7FC0032,0x7EC80001, -0x7FC0032,0x10C0048,0xA5000000,0x91000001,0x8B000001,0x38C0048,0x94EC0001,0x8AF40001,0x4BFC0048,0x8AD00001,0x8400004A,0x38C0048,0x94EC0001,0x8AF40001,0x4BFC0048,0x8AD00001,0x8400004A,0x4BFC0048,0x8AD00001,0x8400004A,0x8400004A,0x38C0048,0x94EC0001,0x8AF40001,0x4BFC0048,0x8AD00001,0x8400004A,0x4BFC0048,0x8AD00001,0x8400004A,0x8400004A,0x4BFC0048, -0x8AD00001,0x8400004A,0x8400004A,0x8400004A,0xF2E00005,0x71C0048,0xFB040008,0xBCD40000,0xA0D40001,0x94D00000,0x8AE00001,0x8AC00001,0xF4C80002,0xB8C80000,0x8CE40001,0x8400004A,0x1DF80048,0xE00048,0xE00048,0xE00048,0xE00048,0xE00048,0xE00048,0xE00048,0xE00048,0xE00048,0xE00048,0x8ED40000,0x8ED40000,0x8ED40000,0x8ED40000,0x8ED40000, -0x8ED40000,0x7AD40001,0x7AD40001,0x7AD40001,0x74D40001,0x14C0048,0x14C0048,0x14C0048,0x14C0048,0x14C0048,0x14C0048,0x7EC00001,0x7EC00001,0x7EC00001,0x74C80001,0x2BF80048,0x2BF80048,0x2BF80048,0x74A40001,0x6E00004A,0xF4D80005,0xE00048,0xE00048,0xBCD40000,0xA2D40000,0x96D40000,0x96D40000,0x86D40000,0xF8C00000,0xBCC80000,0x82D00000,0x7EC00001, -0x1DC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table48[] = { -0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x2FFC0000, -0x2FFC0000,0x2FFC0000,0x2FFC0000,0x72000000,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0x2F40000,0x2F40000,0x2F40000,0x1540000,0x1E80000,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000, -0x1780000,0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0x7E000000,0xF0C0000,0xFC0001,0xFC0001,0x1280000,0x33C0000,0x1580000,0x1580000,0x1AC0000,0x1280000,0x33C0000,0xFFC0000,0x41FC0000, -0xFFC0000,0x1100001,0x1100001,0x1100001,0x1100001,0x1980000,0x1980000,0x1980000,0x51F80000,0x51F80000,0x88000000,0x1980000,0x1980000,0x1980000,0x51F80000,0x51F80000,0x88000000,0x51F80000,0x51F80000,0x88000000,0x88000000,0x1980000,0x1980000,0x1980000,0x51F80000,0x51F80000,0x88000000,0x51F80000,0x51F80000,0x88000000,0x88000000,0x51F80000, -0x51F80000,0x88000000,0x88000000,0x88000000,0x73C0000,0x1240000,0x1100001,0x1740000,0x1CC0000,0x21FC0000,0x39FC0000,0x5FF80000,0x1580000,0x1980000,0x21FC0000,0x88000000,0x21FC0000,0x1280001,0x1BC0000,0x61FC0000,0x94000000,0x1BC0000,0x61FC0000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x1BC0000,0x61FC0000,0x94000000,0x61FC0000,0x94000000, -0x94000000,0x61FC0000,0x94000000,0x94000000,0x94000000,0x1BC0000,0x61FC0000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x94000000,0x94000000,0x3740000,0x73C0000,0x73C0000,0x1F40000,0x4DFC0000,0x7BF40000,0x94000000,0x94000000,0x1940000,0x1DFC0000,0x8FD00000,0x94000000, -0x39FC0000,0x1080274,0xC2FC00F3,0x9EFC00F4,0x94FC00F3,0xB8F40092,0xA0F4004F,0x96F40067,0x98F40092,0x94F0004E,0x8EF00092,0xB6E800F4,0xA4E80033,0x96EC0051,0x9CE4004A,0x94E80002,0x8EE8004D,0x94E400F4,0x90E00053,0x8CE00069,0x88E400F5,0x1880274,0xAAD000F3,0x94E800F4,0xA0CC0092,0x94D80049,0x8EDC0090,0x9EBC00F3,0x94C40032,0x8EC4004D,0x88D000F4,0x49F80274, -0x949C00F3,0x8E980090,0x888C00F4,0x82000278,0xFEEC0012,0xF9000154,0xFB040194,0xC2E80002,0xAAE80002,0x9CE80002,0x94E80006,0x92E40006,0xFCD80009,0xC0DC0000,0x96E00035,0x8EC4004D,0x19FC0274,0x11400F3,0xB7080032,0x9D080032,0x95080032,0xAD000049,0x9EFC0002,0x95000005,0x96FC0049,0x92FC000E,0x8EFC0049,0x39800F3,0xA4E80032,0x94F80032,0x9CE40049,0x94E80001, -0x8EEC0049,0x51FC00F3,0x94C00032,0x8EBC0048,0x880000F4,0x39800F3,0xA4E80032,0x94F80032,0x9CE40049,0x94E80001,0x8EEC0049,0x51FC00F3,0x94C00032,0x8EBC0048,0x880000F4,0x51FC00F3,0x94C00032,0x8EBC0048,0x880000F4,0x880000F4,0xFAF00006,0xFD080073,0xFF0C006B,0xC2E80001,0xAAE80001,0x9CE80001,0x94F00001,0x94E00004,0xFCD80005,0xC0DC0000,0x96DC0033,0x8EBC0048, -0x23FC00F3,0xFC00F3,0xFC00F3,0xFC00F3,0xFC00F3,0xA6F4004A,0xA6F4004A,0xA6F4004A,0x90F0004A,0x90F0004A,0x88F0004A,0xA4E80033,0xA4E80033,0xA4E80033,0x92E80002,0x92E80002,0x8AE8000E,0x8CE40033,0x8CE40033,0x88E40005,0x82E40035,0x37400F3,0x37400F3,0x37400F3,0x94D80049,0x94D80049,0x88E0004A,0x92C80032,0x92C80032,0x88D00001,0x84D40034,0x3FFC00F3, -0x3FFC00F3,0x88B00048,0x82A40034,0x7E0000F4,0xFEE80006,0xF4F80073,0xFC00F3,0xC2E80001,0xA6E80002,0x9AE80002,0x98E80003,0x90E40001,0xFCD40001,0xC0DC0000,0x92E40033,0x88D00001,0xDFC00F3,0x1080032,0x1080032,0x1080032,0x1080032,0x9B000001,0x9B000001,0x9B000001,0x8D000001,0x8D000001,0x88FC0001,0x1880032,0x1880032,0x1880032,0x90EC0001,0x90EC0001, -0x88F40000,0x49F80032,0x49F80032,0x88D40000,0x82000034,0x1880032,0x1880032,0x1880032,0x90EC0001,0x90EC0001,0x88F40000,0x49F80032,0x49F80032,0x88D40000,0x82000034,0x49F80032,0x49F80032,0x88D40000,0x82000034,0x82000034,0xEEF00000,0xF9000002,0x1080032,0xC2E80000,0xA0F00001,0x98EC0000,0x92F00001,0x90E40000,0xF0DC0001,0xBAE00000,0x19FC0032,0x88D40000, -0x19FC0032,0x11C004A,0xAB140001,0x9B100001,0x95100001,0x1A80048,0x9EFC0001,0x95040001,0x59FC0048,0x94E00000,0x8E000048,0x1A80048,0x9EFC0001,0x95040001,0x59FC0048,0x94E00000,0x8E000048,0x59FC0048,0x94E00000,0x8E000048,0x8E000048,0x1A80048,0x9EFC0001,0x95040001,0x59FC0048,0x94E00000,0x8E000048,0x59FC0048,0x94E00000,0x8E000048,0x8E000048,0x59FC0048, -0x94E00000,0x8E000048,0x8E000048,0x8E000048,0xFAF00005,0x1300048,0xF518000D,0xC6E40000,0xAAE40001,0x9EE00000,0x94F00000,0x94CC0000,0xFCD80004,0xC0DC0000,0x96F40000,0x8E000048,0x2DFC0048,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0xF0004A,0x94E80001,0x94E80001,0x94E80001,0x94E80001,0x94E80001, -0x94E80001,0x84E40001,0x84E40001,0x84E40001,0x7EE40001,0x1680048,0x1680048,0x1680048,0x1680048,0x1680048,0x1680048,0x88D00001,0x88D00001,0x88D00001,0x7ED80001,0x39F80048,0x39F80048,0x39F80048,0x7EB40000,0x78000048,0xFCE80005,0xF0004A,0xF0004A,0xBEE80001,0xA8E80001,0x9CE80001,0x9CE80001,0x8EE80001,0xFCD40000,0xC0DC0000,0x88E40001,0x88D00001, -0x3FC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table49[] = { -0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000, -0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xB040000,0xB040000,0xB040000,0x16C0000,0x7FC0000,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000, -0x1900000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x86000000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x86000000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x86000000,0x86000000,0x1200000,0x10C0001,0x10C0001,0x5380000,0x5500000,0x1700000,0x1700000,0x1C40000,0x5380000,0x5500000,0x1FF80000,0x4DFC0000, -0x1FF80000,0x1200001,0x1200001,0x1200001,0x1200001,0x1B00000,0x1B00000,0x1B00000,0x5DF40000,0x5DF40000,0x90000000,0x1B00000,0x1B00000,0x1B00000,0x5DF40000,0x5DF40000,0x90000000,0x5DF40000,0x5DF40000,0x90000000,0x90000000,0x1B00000,0x1B00000,0x1B00000,0x5DF40000,0x5DF40000,0x90000000,0x5DF40000,0x5DF40000,0x90000000,0x90000000,0x5DF40000, -0x5DF40000,0x90000000,0x90000000,0x90000000,0x1500000,0x3340000,0x1200001,0x3880000,0x1E80000,0x31FC0000,0x47F80000,0x69FC0000,0x16C0000,0x1B00000,0x31FC0000,0x90000000,0x31FC0000,0x1380001,0x3D00000,0x6DFC0000,0x9C000000,0x3D00000,0x6DFC0000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x3D00000,0x6DFC0000,0x9C000000,0x6DFC0000,0x9C000000, -0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x3D00000,0x6DFC0000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x9C000000,0x3880000,0xF4C0000,0xF4C0000,0xFFC0000,0x5BFC0000,0x85F40000,0x9C000000,0x9C000000,0x1AC0000,0x2FFC0000,0x97E00000,0x9C000000, -0x47FC0000,0x1180274,0xCB0C00F3,0xA70C00F4,0x9D0C00F3,0xC1040092,0xA904004F,0x9F040067,0xA1040092,0x9D00004E,0x97000092,0xBEF800F4,0xACF80033,0x9EFC0051,0xA4F4004A,0x9CF80002,0x96F8004D,0x9CF400F4,0x98F00053,0x94F00069,0x90F400F5,0x1A00274,0xB2E000F3,0x9CF800F4,0xA8DC0092,0x9CE80049,0x96EC0090,0xA6CC00F3,0x9CD40032,0x96D4004D,0x90E000F4,0x55F80274, -0x9CAC00F3,0x96A80090,0x909C00F4,0x8A000278,0xFCFC0024,0xFF0C0164,0xF31401AB,0xCAF80002,0xB2F80002,0xA4F80002,0x9CF80006,0x9AF40006,0xFCEC0016,0xC8EC0000,0x9EF00035,0x96D4004D,0x27FC0274,0x12400F3,0xBF180032,0xA5180032,0x9D180032,0xB5100049,0xA70C0002,0x9D100005,0x9F0C0049,0x9B0C000E,0x970C0049,0x3B000F3,0xACF80032,0x9D080032,0xA4F40049,0x9CF80001, -0x96FC0049,0x5DFC00F3,0x9CD00032,0x96CC0048,0x900000F4,0x3B000F3,0xACF80032,0x9D080032,0xA4F40049,0x9CF80001,0x96FC0049,0x5DFC00F3,0x9CD00032,0x96CC0048,0x900000F4,0x5DFC00F3,0x9CD00032,0x96CC0048,0x900000F4,0x900000F4,0xFF00000B,0xF5180081,0xF9200076,0xCAF80001,0xB2F80001,0xA4F80001,0x9D000001,0x9CF00004,0xFCEC000D,0xC8EC0000,0x9EEC0033,0x96CC0048, -0x33FC00F3,0x10C00F3,0x10C00F3,0x10C00F3,0x10C00F3,0xAF04004A,0xAF04004A,0xAF04004A,0x9900004A,0x9900004A,0x9100004A,0xACF80033,0xACF80033,0xACF80033,0x9AF80002,0x9AF80002,0x92F8000E,0x94F40033,0x94F40033,0x90F40005,0x8AF40035,0x38C00F3,0x38C00F3,0x38C00F3,0x9CE80049,0x9CE80049,0x90F0004A,0x9AD80032,0x9AD80032,0x90E00001,0x8CE40034,0x4BFC00F3, -0x4BFC00F3,0x90C00048,0x8AB40034,0x860000F4,0xFAFC000B,0xFD080073,0x10C00F3,0xCAF80001,0xAEF80002,0xA2F80002,0xA0F80003,0x98F40001,0xF8E80005,0xC8EC0000,0x9AF40033,0x90E00001,0x1DF800F3,0x1180032,0x1180032,0x1180032,0x1180032,0xA3100001,0xA3100001,0xA3100001,0x95100001,0x95100001,0x910C0001,0x1A00032,0x1A00032,0x1A00032,0x98FC0001,0x98FC0001, -0x91040000,0x55F80032,0x55F80032,0x90E40000,0x8A000034,0x1A00032,0x1A00032,0x1A00032,0x98FC0001,0x98FC0001,0x91040000,0x55F80032,0x55F80032,0x90E40000,0x8A000034,0x55F80032,0x55F80032,0x90E40000,0x8A000034,0x8A000034,0xF7000000,0xF1100005,0x1180032,0xCAF80000,0xA9000001,0xA0FC0000,0x9B000001,0x98F40000,0xF8EC0001,0xC2F00000,0x27FC0032,0x90E40000, -0x27FC0032,0x12C004A,0xB3240001,0xA3200001,0x9D200001,0x1C00048,0xA70C0001,0x9D140001,0x65F80048,0x9CF00000,0x96000048,0x1C00048,0xA70C0001,0x9D140001,0x65F80048,0x9CF00000,0x96000048,0x65F80048,0x9CF00000,0x96000048,0x96000048,0x1C00048,0xA70C0001,0x9D140001,0x65F80048,0x9CF00000,0x96000048,0x65F80048,0x9CF00000,0x96000048,0x96000048,0x65F80048, -0x9CF00000,0x96000048,0x96000048,0x96000048,0xFB040008,0x9400048,0xFD28000D,0xCEF40000,0xB2F40001,0xA6F00000,0x9D000000,0x9CDC0000,0xFEF00005,0xC8EC0000,0x9F040000,0x96000048,0x3DF80048,0x100004A,0x100004A,0x100004A,0x100004A,0x100004A,0x100004A,0x100004A,0x100004A,0x100004A,0x100004A,0x9CF80001,0x9CF80001,0x9CF80001,0x9CF80001,0x9CF80001, -0x9CF80001,0x8CF40001,0x8CF40001,0x8CF40001,0x86F40001,0x1800048,0x1800048,0x1800048,0x1800048,0x1800048,0x1800048,0x90E00001,0x90E00001,0x90E00001,0x86E80001,0x45F80048,0x45F80048,0x45F80048,0x86C40000,0x80000048,0xF4F8000A,0x100004A,0x100004A,0xC6F80001,0xB0F80001,0xA4F80001,0xA4F80001,0x96F80001,0xF8E80001,0xC8EC0000,0x90F40001,0x90E00001, -0x13FC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table50[] = { -0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x47FC0000, -0x47FC0000,0x47FC0000,0x47FC0000,0x82000000,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1180000,0x1180000,0x1180000,0x1840000,0x17FC0000,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000, -0x1A80000,0x59FC0000,0x59FC0000,0x59FC0000,0x8E000000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x59FC0000,0x59FC0000,0x59FC0000,0x8E000000,0x59FC0000,0x59FC0000,0x59FC0000,0x8E000000,0x8E000000,0x1300000,0x11C0001,0x11C0001,0x14C0000,0x5640000,0x1840000,0x1840000,0x1E00000,0x14C0000,0x5640000,0x2DFC0000,0x59FC0000, -0x2DFC0000,0x1300001,0x1300001,0x1300001,0x1300001,0x3C40000,0x3C40000,0x3C40000,0x67FC0000,0x67FC0000,0x98000000,0x3C40000,0x3C40000,0x3C40000,0x67FC0000,0x67FC0000,0x98000000,0x67FC0000,0x67FC0000,0x98000000,0x98000000,0x3C40000,0x3C40000,0x3C40000,0x67FC0000,0x67FC0000,0x98000000,0x67FC0000,0x67FC0000,0x98000000,0x98000000,0x67FC0000, -0x67FC0000,0x98000000,0x98000000,0x98000000,0x1640000,0xB440000,0x1300001,0x1A00000,0x5FC0000,0x3FFC0000,0x55F80000,0x75F80000,0x1800000,0x3C40000,0x3FFC0000,0x98000000,0x3FFC0000,0x1480001,0x3E80000,0x79FC0000,0xA4000000,0x3E80000,0x79FC0000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0x3E80000,0x79FC0000,0xA4000000,0x79FC0000,0xA4000000, -0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0x3E80000,0x79FC0000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0xA4000000,0x39C0000,0x1600000,0x1600000,0x23FC0000,0x69F80000,0x8FF40000,0xA4000000,0xA4000000,0x1C00000,0x41FC0000,0x9FF00000,0xA4000000, -0x57FC0000,0x1280274,0xD31C00F3,0xAF1C00F4,0xA51C00F3,0xC9140092,0xB114004F,0xA7140067,0xA9140092,0xA510004E,0x9F100092,0xC70800F4,0xB5080033,0xA70C0051,0xAD04004A,0xA5080002,0x9F08004D,0xA50400F4,0xA1000053,0x9D000069,0x990400F5,0x1B80274,0xBAF000F3,0xA50800F4,0xB0EC0092,0xA4F80049,0x9EFC0090,0xAEDC00F3,0xA4E40032,0x9EE4004D,0x98F000F4,0x61F80274, -0xA4BC00F3,0x9EB80090,0x98AC00F4,0x92000278,0xFF0C0032,0xF9200172,0xFB2401AB,0xD3080002,0xBB080002,0xAD080002,0xA5080006,0xA3040006,0xFCFC0024,0xD0FC0000,0xA7000035,0x9EE4004D,0x37FC0274,0x13400F3,0xC7280032,0xAD280032,0xA5280032,0xBD200049,0xAF1C0002,0xA5200005,0xA71C0049,0xA31C000E,0x9F1C0049,0x1C800F3,0xB5080032,0xA5180032,0xAD040049,0xA5080001, -0x9F0C0049,0x69FC00F3,0xA4E00032,0x9EDC0048,0x980000F4,0x1C800F3,0xB5080032,0xA5180032,0xAD040049,0xA5080001,0x9F0C0049,0x69FC00F3,0xA4E00032,0x9EDC0048,0x980000F4,0x69FC00F3,0xA4E00032,0x9EDC0048,0x980000F4,0x980000F4,0xFF14000E,0xFD280081,0xFF2C007A,0xD3080001,0xBB080001,0xAD080001,0xA5100001,0xA5000004,0xFF000013,0xD0FC0000,0xA6FC0033,0x9EDC0048, -0x41FC00F3,0x11C00F3,0x11C00F3,0x11C00F3,0x11C00F3,0xB714004A,0xB714004A,0xB714004A,0xA110004A,0xA110004A,0x9910004A,0xB5080033,0xB5080033,0xB5080033,0xA3080002,0xA3080002,0x9B08000E,0x9D040033,0x9D040033,0x99040005,0x93040035,0x3A400F3,0x3A400F3,0x3A400F3,0xA4F80049,0xA4F80049,0x9900004A,0xA2E80032,0xA2E80032,0x98F00001,0x94F40034,0x57FC00F3, -0x57FC00F3,0x98D00048,0x92C40034,0x8E0000F4,0xFF0C000E,0xF518007E,0x11C00F3,0xD3080001,0xB7080002,0xAB080002,0xA9080003,0xA1040001,0xFEF80006,0xD0FC0000,0xA3040033,0x98F00001,0x2BFC00F3,0x1280032,0x1280032,0x1280032,0x1280032,0xAB200001,0xAB200001,0xAB200001,0x9D200001,0x9D200001,0x991C0001,0x1B80032,0x1B80032,0x1B80032,0xA10C0001,0xA10C0001, -0x99140000,0x61F80032,0x61F80032,0x98F40000,0x92000034,0x1B80032,0x1B80032,0x1B80032,0xA10C0001,0xA10C0001,0x99140000,0x61F80032,0x61F80032,0x98F40000,0x92000034,0x61F80032,0x61F80032,0x98F40000,0x92000034,0x92000034,0xFF100000,0xF9200005,0x1280032,0xD3080000,0xB1100001,0xA90C0000,0xA3100001,0xA1040000,0xF5000002,0xCB000000,0x37FC0032,0x98F40000, -0x37FC0032,0x13C004A,0xBB340001,0xAB300001,0xA5300001,0x1D80048,0xAF1C0001,0xA5240001,0x71F80048,0xA5000000,0x9E000048,0x1D80048,0xAF1C0001,0xA5240001,0x71F80048,0xA5000000,0x9E000048,0x71F80048,0xA5000000,0x9E000048,0x9E000048,0x1D80048,0xAF1C0001,0xA5240001,0x71F80048,0xA5000000,0x9E000048,0x71F80048,0xA5000000,0x9E000048,0x9E000048,0x71F80048, -0xA5000000,0x9E000048,0x9E000048,0x9E000048,0xFF14000A,0x1540048,0xF5380012,0xD7040000,0xBB040001,0xAF000000,0xA5100000,0xA4EC0000,0xF7080008,0xD0FC0000,0xA7140000,0x9E000048,0x4BFC0048,0x110004A,0x110004A,0x110004A,0x110004A,0x110004A,0x110004A,0x110004A,0x110004A,0x110004A,0x110004A,0xA5080001,0xA5080001,0xA5080001,0xA5080001,0xA5080001, -0xA5080001,0x95040001,0x95040001,0x95040001,0x8F040001,0x1980048,0x1980048,0x1980048,0x1980048,0x1980048,0x1980048,0x98F00001,0x98F00001,0x98F00001,0x8EF80001,0x51F80048,0x51F80048,0x51F80048,0x8ED40000,0x88000048,0xFD08000A,0x110004A,0x110004A,0xCF080001,0xB9080001,0xAD080001,0xAD080001,0x9F080001,0xF8F80002,0xD0FC0000,0x99040001,0x98F00001, -0x21FC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table51[] = { -0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x53FC0000, -0x53FC0000,0x53FC0000,0x53FC0000,0x8A000000,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1280000,0x1280000,0x1280000,0x19C0000,0x25FC0000,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000, -0x1C00000,0x65F80000,0x65F80000,0x65F80000,0x96000000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x65F80000,0x65F80000,0x65F80000,0x96000000,0x65F80000,0x65F80000,0x65F80000,0x96000000,0x96000000,0x9400000,0x12C0001,0x12C0001,0x1600000,0x5780000,0x3980000,0x3980000,0x1FC0000,0x1600000,0x5780000,0x3DF80000,0x65F80000, -0x3DF80000,0x1400001,0x1400001,0x1400001,0x1400001,0x3DC0000,0x3DC0000,0x3DC0000,0x73FC0000,0x73FC0000,0xA0000000,0x3DC0000,0x3DC0000,0x3DC0000,0x73FC0000,0x73FC0000,0xA0000000,0x73FC0000,0x73FC0000,0xA0000000,0xA0000000,0x3DC0000,0x3DC0000,0x3DC0000,0x73FC0000,0x73FC0000,0xA0000000,0x73FC0000,0x73FC0000,0xA0000000,0xA0000000,0x73FC0000, -0x73FC0000,0xA0000000,0xA0000000,0xA0000000,0x5740000,0x1580000,0x1400001,0x3B40000,0x19FC0000,0x4FFC0000,0x61FC0000,0x7FFC0000,0x1940000,0x3DC0000,0x4FFC0000,0xA0000000,0x4FFC0000,0x1580001,0x7FC0000,0x85FC0000,0xAC000000,0x7FC0000,0x85FC0000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0x7FC0000,0x85FC0000,0xAC000000,0x85FC0000,0xAC000000, -0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0x7FC0000,0x85FC0000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0xAC000000,0x3B00000,0x1700000,0x1700000,0x37FC0000,0x75FC0000,0x99F40000,0xAC000000,0xAC000000,0x3D40000,0x51FC0000,0xA9C40000,0xAC000000, -0x65FC0000,0x1380274,0xDB2C00F3,0xB72C00F4,0xAD2C00F3,0xD1240092,0xB924004F,0xAF240067,0xB1240092,0xAD20004E,0xA7200092,0xCF1800F4,0xBD180033,0xAF1C0051,0xB514004A,0xAD180002,0xA718004D,0xAD1400F4,0xA9100053,0xA5100069,0xA11400F5,0x1D00274,0xC30000F3,0xAD1800F4,0xB8FC0092,0xAD080049,0xA70C0090,0xB6EC00F3,0xACF40032,0xA6F4004D,0xA10000F4,0x6DF80274, -0xACCC00F3,0xA6C80090,0xA0BC00F4,0x9A000278,0xFF20003E,0xFF2C018A,0xF33401C4,0xDB180002,0xC3180002,0xB5180002,0xAD180006,0xAB140006,0xFF10002E,0xD90C0000,0xAF100035,0xA6F4004D,0x45FC0274,0x14400F3,0xCF380032,0xB5380032,0xAD380032,0xC5300049,0xB72C0002,0xAD300005,0xAF2C0049,0xAB2C000E,0xA72C0049,0x1E000F3,0xBD180032,0xAD280032,0xB5140049,0xAD180001, -0xA71C0049,0x75FC00F3,0xACF00032,0xA6EC0048,0xA00000F4,0x1E000F3,0xBD180032,0xAD280032,0xB5140049,0xAD180001,0xA71C0049,0x75FC00F3,0xACF00032,0xA6EC0048,0xA00000F4,0x75FC00F3,0xACF00032,0xA6EC0048,0xA00000F4,0xA00000F4,0xF928001A,0xF73C008B,0xF9400083,0xDB180001,0xC3180001,0xB5180001,0xAD200001,0xAD100004,0xFD140019,0xD90C0000,0xAF0C0033,0xA6EC0048, -0x51FC00F3,0x12C00F3,0x12C00F3,0x12C00F3,0x12C00F3,0xBF24004A,0xBF24004A,0xBF24004A,0xA920004A,0xA920004A,0xA120004A,0xBD180033,0xBD180033,0xBD180033,0xAB180002,0xAB180002,0xA318000E,0xA5140033,0xA5140033,0xA1140005,0x9B140035,0x3BC00F3,0x3BC00F3,0x3BC00F3,0xAD080049,0xAD080049,0xA110004A,0xAAF80032,0xAAF80032,0xA1000001,0x9D040034,0x63FC00F3, -0x63FC00F3,0xA0E00048,0x9AD40034,0x960000F4,0xFD1C0016,0xFD28007E,0x12C00F3,0xDB180001,0xBF180002,0xB3180002,0xB1180003,0xA9140001,0xFD0C000D,0xD90C0000,0xAB140033,0xA1000001,0x3BFC00F3,0x1380032,0x1380032,0x1380032,0x1380032,0xB3300001,0xB3300001,0xB3300001,0xA5300001,0xA5300001,0xA12C0001,0x1D00032,0x1D00032,0x1D00032,0xA91C0001,0xA91C0001, -0xA1240000,0x6DF80032,0x6DF80032,0xA1040000,0x9A000034,0x1D00032,0x1D00032,0x1D00032,0xA91C0001,0xA91C0001,0xA1240000,0x6DF80032,0x6DF80032,0xA1040000,0x9A000034,0x6DF80032,0x6DF80032,0xA1040000,0x9A000034,0x9A000034,0xFF200001,0xF130000A,0x1380032,0xDB180000,0xB9200001,0xB11C0000,0xAB200001,0xA9140000,0xFD100002,0xD3100000,0x45FC0032,0xA1040000, -0x45FC0032,0x14C004A,0xC3440001,0xB3400001,0xAD400001,0x1F00048,0xB72C0001,0xAD340001,0x7DF80048,0xAD100000,0xA6000048,0x1F00048,0xB72C0001,0xAD340001,0x7DF80048,0xAD100000,0xA6000048,0x7DF80048,0xAD100000,0xA6000048,0xA6000048,0x1F00048,0xB72C0001,0xAD340001,0x7DF80048,0xAD100000,0xA6000048,0x7DF80048,0xAD100000,0xA6000048,0xA6000048,0x7DF80048, -0xAD100000,0xA6000048,0xA6000048,0xA6000048,0xFB2C000D,0x1640048,0xFD480012,0xDF140000,0xC3140001,0xB7100000,0xAD200000,0xACFC0000,0xFF180008,0xD90C0000,0xAF240000,0xA6000048,0x5BFC0048,0x120004A,0x120004A,0x120004A,0x120004A,0x120004A,0x120004A,0x120004A,0x120004A,0x120004A,0x120004A,0xAD180001,0xAD180001,0xAD180001,0xAD180001,0xAD180001, -0xAD180001,0x9D140001,0x9D140001,0x9D140001,0x97140001,0x1B00048,0x1B00048,0x1B00048,0x1B00048,0x1B00048,0x1B00048,0xA1000001,0xA1000001,0xA1000001,0x97080001,0x5DF40048,0x5DF40048,0x5DF40048,0x96E40000,0x90000048,0xF71C000D,0x120004A,0x120004A,0xD7180001,0xC1180001,0xB5180001,0xB5180001,0xA7180001,0xFB080004,0xD90C0000,0xA1140001,0xA1000001, -0x31FC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table52[] = { -0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x61F80000, -0x61F80000,0x61F80000,0x61F80000,0x92000001,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x13C0000,0x13C0000,0x13C0000,0x1B80000,0x37FC0000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000, -0x1DC0000,0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x9E000001,0x3540000,0x1400000,0x1400000,0x1740000,0x1900000,0x1B40000,0x1B40000,0x17FC0000,0x1740000,0x1900000,0x4DFC0000,0x73F80000, -0x4DFC0000,0x1540000,0x1540000,0x1540000,0x1540000,0x1F80000,0x1F80000,0x1F80000,0x81FC0000,0x81FC0000,0xA8000001,0x1F80000,0x1F80000,0x1F80000,0x81FC0000,0x81FC0000,0xA8000001,0x81FC0000,0x81FC0000,0xA8000001,0xA8000001,0x1F80000,0x1F80000,0x1F80000,0x81FC0000,0x81FC0000,0xA8000001,0x81FC0000,0x81FC0000,0xA8000001,0xA8000001,0x81FC0000, -0x81FC0000,0xA8000001,0xA8000001,0xA8000001,0x18C0000,0xD680000,0x1540000,0x3CC0000,0x2FFC0000,0x5FFC0000,0x71FC0000,0x8BFC0000,0x3A80000,0x1F80000,0x5FFC0000,0xA8000001,0x5FFC0000,0x16C0000,0x23FC0000,0x93FC0000,0xB4000001,0x23FC0000,0x93FC0000,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0x23FC0000,0x93FC0000,0xB4000001,0x93FC0000,0xB4000001, -0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0x23FC0000,0x93FC0000,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0xB4000001,0x1C80000,0x1840000,0x1840000,0x4DFC0000,0x85FC0000,0xA5F00000,0xB4000001,0xB4000001,0x1F00000,0x65FC0000,0xB1F40000,0xB4000001, -0x77FC0000,0x1480278,0xE34000F4,0xC14000F4,0xB54000F5,0xDD340090,0xC534004D,0xB9380069,0xBB340090,0xB534004D,0xAF340092,0xD92800F3,0xC7280032,0xB9300053,0xBD280049,0xB5280002,0xB128004E,0xB52800F4,0xB3240051,0xAF240067,0xAB2800F3,0x3E80274,0xCB1400F3,0xB52800F4,0xC30C0092,0xB718004A,0xAF200092,0xC0FC00F3,0xB5080033,0xAF08004F,0xAB1000F4,0x79FC0274, -0xB4E400F4,0xAEDC0092,0xAAC800F3,0xA4000274,0xFF340059,0xFB440190,0xFD4801C4,0xE7280000,0xCD280001,0xBD280002,0xB72C0006,0xB5280006,0xFF24004F,0xDF200002,0xB7240035,0xAF08004F,0x57FC0274,0x15400F4,0xD74C0034,0xBF480034,0xB5480035,0xD1400048,0xBF400001,0xB7400005,0xB740004A,0xB53C000E,0xAF40004A,0x1FC00F3,0xC52C0032,0xB7380033,0xBD280049,0xB5280002, -0xAF30004A,0x83F800F3,0xB5080033,0xAF00004A,0xAA0000F3,0x1FC00F3,0xC52C0032,0xB7380033,0xBD280049,0xB5280002,0xAF30004A,0x83F800F3,0xB5080033,0xAF00004A,0xAA0000F3,0x83F800F3,0xB5080033,0xAF00004A,0xAA0000F3,0xAA0000F3,0xFF3C0024,0xFF4C008C,0xF1500095,0xE7280000,0xCD280001,0xBD280002,0xB7300001,0xB5200003,0xFB2C002A,0xDF200001,0xB91C0032,0xAF00004A, -0x61FC00F3,0x14000F4,0x14000F4,0x14000F4,0x14000F4,0xCB340048,0xCB340048,0xCB340048,0xB1340049,0xB1340049,0xA9340049,0xC7280032,0xC7280032,0xC7280032,0xB5280001,0xB5280001,0xAB2C000E,0xAD280032,0xAD280032,0xA9280005,0xA5280032,0x1D800F3,0x1D800F3,0x1D800F3,0xB7180049,0xB7180049,0xA9240049,0xB5080032,0xB5080032,0xA9140002,0xA5180032,0x71F800F3, -0x71F800F3,0xA8F40049,0xA4E00032,0x9E0000F3,0xF9300024,0xF73C008C,0x14000F4,0xE7280000,0xC9280001,0xBD280001,0xB9280004,0xB1280001,0xFF200012,0xDF200001,0xB5240032,0xA9140002,0x4BFC00F3,0x1480034,0x1480034,0x1480034,0x1480034,0xBD400000,0xBD400000,0xBD400000,0xAF400000,0xAF400000,0xA9400001,0x3E80032,0x3E80032,0x3E80032,0xB1300001,0xB1300001, -0xA9380001,0x79FC0032,0x79FC0032,0xA91C0001,0xA4000032,0x3E80032,0x3E80032,0x3E80032,0xB1300001,0xB1300001,0xA9380001,0x79FC0032,0x79FC0032,0xA91C0001,0xA4000032,0x79FC0032,0x79FC0032,0xA91C0001,0xA4000032,0xA4000032,0xFB340004,0xFB440008,0x1480034,0xE7280000,0xC72C0000,0xBB2C0000,0xB7300000,0xB1280001,0xF9280005,0xDF200000,0x57FC0032,0xA91C0001, -0x57FC0032,0x1600048,0xCF540000,0xBB540001,0xB5540001,0xFFC0048,0xBF400001,0xB5480001,0x8BF80048,0xB5240001,0xAE00004A,0xFFC0048,0xBF400001,0xB5480001,0x8BF80048,0xB5240001,0xAE00004A,0x8BF80048,0xB5240001,0xAE00004A,0xAE00004A,0xFFC0048,0xBF400001,0xB5480001,0x8BF80048,0xB5240001,0xAE00004A,0x8BF80048,0xB5240001,0xAE00004A,0xAE00004A,0x8BF80048, -0xB5240001,0xAE00004A,0xAE00004A,0xAE00004A,0xFD400012,0x1780048,0xF75C0019,0xE7280000,0xCB280001,0xBF240000,0xB5340001,0xB5140001,0xFF2C0011,0xE31C0000,0xB7380001,0xAE00004A,0x6BFC0048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0x1340048,0xB9280000,0xB9280000,0xB9280000,0xB9280000,0xB9280000, -0xB9280000,0xA5280001,0xA5280001,0xA5280001,0x9F280001,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0xA9140001,0xA9140001,0xA9140001,0x9F1C0001,0x69FC0048,0x69FC0048,0x69FC0048,0x9EF80001,0x9800004A,0xFF2C000D,0x1340048,0x1340048,0xE7280000,0xCD280000,0xC1280000,0xC1280000,0xB1280000,0xFD1C0005,0xE71C0000,0xAD240000,0xA9140001, -0x41FC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table53[] = { -0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x6DF80000, -0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x14C0000,0x14C0000,0x14C0000,0x1D00000,0x45FC0000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000, -0x1F40000,0x7FF80000,0x7FF80000,0x7FF80000,0xA6000001,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x7FF80000,0x7FF80000,0x7FF80000,0xA6000001,0x7FF80000,0x7FF80000,0x7FF80000,0xA6000001,0xA6000001,0xB640000,0x1500000,0x1500000,0x7840000,0x1A40000,0x1C80000,0x1C80000,0x2BFC0000,0x7840000,0x1A40000,0x5DF80000,0x7FF80000, -0x5DF80000,0x1640000,0x1640000,0x1640000,0x1640000,0x15FC0000,0x15FC0000,0x15FC0000,0x8DFC0000,0x8DFC0000,0xB0000001,0x15FC0000,0x15FC0000,0x15FC0000,0x8DFC0000,0x8DFC0000,0xB0000001,0x8DFC0000,0x8DFC0000,0xB0000001,0xB0000001,0x15FC0000,0x15FC0000,0x15FC0000,0x8DFC0000,0x8DFC0000,0xB0000001,0x8DFC0000,0x8DFC0000,0xB0000001,0xB0000001,0x8DFC0000, -0x8DFC0000,0xB0000001,0xB0000001,0xB0000001,0x59C0000,0x17C0000,0x1640000,0x1E40000,0x43FC0000,0x6FFC0000,0x7FF80000,0x97F80000,0x3BC0000,0x15FC0000,0x6FFC0000,0xB0000001,0x6FFC0000,0x17C0000,0x3BFC0000,0x9FF80000,0xBC000001,0x3BFC0000,0x9FF80000,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0x3BFC0000,0x9FF80000,0xBC000001,0x9FF80000,0xBC000001, -0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0x3BFC0000,0x9FF80000,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0xBC000001,0x1DC0000,0x3940000,0x3940000,0x61FC0000,0x93F80000,0xAFF00000,0xBC000001,0xBC000001,0xDFC0000,0x75FC0000,0xBBC80000,0xBC000001, -0x85FC0000,0x1580278,0xEB5000F4,0xC95000F4,0xBD5000F5,0xE5440090,0xCD44004D,0xC1480069,0xC3440090,0xBD44004D,0xB7440092,0xE13800F3,0xCF380032,0xC1400053,0xC5380049,0xBD380002,0xB938004E,0xBD3800F4,0xBB340051,0xB7340067,0xB33800F3,0x7FC0274,0xD32400F3,0xBD3800F4,0xCB1C0092,0xBF28004A,0xB7300092,0xC90C00F3,0xBD180033,0xB718004F,0xB32000F4,0x85FC0274, -0xBCF400F4,0xB6EC0092,0xB2D800F3,0xAC000274,0xFF44007E,0xF35401B2,0xF55801DD,0xEF380000,0xD5380001,0xC5380002,0xBF3C0006,0xBD380006,0xFF34006A,0xE7300002,0xBF340035,0xB718004F,0x65FC0274,0x16400F4,0xDF5C0034,0xC7580034,0xBD580035,0xD9500048,0xC7500001,0xBF500005,0xBF50004A,0xBD4C000E,0xB750004A,0x19FC00F3,0xCD3C0032,0xBF480033,0xC5380049,0xBD380002, -0xB740004A,0x8FF800F3,0xBD180033,0xB710004A,0xB20000F3,0x19FC00F3,0xCD3C0032,0xBF480033,0xC5380049,0xBD380002,0xB740004A,0x8FF800F3,0xBD180033,0xB710004A,0xB20000F3,0x8FF800F3,0xBD180033,0xB710004A,0xB20000F3,0xB20000F3,0xFD4C002D,0xF960009A,0xF9600095,0xEF380000,0xD5380001,0xC5380002,0xBF400001,0xBD300003,0xFD400033,0xE7300001,0xC12C0032,0xB710004A, -0x71FC00F3,0x15000F4,0x15000F4,0x15000F4,0x15000F4,0xD3440048,0xD3440048,0xD3440048,0xB9440049,0xB9440049,0xB1440049,0xCF380032,0xCF380032,0xCF380032,0xBD380001,0xBD380001,0xB33C000E,0xB5380032,0xB5380032,0xB1380005,0xAD380032,0x1F000F3,0x1F000F3,0x1F000F3,0xBF280049,0xBF280049,0xB1340049,0xBD180032,0xBD180032,0xB1240002,0xAD280032,0x7DF800F3, -0x7DF800F3,0xB1040049,0xACF00032,0xA60000F3,0xF940002D,0xFF4C008C,0x15000F4,0xEF380000,0xD1380001,0xC5380001,0xC1380004,0xB9380001,0xFF340019,0xE7300001,0xBD340032,0xB1240002,0x5BFC00F3,0x1580034,0x1580034,0x1580034,0x1580034,0xC5500000,0xC5500000,0xC5500000,0xB7500000,0xB7500000,0xB1500001,0x7FC0032,0x7FC0032,0x7FC0032,0xB9400001,0xB9400001, -0xB1480001,0x85FC0032,0x85FC0032,0xB12C0001,0xAC000032,0x7FC0032,0x7FC0032,0x7FC0032,0xB9400001,0xB9400001,0xB1480001,0x85FC0032,0x85FC0032,0xB12C0001,0xAC000032,0x85FC0032,0x85FC0032,0xB12C0001,0xAC000032,0xAC000032,0xF7480005,0xF354000D,0x1580034,0xEF380000,0xCF3C0000,0xC33C0000,0xBF400000,0xB9380001,0xF53C0008,0xE7300000,0x65FC0032,0xB12C0001, -0x65FC0032,0x1700048,0xD7640000,0xC3640001,0xBD640001,0x29FC0048,0xC7500001,0xBD580001,0x97F80048,0xBD340001,0xB600004A,0x29FC0048,0xC7500001,0xBD580001,0x97F80048,0xBD340001,0xB600004A,0x97F80048,0xBD340001,0xB600004A,0xB600004A,0x29FC0048,0xC7500001,0xBD580001,0x97F80048,0xBD340001,0xB600004A,0x97F80048,0xBD340001,0xB600004A,0xB600004A,0x97F80048, -0xBD340001,0xB600004A,0xB600004A,0xB600004A,0xFF500014,0x1880048,0xFF6C0019,0xEF380000,0xD3380001,0xC7340000,0xBD440001,0xBD240001,0xF9480012,0xEB2C0000,0xBF480001,0xB600004A,0x7BFC0048,0x1440048,0x1440048,0x1440048,0x1440048,0x1440048,0x1440048,0x1440048,0x1440048,0x1440048,0x1440048,0xC1380000,0xC1380000,0xC1380000,0xC1380000,0xC1380000, -0xC1380000,0xAD380001,0xAD380001,0xAD380001,0xA7380001,0x1E00048,0x1E00048,0x1E00048,0x1E00048,0x1E00048,0x1E00048,0xB1240001,0xB1240001,0xB1240001,0xA72C0001,0x75FC0048,0x75FC0048,0x75FC0048,0xA7080001,0xA000004A,0xF73C0014,0x1440048,0x1440048,0xEF380000,0xD5380000,0xC9380000,0xC9380000,0xB9380000,0xF9300008,0xEF2C0000,0xB5340000,0xB1240001, -0x51FC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table54[] = { -0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x79F80000, -0x79F80000,0x79F80000,0x79F80000,0xA2000001,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x75C0000,0x75C0000,0x75C0000,0x1E80000,0x55FC0000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000, -0xFFC0000,0x8BF80000,0x8BF80000,0x8BF80000,0xAE000001,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0x8BF80000,0x8BF80000,0x8BF80000,0xAE000001,0x8BF80000,0x8BF80000,0x8BF80000,0xAE000001,0xAE000001,0x1780000,0x1600000,0x1600000,0x3980000,0x1B80000,0x3DC0000,0x3DC0000,0x3DFC0000,0x3980000,0x1B80000,0x6BFC0000,0x8BF80000, -0x6BFC0000,0x1740000,0x1740000,0x1740000,0x1740000,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x99FC0000,0x99FC0000,0xB8000001,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x99FC0000,0x99FC0000,0xB8000001,0x99FC0000,0x99FC0000,0xB8000001,0xB8000001,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x99FC0000,0x99FC0000,0xB8000001,0x99FC0000,0x99FC0000,0xB8000001,0xB8000001,0x99FC0000, -0x99FC0000,0xB8000001,0xB8000001,0xB8000001,0x1B00000,0x18C0000,0x1740000,0x3F80000,0x57FC0000,0x7FF80000,0x8BFC0000,0xA1FC0000,0x5D00000,0x2FFC0000,0x7FF80000,0xB8000001,0x7FF80000,0x18C0000,0x53FC0000,0xABF80000,0xC4000001,0x53FC0000,0xABF80000,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0x53FC0000,0xABF80000,0xC4000001,0xABF80000,0xC4000001, -0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xC4000001,0x53FC0000,0xABF80000,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xC4000001,0xC4000001,0x1F00000,0xBA40000,0xBA40000,0x73FC0000,0x9FFC0000,0xB9F00000,0xC4000001,0xC4000001,0x2BFC0000,0x87FC0000,0xC3D80000,0xC4000001, -0x95FC0000,0x1680278,0xF36000F4,0xD16000F4,0xC56000F5,0xED540090,0xD554004D,0xC9580069,0xCB540090,0xC554004D,0xBF540092,0xE94800F3,0xD7480032,0xC9500053,0xCD480049,0xC5480002,0xC148004E,0xC54800F4,0xC3440051,0xBF440067,0xBB4800F3,0x1FFC0274,0xDB3400F3,0xC54800F4,0xD32C0092,0xC738004A,0xBF400092,0xD11C00F3,0xC5280033,0xBF28004F,0xBB3000F4,0x91FC0274, -0xC50400F4,0xBEFC0092,0xBAE800F3,0xB4000274,0xFF580096,0xFB6401B2,0xFD6801DD,0xF7480000,0xDD480001,0xCD480002,0xC74C0006,0xC5480006,0xFD4C008A,0xEF400002,0xC7440035,0xBF28004F,0x75FC0274,0x17400F4,0xE76C0034,0xCF680034,0xC5680035,0xE1600048,0xCF600001,0xC7600005,0xC760004A,0xC55C000E,0xBF60004A,0x31FC00F3,0xD54C0032,0xC7580033,0xCD480049,0xC5480002, -0xBF50004A,0x9BF800F3,0xC5280033,0xBF20004A,0xBA0000F3,0x31FC00F3,0xD54C0032,0xC7580033,0xCD480049,0xC5480002,0xBF50004A,0x9BF800F3,0xC5280033,0xBF20004A,0xBA0000F3,0x9BF800F3,0xC5280033,0xBF20004A,0xBA0000F3,0xBA0000F3,0xFD60003E,0xFF6C009E,0xF37400A4,0xF7480000,0xDD480001,0xCD480002,0xC7500001,0xC5400003,0xFB54003D,0xEF400001,0xC93C0032,0xBF20004A, -0x7FFC00F3,0x16000F4,0x16000F4,0x16000F4,0x16000F4,0xDB540048,0xDB540048,0xDB540048,0xC1540049,0xC1540049,0xB9540049,0xD7480032,0xD7480032,0xD7480032,0xC5480001,0xC5480001,0xBB4C000E,0xBD480032,0xBD480032,0xB9480005,0xB5480032,0xDFC00F3,0xDFC00F3,0xDFC00F3,0xC7380049,0xC7380049,0xB9440049,0xC5280032,0xC5280032,0xB9340002,0xB5380032,0x89F800F3, -0x89F800F3,0xB9140049,0xB5000032,0xAE0000F3,0xFD540035,0xF75C0099,0x16000F4,0xF7480000,0xD9480001,0xCD480001,0xC9480004,0xC1480001,0xFB480029,0xEF400001,0xC5440032,0xB9340002,0x69FC00F3,0x1680034,0x1680034,0x1680034,0x1680034,0xCD600000,0xCD600000,0xCD600000,0xBF600000,0xBF600000,0xB9600001,0x1FFC0032,0x1FFC0032,0x1FFC0032,0xC1500001,0xC1500001, -0xB9580001,0x91FC0032,0x91FC0032,0xB93C0001,0xB4000032,0x1FFC0032,0x1FFC0032,0x1FFC0032,0xC1500001,0xC1500001,0xB9580001,0x91FC0032,0x91FC0032,0xB93C0001,0xB4000032,0x91FC0032,0x91FC0032,0xB93C0001,0xB4000032,0xB4000032,0xFF580005,0xFB64000D,0x1680034,0xF7480000,0xD74C0000,0xCB4C0000,0xC7500000,0xC1480001,0xFD4C0008,0xEF400000,0x75FC0032,0xB93C0001, -0x75FC0032,0x1800048,0xDF740000,0xCB740001,0xC5740001,0x41FC0048,0xCF600001,0xC5680001,0xA1FC0048,0xC5440001,0xBE00004A,0x41FC0048,0xCF600001,0xC5680001,0xA1FC0048,0xC5440001,0xBE00004A,0xA1FC0048,0xC5440001,0xBE00004A,0xBE00004A,0x41FC0048,0xCF600001,0xC5680001,0xA1FC0048,0xC5440001,0xBE00004A,0xA1FC0048,0xC5440001,0xBE00004A,0xBE00004A,0xA1FC0048, -0xC5440001,0xBE00004A,0xBE00004A,0xBE00004A,0xF7680019,0x5980048,0xF77C0020,0xF7480000,0xDB480001,0xCF440000,0xC5540001,0xC5340001,0xFD580014,0xF33C0000,0xC7580001,0xBE00004A,0x89FC0048,0x1540048,0x1540048,0x1540048,0x1540048,0x1540048,0x1540048,0x1540048,0x1540048,0x1540048,0x1540048,0xC9480000,0xC9480000,0xC9480000,0xC9480000,0xC9480000, -0xC9480000,0xB5480001,0xB5480001,0xB5480001,0xAF480001,0x1F80048,0x1F80048,0x1F80048,0x1F80048,0x1F80048,0x1F80048,0xB9340001,0xB9340001,0xB9340001,0xAF3C0001,0x81FC0048,0x81FC0048,0x81FC0048,0xAF180001,0xA800004A,0xFF4C0014,0x1540048,0x1540048,0xF7480000,0xDD480000,0xD1480000,0xD1480000,0xC1480000,0xF544000D,0xF73C0000,0xBD440000,0xB9340001, -0x5FFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table55[] = { -0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x85F80000, -0x85F80000,0x85F80000,0x85F80000,0xAA000001,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0xF6C0000,0xF6C0000,0xF6C0000,0x3FC0000,0x63FC0000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000, -0x29FC0000,0x97F80000,0x97F80000,0x97F80000,0xB6000001,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x97F80000,0x97F80000,0x97F80000,0xB6000001,0x97F80000,0x97F80000,0x97F80000,0xB6000001,0xB6000001,0x1880000,0x1700000,0x1700000,0x1AC0000,0x3CC0000,0x1F40000,0x1F40000,0x51FC0000,0x1AC0000,0x3CC0000,0x7BFC0000,0x97F80000, -0x7BFC0000,0x1840000,0x1840000,0x1840000,0x1840000,0x47FC0000,0x47FC0000,0x47FC0000,0xA5F80000,0xA5F80000,0xC0000001,0x47FC0000,0x47FC0000,0x47FC0000,0xA5F80000,0xA5F80000,0xC0000001,0xA5F80000,0xA5F80000,0xC0000001,0xC0000001,0x47FC0000,0x47FC0000,0x47FC0000,0xA5F80000,0xA5F80000,0xC0000001,0xA5F80000,0xA5F80000,0xC0000001,0xC0000001,0xA5F80000, -0xA5F80000,0xC0000001,0xC0000001,0xC0000001,0x1C40000,0x79C0000,0x1840000,0x1BFC0000,0x6BFC0000,0x8DFC0000,0x99FC0000,0xADF80000,0x5E40000,0x47FC0000,0x8DFC0000,0xC0000001,0x8DFC0000,0x19C0000,0x6BFC0000,0xB7F80000,0xCC000001,0x6BFC0000,0xB7F80000,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0x6BFC0000,0xB7F80000,0xCC000001,0xB7F80000,0xCC000001, -0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0x6BFC0000,0xB7F80000,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0xCC000001,0x11FC0000,0x1B80000,0x1B80000,0x87FC0000,0xADFC0000,0xC3F00000,0xCC000001,0xCC000001,0x49FC0000,0x97FC0000,0xCBE80000,0xCC000001, -0xA3FC0000,0x1780278,0xFB7000F4,0xD97000F4,0xCD7000F5,0xF5640090,0xDD64004D,0xD1680069,0xD3640090,0xCD64004D,0xC7640092,0xF15800F3,0xDF580032,0xD1600053,0xD5580049,0xCD580002,0xC958004E,0xCD5800F4,0xCB540051,0xC7540067,0xC35800F3,0x37FC0274,0xE34400F3,0xCD5800F4,0xDB3C0092,0xCF48004A,0xC7500092,0xD92C00F3,0xCD380033,0xC738004F,0xC34000F4,0x9DFC0274, -0xCD1400F4,0xC70C0092,0xC2F800F3,0xBC000274,0xFF6C00C2,0xF37401D8,0xF57801F8,0xFF580000,0xE5580001,0xD5580002,0xCF5C0006,0xCD580006,0xFF5C00A6,0xF7500002,0xCF540035,0xC738004F,0x83FC0274,0x18400F4,0xEF7C0034,0xD7780034,0xCD780035,0xE9700048,0xD7700001,0xCF700005,0xCF70004A,0xCD6C000E,0xC770004A,0x49FC00F3,0xDD5C0032,0xCF680033,0xD5580049,0xCD580002, -0xC760004A,0xA7F800F3,0xCD380033,0xC730004A,0xC20000F3,0x49FC00F3,0xDD5C0032,0xCF680033,0xD5580049,0xCD580002,0xC760004A,0xA7F800F3,0xCD380033,0xC730004A,0xC20000F3,0xA7F800F3,0xCD380033,0xC730004A,0xC20000F3,0xC20000F3,0xFD740049,0xF98000A8,0xFB8400A4,0xFF580000,0xE5580001,0xD5580002,0xCF600001,0xCD500003,0xFB680055,0xF7500001,0xD14C0032,0xC730004A, -0x8FFC00F3,0x17000F4,0x17000F4,0x17000F4,0x17000F4,0xE3640048,0xE3640048,0xE3640048,0xC9640049,0xC9640049,0xC1640049,0xDF580032,0xDF580032,0xDF580032,0xCD580001,0xCD580001,0xC35C000E,0xC5580032,0xC5580032,0xC1580005,0xBD580032,0x25FC00F3,0x25FC00F3,0x25FC00F3,0xCF480049,0xCF480049,0xC1540049,0xCD380032,0xCD380032,0xC1440002,0xBD480032,0x95F800F3, -0x95F800F3,0xC1240049,0xBD100032,0xB60000F3,0xFD64003E,0xFF6C0099,0x17000F4,0xFF580000,0xE1580001,0xD5580001,0xD1580004,0xC9580001,0xFF580032,0xF7500001,0xCD540032,0xC1440002,0x79FC00F3,0x1780034,0x1780034,0x1780034,0x1780034,0xD5700000,0xD5700000,0xD5700000,0xC7700000,0xC7700000,0xC1700001,0x37FC0032,0x37FC0032,0x37FC0032,0xC9600001,0xC9600001, -0xC1680001,0x9DFC0032,0x9DFC0032,0xC14C0001,0xBC000032,0x37FC0032,0x37FC0032,0x37FC0032,0xC9600001,0xC9600001,0xC1680001,0x9DFC0032,0x9DFC0032,0xC14C0001,0xBC000032,0x9DFC0032,0x9DFC0032,0xC14C0001,0xBC000032,0xBC000032,0xFB6C0008,0xF3740014,0x1780034,0xFF580000,0xDF5C0000,0xD35C0000,0xCF600000,0xC9580001,0xF564000D,0xF7500000,0x83FC0032,0xC14C0001, -0x83FC0032,0x1900048,0xE7840000,0xD3840001,0xCD840001,0x59FC0048,0xD7700001,0xCD780001,0xADFC0048,0xCD540001,0xC600004A,0x59FC0048,0xD7700001,0xCD780001,0xADFC0048,0xCD540001,0xC600004A,0xADFC0048,0xCD540001,0xC600004A,0xC600004A,0x59FC0048,0xD7700001,0xCD780001,0xADFC0048,0xCD540001,0xC600004A,0xADFC0048,0xCD540001,0xC600004A,0xC600004A,0xADFC0048, -0xCD540001,0xC600004A,0xC600004A,0xC600004A,0xFF780019,0xDA80048,0xFF8C0020,0xFF580000,0xE3580001,0xD7540000,0xCD640001,0xCD440001,0xFF700019,0xFB4C0000,0xCF680001,0xC600004A,0x99FC0048,0x1640048,0x1640048,0x1640048,0x1640048,0x1640048,0x1640048,0x1640048,0x1640048,0x1640048,0x1640048,0xD1580000,0xD1580000,0xD1580000,0xD1580000,0xD1580000, -0xD1580000,0xBD580001,0xBD580001,0xBD580001,0xB7580001,0x15FC0048,0x15FC0048,0x15FC0048,0x15FC0048,0x15FC0048,0x15FC0048,0xC1440001,0xC1440001,0xC1440001,0xB74C0001,0x8DFC0048,0x8DFC0048,0x8DFC0048,0xB7280001,0xB000004A,0xF9600019,0x1640048,0x1640048,0xFF580000,0xE5580000,0xD9580000,0xD9580000,0xC9580000,0xFD54000D,0xFF4C0000,0xC5540000,0xC1440001, -0x6FFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table56[] = { -0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x91FC0000, -0x91FC0000,0x91FC0000,0x91FC0000,0xB4000000,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x9800000,0x9800000,0x9800000,0x1FFC0000,0x75FC0000,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000, -0x43FC0000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0xC0000000,0x19C0000,0x1800001,0x1800001,0x1C00000,0x1E40000,0x17FC0000,0x17FC0000,0x67FC0000,0x1C00000,0x1E40000,0x8BFC0000,0xA3FC0000, -0x8BFC0000,0x1940001,0x1940001,0x1940001,0x1940001,0x63FC0000,0x63FC0000,0x63FC0000,0xB3F80000,0xB3F80000,0xCA000000,0x63FC0000,0x63FC0000,0x63FC0000,0xB3F80000,0xB3F80000,0xCA000000,0xB3F80000,0xB3F80000,0xCA000000,0xCA000000,0x63FC0000,0x63FC0000,0x63FC0000,0xB3F80000,0xB3F80000,0xCA000000,0xB3F80000,0xB3F80000,0xCA000000,0xCA000000,0xB3F80000, -0xB3F80000,0xCA000000,0xCA000000,0xCA000000,0x1D80000,0x1B00000,0x1940001,0x3DFC0000,0x81FC0000,0x9FF80000,0xA9F80000,0xB9F80000,0x1FC0000,0x63FC0000,0x9FF80000,0xCA000000,0x9FF80000,0x1AC0001,0x87FC0000,0xC5F80000,0xD6000000,0x87FC0000,0xC5F80000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0x87FC0000,0xC5F80000,0xD6000000,0xC5F80000,0xD6000000, -0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0x87FC0000,0xC5F80000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0xD6000000,0x3DFC0000,0xDC80000,0xDC80000,0x9DFC0000,0xBDF80000,0xCDF80000,0xD6000000,0xD6000000,0x6BFC0000,0xABFC0000,0xD5DC0000,0xD6000000, -0xB5FC0000,0x18C0274,0xFF8000F7,0xE18000F4,0xD78000F3,0xFB780092,0xE378004F,0xD9780067,0xDB780092,0xD774004E,0xD1740092,0xF96C00F4,0xE76C0033,0xD9700051,0xDF68004A,0xD76C0002,0xD16C004D,0xD76800F4,0xD3640053,0xCF640069,0xCB6800F5,0x53FC0274,0xED5400F3,0xD76C00F4,0xE3500092,0xD75C0049,0xD1600090,0xE14000F3,0xD7480032,0xD148004D,0xCB5400F4,0xABF80274, -0xD72000F3,0xD11C0090,0xCB1000F4,0xC4000278,0xFF8000EA,0xFD8801D4,0xFD8801FC,0xFF70000E,0xED6C0002,0xDF6C0002,0xD76C0006,0xD5680006,0xFD7400D7,0xFF600006,0xD9640035,0xD148004D,0x95FC0274,0x19800F3,0xF98C0032,0xDF8C0032,0xD78C0032,0xEF840049,0xE1800002,0xD7840005,0xD9800049,0xD580000E,0xD1800049,0x65FC00F3,0xE76C0032,0xD77C0032,0xDF680049,0xD76C0001, -0xD1700049,0xB3FC00F3,0xD7440032,0xD1400048,0xCA0000F4,0x65FC00F3,0xE76C0032,0xD77C0032,0xDF680049,0xD76C0001,0xD1700049,0xB3FC00F3,0xD7440032,0xD1400048,0xCA0000F4,0xB3FC00F3,0xD7440032,0xD1400048,0xCA0000F4,0xCA0000F4,0xFD880063,0xF39400B9,0xF39400B6,0xFF700005,0xED6C0001,0xDF6C0001,0xD7740001,0xD7640004,0xFF780062,0xFF640002,0xD9600033,0xD1400048, -0x9FFC00F3,0x18000F3,0x18000F3,0x18000F3,0x18000F3,0xE978004A,0xE978004A,0xE978004A,0xD374004A,0xD374004A,0xCB74004A,0xE76C0033,0xE76C0033,0xE76C0033,0xD56C0002,0xD56C0002,0xCD6C000E,0xCF680033,0xCF680033,0xCB680005,0xC5680035,0x41FC00F3,0x41FC00F3,0x41FC00F3,0xD75C0049,0xD75C0049,0xCB64004A,0xD54C0032,0xD54C0032,0xCB540001,0xC7580034,0xA1FC00F3, -0xA1FC00F3,0xCB340048,0xC5280034,0xC00000F4,0xFF740053,0xF77C00AB,0x18000F3,0xFD6C0006,0xE96C0002,0xDD6C0002,0xDB6C0003,0xD3680001,0xFF6C0049,0xFF600002,0xD5680033,0xCB540001,0x89FC00F3,0x18C0032,0x18C0032,0x18C0032,0x18C0032,0xDD840001,0xDD840001,0xDD840001,0xCF840001,0xCF840001,0xCB800001,0x53FC0032,0x53FC0032,0x53FC0032,0xD3700001,0xD3700001, -0xCB780000,0xABF80032,0xABF80032,0xCB580000,0xC4000034,0x53FC0032,0x53FC0032,0x53FC0032,0xD3700001,0xD3700001,0xCB780000,0xABF80032,0xABF80032,0xCB580000,0xC4000034,0xABF80032,0xABF80032,0xCB580000,0xC4000034,0xC4000034,0xF780000D,0xFD880012,0x18C0032,0xFB700001,0xE3740001,0xDB700000,0xD5740001,0xD3680000,0xFD74000D,0xFD640000,0x95FC0032,0xCB580000, -0x95FC0032,0x1A0004A,0xED980001,0xDD940001,0xD7940001,0x75FC0048,0xE1800001,0xD7880001,0xBBFC0048,0xD7640000,0xD0000048,0x75FC0048,0xE1800001,0xD7880001,0xBBFC0048,0xD7640000,0xD0000048,0xBBFC0048,0xD7640000,0xD0000048,0xD0000048,0x75FC0048,0xE1800001,0xD7880001,0xBBFC0048,0xD7640000,0xD0000048,0xBBFC0048,0xD7640000,0xD0000048,0xD0000048,0xBBFC0048, -0xD7640000,0xD0000048,0xD0000048,0xD0000048,0xFD900020,0x7BC0048,0xF9A00029,0xFF740002,0xED680001,0xE1640000,0xD7740000,0xD7500000,0xFB880020,0xFF640001,0xD9780000,0xD0000048,0xA9FC0048,0x174004A,0x174004A,0x174004A,0x174004A,0x174004A,0x174004A,0x174004A,0x174004A,0x174004A,0x174004A,0xD76C0001,0xD76C0001,0xD76C0001,0xD76C0001,0xD76C0001, -0xD76C0001,0xC7680001,0xC7680001,0xC7680001,0xC1680001,0x31FC0048,0x31FC0048,0x31FC0048,0x31FC0048,0x31FC0048,0x31FC0048,0xCB540001,0xCB540001,0xCB540001,0xC15C0001,0x9BF80048,0x9BF80048,0x9BF80048,0xC1380000,0xBA000048,0xF1700022,0x174004A,0x174004A,0xFB6C0002,0xEB6C0001,0xDF6C0001,0xDF6C0001,0xD16C0001,0xF9680012,0xFD600001,0xCB680001,0xCB540001, -0x7FFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table57[] = { -0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000, -0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1940000,0x1940000,0x1940000,0x37FC0000,0x83FC0000,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000, -0x5BFC0000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xC8000000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xC8000000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xC8000000,0xC8000000,0x1AC0000,0x1900001,0x1900001,0x1D40000,0x1F80000,0x35FC0000,0x35FC0000,0x7BFC0000,0x1D40000,0x1F80000,0x9BFC0000,0xAFFC0000, -0x9BFC0000,0x1A40001,0x1A40001,0x1A40001,0x1A40001,0x7BFC0000,0x7BFC0000,0x7BFC0000,0xBFF80000,0xBFF80000,0xD2000000,0x7BFC0000,0x7BFC0000,0x7BFC0000,0xBFF80000,0xBFF80000,0xD2000000,0xBFF80000,0xBFF80000,0xD2000000,0xD2000000,0x7BFC0000,0x7BFC0000,0x7BFC0000,0xBFF80000,0xBFF80000,0xD2000000,0xBFF80000,0xBFF80000,0xD2000000,0xD2000000,0xBFF80000, -0xBFF80000,0xD2000000,0xD2000000,0xD2000000,0x7E80000,0x9C00000,0x1A40001,0x5BFC0000,0x93FC0000,0xADFC0000,0xB5FC0000,0xC3FC0000,0x29FC0000,0x7BFC0000,0xADFC0000,0xD2000000,0xADFC0000,0x1BC0001,0x9FFC0000,0xD1F80000,0xDE000000,0x9FFC0000,0xD1F80000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0x9FFC0000,0xD1F80000,0xDE000000,0xD1F80000,0xDE000000, -0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0x9FFC0000,0xD1F80000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0xDE000000,0x63FC0000,0x1DC0000,0x1DC0000,0xB1FC0000,0xC9FC0000,0xD7F80000,0xDE000000,0xDE000000,0x89FC0000,0xBBFC0000,0xDDEC0000,0xDE000000, -0xC3FC0000,0x19C0274,0xFD94010B,0xE99000F4,0xDF9000F3,0xFD88009A,0xEB88004F,0xE1880067,0xE3880092,0xDF84004E,0xD9840092,0xFD7C00F5,0xEF7C0033,0xE1800051,0xE778004A,0xDF7C0002,0xD97C004D,0xDF7800F4,0xDB740053,0xD7740069,0xD37800F5,0x6BFC0274,0xF56400F3,0xDF7C00F4,0xEB600092,0xDF6C0049,0xD9700090,0xE95000F3,0xDF580032,0xD958004D,0xD36400F4,0xB7F80274, -0xDF3000F3,0xD92C0090,0xD32000F4,0xCC000278,0xFF8C0114,0xF59801FA,0xF79C0217,0xFF800026,0xF57C0002,0xE77C0002,0xDF7C0006,0xDD780006,0xFF880104,0xFF78001B,0xE1740035,0xD958004D,0xA3FC0274,0x1A800F3,0xFF9C0033,0xE79C0032,0xDF9C0032,0xF7940049,0xE9900002,0xDF940005,0xE1900049,0xDD90000E,0xD9900049,0x7DFC00F3,0xEF7C0032,0xDF8C0032,0xE7780049,0xDF7C0001, -0xD9800049,0xBFFC00F3,0xDF540032,0xD9500048,0xD20000F4,0x7DFC00F3,0xEF7C0032,0xDF8C0032,0xE7780049,0xDF7C0001,0xD9800049,0xBFFC00F3,0xDF540032,0xD9500048,0xD20000F4,0xBFFC00F3,0xDF540032,0xD9500048,0xD20000F4,0xD20000F4,0xFB980075,0xFBA400B9,0xFBA400B6,0xFF880013,0xF57C0001,0xE77C0001,0xDF840001,0xDF740004,0xFF900071,0xFD7C000D,0xE1700033,0xD9500048, -0xAFFC00F3,0x19000F3,0x19000F3,0x19000F3,0x19000F3,0xF188004A,0xF188004A,0xF188004A,0xDB84004A,0xDB84004A,0xD384004A,0xEF7C0033,0xEF7C0033,0xEF7C0033,0xDD7C0002,0xDD7C0002,0xD57C000E,0xD7780033,0xD7780033,0xD3780005,0xCD780035,0x59FC00F3,0x59FC00F3,0x59FC00F3,0xDF6C0049,0xDF6C0049,0xD374004A,0xDD5C0032,0xDD5C0032,0xD3640001,0xCF680034,0xADFC00F3, -0xADFC00F3,0xD3440048,0xCD380034,0xC80000F4,0xFF840062,0xFF8C00AB,0x19000F3,0xFF80000D,0xF17C0002,0xE57C0002,0xE37C0003,0xDB780001,0xFF800055,0xFF740006,0xDD780033,0xD3640001,0x99FC00F3,0x19C0032,0x19C0032,0x19C0032,0x19C0032,0xE5940001,0xE5940001,0xE5940001,0xD7940001,0xD7940001,0xD3900001,0x6BFC0032,0x6BFC0032,0x6BFC0032,0xDB800001,0xDB800001, -0xD3880000,0xB7F80032,0xB7F80032,0xD3680000,0xCC000034,0x6BFC0032,0x6BFC0032,0x6BFC0032,0xDB800001,0xDB800001,0xD3880000,0xB7F80032,0xB7F80032,0xD3680000,0xCC000034,0xB7F80032,0xB7F80032,0xD3680000,0xCC000034,0xCC000034,0xFF90000D,0xF5980019,0x19C0032,0xFD840002,0xEB840001,0xE3800000,0xDD840001,0xDB780000,0xFD880012,0xFB7C0002,0xA3FC0032,0xD3680000, -0xA3FC0032,0x1B0004A,0xF5A80001,0xE5A40001,0xDFA40001,0x8DFC0048,0xE9900001,0xDF980001,0xC7FC0048,0xDF740000,0xD8000048,0x8DFC0048,0xE9900001,0xDF980001,0xC7FC0048,0xDF740000,0xD8000048,0xC7FC0048,0xDF740000,0xD8000048,0xD8000048,0x8DFC0048,0xE9900001,0xDF980001,0xC7FC0048,0xDF740000,0xD8000048,0xC7FC0048,0xDF740000,0xD8000048,0xD8000048,0xC7FC0048, -0xDF740000,0xD8000048,0xD8000048,0xD8000048,0xF7A40029,0xFCC0048,0xFFAC002D,0xFF8C0008,0xF5780001,0xE9740000,0xDF840000,0xDF600000,0xFF980022,0xFD800005,0xE1880000,0xD8000048,0xB9FC0048,0x184004A,0x184004A,0x184004A,0x184004A,0x184004A,0x184004A,0x184004A,0x184004A,0x184004A,0x184004A,0xDF7C0001,0xDF7C0001,0xDF7C0001,0xDF7C0001,0xDF7C0001, -0xDF7C0001,0xCF780001,0xCF780001,0xCF780001,0xC9780001,0x49FC0048,0x49FC0048,0x49FC0048,0x49FC0048,0x49FC0048,0x49FC0048,0xD3640001,0xD3640001,0xD3640001,0xC96C0001,0xA7F80048,0xA7F80048,0xA7F80048,0xC9480000,0xC2000048,0xF9800022,0x184004A,0x184004A,0xFB7C0005,0xF37C0001,0xE77C0001,0xE77C0001,0xD97C0001,0xF57C0019,0xFD740002,0xD3780001,0xD3640001, -0x8FFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table58[] = { -0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0xA9FC0000, -0xA9FC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1A40000,0x1A40000,0x1A40000,0x4FFC0000,0x93FC0000,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000, -0x75FC0000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xD0000000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xD0000000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xD0000000,0xD0000000,0x7BC0000,0x1A00001,0x1A00001,0x5E40000,0x1FFC0000,0x53FC0000,0x53FC0000,0x8FFC0000,0x5E40000,0x1FFC0000,0xA9FC0000,0xBBFC0000, -0xA9FC0000,0x1B40001,0x1B40001,0x1B40001,0x1B40001,0x93FC0000,0x93FC0000,0x93FC0000,0xCBF80000,0xCBF80000,0xDA000000,0x93FC0000,0x93FC0000,0x93FC0000,0xCBF80000,0xCBF80000,0xDA000000,0xCBF80000,0xCBF80000,0xDA000000,0xDA000000,0x93FC0000,0x93FC0000,0x93FC0000,0xCBF80000,0xCBF80000,0xDA000000,0xCBF80000,0xCBF80000,0xDA000000,0xDA000000,0xCBF80000, -0xCBF80000,0xDA000000,0xDA000000,0xDA000000,0x3FC0000,0x1D40000,0x1B40001,0x79FC0000,0xA7FC0000,0xBDF80000,0xC3FC0000,0xCFF80000,0x51FC0000,0x93FC0000,0xBDF80000,0xDA000000,0xBDF80000,0x1CC0001,0xB7FC0000,0xDDF40000,0xE6000000,0xB7FC0000,0xDDF40000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xB7FC0000,0xDDF40000,0xE6000000,0xDDF40000,0xE6000000, -0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0xB7FC0000,0xDDF40000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0xE6000000,0x8BFC0000,0x1EC0000,0x1EC0000,0xC5FC0000,0xD7FC0000,0xE1FC0000,0xE6000000,0xE6000000,0xA7FC0000,0xCDFC0000,0xE5FC0000,0xE6000000, -0xD3FC0000,0x1AC0274,0xFFA4011F,0xF1A000F4,0xE7A000F3,0xFF9800B2,0xF398004F,0xE9980067,0xEB980092,0xE794004E,0xE1940092,0xFF900104,0xF78C0033,0xE9900051,0xEF88004A,0xE78C0002,0xE18C004D,0xE78800F4,0xE3840053,0xDF840069,0xDB8800F5,0x83FC0274,0xFD7400F3,0xE78C00F4,0xF3700092,0xE77C0049,0xE1800090,0xF16000F3,0xE7680032,0xE168004D,0xDB7400F4,0xC3F80274, -0xE74000F3,0xE13C0090,0xDB3000F4,0xD4000278,0xFFA00136,0xFDA801FA,0xFFAC0217,0xFF940053,0xFD8C0002,0xEF8C0002,0xE78C0006,0xE5880006,0xFF98012A,0xFF8C0042,0xE9840035,0xE168004D,0xB3FC0274,0x1B800F3,0xFFB0003E,0xEFAC0032,0xE7AC0032,0xFFA40049,0xF1A00002,0xE7A40005,0xE9A00049,0xE5A0000E,0xE1A00049,0x95FC00F3,0xF78C0032,0xE79C0032,0xEF880049,0xE78C0001, -0xE1900049,0xCBFC00F3,0xE7640032,0xE1600048,0xDA0000F4,0x95FC00F3,0xF78C0032,0xE79C0032,0xEF880049,0xE78C0001,0xE1900049,0xCBFC00F3,0xE7640032,0xE1600048,0xDA0000F4,0xCBFC00F3,0xE7640032,0xE1600048,0xDA0000F4,0xDA0000F4,0xFBAC0082,0xF3B400CB,0xF3B400CB,0xFF980029,0xFD8C0001,0xEF8C0001,0xE7940001,0xE7840004,0xFFA40082,0xFF90001E,0xE9800033,0xE1600048, -0xBFF800F3,0x1A000F3,0x1A000F3,0x1A000F3,0x1A000F3,0xF998004A,0xF998004A,0xF998004A,0xE394004A,0xE394004A,0xDB94004A,0xF78C0033,0xF78C0033,0xF78C0033,0xE58C0002,0xE58C0002,0xDD8C000E,0xDF880033,0xDF880033,0xDB880005,0xD5880035,0x71FC00F3,0x71FC00F3,0x71FC00F3,0xE77C0049,0xE77C0049,0xDB84004A,0xE56C0032,0xE56C0032,0xDB740001,0xD7780034,0xB9FC00F3, -0xB9FC00F3,0xDB540048,0xD5480034,0xD00000F4,0xFB980075,0xF9A000BA,0x1A000F3,0xFF90001A,0xF98C0002,0xED8C0002,0xEB8C0003,0xE3880001,0xFF940064,0xFD8C0019,0xE5880033,0xDB740001,0xA7FC00F3,0x1AC0032,0x1AC0032,0x1AC0032,0x1AC0032,0xEDA40001,0xEDA40001,0xEDA40001,0xDFA40001,0xDFA40001,0xDBA00001,0x83FC0032,0x83FC0032,0x83FC0032,0xE3900001,0xE3900001, -0xDB980000,0xC3F80032,0xC3F80032,0xDB780000,0xD4000034,0x83FC0032,0x83FC0032,0x83FC0032,0xE3900001,0xE3900001,0xDB980000,0xC3F80032,0xC3F80032,0xDB780000,0xD4000034,0xC3F80032,0xC3F80032,0xDB780000,0xD4000034,0xD4000034,0xFFA00014,0xFDA80019,0x1AC0032,0xFF980005,0xF3940001,0xEB900000,0xE5940001,0xE3880000,0xF5A00019,0xFB900005,0xB3FC0032,0xDB780000, -0xB3FC0032,0x1C0004A,0xFDB80001,0xEDB40001,0xE7B40001,0xA5FC0048,0xF1A00001,0xE7A80001,0xD3FC0048,0xE7840000,0xE0000048,0xA5FC0048,0xF1A00001,0xE7A80001,0xD3FC0048,0xE7840000,0xE0000048,0xD3FC0048,0xE7840000,0xE0000048,0xE0000048,0xA5FC0048,0xF1A00001,0xE7A80001,0xD3FC0048,0xE7840000,0xE0000048,0xD3FC0048,0xE7840000,0xE0000048,0xE0000048,0xD3FC0048, -0xE7840000,0xE0000048,0xE0000048,0xE0000048,0xFFB40029,0x1E00048,0xF9C00032,0xFFA00011,0xFD880001,0xF1840000,0xE7940000,0xE7700000,0xFFAC002D,0xFD9C000D,0xE9980000,0xE0000048,0xC7FC0048,0x194004A,0x194004A,0x194004A,0x194004A,0x194004A,0x194004A,0x194004A,0x194004A,0x194004A,0x194004A,0xE78C0001,0xE78C0001,0xE78C0001,0xE78C0001,0xE78C0001, -0xE78C0001,0xD7880001,0xD7880001,0xD7880001,0xD1880001,0x63FC0048,0x63FC0048,0x63FC0048,0x63FC0048,0x63FC0048,0x63FC0048,0xDB740001,0xDB740001,0xDB740001,0xD17C0001,0xB3F80048,0xB3F80048,0xB3F80048,0xD1580000,0xCA000048,0xF3940029,0x194004A,0x194004A,0xFD8C000A,0xFB8C0001,0xEF8C0001,0xEF8C0001,0xE18C0001,0xFD8C0019,0xF9880008,0xDB880001,0xDB740001, -0x9FF80048,}; -static const uint32_t g_etc1_to_bc7_m6_table59[] = { -0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0xB5FC0000, -0xB5FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x3B40000,0x3B40000,0x3B40000,0x69FC0000,0xA1FC0000,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x1B00001,0x8DFC0000,0x8DFC0000,0x8DFC0000,0x8DFC0000,0x8DFC0000, -0x8DFC0000,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xD8000000,0x8DFC0000,0x8DFC0000,0x8DFC0000,0x8DFC0000,0x8DFC0000,0x8DFC0000,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xD8000000,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xD8000000,0xD8000000,0xFCC0000,0x1B00001,0x1B00001,0x1F80000,0x47FC0000,0x71FC0000,0x71FC0000,0xA3FC0000,0x1F80000,0x47FC0000,0xB9FC0000,0xC7FC0000, -0xB9FC0000,0x1C40001,0x1C40001,0x1C40001,0x1C40001,0xABFC0000,0xABFC0000,0xABFC0000,0xD7F80000,0xD7F80000,0xE2000000,0xABFC0000,0xABFC0000,0xABFC0000,0xD7F80000,0xD7F80000,0xE2000000,0xD7F80000,0xD7F80000,0xE2000000,0xE2000000,0xABFC0000,0xABFC0000,0xABFC0000,0xD7F80000,0xD7F80000,0xE2000000,0xD7F80000,0xD7F80000,0xE2000000,0xE2000000,0xD7F80000, -0xD7F80000,0xE2000000,0xE2000000,0xE2000000,0x3BFC0000,0x1E40000,0x1C40001,0x97FC0000,0xBBFC0000,0xCBFC0000,0xD1FC0000,0xD9FC0000,0x77FC0000,0xABFC0000,0xCBFC0000,0xE2000000,0xCBFC0000,0x1DC0001,0xCFFC0000,0xE7FC0000,0xEE000000,0xCFFC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xCFFC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xEE000000, -0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0xCFFC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0xEE000000,0xB3FC0000,0x7FC0000,0x7FC0000,0xD9FC0000,0xE5FC0000,0xEBFC0000,0xEE000000,0xEE000000,0xC5FC0000,0xDDFC0000,0xEFD00000,0xEE000000, -0xE1FC0000,0x1BC0274,0xFFB4014C,0xF9B000F4,0xEFB000F3,0xFFB000E2,0xFBA8004F,0xF1A80067,0xF3A80092,0xEFA4004E,0xE9A40092,0xFFA40121,0xFF9C0033,0xF1A00051,0xF798004A,0xEF9C0002,0xE99C004D,0xEF9800F4,0xEB940053,0xE7940069,0xE39800F5,0x9BFC0274,0xFD9000FD,0xEF9C00F4,0xFB800092,0xEF8C0049,0xE9900090,0xF97000F3,0xEF780032,0xE978004D,0xE38400F4,0xCFF80274, -0xEF5000F3,0xE94C0090,0xE34000F4,0xDC000278,0xFFB4016B,0xF5B80224,0xF7BC0234,0xFFAC009E,0xFF9C0013,0xF79C0002,0xEF9C0006,0xED980006,0xFDB0016B,0xFFA00086,0xF1940035,0xE978004D,0xC1FC0274,0x1C800F3,0xFDC00053,0xF7BC0032,0xEFBC0032,0xFDB80059,0xF9B00002,0xEFB40005,0xF1B00049,0xEDB0000E,0xE9B00049,0xAFFC00F3,0xFF9C0032,0xEFAC0032,0xF7980049,0xEF9C0001, -0xE9A00049,0xD7FC00F3,0xEF740032,0xE9700048,0xE20000F4,0xAFFC00F3,0xFF9C0032,0xEFAC0032,0xF7980049,0xEF9C0001,0xE9A00049,0xD7FC00F3,0xEF740032,0xE9700048,0xE20000F4,0xD7FC00F3,0xEF740032,0xE9700048,0xE20000F4,0xE20000F4,0xFFBC0095,0xFBC400CB,0xFBC400CB,0xFFB00042,0xFFA40009,0xF79C0001,0xEFA40001,0xEF940004,0xFFB4009E,0xFFAC003D,0xF1900033,0xE9700048, -0xCDFC00F3,0x1B000F3,0x1B000F3,0x1B000F3,0x1B000F3,0xFFA8004B,0xFFA8004B,0xFFA8004B,0xEBA4004A,0xEBA4004A,0xE3A4004A,0xFF9C0033,0xFF9C0033,0xFF9C0033,0xED9C0002,0xED9C0002,0xE59C000E,0xE7980033,0xE7980033,0xE3980005,0xDD980035,0x89FC00F3,0x89FC00F3,0x89FC00F3,0xEF8C0049,0xEF8C0049,0xE394004A,0xED7C0032,0xED7C0032,0xE3840001,0xDF880034,0xC5FC00F3, -0xC5FC00F3,0xE3640048,0xDD580034,0xD80000F4,0xFFAC0082,0xFFAC00BE,0x1B000F3,0xFFA40033,0xFF9C0003,0xF59C0002,0xF39C0003,0xEB980001,0xFFA00079,0xFF9C002A,0xED980033,0xE3840001,0xB7FC00F3,0x1BC0032,0x1BC0032,0x1BC0032,0x1BC0032,0xF5B40001,0xF5B40001,0xF5B40001,0xE7B40001,0xE7B40001,0xE3B00001,0x9BFC0032,0x9BFC0032,0x9BFC0032,0xEBA00001,0xEBA00001, -0xE3A80000,0xCFF80032,0xCFF80032,0xE3880000,0xDC000034,0x9BFC0032,0x9BFC0032,0x9BFC0032,0xEBA00001,0xEBA00001,0xE3A80000,0xCFF80032,0xCFF80032,0xE3880000,0xDC000034,0xCFF80032,0xCFF80032,0xE3880000,0xDC000034,0xDC000034,0xFBB40019,0xF5B80022,0x1BC0032,0xFBAC000D,0xFBA40001,0xF3A00000,0xEDA40001,0xEB980000,0xFDB00019,0xFFA40008,0xC1FC0032,0xE3880000, -0xC1FC0032,0x1D0004A,0xFFC80005,0xF5C40001,0xEFC40001,0xBDFC0048,0xF9B00001,0xEFB80001,0xDFF80048,0xEF940000,0xE8000048,0xBDFC0048,0xF9B00001,0xEFB80001,0xDFF80048,0xEF940000,0xE8000048,0xDFF80048,0xEF940000,0xE8000048,0xE8000048,0xBDFC0048,0xF9B00001,0xEFB80001,0xDFF80048,0xEF940000,0xE8000048,0xDFF80048,0xEF940000,0xE8000048,0xE8000048,0xDFF80048, -0xEF940000,0xE8000048,0xE8000048,0xE8000048,0xFBC80034,0x1F00048,0xFFCC003A,0xFDBC0019,0xFFA40005,0xF9940000,0xEFA40000,0xEF800000,0xF9C80032,0xFBB80019,0xF1A80000,0xE8000048,0xD7FC0048,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0x1A4004A,0xEF9C0001,0xEF9C0001,0xEF9C0001,0xEF9C0001,0xEF9C0001, -0xEF9C0001,0xDF980001,0xDF980001,0xDF980001,0xD9980001,0x7BFC0048,0x7BFC0048,0x7BFC0048,0x7BFC0048,0x7BFC0048,0x7BFC0048,0xE3840001,0xE3840001,0xE3840001,0xD98C0001,0xBFF80048,0xBFF80048,0xBFF80048,0xD9680000,0xD2000048,0xFBA40029,0x1A4004A,0x1A4004A,0xFFA0000D,0xFD9C0002,0xF79C0001,0xF79C0001,0xE99C0001,0xFD9C0020,0xFB98000D,0xE3980001,0xE3840001, -0xADFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table60[] = { -0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0xC3F80000, -0xC3F80000,0xC3F80000,0xC3F80000,0xD4000001,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1C80000,0x1C80000,0x1C80000,0x83FC0000,0xB3FC0000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000, -0xA9FC0000,0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0xE0000001,0x9E00000,0x1C40000,0x1C40000,0x35FC0000,0x73FC0000,0x93FC0000,0x93FC0000,0xB9FC0000,0x35FC0000,0x73FC0000,0xC9FC0000,0xD5F80000, -0xC9FC0000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xE3FC0000,0xE3FC0000,0xEA000001,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xE3FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xE3FC0000,0xEA000001,0xEA000001,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xE3FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xE3FC0000,0xEA000001,0xEA000001,0xE3FC0000, -0xE3FC0000,0xEA000001,0xEA000001,0xEA000001,0x7BFC0000,0x1F80000,0x1D80000,0xB9FC0000,0xD1FC0000,0xDDF80000,0xDFFC0000,0xE5FC0000,0xA3FC0000,0xC7FC0000,0xDDF80000,0xEA000001,0xDDF80000,0x1F00000,0xEBFC0000,0xF5FC0000,0xF6000001,0xEBFC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xEBFC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF6000001, -0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xEBFC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xF6000001,0xDFFC0000,0x97FC0000,0x97FC0000,0xEFFC0000,0xF5F80000,0xF7F40000,0xF6000001,0xF6000001,0xE7FC0000,0xF1FC0000,0xF9C40000,0xF6000001, -0xF3FC0000,0x1CC0278,0xFFC80181,0xFFC400FD,0xF7C400F5,0xFFC40120,0xFFBC0069,0xFBBC0069,0xFDB80090,0xF7B8004D,0xF1B80092,0xFFBC015B,0xFFB4005D,0xFBB40053,0xFFAC0049,0xF7AC0002,0xF3AC004E,0xF7AC00F4,0xF5A80051,0xF1A80067,0xEDAC00F3,0xB7FC0274,0xFFAC011F,0xF7AC00F4,0xFF9C00AA,0xF99C004A,0xF1A40092,0xFF8800F5,0xF78C0033,0xF18C004F,0xED9400F4,0xDDF40274, -0xF76800F4,0xF1600092,0xED4C00F3,0xE6000274,0xFFC401B8,0xFFCC0220,0xFFCC0234,0xFFC000F1,0xFFB40059,0xFFAC0002,0xF9B00006,0xF7AC0006,0xFFC401A8,0xFFB800EA,0xF9A80035,0xF18C004F,0xD3FC0274,0x1D800F4,0xFFD00074,0xFFCC0035,0xF7CC0035,0xFFD00074,0xFFC40009,0xF9C40005,0xF9C4004A,0xF7C0000E,0xF1C4004A,0xC9FC00F3,0xFFB80042,0xF9BC0033,0xFFAC0049,0xF7AC0002, -0xF1B4004A,0xE5F800F3,0xF78C0033,0xF184004A,0xEC0000F3,0xC9FC00F3,0xFFB80042,0xF9BC0033,0xFFAC0049,0xF7AC0002,0xF1B4004A,0xE5F800F3,0xF78C0033,0xF184004A,0xEC0000F3,0xE5F800F3,0xF78C0033,0xF184004A,0xEC0000F3,0xEC0000F3,0xFFD000AB,0xF5D800DE,0xF5D800DD,0xFFC80076,0xFFBC002E,0xFFAC0002,0xF9B40001,0xF7A40003,0xFDD000B5,0xFFC80063,0xFBA00032,0xF184004A, -0xDFF800F3,0x1C400F4,0x1C400F4,0x1C400F4,0x1C400F4,0xFFBC0059,0xFFBC0059,0xFFBC0059,0xF3B80049,0xF3B80049,0xEBB80049,0xFFB0003E,0xFFB0003E,0xFFB0003E,0xF7AC0001,0xF7AC0001,0xEDB0000E,0xEFAC0032,0xEFAC0032,0xEBAC0005,0xE7AC0032,0xA5FC00F3,0xA5FC00F3,0xA5FC00F3,0xF99C0049,0xF99C0049,0xEBA80049,0xF78C0032,0xF78C0032,0xEB980002,0xE79C0032,0xD3FC00F3, -0xD3FC00F3,0xEB780049,0xE7640032,0xE00000F3,0xFFBC0095,0xF9C000CC,0x1C400F4,0xFDB80056,0xFFB00018,0xFFAC0001,0xFBAC0004,0xF3AC0001,0xFFB40091,0xFFB00045,0xF7A80032,0xEB980002,0xC7FC00F3,0x1CC0034,0x1CC0034,0x1CC0034,0x1CC0034,0xFFC40000,0xFFC40000,0xFFC40000,0xF1C40000,0xF1C40000,0xEBC40001,0xB7FC0032,0xB7FC0032,0xB7FC0032,0xF3B40001,0xF3B40001, -0xEBBC0001,0xDDF40032,0xDDF40032,0xEBA00001,0xE6000032,0xB7FC0032,0xB7FC0032,0xB7FC0032,0xF3B40001,0xF3B40001,0xEBBC0001,0xDDF40032,0xDDF40032,0xEBA00001,0xE6000032,0xDDF40032,0xDDF40032,0xEBA00001,0xE6000032,0xE6000032,0xFDC80020,0xFFCC0020,0x1CC0034,0xFDC00014,0xFDBC0005,0xFDB00000,0xF9B40000,0xF3AC0001,0xFFC40020,0xFBC00012,0xD3FC0032,0xEBA00001, -0xD3FC0032,0x1E40048,0xFFDC0014,0xFDD80001,0xF7D80001,0xD9FC0048,0xFFC80005,0xF7CC0001,0xEDF80048,0xF7A80001,0xF000004A,0xD9FC0048,0xFFC80005,0xF7CC0001,0xEDF80048,0xF7A80001,0xF000004A,0xEDF80048,0xF7A80001,0xF000004A,0xF000004A,0xD9FC0048,0xFFC80005,0xF7CC0001,0xEDF80048,0xF7A80001,0xF000004A,0xEDF80048,0xF7A80001,0xF000004A,0xF000004A,0xEDF80048, -0xF7A80001,0xF000004A,0xF000004A,0xF000004A,0xF5E4003D,0x37FC0048,0xFBE4003D,0xFFD40029,0xFDCC0019,0xFFAC0001,0xF7B80001,0xF7980001,0xFFDC0032,0xFFCC0028,0xF9BC0001,0xF000004A,0xE7FC0048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0x1B80048,0xFBAC0000,0xFBAC0000,0xFBAC0000,0xFBAC0000,0xFBAC0000, -0xFBAC0000,0xE7AC0001,0xE7AC0001,0xE7AC0001,0xE1AC0001,0x95FC0048,0x95FC0048,0x95FC0048,0x95FC0048,0x95FC0048,0x95FC0048,0xEB980001,0xEB980001,0xEB980001,0xE1A00001,0xCBFC0048,0xCBFC0048,0xCBFC0048,0xE17C0001,0xDA00004A,0xF3B40034,0x1B80048,0x1B80048,0xFBB40019,0xFDB00008,0xFFAC0001,0xFFAC0001,0xF3AC0000,0xF9B00029,0xFBAC0014,0xEFA80000,0xEB980001, -0xBFF80048,}; -static const uint32_t g_etc1_to_bc7_m6_table61[] = { -0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000, -0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x5D80000,0x5D80000,0x5D80000,0x9BFC0000,0xC1FC0000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000, -0xC1FC0000,0xE1F80000,0xE1F80000,0xE1F80000,0xE8000001,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xE1F80000,0xE1F80000,0xE1F80000,0xE8000001,0xE1F80000,0xE1F80000,0xE1F80000,0xE8000001,0xE8000001,0x1F40000,0x1D40000,0x1D40000,0x6DFC0000,0x9BFC0000,0xB1FC0000,0xB1FC0000,0xCDFC0000,0x6DFC0000,0x9BFC0000,0xD9FC0000,0xE1F80000, -0xD9FC0000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0xDFFC0000,0xDFFC0000,0xDFFC0000,0xEFFC0000,0xEFFC0000,0xF2000001,0xDFFC0000,0xDFFC0000,0xDFFC0000,0xEFFC0000,0xEFFC0000,0xF2000001,0xEFFC0000,0xEFFC0000,0xF2000001,0xF2000001,0xDFFC0000,0xDFFC0000,0xDFFC0000,0xEFFC0000,0xEFFC0000,0xF2000001,0xEFFC0000,0xEFFC0000,0xF2000001,0xF2000001,0xEFFC0000, -0xEFFC0000,0xF2000001,0xF2000001,0xF2000001,0xB5FC0000,0x57FC0000,0x1E80000,0xD7FC0000,0xE5FC0000,0xEBFC0000,0xEDFC0000,0xF1F80000,0xCBFC0000,0xDFFC0000,0xEBFC0000,0xF2000001,0xEBFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1DC0255,0xFFDC01AD,0xFFD40125,0xFFD400F4,0xFFD00159,0xFFCC00B4,0xFFCC0074,0xFFCC0099,0xFFC8004C,0xF9C80085,0xFFD00179,0xFFC800AF,0xFFC40054,0xFFC00069,0xFFBC0001,0xF9C00045,0xFFBC00DD,0xFBBC004A,0xF9B8005A,0xF5BC00DE,0xCFFC0253,0xFFC00158,0xFFBC00F3,0xFFB800D3,0xFFAC004E,0xF9B40085,0xFFAC0106,0xFF9C0032,0xF99C0042,0xF5A400DF,0xE7FC0253, -0xFF7800F3,0xF9700085,0xF55C00DE,0xEE000253,0xFFD801C7,0xF7DC0229,0xF7DC0234,0xFFD40139,0xFFCC00B5,0xFFC0003C,0xFFC0000C,0xFFBC0005,0xFFD401B7,0xFFD00122,0xFFB80036,0xF99C0042,0xE1FC0253,0x1E800DD,0xFDE40095,0xFFE0004D,0xFFDC0034,0xFFDC0089,0xFFD8002C,0xFFD80008,0xFFD40041,0xFDD0000C,0xF9D4003D,0xDFFC00DD,0xFFD80068,0xFFCC0034,0xFFCC0059,0xFFBC0001, -0xF9C4003D,0xEFFC00DD,0xFF9C0032,0xF994003D,0xF40000DE,0xDFFC00DD,0xFFD80068,0xFFCC0034,0xFFCC0059,0xFFBC0001,0xF9C4003D,0xEFFC00DD,0xFF9C0032,0xF994003D,0xF40000DE,0xEFFC00DD,0xFF9C0032,0xF994003D,0xF40000DE,0xF40000DE,0xFFE400B5,0xFDE800C9,0xFDE800C8,0xFFDC0089,0xFFD40062,0xFFC8001E,0xFFC40001,0xFFB40002,0xFFE000BA,0xFFDC0082,0xFFB80036,0xF994003D, -0xEBFC00DD,0x1D400F4,0x1D400F4,0x1D400F4,0x1D400F4,0xFDCC0074,0xFDCC0074,0xFDCC0074,0xFBC80049,0xFBC80049,0xF3C80049,0xFFC40054,0xFFC40054,0xFFC40054,0xFFBC0001,0xFFBC0001,0xF5C0000E,0xF7BC0032,0xF7BC0032,0xF3BC0005,0xEFBC0032,0xBDFC00F3,0xBDFC00F3,0xBDFC00F3,0xFDB4004E,0xFDB4004E,0xF3B80049,0xFF9C0032,0xFF9C0032,0xF3A80002,0xEFAC0032,0xDFF800F3, -0xDFF800F3,0xF3880049,0xEF740032,0xE80000F3,0xFFCC00A8,0xFFCC00E0,0x1D400F4,0xFFCC0071,0xFFC40038,0xFFC00018,0xFFC0000C,0xFBBC0001,0xFDCC00A3,0xFFC40068,0xFFB80032,0xF3A80002,0xD7FC00F3,0x1DC0034,0x1DC0034,0x1DC0034,0x1DC0034,0xFDD80008,0xFDD80008,0xFDD80008,0xF9D40000,0xF9D40000,0xF3D40001,0xCFFC0032,0xCFFC0032,0xCFFC0032,0xFBC40001,0xFBC40001, -0xF3CC0001,0xE7FC0032,0xE7FC0032,0xF3B00001,0xEE000032,0xCFFC0032,0xCFFC0032,0xCFFC0032,0xFBC40001,0xFBC40001,0xF3CC0001,0xE7FC0032,0xE7FC0032,0xF3B00001,0xEE000032,0xE7FC0032,0xE7FC0032,0xF3B00001,0xEE000032,0xEE000032,0xFFD80022,0xF7DC0029,0x1DC0034,0xFDD80019,0xFDD0000D,0xFFC80005,0xFFC40001,0xFBBC0001,0xF1DC0029,0xFBD40019,0xE1FC0032,0xF3B00001, -0xE1FC0032,0x1F4003D,0xFFEC0028,0xFFEC000D,0xFFE80000,0xEFFC003D,0xFFE40014,0xFFDC0000,0xF7F8003D,0xFFB80000,0xF800003D,0xEFFC003D,0xFFE40014,0xFFDC0000,0xF7F8003D,0xFFB80000,0xF800003D,0xF7F8003D,0xFFB80000,0xF800003D,0xF800003D,0xEFFC003D,0xFFE40014,0xFFDC0000,0xF7F8003D,0xFFB80000,0xF800003D,0xF7F8003D,0xFFB80000,0xF800003D,0xF800003D,0xF7F8003D, -0xFFB80000,0xF800003D,0xF800003D,0xF800003D,0xFBF00034,0xA7FC003D,0xF3F4003D,0xFFEC0029,0xFFE80020,0xFFD40011,0xFFC80000,0xFFA80000,0xFFF00032,0xFFEC0032,0xFFD00001,0xF800003D,0xF5FC003D,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0x1C80048,0xFFBC0001,0xFFBC0001,0xFFBC0001,0xFFBC0001,0xFFBC0001, -0xFFBC0001,0xEFBC0001,0xEFBC0001,0xEFBC0001,0xE9BC0001,0xAFFC0048,0xAFFC0048,0xAFFC0048,0xAFFC0048,0xAFFC0048,0xAFFC0048,0xF3A80001,0xF3A80001,0xF3A80001,0xE9B00001,0xD7FC0048,0xD7FC0048,0xD7FC0048,0xE98C0001,0xE200004A,0xFBC40034,0x1C80048,0x1C80048,0xFBC40020,0xFDC00014,0xFDC00008,0xFDC00008,0xFBBC0000,0xF5C40032,0xFFBC001D,0xF7B80000,0xF3A80001, -0xCDFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table62[] = { -0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xDBF80000, -0xDBF80000,0xDBF80000,0xDBF80000,0xE4000001,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0xDE80000,0xDE80000,0xDE80000,0xB5FC0000,0xD1FC0000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000, -0xD9FC0000,0xEDF80000,0xEDF80000,0xEDF80000,0xF0000001,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xEDF80000,0xEDF80000,0xEDF80000,0xF0000001,0xEDF80000,0xEDF80000,0xEDF80000,0xF0000001,0xF0000001,0x37FC0000,0x1E40000,0x1E40000,0xA7FC0000,0xC1FC0000,0xCFFC0000,0xCFFC0000,0xE1FC0000,0xA7FC0000,0xC1FC0000,0xE7FC0000,0xEDF80000, -0xE7FC0000,0x1F80000,0x1F80000,0x1F80000,0x1F80000,0xF7FC0000,0xF7FC0000,0xF7FC0000,0xFBFC0000,0xFBFC0000,0xFA000001,0xF7FC0000,0xF7FC0000,0xF7FC0000,0xFBFC0000,0xFBFC0000,0xFA000001,0xFBFC0000,0xFBFC0000,0xFA000001,0xFA000001,0xF7FC0000,0xF7FC0000,0xF7FC0000,0xFBFC0000,0xFBFC0000,0xFA000001,0xFBFC0000,0xFBFC0000,0xFA000001,0xFA000001,0xFBFC0000, -0xFBFC0000,0xFA000001,0xFA000001,0xFA000001,0xEDFC0000,0xD7FC0000,0x1F80000,0xF5FC0000,0xF9FC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xF3FC0000,0xF7FC0000,0xFBFC0000,0xFA000001,0xFBFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1E80181,0xFFE80139,0xFFE40104,0xFFE400F4,0xFFE000FD,0xFFE000B2,0xFFDC0090,0xFFD80075,0xFFD80051,0xFDD8004D,0xFFDC00FD,0xFFDC00A8,0xFFDC0084,0xFFD80051,0xFFD00021,0xFFD00011,0xFFCC0072,0xFFCC0032,0xFDCC000E,0xF9CC005E,0xE3FC017F,0xFFD80118,0xFFD400F3,0xFFCC00A9,0xFFCC0069,0xFDC8004D,0xFFC000AE,0xFFB80045,0xFDB40006,0xF9B8005E,0xF1F8017F, -0xFFA800F3,0xFD90004D,0xF97C005E,0xF400017F,0xFFE40135,0xFDE8015D,0xFDE8016C,0xFFE000F5,0xFFDC00A3,0xFFD40055,0xFFD00038,0xFFD0000E,0xFFE40142,0xFFDC00E3,0xFFD0004E,0xFDB40006,0xEDFC017F,0x1F4005D,0xFDF0004D,0xFFF00038,0xFFEC0034,0xFFEC003D,0xFFEC0022,0xFFE80014,0xFFE40011,0xFFE40001,0xFDE40005,0xF1FC005D,0xFFEC0043,0xFFE40034,0xFFE40021,0xFFD80009, -0xFDD80005,0xF9F8005D,0xFFCC0032,0xFDB40005,0xF800005E,0xF1FC005D,0xFFEC0043,0xFFE40034,0xFFE40021,0xFFD80009,0xFDD80005,0xF9F8005D,0xFFCC0032,0xFDB40005,0xF800005E,0xF9F8005D,0xFFCC0032,0xFDB40005,0xF800005E,0xF800005E,0xFDF00051,0xF3F4005D,0xF3F4005D,0xFFEC0042,0xFFE80030,0xFFE4001B,0xFFE0000D,0xFFD80008,0xFBF00051,0xFFE80044,0xFFDC0033,0xFDB40005, -0xF7FC005D,0x1E400F4,0x1E400F4,0x1E400F4,0x1E400F4,0xFFDC0090,0xFFDC0090,0xFFDC0090,0xFFD80051,0xFFD80051,0xFBD80049,0xFFDC0084,0xFFDC0084,0xFFDC0084,0xFFD00021,0xFFD00021,0xFDD0000E,0xFFCC0032,0xFFCC0032,0xFBCC0005,0xF7CC0032,0xD5FC00F3,0xD5FC00F3,0xD5FC00F3,0xFFCC0069,0xFFCC0069,0xFBC80049,0xFFB80045,0xFFB80045,0xFBB80002,0xF7BC0032,0xEBF800F3, -0xEBF800F3,0xFB980049,0xF7840032,0xF00000F3,0xFBE000C9,0xF9E000E1,0x1E400F4,0xFFDC0095,0xFFD80068,0xFFD40045,0xFFD00038,0xFFD0000E,0xFDE000CA,0xFFDC0092,0xFFD0004D,0xFBB80002,0xE5FC00F3,0x1EC0034,0x1EC0034,0x1EC0034,0x1EC0034,0xFFE80014,0xFFE80014,0xFFE80014,0xFFE40001,0xFFE40001,0xFBE40001,0xE9FC0032,0xE9FC0032,0xE9FC0032,0xFFD80009,0xFFD80009, -0xFBDC0001,0xF3FC0032,0xF3FC0032,0xFBC00001,0xF6000032,0xE9FC0032,0xE9FC0032,0xE9FC0032,0xFFD80009,0xFFD80009,0xFBDC0001,0xF3FC0032,0xF3FC0032,0xFBC00001,0xF6000032,0xF3FC0032,0xF3FC0032,0xFBC00001,0xF6000032,0xF6000032,0xFBEC0029,0xFFEC0029,0x1EC0034,0xF9EC0029,0xFDE80020,0xFFE40012,0xFFE0000D,0xFFD80008,0xF9EC0029,0xFFE80020,0xF1FC0032,0xFBC00001, -0xF1FC0032,0x1FC0005,0xFFF80004,0xFFF80001,0xFFF80000,0xFBFC0005,0xFFF80002,0xFFF40000,0xFDF80005,0xFFEC0000,0xFC000005,0xFBFC0005,0xFFF80002,0xFFF40000,0xFDF80005,0xFFEC0000,0xFC000005,0xFDF80005,0xFFEC0000,0xFC000005,0xFC000005,0xFBFC0005,0xFFF80002,0xFFF40000,0xFDF80005,0xFFEC0000,0xFC000005,0xFDF80005,0xFFEC0000,0xFC000005,0xFC000005,0xFDF80005, -0xFFEC0000,0xFC000005,0xFC000005,0xFC000005,0xFFF80004,0xE7FC0005,0xF7FC0005,0xFBFC0005,0xFFF80002,0xFFF00001,0xFFF00000,0xFFE40000,0xF9FC0005,0xFBFC0005,0xFFF00000,0xFC000005,0xFDF80005,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0x1D80048,0xFFD00008,0xFFD00008,0xFFD00008,0xFFD00008,0xFFD00008, -0xFFD00008,0xF7CC0001,0xF7CC0001,0xF7CC0001,0xF1CC0001,0xC7FC0048,0xC7FC0048,0xC7FC0048,0xC7FC0048,0xC7FC0048,0xC7FC0048,0xFBB80001,0xFBB80001,0xFBB80001,0xF1C00001,0xE3FC0048,0xE3FC0048,0xE3FC0048,0xF19C0001,0xEA00004A,0xF5D8003D,0x1D80048,0x1D80048,0xFDD40029,0xFFD0001D,0xFDD00014,0xFDD00014,0xFFCC0004,0xFDD40032,0xFFD00022,0xFFC80000,0xFBB80001, -0xDDF80048,}; -static const uint32_t g_etc1_to_bc7_m6_table63[] = { -0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xE7F80000, -0xE7F80000,0xE7F80000,0xE7F80000,0xEC000001,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1FC0000,0x1FC0000,0x1FC0000,0xCDFC0000,0xDFFC0000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0xF1FC0000,0xF1FC0000,0xF1FC0000,0xF1FC0000,0xF1FC0000, -0xF1FC0000,0xF9F80000,0xF9F80000,0xF9F80000,0xF8000001,0xF1FC0000,0xF1FC0000,0xF1FC0000,0xF1FC0000,0xF1FC0000,0xF1FC0000,0xF9F80000,0xF9F80000,0xF9F80000,0xF8000001,0xF9F80000,0xF9F80000,0xF9F80000,0xF8000001,0xF8000001,0xB7FC0000,0x1F40000,0x1F40000,0xDFFC0000,0xE9FC0000,0xEFFC0000,0xEFFC0000,0xF3FC0000,0xDFFC0000,0xE9FC0000,0xF7FC0000,0xF9F80000, -0xF7FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1F400C2,0xFDF000B2,0xFFF0009D,0xFFF00099,0xFFEC0098,0xFFEC007D,0xFFEC0074,0xFFEC0062,0xFFE80058,0xFFE80048,0xFFEC0089,0xFFE80069,0xFFE80059,0xFFE40040,0xFFE40030,0xFFE0001D,0xFFE40031,0xFFE0001D,0xFFDC0001,0xFDDC0011,0xEFFC00C2,0xFFEC00A7,0xFFE80099,0xFFE40070,0xFFE40060,0xFFDC0048,0xFFD80059,0xFFD80035,0xFFCC0009,0xFDCC0011,0xF7F800C2, -0xFFD40099,0xFFB80048,0xFD9C0011,0xF80000C2,0xFDF000B0,0xF3F400C2,0xF3F400C2,0xFFF0008E,0xFFEC006D,0xFFE8004A,0xFFE8003D,0xFFE40022,0xFFF000A2,0xFFF0008E,0xFFE0003F,0xFFCC0009,0xF5FC00C2,0x1FC0012,0xFFF80011,0xFFF8000E,0xFFF8000D,0xFFF8000C,0xFFF80009,0xFFF80008,0xFFF80006,0xFFF40004,0xFFF40000,0xFBFC0011,0xFFF8000E,0xFFF4000D,0xFFF00008,0xFFF00004, -0xFFF00000,0xFDF80011,0xFFEC000D,0xFFE00000,0xFC000011,0xFBFC0011,0xFFF8000E,0xFFF4000D,0xFFF00008,0xFFF00004,0xFFF00000,0xFDF80011,0xFFEC000D,0xFFE00000,0xFC000011,0xFDF80011,0xFFEC000D,0xFFE00000,0xFC000011,0xFC000011,0xFFF80011,0xF7FC0012,0xF7FC0012,0xFFF8000C,0xFFF4000E,0xFFF40006,0xFFF40005,0xFFEC0004,0xFFF8000C,0xFBFC0011,0xFFF0000D,0xFFE00000, -0xFDF80011,0x1F00099,0x1F00099,0x1F00099,0x1F00099,0xFFEC0074,0xFFEC0074,0xFFEC0074,0xFFE80058,0xFFE80058,0xFFE80048,0xFFE80059,0xFFE80059,0xFFE80059,0xFFE40030,0xFFE40030,0xFFE0001D,0xFFE0001D,0xFFE0001D,0xFFDC0001,0xFDDC000D,0xEBFC0099,0xEBFC0099,0xEBFC0099,0xFFE40060,0xFFE40060,0xFFDC0048,0xFFD80035,0xFFD80035,0xFFCC0009,0xFDCC000D,0xF5FC0099, -0xF5FC0099,0xFFB80048,0xFD9C000D,0xF600009A,0xFFEC0089,0xFFEC0090,0x1F00099,0xFFE80074,0xFFEC005D,0xFFE80046,0xFFE8003D,0xFFE40022,0xFBEC0089,0xFFE80072,0xFFE0003E,0xFFCC0009,0xF3FC0099,0x1F8000D,0x1F8000D,0x1F8000D,0x1F8000D,0xFFF80008,0xFFF80008,0xFFF80008,0xFFF40004,0xFFF40004,0xFFF40000,0xF7FC000D,0xF7FC000D,0xF7FC000D,0xFFF00004,0xFFF00004, -0xFFF00000,0xFBFC000D,0xFBFC000D,0xFFE00000,0xFC00000D,0xF7FC000D,0xF7FC000D,0xF7FC000D,0xFFF00004,0xFFF00004,0xFFF00000,0xFBFC000D,0xFBFC000D,0xFFE00000,0xFC00000D,0xFBFC000D,0xFBFC000D,0xFFE00000,0xFC00000D,0xFC00000D,0xF5FC000D,0xF5F8000D,0x1F8000D,0xFFF80008,0xFFF4000A,0xFFF40005,0xFFF40005,0xFFEC0004,0xFFF80008,0xFFF4000A,0xFBFC000D,0xFFE00000, -0xFBFC000D,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0x1E80048,0xFFE0001D,0xFFE0001D,0xFFE0001D,0xFFE0001D,0xFFE0001D, -0xFFE0001D,0xFFDC0001,0xFFDC0001,0xFFDC0001,0xF9DC0001,0xDFFC0048,0xDFFC0048,0xDFFC0048,0xDFFC0048,0xDFFC0048,0xDFFC0048,0xFFCC0009,0xFFCC0009,0xFFCC0009,0xF9D00001,0xEFFC0048,0xEFFC0048,0xEFFC0048,0xF9AC0001,0xF200004A,0xFDE8003D,0x1E80048,0x1E80048,0xFDE40034,0xFFE40029,0xFFE00028,0xFFE00028,0xFFE00014,0xF9E8003D,0xFFE40032,0xFFDC000A,0xFFCC0009, -0xEBFC0048,}; -static const uint32_t g_etc1_to_bc7_m6_table64[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x100001,0x100001,0x100001,0x100001,0x2180000,0x2180000,0x2180000,0x300000,0x300000,0x8000000,0x2180000,0x2180000,0x2180000,0x300000,0x300000,0x8000000,0x300000,0x300000,0x8000000,0x8000000,0x2180000,0x2180000,0x2180000,0x300000,0x300000,0x8000000,0x300000,0x300000,0x8000000,0x8000000,0x300000, -0x300000,0x8000000,0x8000000,0x8000000,0x140000,0x140000,0x100001,0x180000,0x1C0000,0x240000,0x280000,0x3C0000,0x2140000,0x2180000,0x240000,0x8000000,0x240000,0x380001,0x540000,0xAC0000,0x1C000000,0x540000,0xAC0000,0x1C000000,0xAC0000,0x1C000000,0x1C000000,0x540000,0xAC0000,0x1C000000,0xAC0000,0x1C000000, -0x1C000000,0xAC0000,0x1C000000,0x1C000000,0x1C000000,0x540000,0xAC0000,0x1C000000,0xAC0000,0x1C000000,0x1C000000,0xAC0000,0x1C000000,0x1C000000,0x1C000000,0xAC0000,0x1C000000,0x1C000000,0x1C000000,0x1C000000,0x480000,0x63C0000,0x63C0000,0x600000,0x8C0000,0x1140000,0x1C000000,0x1C000000,0x24C0000,0x6C0000,0xFD00000,0x1C000000, -0x780000,0x140232,0x4E080039,0x28080039,0x1C040039,0x380000C8,0x28000011,0x1C000001,0x1C0000C8,0x16000048,0x120000C8,0x260001B9,0x22000096,0x18000051,0x18000110,0x16000088,0x120000EC,0x120001B9,0x1000010D,0x10000149,0xC0001B9,0x1C0232,0x1E000109,0x18000091,0x18000150,0x140000BB,0x12000110,0x120001DD,0x10000131,0xE000165,0xC0001C9,0x300232, -0x10000186,0xA0001AA,0xA0001F2,0x8000232,0x7400007B,0xFA0400D2,0xFE0C0082,0x3400007B,0x2200008A,0x1A00007B,0x16000061,0x140000B5,0x460000F1,0x280000BD,0x160000CB,0xE000165,0x240232,0x1801BA,0x4E080029,0x28080029,0x1C080029,0x380000C8,0x28000011,0x1C000001,0x1C0000C8,0x16000048,0x120000C8,0x22401B9,0x22000096,0x18000051,0x18000110,0x16000088, -0x120000EC,0x4C01B9,0x1000010D,0x10000149,0xC0001B9,0x22401B9,0x22000096,0x18000051,0x18000110,0x16000088,0x120000EC,0x4C01B9,0x1000010D,0x10000149,0xC0001B9,0x4C01B9,0x1000010D,0x10000149,0xC0001B9,0xC0001B9,0x7400007B,0xFA0400CE,0xFE0C005E,0x3400007B,0x2200008A,0x1A00007B,0x16000061,0x140000B5,0x500000DB,0x280000B4,0x160000CA,0x10000149, -0x3401B9,0x40039,0x40039,0x40039,0x40039,0x1A000000,0x1A000000,0x1A000000,0xC000000,0xC000000,0x8000000,0xA000029,0xA000029,0xA000029,0xC000010,0xC000010,0x6000008,0x6000029,0x6000029,0x4000019,0x4000029,0x80036,0x80036,0x80036,0x6000018,0x6000018,0x600000C,0x600002D,0x600002D,0x400001D,0x400002D,0xC0036, -0xC0036,0x4000022,0x2000031,0x2000036,0x3600000A,0x88000000,0x40039,0x1C000011,0x1000000D,0xC00000D,0xC00000A,0xA000011,0x1600001A,0x10000013,0x6000029,0x400001D,0xC0036,0x80029,0x80029,0x80029,0x80029,0x1A000000,0x1A000000,0x1A000000,0xC000000,0xC000000,0x8000000,0xC0029,0xC0029,0xC0029,0xC000010,0xC000010, -0x6000008,0x140029,0x140029,0x4000019,0x4000029,0xC0029,0xC0029,0xC0029,0xC000010,0xC000010,0x6000008,0x140029,0x140029,0x4000019,0x4000029,0x140029,0x140029,0x4000019,0x4000029,0x4000029,0x3600000A,0x88000000,0x80029,0x1C000011,0x1000000D,0xC00000D,0xC00000A,0xA000011,0x16000019,0x10000012,0x100029,0x4000019, -0x100029,0x2400CA,0x42140001,0x26100001,0x1C100001,0x3800C8,0x28000011,0x1C000001,0x7000C8,0x16000048,0x120000C8,0x3800C8,0x28000011,0x1C000001,0x7000C8,0x16000048,0x120000C8,0x7000C8,0x16000048,0x120000C8,0x120000C8,0x3800C8,0x28000011,0x1C000001,0x7000C8,0x16000048,0x120000C8,0x7000C8,0x16000048,0x120000C8,0x120000C8,0x7000C8, -0x16000048,0x120000C8,0x120000C8,0x120000C8,0x7400004A,0x2800C8,0xF418000D,0x3C000041,0x2A000049,0x1E000041,0x18000034,0x18000061,0x50000062,0x34000050,0x1C000028,0x120000C8,0x5000C8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table65[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x200001,0x200001,0x200001,0x200001,0x2300000,0x2300000,0x2300000,0x640000,0x640000,0x10000000,0x2300000,0x2300000,0x2300000,0x640000,0x640000,0x10000000,0x640000,0x640000,0x10000000,0x10000000,0x2300000,0x2300000,0x2300000,0x640000,0x640000,0x10000000,0x640000,0x640000,0x10000000,0x10000000,0x640000, -0x640000,0x10000000,0x10000000,0x10000000,0x280000,0x240000,0x200001,0x22C0000,0x380000,0x480000,0x500000,0x780000,0x2280000,0x2300000,0x480000,0x10000000,0x480000,0x480001,0x6C0000,0xDC0000,0x24000000,0x6C0000,0xDC0000,0x24000000,0xDC0000,0x24000000,0x24000000,0x6C0000,0xDC0000,0x24000000,0xDC0000,0x24000000, -0x24000000,0xDC0000,0x24000000,0x24000000,0x24000000,0x6C0000,0xDC0000,0x24000000,0xDC0000,0x24000000,0x24000000,0xDC0000,0x24000000,0x24000000,0x24000000,0xDC0000,0x24000000,0x24000000,0x24000000,0x24000000,0x5C0000,0xE4C0000,0xE4C0000,0x7C0000,0xB40000,0x1600000,0x24000000,0x24000000,0x640000,0x880000,0x17E00000,0x24000000, -0x9C0000,0x1C03A2,0x620C00C1,0x320C00C2,0x240C00C1,0x500000C8,0x34000001,0x26000014,0x260000CA,0x20000029,0x1A0000C8,0x360002AE,0x2E0000FE,0x220000A1,0x22000153,0x1E000098,0x18000110,0x1A0002AE,0x160001A9,0x160001C9,0x100002B1,0x2803A2,0x280001B3,0x2200011A,0x220001CC,0x1E0000FC,0x18000150,0x180002F1,0x160001E9,0x14000205,0x100002D5,0x4C03A2, -0x1600028A,0x10000282,0x1000032A,0xC0003A2,0x96000085,0xFE0C0142,0xF2140189,0x48000099,0x360000A2,0x26000098,0x1E000065,0x1C0000E0,0x6400015C,0x3C0000E9,0x1E000145,0x14000205,0x3403A2,0x2402AE,0x5E100091,0x32100091,0x24100091,0x500000C8,0x34000001,0x26040011,0x260000CA,0x20000029,0x1A0000C8,0x3402AE,0x2E0000FE,0x220000A1,0x22000153,0x1E000098, -0x18000110,0x6802AE,0x160001A9,0x160001C9,0x100002B1,0x3402AE,0x2E0000FE,0x220000A1,0x22000153,0x1E000098,0x18000110,0x6802AE,0x160001A9,0x160001C9,0x100002B1,0x6802AE,0x160001A9,0x160001C9,0x100002B1,0x100002B1,0x96000085,0xFE0C011E,0xF418010D,0x48000099,0x360000A2,0x26000098,0x1E000065,0x1C0000E0,0x64000138,0x3C0000D9,0x1E000141,0x160001C9, -0x4C02AE,0xC00C1,0xC00C1,0xC00C1,0xC00C1,0x32000000,0x32000000,0x32000000,0x18000000,0x18000000,0x10000000,0x16000091,0x16000091,0x16000091,0x12000034,0x12000034,0xE00001D,0xC000091,0xC000091,0xA000055,0x8000091,0x1000C1,0x1000C1,0x1000C1,0x12000058,0x12000058,0xC000030,0xC0000A1,0xC0000A1,0xA000065,0x6000099,0x2000C1, -0x2000C1,0xA000086,0x60000AE,0x40000C2,0x6000002D,0xF8000001,0xC00C1,0x3200003A,0x1E000034,0x1A00003A,0x1600002D,0xE000048,0x3400005E,0x26000054,0xE000092,0xA000065,0x1800C1,0x100091,0x100091,0x100091,0x100091,0x32000000,0x32000000,0x32000000,0x18000000,0x18000000,0x10000000,0x180091,0x180091,0x180091,0x12000034,0x12000034, -0xE00001D,0x2C0091,0x2C0091,0xA000055,0x8000091,0x180091,0x180091,0x180091,0x12000034,0x12000034,0xE00001D,0x2C0091,0x2C0091,0xA000055,0x8000091,0x2C0091,0x2C0091,0xA000055,0x8000091,0x8000091,0x6000002D,0xF8000001,0x100091,0x3200003A,0x1E000034,0x1A00003A,0x1600002D,0xE000048,0x34000055,0x26000050,0x200091,0xA000055, -0x200091,0x3400CA,0x4A240001,0x2E200001,0x24200001,0x5000C8,0x34000001,0x240C0001,0xA000C8,0x20000029,0x1A0000C8,0x5000C8,0x34000001,0x240C0001,0xA000C8,0x20000029,0x1A0000C8,0xA000C8,0x20000029,0x1A0000C8,0x1A0000C8,0x5000C8,0x34000001,0x240C0001,0xA000C8,0x20000029,0x1A0000C8,0xA000C8,0x20000029,0x1A0000C8,0x1A0000C8,0xA000C8, -0x20000029,0x1A0000C8,0x1A0000C8,0x1A0000C8,0xA400002D,0x43800C8,0xFC28000D,0x52000022,0x36000029,0x28000029,0x22000014,0x20000041,0x72000048,0x46000034,0x2400000D,0x1A0000C8,0x7000C8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table66[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0x140000,0x140000,0x140000,0x140000,0x140000, -0x140000,0x240000,0x240000,0x240000,0x6000000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x240000,0x240000,0x240000,0x6000000,0x240000,0x240000,0x240000,0x6000000,0x6000000,0xE0C0000,0xC0001,0xC0001,0x100000,0x100000,0x2100000,0x2100000,0x2140000,0x100000,0x100000,0x1C0000,0x240000, -0x1C0000,0x300001,0x300001,0x300001,0x300001,0x480000,0x480000,0x480000,0x940000,0x940000,0x18000000,0x480000,0x480000,0x480000,0x940000,0x940000,0x18000000,0x940000,0x940000,0x18000000,0x18000000,0x480000,0x480000,0x480000,0x940000,0x940000,0x18000000,0x940000,0x940000,0x18000000,0x18000000,0x940000, -0x940000,0x18000000,0x18000000,0x18000000,0x4380000,0x2340000,0x300001,0x440000,0x540000,0x680000,0x780000,0xB40000,0x23C0000,0x480000,0x680000,0x18000000,0x680000,0x580001,0x840000,0x10C0000,0x2C000000,0x840000,0x10C0000,0x2C000000,0x10C0000,0x2C000000,0x2C000000,0x840000,0x10C0000,0x2C000000,0x10C0000,0x2C000000, -0x2C000000,0x10C0000,0x2C000000,0x2C000000,0x2C000000,0x840000,0x10C0000,0x2C000000,0x10C0000,0x2C000000,0x2C000000,0x10C0000,0x2C000000,0x2C000000,0x2C000000,0x10C0000,0x2C000000,0x2C000000,0x2C000000,0x2C000000,0x700000,0x600000,0x600000,0x2940000,0xDC0000,0x1B00000,0x2C000000,0x2C000000,0x2780000,0xA80000,0x1FF00000,0x2C000000, -0xBC0000,0x2804C3,0x7414014E,0x3C14014F,0x2C14014E,0x600800E1,0x4008001A,0x2C0C0049,0x300800E3,0x28040036,0x220800E1,0x4E0002D3,0x3A0000CD,0x2C0000A4,0x2E00011A,0x2800003D,0x220000D8,0x260002D3,0x2000017A,0x1C0001A0,0x180002D4,0x3804C1,0x34000216,0x2800016D,0x280001F7,0x280000E6,0x22000151,0x22000354,0x200001F3,0x1C000204,0x18000314,0x7004C1, -0x1C00031D,0x1A000305,0x160003C9,0x120004C1,0xC2000036,0xF41801F1,0xF8200266,0x6600003E,0x40000049,0x34000043,0x2A000015,0x24000084,0x82000121,0x5000009F,0x26000118,0x1C000204,0x5004C1,0x3402D3,0x662000A2,0x3A2000A2,0x2C2000A2,0x581000C9,0x3C100002,0x2E100015,0x300C00C9,0x2A080026,0x220C00C9,0x4C02D3,0x3A0000CD,0x2C0400A2,0x2E00011A,0x2800003D, -0x220000D8,0x9802D3,0x2000017A,0x1C0001A0,0x180002D4,0x4C02D3,0x3A0000CD,0x2C0400A2,0x2E00011A,0x2800003D,0x220000D8,0x9802D3,0x2000017A,0x1C0001A0,0x180002D4,0x9802D3,0x2000017A,0x1C0001A0,0x180002D4,0x180002D4,0xC2000036,0xF8200139,0xFC280126,0x6600003E,0x40000049,0x34000043,0x2A000015,0x24000084,0x900000DD,0x50000086,0x26000114,0x1C0001A0, -0x6C02D3,0x14014E,0x14014E,0x14014E,0x14014E,0x42080019,0x42080019,0x42080019,0x22080019,0x22080019,0x18080019,0x300000A2,0x300000A2,0x300000A2,0x22000011,0x22000011,0x18000001,0x160000A4,0x160000A4,0x14000041,0xE0000A4,0x20014D,0x20014D,0x20014D,0x1E00007D,0x1E00007D,0x14000041,0x120000D8,0x120000D8,0x1200006C,0xE0000BD,0x3C014D, -0x3C014D,0x100000C9,0xA000105,0xA00014D,0xA000000D,0xFE0C002E,0x14014E,0x50000019,0x32000019,0x2A000014,0x2600000D,0x20000025,0x56000063,0x3C000042,0x1E0000A6,0x1200006C,0x2C014D,0x2000A2,0x2000A2,0x2000A2,0x2000A2,0x3A100001,0x3A100001,0x3A100001,0x20100001,0x20100001,0x180C0001,0x3000A2,0x3000A2,0x3000A2,0x22000011,0x22000011, -0x18000001,0x5C00A2,0x5C00A2,0x14000041,0xE0000A4,0x3000A2,0x3000A2,0x3000A2,0x22000011,0x22000011,0x18000001,0x5C00A2,0x5C00A2,0x14000041,0xE0000A4,0x5C00A2,0x5C00A2,0x14000041,0xE0000A4,0xE0000A4,0xA000000D,0xF0100005,0x2000A2,0x50000019,0x32000019,0x2A000014,0x2600000D,0x20000025,0x64000041,0x3C000032,0x4000A2,0x14000041, -0x4000A2,0x4400CA,0x52340001,0x36300001,0x2C300001,0x6800C8,0x3C100001,0x2C1C0001,0xD000C8,0x2A000014,0x220000C8,0x6800C8,0x3C100001,0x2C1C0001,0xD000C8,0x2A000014,0x220000C8,0xD000C8,0x2A000014,0x220000C8,0x220000C8,0x6800C8,0x3C100001,0x2C1C0001,0xD000C8,0x2A000014,0x220000C8,0xD000C8,0x2A000014,0x220000C8,0x220000C8,0xD000C8, -0x2A000014,0x220000C8,0x220000C8,0x220000C8,0xC4040019,0xC4800C8,0xF4380012,0x6600000D,0x42040019,0x36000011,0x2C000004,0x28000029,0x94000032,0x58000019,0x2E000001,0x220000C8,0x9400C8,0x80019,0x80019,0x80019,0x80019,0x80019,0x80019,0x80019,0x80019,0x80019,0x80019,0x14000000,0x14000000,0x14000000,0x14000000,0x14000000, -0x14000000,0xA000000,0xA000000,0xA000000,0x6000000,0x80019,0x80019,0x80019,0x80019,0x80019,0x80019,0x6000008,0x6000008,0x6000008,0x6000004,0xC0019,0xC0019,0xC0019,0x400000D,0x2000019,0x68000000,0x80019,0x80019,0x2E000000,0x20000000,0x18000000,0x18000000,0x10000000,0x20000008,0x20000004,0xC000001,0x6000008, -0xC0019,}; -static const uint32_t g_etc1_to_bc7_m6_table67[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000, -0x2C0000,0x580000,0x580000,0x580000,0xE000000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x580000,0x580000,0x580000,0xE000000,0x580000,0x580000,0x580000,0xE000000,0xE000000,0x200000,0x1C0001,0x1C0001,0x6200000,0x240000,0x280000,0x280000,0x300000,0x6200000,0x240000,0x3C0000,0x580000, -0x3C0000,0x400001,0x400001,0x400001,0x400001,0x600000,0x600000,0x600000,0xC40000,0xC40000,0x20000000,0x600000,0x600000,0x600000,0xC40000,0xC40000,0x20000000,0xC40000,0xC40000,0x20000000,0x20000000,0x600000,0x600000,0x600000,0xC40000,0xC40000,0x20000000,0xC40000,0xC40000,0x20000000,0x20000000,0xC40000, -0xC40000,0x20000000,0x20000000,0x20000000,0x4C0000,0xA440000,0x400001,0x580000,0x26C0000,0x8C0000,0xA00000,0xF00000,0x4500000,0x600000,0x8C0000,0x20000000,0x8C0000,0x680001,0x9C0000,0x13C0000,0x34000000,0x9C0000,0x13C0000,0x34000000,0x13C0000,0x34000000,0x34000000,0x9C0000,0x13C0000,0x34000000,0x13C0000,0x34000000, -0x34000000,0x13C0000,0x34000000,0x34000000,0x34000000,0x9C0000,0x13C0000,0x34000000,0x13C0000,0x34000000,0x34000000,0x13C0000,0x34000000,0x34000000,0x34000000,0x13C0000,0x34000000,0x34000000,0x34000000,0x34000000,0x840000,0x700000,0x700000,0xB00000,0x1000000,0x3F00000,0x34000000,0x34000000,0x900000,0xC40000,0x29C40000,0x34000000, -0xE00000,0x340627,0x80200222,0x46200222,0x34200222,0x72100139,0x4C100076,0x361400C1,0x3A10013B,0x320C0082,0x2A100139,0x660002D3,0x4C0000A5,0x360800C8,0x3C0000E9,0x32000009,0x2A0000C9,0x320002D3,0x2C00012A,0x26000161,0x200002D4,0x480625,0x400002BE,0x34000225,0x3400024F,0x2E000106,0x2800017D,0x2E0003BC,0x280001FB,0x24000204,0x1E00034C,0x940625, -0x26000412,0x200003A5,0x1C00047D,0x18000625,0xF8000009,0xFA2402DD,0xFE2C038E,0x7E00000B,0x5600000E,0x40000009,0x36000004,0x30000032,0xA40000F6,0x66000062,0x340000D4,0x24000204,0x680625,0x4402D3,0x6E3000A2,0x423000A2,0x343000A2,0x602000C9,0x44200002,0x36200015,0x381C00C9,0x32180026,0x2A1C00C9,0x6402D3,0x4C0000A5,0x341400A2,0x3C0000E9,0x32000009, -0x2A0400C8,0xCC02D3,0x2C00012A,0x26000161,0x200002D4,0x6402D3,0x4C0000A5,0x341400A2,0x3C0000E9,0x32000009,0x2A0400C8,0xCC02D3,0x2C00012A,0x26000161,0x200002D4,0xCC02D3,0x2C00012A,0x26000161,0x200002D4,0x200002D4,0xF8000009,0xFE2C0141,0xF438013B,0x7E00000B,0x5600000E,0x40000009,0x34040002,0x30000032,0xAC000086,0x68000035,0x340000CB,0x26000161, -0x9002D3,0x200222,0x200222,0x200222,0x200222,0x52100071,0x52100071,0x52100071,0x2C100071,0x2C100071,0x20100071,0x480000A2,0x480000A2,0x480000A2,0x2E000001,0x2E000001,0x2204000C,0x220000A2,0x220000A2,0x1C000020,0x160000A4,0x300222,0x300222,0x300222,0x280000C6,0x280000C6,0x1E000081,0x1E000118,0x1E000118,0x1A00007E,0x160000E4,0x5C0222, -0x5C0222,0x16000145,0x14000178,0xE000225,0xE8000000,0xF21400BD,0x200222,0x7A000004,0x50000001,0x3C000002,0x36000000,0x2A000005,0x8200006D,0x56000032,0x2C0000AB,0x1A00007E,0x400222,0x3000A2,0x3000A2,0x3000A2,0x3000A2,0x42200001,0x42200001,0x42200001,0x28200001,0x28200001,0x201C0001,0x24400A2,0x24400A2,0x24400A2,0x2E000001,0x2E000001, -0x200C0000,0x8C00A2,0x8C00A2,0x1C000020,0x160000A4,0x24400A2,0x24400A2,0x24400A2,0x2E000001,0x2E000001,0x200C0000,0x8C00A2,0x8C00A2,0x1C000020,0x160000A4,0x8C00A2,0x8C00A2,0x1C000020,0x160000A4,0x160000A4,0xE8000000,0xF8200005,0x3000A2,0x7A000004,0x50000001,0x3C000002,0x36000000,0x2A000005,0x96000028,0x5A000012,0x6400A2,0x1C000020, -0x6400A2,0x5400CA,0x5A440001,0x3E400001,0x34400001,0x8000C8,0x44200001,0x342C0001,0x10000C8,0x32000005,0x2A0000C8,0x8000C8,0x44200001,0x342C0001,0x10000C8,0x32000005,0x2A0000C8,0x10000C8,0x32000005,0x2A0000C8,0x2A0000C8,0x8000C8,0x44200001,0x342C0001,0x10000C8,0x32000005,0x2A0000C8,0x10000C8,0x32000005,0x2A0000C8,0x2A0000C8,0x10000C8, -0x32000005,0x2A0000C8,0x2A0000C8,0x2A0000C8,0xF8000008,0x5C00C8,0xFC480012,0x7E000002,0x56000005,0x3E040005,0x34080000,0x32000014,0xB6000020,0x6E00000A,0x36100001,0x2A0000C8,0xB400C8,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x2C000000,0x2C000000,0x2C000000,0x2C000000,0x2C000000, -0x2C000000,0x16000000,0x16000000,0x16000000,0xE000000,0x140071,0x140071,0x140071,0x140071,0x140071,0x140071,0x12000028,0x12000028,0x12000028,0xC000014,0x240071,0x240071,0x240071,0xA000041,0x6000071,0xE8000000,0x100071,0x100071,0x68000000,0x48000000,0x36000000,0x36000000,0x24000000,0x52000022,0x42000011,0x1C000004,0x12000028, -0x1C0071,}; -static const uint32_t g_etc1_to_bc7_m6_table68[] = { -0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x140000, -0x140000,0x140000,0x140000,0x2000001,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0xC0000,0x100000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000, -0x2440000,0x8C0000,0x8C0000,0x8C0000,0x16000001,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x8C0000,0x8C0000,0x8C0000,0x16000001,0x8C0000,0x8C0000,0x8C0000,0x16000001,0x16000001,0x340000,0x300000,0x300000,0x380000,0x3C0000,0x400000,0x400000,0x500000,0x380000,0x3C0000,0x640000,0x8C0000, -0x640000,0x540000,0x540000,0x540000,0x540000,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0x28000001,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0x28000001,0xFC0000,0xFC0000,0x28000001,0x28000001,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0x28000001,0xFC0000,0xFC0000,0x28000001,0x28000001,0xFC0000, -0xFC0000,0x28000001,0x28000001,0x28000001,0x2600000,0x4580000,0x540000,0x2700000,0x8C0000,0xB00000,0xCC0000,0x1340000,0x680000,0x7C0000,0xB00000,0x28000001,0xB00000,0x7C0000,0xB80000,0x1740000,0x3C000001,0xB80000,0x1740000,0x3C000001,0x1740000,0x3C000001,0x3C000001,0xB80000,0x1740000,0x3C000001,0x1740000,0x3C000001, -0x3C000001,0x1740000,0x3C000001,0x3C000001,0x3C000001,0xB80000,0x1740000,0x3C000001,0x1740000,0x3C000001,0x3C000001,0x1740000,0x3C000001,0x3C000001,0x3C000001,0x1740000,0x3C000001,0x3C000001,0x3C000001,0x3C000001,0x9C0000,0x840000,0x840000,0xD00000,0x12C0000,0xDF80000,0x3C000001,0x3C000001,0xA80000,0xE80000,0x31F40000,0x3C000001, -0x1080000,0x400738,0x8A3002D4,0x503002D4,0x3C3002D5,0x801C0190,0x581C00D5,0x3E24013A,0x461C0190,0x3A1C00D5,0x321C0192,0x7A0802D3,0x5A0800A2,0x421400FF,0x4A0800D1,0x3C080002,0x320C00D7,0x3C0802D4,0x380000FD,0x3000013B,0x2A0802D3,0x600734,0x5200031F,0x3C0802D4,0x46000252,0x3A000107,0x320001A4,0x3A0003C9,0x340001AE,0x2E0001B3,0x2800032C,0xC40734, -0x2C000479,0x2C0003F2,0x260004DF,0x20000734,0xFC100021,0xF23403D0,0xF63C049C,0x92080000,0x64080001,0x4A080002,0x3E0C0012,0x3A080011,0xD000008E,0x7E000018,0x3E0000AB,0x2E0001B3,0x8C0734,0x5402D4,0x764400A4,0x4A4400A4,0x3C4000A5,0x6C3000C8,0x4E300001,0x3E340015,0x403000C8,0x3A2C0026,0x323000CA,0x8002D3,0x580C00A2,0x3C2800A3,0x4C0000C9,0x3C080002, -0x341400CA,0x10002D3,0x380000ED,0x3000012B,0x2A0002D3,0x8002D3,0x580C00A2,0x3C2800A3,0x4C0000C9,0x3C080002,0x341400CA,0x10002D3,0x380000ED,0x3000012B,0x2A0002D3,0x10002D3,0x380000ED,0x3000012B,0x2A0002D3,0x2A0002D3,0xFE140009,0xFA44014C,0xFE4C0138,0x92080000,0x64080001,0x4A080002,0x3E140002,0x3A00000A,0xD000003D,0x7E000008,0x3E0000AB,0x3000012B, -0xB402D3,0x3002D4,0x3002D4,0x3002D4,0x3002D4,0x621C00C8,0x621C00C8,0x621C00C8,0x361C00C8,0x361C00C8,0x281C00C9,0x5A0800A2,0x5A0800A2,0x5A0800A2,0x3C080001,0x3C080001,0x2C0C0026,0x2E0800A2,0x2E0800A2,0x28040015,0x200800A2,0x4402D3,0x4402D3,0x4402D3,0x340000FE,0x340000FE,0x2A0000C9,0x2E00011D,0x2E00011D,0x2400005A,0x1E0000CE,0x8802D3, -0x8802D3,0x20000199,0x1C0001A3,0x160002D3,0xFE0C0009,0xFA240139,0x3002D4,0x92080000,0x60080001,0x4A080001,0x440C0006,0x36080002,0xB400004B,0x76000012,0x3E0000A2,0x2400005A,0x6002D3,0x4000A4,0x4000A4,0x4000A4,0x4000A4,0x4E300000,0x4E300000,0x4E300000,0x32300000,0x32300000,0x28300001,0x6000A2,0x6000A2,0x6000A2,0x38100001,0x38100001, -0x28200001,0xC400A2,0xC400A2,0x2600000D,0x200000A2,0x6000A2,0x6000A2,0x6000A2,0x38100001,0x38100001,0x28200001,0xC400A2,0xC400A2,0x2600000D,0x200000A2,0xC400A2,0xC400A2,0x2600000D,0x200000A2,0x200000A2,0xEA140000,0xF2340008,0x4000A4,0x92080000,0x5E0C0000,0x480C0000,0x3E140001,0x38040000,0xC200000D,0x7C000002,0x8C00A2,0x2600000D, -0x8C00A2,0x6800C8,0x66540000,0x46540001,0x3C540001,0x29800C8,0x4E300001,0x3C400001,0x13800C8,0x3C040001,0x320000CA,0x29800C8,0x4E300001,0x3C400001,0x13800C8,0x3C040001,0x320000CA,0x13800C8,0x3C040001,0x320000CA,0x320000CA,0x29800C8,0x4E300001,0x3C400001,0x13800C8,0x3C040001,0x320000CA,0x13800C8,0x3C040001,0x320000CA,0x320000CA,0x13800C8, -0x3C040001,0x320000CA,0x320000CA,0x320000CA,0xFE140008,0xE6C00C8,0xF65C0019,0x8E0C0000,0x64040001,0x4C040000,0x3C1C0001,0x3A00000A,0xD6040012,0x7E040002,0x40200000,0x320000CA,0xDC00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x40080000,0x40080000,0x40080000,0x40080000,0x40080000, -0x40080000,0x20080001,0x20080001,0x20080001,0x16080001,0x2800C8,0x2800C8,0x2800C8,0x2800C8,0x2800C8,0x2800C8,0x1E00002D,0x1E00002D,0x1E00002D,0x16000011,0x5000C8,0x5000C8,0x5000C8,0x10000062,0xC0000CA,0xFE0C0008,0x1C00C8,0x1C00C8,0x8E080000,0x64080000,0x4E080000,0x4E080000,0x34080000,0x92000022,0x74000009,0x28040001,0x1E00002D, -0x3800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table69[] = { -0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x240000,0x240000,0x240000,0x240000,0x240000,0x240000,0x240000,0x240000,0x240000,0x240000,0x440000, -0x440000,0x440000,0x440000,0xA000001,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x4180000,0x4180000,0x4180000,0x240000,0x300000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000, -0x25C0000,0xBC0000,0xBC0000,0xBC0000,0x1E000001,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0xBC0000,0xBC0000,0xBC0000,0x1E000001,0xBC0000,0xBC0000,0xBC0000,0x1E000001,0x1E000001,0x440000,0x400000,0x400000,0x4480000,0x500000,0x2540000,0x2540000,0x6C0000,0x4480000,0x500000,0x880000,0xBC0000, -0x880000,0x640000,0x640000,0x640000,0x640000,0x940000,0x940000,0x940000,0x12C0000,0x12C0000,0x30000001,0x940000,0x940000,0x940000,0x12C0000,0x12C0000,0x30000001,0x12C0000,0x12C0000,0x30000001,0x30000001,0x940000,0x940000,0x940000,0x12C0000,0x12C0000,0x30000001,0x12C0000,0x12C0000,0x30000001,0x30000001,0x12C0000, -0x12C0000,0x30000001,0x30000001,0x30000001,0x740000,0xC680000,0x640000,0x880000,0xA80000,0xD40000,0xF40000,0x1700000,0x7C0000,0x940000,0xD40000,0x30000001,0xD40000,0x8C0000,0xD00000,0x1A40000,0x44000001,0xD00000,0x1A40000,0x44000001,0x1A40000,0x44000001,0x44000001,0xD00000,0x1A40000,0x44000001,0x1A40000,0x44000001, -0x44000001,0x1A40000,0x44000001,0x44000001,0x44000001,0xD00000,0x1A40000,0x44000001,0x1A40000,0x44000001,0x44000001,0x1A40000,0x44000001,0x44000001,0x44000001,0x1A40000,0x44000001,0x44000001,0x44000001,0x44000001,0xB00000,0x2940000,0x2940000,0xEC0000,0x1540000,0x17F80000,0x44000001,0x44000001,0x2BC0000,0x1040000,0x3BC80000,0x44000001, -0x1280000,0x500738,0x924002D4,0x584002D4,0x444002D5,0x882C0190,0x602C00D5,0x4634013A,0x4E2C0190,0x422C00D5,0x3A2C0192,0x821802D3,0x621800A2,0x4A2400FF,0x521800D1,0x44180002,0x3A1C00D7,0x441802D4,0x401000FD,0x3810013B,0x321802D3,0x780734,0x620002DD,0x441802D4,0x520001E2,0x460000CF,0x3A080192,0x46000361,0x4000011E,0x3800012F,0x300002EB,0xF40734, -0x38000401,0x32000352,0x2C000477,0x28000734,0xFE20002A,0xFA4403D0,0xFE4C049C,0x9A180000,0x6C180001,0x52180002,0x461C0012,0x42180011,0xF6000022,0x8E080002,0x480C00A9,0x3800012F,0xAC0734,0x6402D4,0x7E5400A4,0x525400A4,0x445000A5,0x744000C8,0x56400001,0x46440015,0x484000C8,0x423C0026,0x3A4000CA,0x9802D3,0x601C00A2,0x443800A3,0x541000C9,0x44180002, -0x3C2400CA,0x13002D3,0x420000CB,0x380000FE,0x320002D3,0x9802D3,0x601C00A2,0x443800A3,0x541000C9,0x44180002,0x3C2400CA,0x13002D3,0x420000CB,0x380000FE,0x320002D3,0x13002D3,0x420000CB,0x380000FE,0x320002D3,0x320002D3,0xF8280011,0xF254015E,0xF65C014D,0x9A180000,0x6C180001,0x52180002,0x46240002,0x440C0005,0xFA000013,0x8E080001,0x4A0400A2,0x380000FE, -0xD802D3,0x4002D4,0x4002D4,0x4002D4,0x4002D4,0x6A2C00C8,0x6A2C00C8,0x6A2C00C8,0x3E2C00C8,0x3E2C00C8,0x302C00C9,0x621800A2,0x621800A2,0x621800A2,0x44180001,0x44180001,0x341C0026,0x361800A2,0x361800A2,0x30140015,0x281800A2,0x5C02D3,0x5C02D3,0x5C02D3,0x460000CE,0x460000CE,0x321000C9,0x3A0000D5,0x3A0000D5,0x2E000012,0x280000A3,0xB802D3, -0xB802D3,0x2A00015B,0x2400016B,0x1E0002D3,0xFC1C0011,0xF234014C,0x4002D4,0x9A180000,0x68180001,0x52180001,0x4C1C0006,0x3E180002,0xE400000D,0x8E080001,0x461000A2,0x2E000012,0x8002D3,0x5000A4,0x5000A4,0x5000A4,0x5000A4,0x56400000,0x56400000,0x56400000,0x3A400000,0x3A400000,0x30400001,0x7800A2,0x7800A2,0x7800A2,0x40200001,0x40200001, -0x30300001,0xF400A2,0xF400A2,0x30000002,0x280000A2,0x7800A2,0x7800A2,0x7800A2,0x40200001,0x40200001,0x30300001,0xF400A2,0xF400A2,0x30000002,0x280000A2,0xF400A2,0xF400A2,0x30000002,0x280000A2,0x280000A2,0xF2240000,0xFA440008,0x5000A4,0x9A180000,0x661C0000,0x501C0000,0x46240001,0x40140000,0xF4000004,0x8E080000,0xAC00A2,0x30000002, -0xAC00A2,0x7800C8,0x6E640000,0x4E640001,0x44640001,0x2B000C8,0x56400001,0x44500001,0x16800C8,0x44140001,0x3A0000CA,0x2B000C8,0x56400001,0x44500001,0x16800C8,0x44140001,0x3A0000CA,0x16800C8,0x44140001,0x3A0000CA,0x3A0000CA,0x2B000C8,0x56400001,0x44500001,0x16800C8,0x44140001,0x3A0000CA,0x16800C8,0x44140001,0x3A0000CA,0x3A0000CA,0x16800C8, -0x44140001,0x3A0000CA,0x3A0000CA,0x3A0000CA,0xF828000D,0x8000C8,0xFE6C0019,0x961C0000,0x6C140001,0x54140000,0x442C0001,0x44000002,0xF8040008,0x90080000,0x48300000,0x3A0000CA,0xFC00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x2C00C8,0x48180000,0x48180000,0x48180000,0x48180000,0x48180000, -0x48180000,0x28180001,0x28180001,0x28180001,0x1E180001,0x4000C8,0x4000C8,0x4000C8,0x4000C8,0x4000C8,0x4000C8,0x2E000009,0x2E000009,0x2E000009,0x1E040001,0x8000C8,0x8000C8,0x8000C8,0x1C00003A,0x140000CA,0xF61C000D,0x2C00C8,0x2C00C8,0x96180000,0x6C180000,0x56180000,0x56180000,0x3C180000,0xE0000004,0x86080001,0x30140001,0x2E000009, -0x5C00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table70[] = { -0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x740000, -0x740000,0x740000,0x740000,0x12000001,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0xC280000,0xC280000,0xC280000,0x3C0000,0x540000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000, -0x2740000,0xF00000,0xF00000,0xF00000,0x26000001,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0xF00000,0xF00000,0xF00000,0x26000001,0xF00000,0xF00000,0xF00000,0x26000001,0x26000001,0x2540000,0x500000,0x500000,0x5C0000,0x640000,0x6C0000,0x6C0000,0x840000,0x5C0000,0x640000,0xA80000,0xF00000, -0xA80000,0x740000,0x740000,0x740000,0x740000,0xAC0000,0xAC0000,0xAC0000,0x15C0000,0x15C0000,0x38000001,0xAC0000,0xAC0000,0xAC0000,0x15C0000,0x15C0000,0x38000001,0x15C0000,0x15C0000,0x38000001,0x38000001,0xAC0000,0xAC0000,0xAC0000,0x15C0000,0x15C0000,0x38000001,0x15C0000,0x15C0000,0x38000001,0x38000001,0x15C0000, -0x15C0000,0x38000001,0x38000001,0x38000001,0x6840000,0x7C0000,0x740000,0x9C0000,0x2C00000,0xF40000,0x11C0000,0x1AC0000,0x900000,0xAC0000,0xF40000,0x38000001,0xF40000,0x9C0000,0xE80000,0x1D80000,0x4C000001,0xE80000,0x1D80000,0x4C000001,0x1D80000,0x4C000001,0x4C000001,0xE80000,0x1D80000,0x4C000001,0x1D80000,0x4C000001, -0x4C000001,0x1D80000,0x4C000001,0x4C000001,0x4C000001,0xE80000,0x1D80000,0x4C000001,0x1D80000,0x4C000001,0x4C000001,0x1D80000,0x4C000001,0x4C000001,0x4C000001,0x1D80000,0x4C000001,0x4C000001,0x4C000001,0x4C000001,0xC40000,0xAA40000,0xAA40000,0x1040000,0x17C0000,0x21FC0000,0x4C000001,0x4C000001,0xD40000,0x1240000,0x43D80000,0x4C000001, -0x14C0000,0x600738,0x9A5002D4,0x605002D4,0x4C5002D5,0x903C0190,0x683C00D5,0x4E44013A,0x563C0190,0x4A3C00D5,0x423C0192,0x8A2802D3,0x6A2800A2,0x523400FF,0x5A2800D1,0x4C280002,0x422C00D7,0x4C2802D4,0x482000FD,0x4020013B,0x3A2802D3,0x900734,0x720402D3,0x4C2802D4,0x6200019A,0x4E1000CF,0x42180192,0x52000319,0x4A0000C6,0x420000E7,0x3A0002D4,0x1240734, -0x440003A9,0x3E0002E2,0x3600041C,0x30000734,0xFE34003D,0xF2540402,0xF65C04C1,0xA2280000,0x74280001,0x5A280002,0x4E2C0012,0x4A280011,0xFE100022,0x96180002,0x501C00A9,0x420000E7,0xD00734,0x7402D4,0x866400A4,0x5A6400A4,0x4C6000A5,0x7C5000C8,0x5E500001,0x4E540015,0x505000C8,0x4A4C0026,0x425000CA,0xB002D3,0x682C00A2,0x4C4800A3,0x5C2000C9,0x4C280002, -0x443400CA,0x16402D3,0x4A0000AD,0x420000E3,0x3A0002D3,0xB002D3,0x682C00A2,0x4C4800A3,0x5C2000C9,0x4C280002,0x443400CA,0x16402D3,0x4A0000AD,0x420000E3,0x3A0002D3,0x16402D3,0x4A0000AD,0x420000E3,0x3A0002D3,0x3A0002D3,0xFC380018,0xFA64015E,0xFE6C014D,0xA2280000,0x74280001,0x5A280002,0x4E340002,0x4C1C0005,0xFE100019,0x96180001,0x521400A2,0x420000E3, -0xF802D3,0x5002D4,0x5002D4,0x5002D4,0x5002D4,0x723C00C8,0x723C00C8,0x723C00C8,0x463C00C8,0x463C00C8,0x383C00C9,0x6A2800A2,0x6A2800A2,0x6A2800A2,0x4C280001,0x4C280001,0x3C2C0026,0x3E2800A2,0x3E2800A2,0x38240015,0x302800A2,0x7402D3,0x7402D3,0x7402D3,0x520800C9,0x520800C9,0x3A2000C9,0x460000AD,0x460000AD,0x38040002,0x300C00A2,0xE802D3, -0xE802D3,0x32000119,0x2C000126,0x260002D3,0xFE2C0016,0xFA44014C,0x5002D4,0xA2280000,0x70280001,0x5A280001,0x542C0006,0x46280002,0xFA0C0005,0x96180001,0x4E2000A2,0x38040002,0xA402D3,0x6000A4,0x6000A4,0x6000A4,0x6000A4,0x5E500000,0x5E500000,0x5E500000,0x42500000,0x42500000,0x38500001,0x9000A2,0x9000A2,0x9000A2,0x48300001,0x48300001, -0x38400001,0x12400A2,0x12400A2,0x38080001,0x300000A2,0x9000A2,0x9000A2,0x9000A2,0x48300001,0x48300001,0x38400001,0x12400A2,0x12400A2,0x38080001,0x300000A2,0x12400A2,0x12400A2,0x38080001,0x300000A2,0x300000A2,0xFA340000,0xF254000D,0x6000A4,0xA2280000,0x6E2C0000,0x582C0000,0x4E340001,0x48240000,0xFE0C0002,0x96180000,0xD000A2,0x38080001, -0xD000A2,0x8800C8,0x76740000,0x56740001,0x4C740001,0xC800C8,0x5E500001,0x4C600001,0x19800C8,0x4C240001,0x420000CA,0xC800C8,0x5E500001,0x4C600001,0x19800C8,0x4C240001,0x420000CA,0x19800C8,0x4C240001,0x420000CA,0x420000CA,0xC800C8,0x5E500001,0x4C600001,0x19800C8,0x4C240001,0x420000CA,0x19800C8,0x4C240001,0x420000CA,0x420000CA,0x19800C8, -0x4C240001,0x420000CA,0x420000CA,0x420000CA,0xFA3C0012,0x9000C8,0xF67C0020,0x9E2C0000,0x74240001,0x5C240000,0x4C3C0001,0x4C080001,0xFC14000A,0x98180000,0x50400000,0x420000CA,0x12000C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x3C00C8,0x50280000,0x50280000,0x50280000,0x50280000,0x50280000, -0x50280000,0x30280001,0x30280001,0x30280001,0x26280001,0x5800C8,0x5800C8,0x5800C8,0x5800C8,0x5800C8,0x5800C8,0x38040001,0x38040001,0x38040001,0x26140001,0xB000C8,0xB000C8,0xB000C8,0x24000022,0x1C0000CA,0xFE2C000D,0x3C00C8,0x3C00C8,0x9E280000,0x74280000,0x5E280000,0x5E280000,0x44280000,0xF40C0001,0x8E180001,0x38240001,0x38040001, -0x7C00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table71[] = { -0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0xA40000, -0xA40000,0xA40000,0xA40000,0x1A000001,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x3C0000,0x3C0000,0x3C0000,0x2500000,0x740000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000, -0x28C0000,0x1200000,0x1200000,0x1200000,0x2E000001,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x1200000,0x1200000,0x1200000,0x2E000001,0x1200000,0x1200000,0x1200000,0x2E000001,0x2E000001,0xA640000,0x600000,0x600000,0x700000,0x780000,0x2800000,0x2800000,0xA00000,0x700000,0x780000,0xCC0000,0x1200000, -0xCC0000,0x840000,0x840000,0x840000,0x840000,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x40000001,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x40000001,0x18C0000,0x18C0000,0x40000001,0x40000001,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x40000001,0x18C0000,0x18C0000,0x40000001,0x40000001,0x18C0000, -0x18C0000,0x40000001,0x40000001,0x40000001,0x2980000,0x8C0000,0x840000,0xB40000,0xDC0000,0x1180000,0x1400000,0x1E80000,0xA40000,0xC40000,0x1180000,0x40000001,0x1180000,0xAC0000,0x1000000,0x5F80000,0x54000001,0x1000000,0x5F80000,0x54000001,0x5F80000,0x54000001,0x54000001,0x1000000,0x5F80000,0x54000001,0x5F80000,0x54000001, -0x54000001,0x5F80000,0x54000001,0x54000001,0x54000001,0x1000000,0x5F80000,0x54000001,0x5F80000,0x54000001,0x54000001,0x5F80000,0x54000001,0x54000001,0x54000001,0x5F80000,0x54000001,0x54000001,0x54000001,0x54000001,0xD80000,0xB80000,0xB80000,0x1200000,0x1A40000,0x2BFC0000,0x54000001,0x54000001,0x2E80000,0x3400000,0x4BE80000,0x54000001, -0x16C0000,0x700738,0xA26002D4,0x686002D4,0x546002D5,0x984C0190,0x704C00D5,0x5654013A,0x5E4C0190,0x524C00D5,0x4A4C0192,0x923802D3,0x723800A2,0x5A4400FF,0x623800D1,0x54380002,0x4A3C00D7,0x543802D4,0x503000FD,0x4830013B,0x423802D3,0xA80734,0x7A1402D3,0x543802D4,0x6C080192,0x562000CF,0x4A280192,0x620002E3,0x540000A3,0x4A0000D7,0x421002D4,0x1580734, -0x4A000361,0x44000272,0x3E0003BF,0x38000734,0xFE440056,0xFA640402,0xFE6C04C1,0xAA380000,0x7C380001,0x62380002,0x563C0012,0x52380011,0xFE24003B,0x9E280002,0x582C00A9,0x4A0000D7,0xF00734,0x8402D4,0x8E7400A4,0x627400A4,0x547000A5,0x846000C8,0x66600001,0x56640015,0x586000C8,0x525C0026,0x4A6000CA,0x2C402D3,0x703C00A2,0x545800A3,0x643000C9,0x54380002, -0x4C4400CA,0x19402D3,0x540000A3,0x4A0000CE,0x420002D3,0x2C402D3,0x703C00A2,0x545800A3,0x643000C9,0x54380002,0x4C4400CA,0x19402D3,0x540000A3,0x4A0000CE,0x420002D3,0x19402D3,0x540000A3,0x4A0000CE,0x420002D3,0x420002D3,0xFC4C001D,0xF2740174,0xF67C0164,0xAA380000,0x7C380001,0x62380002,0x56440002,0x542C0005,0xFE240022,0x9E280001,0x5A2400A2,0x4A0000CE, -0x11C02D3,0x6002D4,0x6002D4,0x6002D4,0x6002D4,0x7A4C00C8,0x7A4C00C8,0x7A4C00C8,0x4E4C00C8,0x4E4C00C8,0x404C00C9,0x723800A2,0x723800A2,0x723800A2,0x54380001,0x54380001,0x443C0026,0x463800A2,0x463800A2,0x40340015,0x383800A2,0x8C02D3,0x8C02D3,0x8C02D3,0x5A1800C9,0x5A1800C9,0x423000C9,0x540000A2,0x540000A2,0x40140002,0x381C00A2,0x11802D3, -0x11802D3,0x3E0000F1,0x360000FB,0x2E0002D3,0xF840001D,0xF2540161,0x6002D4,0xAA380000,0x78380001,0x62380001,0x5C3C0006,0x4E380002,0xFC1C000A,0x9E280001,0x563000A2,0x40140002,0xC802D3,0x7000A4,0x7000A4,0x7000A4,0x7000A4,0x66600000,0x66600000,0x66600000,0x4A600000,0x4A600000,0x40600001,0xA800A2,0xA800A2,0xA800A2,0x50400001,0x50400001, -0x40500001,0x15800A2,0x15800A2,0x40180001,0x380000A2,0xA800A2,0xA800A2,0xA800A2,0x50400001,0x50400001,0x40500001,0x15800A2,0x15800A2,0x40180001,0x380000A2,0x15800A2,0x15800A2,0x40180001,0x380000A2,0x380000A2,0xF6480001,0xFA64000D,0x7000A4,0xAA380000,0x763C0000,0x603C0000,0x56440001,0x50340000,0xF6240005,0x9E280000,0xF000A2,0x40180001, -0xF000A2,0x9800C8,0x7E840000,0x5E840001,0x54840001,0xE000C8,0x66600001,0x54700001,0x1CC00C8,0x54340001,0x4A0000CA,0xE000C8,0x66600001,0x54700001,0x1CC00C8,0x54340001,0x4A0000CA,0x1CC00C8,0x54340001,0x4A0000CA,0x4A0000CA,0xE000C8,0x66600001,0x54700001,0x1CC00C8,0x54340001,0x4A0000CA,0x1CC00C8,0x54340001,0x4A0000CA,0x4A0000CA,0x1CC00C8, -0x54340001,0x4A0000CA,0x4A0000CA,0x4A0000CA,0xFC4C0014,0x8A000C8,0xFE8C0020,0xA63C0000,0x7C340001,0x64340000,0x544C0001,0x54180001,0xFE2C000D,0xA0280000,0x58500000,0x4A0000CA,0x14000C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x4C00C8,0x58380000,0x58380000,0x58380000,0x58380000,0x58380000, -0x58380000,0x38380001,0x38380001,0x38380001,0x2E380001,0x7000C8,0x7000C8,0x7000C8,0x7000C8,0x7000C8,0x7000C8,0x40140001,0x40140001,0x40140001,0x2E240001,0xE400C8,0xE400C8,0xE400C8,0x2C00000D,0x240000CA,0xF63C0014,0x4C00C8,0x4C00C8,0xA6380000,0x7C380000,0x66380000,0x66380000,0x4C380000,0xFC1C0001,0x96280001,0x40340001,0x40140001, -0xA000C8,}; -static const uint32_t g_etc1_to_bc7_m6_table72[] = { -0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0xDC0000, -0xDC0000,0xDC0000,0xDC0000,0x24000000,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0x480001,0xE4C0000,0xE4C0000,0xE4C0000,0x6C0000,0x9C0000,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000, -0xA80000,0x1580000,0x1580000,0x1580000,0x38000000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x1580000,0x38000000,0x1580000,0x1580000,0x1580000,0x38000000,0x38000000,0x4780000,0x700001,0x700001,0x840000,0x48C0000,0x2980000,0x2980000,0xC00000,0x840000,0x48C0000,0xF00000,0x1580000, -0xF00000,0x940001,0x940001,0x940001,0x940001,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x4A000000,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x4A000000,0x1C40000,0x1C40000,0x4A000000,0x4A000000,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x4A000000,0x1C40000,0x1C40000,0x4A000000,0x4A000000,0x1C40000, -0x1C40000,0x4A000000,0x4A000000,0x4A000000,0x4AC0000,0xA00000,0x940001,0xCC0000,0xFC0000,0x13C0000,0x16C0000,0xBF80000,0xBC0000,0x2DC0000,0x13C0000,0x4A000000,0x13C0000,0xBC0001,0x3180000,0x11FC0000,0x5E000000,0x3180000,0x11FC0000,0x5E000000,0x11FC0000,0x5E000000,0x5E000000,0x3180000,0x11FC0000,0x5E000000,0x11FC0000,0x5E000000, -0x5E000000,0x11FC0000,0x5E000000,0x5E000000,0x5E000000,0x3180000,0x11FC0000,0x5E000000,0x11FC0000,0x5E000000,0x5E000000,0x11FC0000,0x5E000000,0x5E000000,0x5E000000,0x11FC0000,0x5E000000,0x5E000000,0x5E000000,0x5E000000,0x2EC0000,0xCC80000,0xCC80000,0x1400000,0x1D00000,0x37F40000,0x5E000000,0x5E000000,0x3000000,0x1640000,0x55DC0000,0x5E000000, -0x1940000,0x840734,0xAE7002D3,0x707002D4,0x5E7002D3,0xA0600192,0x786000D7,0x6264013B,0x66600192,0x5C5C00D7,0x545C0192,0x984C02D4,0x7A4C00A3,0x625400FD,0x6A4800CF,0x5E4C0002,0x545000D5,0x5E4802D4,0x584000FF,0x5048013A,0x4A4802D5,0xC40734,0x822802D3,0x5E4C02D4,0x76180192,0x5E3000D1,0x54380190,0x700002D3,0x5E1000A2,0x541400D5,0x4A2402D4,0x18C0734, -0x5600031B,0x50000212,0x48000378,0x40000738,0xFE580072,0xF4780434,0xF67C04EC,0xB24C0002,0x84480003,0x6C4C0002,0x5E500011,0x5C440012,0xFE34004E,0xAA380000,0x604000A9,0x541400D5,0x1180734,0x9802D3,0x988400A2,0x6C8400A2,0x5E8400A2,0x8A7400C9,0x6E740002,0x60740015,0x627000C9,0x5C6C0026,0x547000C9,0xE002D3,0x7A4C00A2,0x5E6800A2,0x6E4000C9,0x5E4C0001, -0x545800C8,0x1CC02D3,0x5E0C00A2,0x540000C8,0x4A0002D4,0xE002D3,0x7A4C00A2,0x5E6800A2,0x6E4000C9,0x5E4C0001,0x545800C8,0x1CC02D3,0x5E0C00A2,0x540000C8,0x4A0002D4,0x1CC02D3,0x5E0C00A2,0x540000C8,0x4A0002D4,0x4A0002D4,0xFC60002D,0xFC880173,0xFE8C016B,0xB24C0001,0x84480002,0x6C4C0001,0x5E580002,0x5C3C0006,0xFE3C0033,0xAA380000,0x623800A2,0x540000C8, -0x14002D3,0x7002D3,0x7002D3,0x7002D3,0x7002D3,0x806000CA,0x806000CA,0x806000CA,0x585C00CA,0x585C00CA,0x4A5C00CA,0x7A4C00A3,0x7A4C00A3,0x7A4C00A3,0x5C4C0002,0x5C4C0002,0x4C500026,0x4E4C00A3,0x4E4C00A3,0x48480015,0x404800A5,0x2A402D3,0x2A402D3,0x2A402D3,0x622C00C9,0x622C00C9,0x4A4400C8,0x5C1400A2,0x5C1400A2,0x4A240001,0x403000A4,0x15002D3, -0x15002D3,0x480000D4,0x3E0000CD,0x380002D4,0xFC540026,0xFC68015E,0x7002D3,0xB6480001,0x804C0002,0x6A4C0002,0x644C0005,0x58480002,0xFE34000E,0xAA380000,0x5E4400A3,0x4A240001,0xEC02D3,0x8400A2,0x8400A2,0x8400A2,0x8400A2,0x6C740001,0x6C740001,0x6C740001,0x52740001,0x52740001,0x4A700001,0xC400A2,0xC400A2,0xC400A2,0x58540001,0x58540001, -0x4A600000,0x18C00A2,0x18C00A2,0x4A280000,0x400000A4,0xC400A2,0xC400A2,0xC400A2,0x58540001,0x58540001,0x4A600000,0x18C00A2,0x18C00A2,0x4A280000,0x400000A4,0x18C00A2,0x18C00A2,0x4A280000,0x400000A4,0x400000A4,0xFE580001,0xF4780012,0x8400A2,0xB6480000,0x7C500000,0x68500000,0x60540000,0x58480001,0xFE340005,0xAA380000,0x11800A2,0x4A280000, -0x11800A2,0xA800CA,0x84980001,0x68940001,0x5E940001,0xFC00C8,0x6E740001,0x5E800001,0x3F800C8,0x5E440000,0x540000C8,0xFC00C8,0x6E740001,0x5E800001,0x3F800C8,0x5E440000,0x540000C8,0x3F800C8,0x5E440000,0x540000C8,0x540000C8,0xFC00C8,0x6E740001,0x5E800001,0x3F800C8,0x5E440000,0x540000C8,0x3F800C8,0x5E440000,0x540000C8,0x540000C8,0x3F800C8, -0x5E440000,0x540000C8,0x540000C8,0x540000C8,0xF6680019,0x2B400C8,0xF8A00029,0xB24C0000,0x84480001,0x6E440000,0x5E5C0000,0x5E240000,0xF4480012,0xAA380000,0x60640001,0x540000C8,0x16800C8,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5C00CA,0x5E4C0001,0x5E4C0001,0x5E4C0001,0x5E4C0001,0x5E4C0001, -0x5E4C0001,0x42480001,0x42480001,0x42480001,0x38480001,0x8C00C8,0x8C00C8,0x8C00C8,0x8C00C8,0x8C00C8,0x8C00C8,0x48280001,0x48280001,0x48280001,0x38340001,0x11800C8,0x11800C8,0x11800C8,0x38000001,0x2E0000C8,0xF0500019,0x5C00CA,0x5C00CA,0xAA4C0001,0x824C0001,0x6C4C0001,0x6C4C0001,0x544C0001,0xF8300002,0xA8380000,0x4C440000,0x48280001, -0xC800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table73[] = { -0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x10C0000, -0x10C0000,0x10C0000,0x10C0000,0x2C000000,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x580001,0x600000,0x600000,0x600000,0x840000,0xBC0000,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000, -0xC00000,0x1880000,0x1880000,0x1880000,0x40000000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0x1880000,0x1880000,0x1880000,0x40000000,0x1880000,0x1880000,0x1880000,0x40000000,0x40000000,0xC880000,0x800001,0x800001,0x980000,0x4A00000,0xB00000,0xB00000,0xD80000,0x980000,0x4A00000,0x1140000,0x1880000, -0x1140000,0xA40001,0xA40001,0xA40001,0xA40001,0x2F40000,0x2F40000,0x2F40000,0x1F40000,0x1F40000,0x52000000,0x2F40000,0x2F40000,0x2F40000,0x1F40000,0x1F40000,0x52000000,0x1F40000,0x1F40000,0x52000000,0x52000000,0x2F40000,0x2F40000,0x2F40000,0x1F40000,0x1F40000,0x52000000,0x1F40000,0x1F40000,0x52000000,0x52000000,0x1F40000, -0x1F40000,0x52000000,0x52000000,0x52000000,0xC00000,0xB00000,0xA40001,0xE00000,0x3140000,0x1600000,0x1940000,0x15FC0000,0xD00000,0x2F40000,0x1600000,0x52000000,0x1600000,0xCC0001,0x3300000,0x1DFC0000,0x66000000,0x3300000,0x1DFC0000,0x66000000,0x1DFC0000,0x66000000,0x66000000,0x3300000,0x1DFC0000,0x66000000,0x1DFC0000,0x66000000, -0x66000000,0x1DFC0000,0x66000000,0x66000000,0x66000000,0x3300000,0x1DFC0000,0x66000000,0x1DFC0000,0x66000000,0x66000000,0x1DFC0000,0x66000000,0x66000000,0x66000000,0x1DFC0000,0x66000000,0x66000000,0x66000000,0x66000000,0x3000000,0xDC0000,0xDC0000,0x1580000,0x1F80000,0x41F40000,0x66000000,0x66000000,0x1180000,0x3800000,0x5DEC0000,0x66000000, -0x1B40000,0x940734,0xB68002D3,0x788002D4,0x668002D3,0xA8700192,0x807000D7,0x6A74013B,0x6E700192,0x646C00D7,0x5C6C0192,0xA05C02D4,0x825C00A3,0x6A6400FD,0x725800CF,0x665C0002,0x5C6000D5,0x665802D4,0x605000FF,0x5858013A,0x525802D5,0xDC0734,0x8A3802D3,0x665C02D4,0x7E280192,0x664000D1,0x5C480190,0x781002D3,0x662000A2,0x5C2400D5,0x523402D4,0x1BC0734, -0x600002F8,0x5A0001E0,0x50000339,0x48000738,0xFE6C0096,0xFC880434,0xFE8C04EC,0xBA5C0002,0x8C580003,0x745C0002,0x66600011,0x64540012,0xFC4C006E,0xB2480000,0x685000A9,0x5C2400D5,0x1380734,0xA802D3,0xA09400A2,0x749400A2,0x669400A2,0x928400C9,0x76840002,0x68840015,0x6A8000C9,0x647C0026,0x5C8000C9,0xF802D3,0x825C00A2,0x667800A2,0x765000C9,0x665C0001, -0x5C6800C8,0x1FC02D3,0x661C00A2,0x5C1000C8,0x520002D4,0xF802D3,0x825C00A2,0x667800A2,0x765000C9,0x665C0001,0x5C6800C8,0x1FC02D3,0x661C00A2,0x5C1000C8,0x520002D4,0x1FC02D3,0x661C00A2,0x5C1000C8,0x520002D4,0x520002D4,0xFC740036,0xF4980189,0xF8A0017A,0xBA5C0001,0x8C580002,0x745C0001,0x66680002,0x644C0006,0xFC50003D,0xB2480000,0x6A4800A2,0x5C1000C8, -0x16402D3,0x8002D3,0x8002D3,0x8002D3,0x8002D3,0x887000CA,0x887000CA,0x887000CA,0x606C00CA,0x606C00CA,0x526C00CA,0x825C00A3,0x825C00A3,0x825C00A3,0x645C0002,0x645C0002,0x54600026,0x565C00A3,0x565C00A3,0x50580015,0x485800A5,0x2BC02D3,0x2BC02D3,0x2BC02D3,0x6A3C00C9,0x6A3C00C9,0x525400C8,0x642400A2,0x642400A2,0x52340001,0x484000A4,0x18002D3, -0x18002D3,0x520000CA,0x480000B4,0x400002D4,0xFC64002D,0xF4780173,0x8002D3,0xBE580001,0x885C0002,0x725C0002,0x6C5C0005,0x60580002,0xFE440019,0xB2480000,0x665400A3,0x52340001,0x11002D3,0x9400A2,0x9400A2,0x9400A2,0x9400A2,0x74840001,0x74840001,0x74840001,0x5A840001,0x5A840001,0x52800001,0xDC00A2,0xDC00A2,0xDC00A2,0x60640001,0x60640001, -0x52700000,0x1BC00A2,0x1BC00A2,0x52380000,0x480000A4,0xDC00A2,0xDC00A2,0xDC00A2,0x60640001,0x60640001,0x52700000,0x1BC00A2,0x1BC00A2,0x52380000,0x480000A4,0x1BC00A2,0x1BC00A2,0x52380000,0x480000A4,0x480000A4,0xFA6C0002,0xFC880012,0x9400A2,0xBE580000,0x84600000,0x70600000,0x68640000,0x60580001,0xFA48000A,0xB2480000,0x13800A2,0x52380000, -0x13800A2,0xB800CA,0x8CA80001,0x70A40001,0x66A40001,0x11400C8,0x76840001,0x66900001,0xFF800C8,0x66540000,0x5C0000C8,0x11400C8,0x76840001,0x66900001,0xFF800C8,0x66540000,0x5C0000C8,0xFF800C8,0x66540000,0x5C0000C8,0x5C0000C8,0x11400C8,0x76840001,0x66900001,0xFF800C8,0x66540000,0x5C0000C8,0xFF800C8,0x66540000,0x5C0000C8,0x5C0000C8,0xFF800C8, -0x66540000,0x5C0000C8,0x5C0000C8,0x5C0000C8,0xFE780019,0xAC400C8,0xFEAC002D,0xBA5C0000,0x8C580001,0x76540000,0x666C0000,0x66340000,0xFC580012,0xB2480000,0x68740001,0x5C0000C8,0x18C00C8,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x6C00CA,0x665C0001,0x665C0001,0x665C0001,0x665C0001,0x665C0001, -0x665C0001,0x4A580001,0x4A580001,0x4A580001,0x40580001,0xA400C8,0xA400C8,0xA400C8,0xA400C8,0xA400C8,0xA400C8,0x50380001,0x50380001,0x50380001,0x40440001,0x14C00C8,0x14C00C8,0x14C00C8,0x40080000,0x360000C8,0xF8600019,0x6C00CA,0x6C00CA,0xB25C0001,0x8A5C0001,0x745C0001,0x745C0001,0x5C5C0001,0xF4440005,0xB0480000,0x54540000,0x50380001, -0xE800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table74[] = { -0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x13C0000, -0x13C0000,0x13C0000,0x13C0000,0x34000000,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x700000,0x700000,0x700000,0x9C0000,0xE00000,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000, -0xD80000,0x1B80000,0x1B80000,0x1B80000,0x48000000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0x1B80000,0x1B80000,0x1B80000,0x48000000,0x1B80000,0x1B80000,0x1B80000,0x48000000,0x48000000,0x9C0000,0x900001,0x900001,0x2A80000,0x4B40000,0x2C40000,0x2C40000,0xF40000,0x2A80000,0x4B40000,0x1340000,0x1B80000, -0x1340000,0xB40001,0xB40001,0xB40001,0xB40001,0x30C0000,0x30C0000,0x30C0000,0xBFC0000,0xBFC0000,0x5A000000,0x30C0000,0x30C0000,0x30C0000,0xBFC0000,0xBFC0000,0x5A000000,0xBFC0000,0xBFC0000,0x5A000000,0x5A000000,0x30C0000,0x30C0000,0x30C0000,0xBFC0000,0xBFC0000,0x5A000000,0xBFC0000,0xBFC0000,0x5A000000,0x5A000000,0xBFC0000, -0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0xD40000,0x8C00000,0xB40001,0xF80000,0x1300000,0x1800000,0x1BC0000,0x21F40000,0xE40000,0x30C0000,0x1800000,0x5A000000,0x1800000,0xDC0001,0x1480000,0x29FC0000,0x6E000000,0x1480000,0x29FC0000,0x6E000000,0x29FC0000,0x6E000000,0x6E000000,0x1480000,0x29FC0000,0x6E000000,0x29FC0000,0x6E000000, -0x6E000000,0x29FC0000,0x6E000000,0x6E000000,0x6E000000,0x1480000,0x29FC0000,0x6E000000,0x29FC0000,0x6E000000,0x6E000000,0x29FC0000,0x6E000000,0x6E000000,0x6E000000,0x29FC0000,0x6E000000,0x6E000000,0x6E000000,0x6E000000,0x3140000,0xEC0000,0xEC0000,0x1740000,0xDFC0000,0x4BF40000,0x6E000000,0x6E000000,0x32C0000,0x1A00000,0x65FC0000,0x6E000000, -0x1D80000,0xA40734,0xBE9002D3,0x809002D4,0x6E9002D3,0xB0800192,0x888000D7,0x7284013B,0x76800192,0x6C7C00D7,0x647C0192,0xA86C02D4,0x8A6C00A3,0x727400FD,0x7A6800CF,0x6E6C0002,0x647000D5,0x6E6802D4,0x686000FF,0x6068013A,0x5A6802D5,0xF40734,0x924802D3,0x6E6C02D4,0x86380192,0x6E5000D1,0x64580190,0x802002D3,0x6E3000A2,0x643400D5,0x5A4402D4,0x1F00734, -0x6C0002D8,0x600001B8,0x5A000314,0x50000738,0xFC7C00BA,0xF498046A,0xF8A00513,0xC26C0002,0x94680003,0x7C6C0002,0x6E700011,0x6C640012,0xFE5C0082,0xBA580000,0x706000A9,0x643400D5,0x15C0734,0xB802D3,0xA8A400A2,0x7CA400A2,0x6EA400A2,0x9A9400C9,0x7E940002,0x70940015,0x729000C9,0x6C8C0026,0x649000C9,0x11002D3,0x8A6C00A2,0x6E8800A2,0x7E6000C9,0x6E6C0001, -0x647800C8,0xDFC02D3,0x6E2C00A2,0x642000C8,0x5A0002D4,0x11002D3,0x8A6C00A2,0x6E8800A2,0x7E6000C9,0x6E6C0001,0x647800C8,0xDFC02D3,0x6E2C00A2,0x642000C8,0x5A0002D4,0xDFC02D3,0x6E2C00A2,0x642000C8,0x5A0002D4,0x5A0002D4,0xFE800049,0xFCA80189,0xFEAC0186,0xC26C0001,0x94680002,0x7C6C0001,0x6E780002,0x6C5C0006,0xFE600051,0xBA580000,0x725800A2,0x642000C8, -0x18802D3,0x9002D3,0x9002D3,0x9002D3,0x9002D3,0x908000CA,0x908000CA,0x908000CA,0x687C00CA,0x687C00CA,0x5A7C00CA,0x8A6C00A3,0x8A6C00A3,0x8A6C00A3,0x6C6C0002,0x6C6C0002,0x5C700026,0x5E6C00A3,0x5E6C00A3,0x58680015,0x506800A5,0xD402D3,0xD402D3,0xD402D3,0x724C00C9,0x724C00C9,0x5A6400C8,0x6C3400A2,0x6C3400A2,0x5A440001,0x505000A4,0x1B002D3, -0x1B002D3,0x5A0C00C8,0x500000A5,0x480002D4,0xFE74003B,0xFC880173,0x9002D3,0xC6680001,0x906C0002,0x7A6C0002,0x746C0005,0x68680002,0xFE580021,0xBA580000,0x6E6400A3,0x5A440001,0x13002D3,0xA400A2,0xA400A2,0xA400A2,0xA400A2,0x7C940001,0x7C940001,0x7C940001,0x62940001,0x62940001,0x5A900001,0xF400A2,0xF400A2,0xF400A2,0x68740001,0x68740001, -0x5A800000,0x1F000A2,0x1F000A2,0x5A480000,0x500000A4,0xF400A2,0xF400A2,0xF400A2,0x68740001,0x68740001,0x5A800000,0x1F000A2,0x1F000A2,0x5A480000,0x500000A4,0x1F000A2,0x1F000A2,0x5A480000,0x500000A4,0x500000A4,0xF6800005,0xF4980019,0xA400A2,0xC6680000,0x8C700000,0x78700000,0x70740000,0x68680001,0xF260000D,0xBA580000,0x15C00A2,0x5A480000, -0x15C00A2,0xC800CA,0x94B80001,0x78B40001,0x6EB40001,0x12C00C8,0x7E940001,0x6EA00001,0x1BF800C8,0x6E640000,0x640000C8,0x12C00C8,0x7E940001,0x6EA00001,0x1BF800C8,0x6E640000,0x640000C8,0x1BF800C8,0x6E640000,0x640000C8,0x640000C8,0x12C00C8,0x7E940001,0x6EA00001,0x1BF800C8,0x6E640000,0x640000C8,0x1BF800C8,0x6E640000,0x640000C8,0x640000C8,0x1BF800C8, -0x6E640000,0x640000C8,0x640000C8,0x640000C8,0xFA8C0020,0xD800C8,0xF8C00032,0xC26C0000,0x94680001,0x7E640000,0x6E7C0000,0x6E440000,0xFC6C0019,0xBA580000,0x70840001,0x640000C8,0x1AC00C8,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x7C00CA,0x6E6C0001,0x6E6C0001,0x6E6C0001,0x6E6C0001,0x6E6C0001, -0x6E6C0001,0x52680001,0x52680001,0x52680001,0x48680001,0xBC00C8,0xBC00C8,0xBC00C8,0xBC00C8,0xBC00C8,0xBC00C8,0x58480001,0x58480001,0x58480001,0x48540001,0x17C00C8,0x17C00C8,0x17C00C8,0x48180000,0x3E0000C8,0xF0700022,0x7C00CA,0x7C00CA,0xBA6C0001,0x926C0001,0x7C6C0001,0x7C6C0001,0x646C0001,0xFC540005,0xB8580000,0x5C640000,0x58480001, -0x10C00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table75[] = { -0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x1700000, -0x1700000,0x1700000,0x1700000,0x3C000000,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x8800000,0x8800000,0x8800000,0xB40000,0x1000000,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000, -0xF00000,0x1E80000,0x1E80000,0x1E80000,0x50000000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0x1E80000,0x1E80000,0x1E80000,0x50000000,0x1E80000,0x1E80000,0x1E80000,0x50000000,0x50000000,0xAC0000,0xA00001,0xA00001,0xBC0000,0xCC0000,0xDC0000,0xDC0000,0x1100000,0xBC0000,0xCC0000,0x1580000,0x1E80000, -0x1580000,0xC40001,0xC40001,0xC40001,0xC40001,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x62000000,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x62000000,0x17FC0000,0x17FC0000,0x62000000,0x62000000,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x62000000,0x17FC0000,0x17FC0000,0x62000000,0x62000000,0x17FC0000, -0x17FC0000,0x62000000,0x62000000,0x62000000,0x4E40000,0xD40000,0xC40001,0x10C0000,0x14C0000,0x1A40000,0x1E40000,0x2BF80000,0xF80000,0x3240000,0x1A40000,0x62000000,0x1A40000,0xEC0001,0x1600000,0x35FC0000,0x76000000,0x1600000,0x35FC0000,0x76000000,0x35FC0000,0x76000000,0x76000000,0x1600000,0x35FC0000,0x76000000,0x35FC0000,0x76000000, -0x76000000,0x35FC0000,0x76000000,0x76000000,0x76000000,0x1600000,0x35FC0000,0x76000000,0x35FC0000,0x76000000,0x76000000,0x35FC0000,0x76000000,0x76000000,0x76000000,0x35FC0000,0x76000000,0x76000000,0x76000000,0x76000000,0x3280000,0x6FC0000,0x6FC0000,0x1900000,0x1BFC0000,0x55F40000,0x76000000,0x76000000,0x1440000,0x1C00000,0x6FD00000,0x76000000, -0x1F80000,0xB40734,0xC6A002D3,0x88A002D4,0x76A002D3,0xB8900192,0x909000D7,0x7A94013B,0x7E900192,0x748C00D7,0x6C8C0192,0xB07C02D4,0x927C00A3,0x7A8400FD,0x827800CF,0x767C0002,0x6C8000D5,0x767802D4,0x707000FF,0x6878013A,0x627802D5,0x10C0734,0x9A5802D3,0x767C02D4,0x8E480192,0x766000D1,0x6C680190,0x883002D3,0x764000A2,0x6C4400D5,0x625402D4,0xBF80734, -0x760002D3,0x6C000198,0x600002F8,0x58000738,0xFE8C00D4,0xFCA8046A,0xFEAC0517,0xCA7C0002,0x9C780003,0x847C0002,0x76800011,0x74740012,0xFE7000A7,0xC2680000,0x787000A9,0x6C4400D5,0x17C0734,0xC802D3,0xB0B400A2,0x84B400A2,0x76B400A2,0xA2A400C9,0x86A40002,0x78A40015,0x7AA000C9,0x749C0026,0x6CA000C9,0x12802D3,0x927C00A2,0x769800A2,0x867000C9,0x767C0001, -0x6C8800C8,0x19FC02D3,0x763C00A2,0x6C3000C8,0x620002D4,0x12802D3,0x927C00A2,0x769800A2,0x867000C9,0x767C0001,0x6C8800C8,0x19FC02D3,0x763C00A2,0x6C3000C8,0x620002D4,0x19FC02D3,0x763C00A2,0x6C3000C8,0x620002D4,0x620002D4,0xFE940050,0xF4B801A3,0xF8C00193,0xCA7C0001,0x9C780002,0x847C0001,0x76880002,0x746C0006,0xFE780056,0xC2680000,0x7A6800A2,0x6C3000C8, -0x1A802D3,0xA002D3,0xA002D3,0xA002D3,0xA002D3,0x989000CA,0x989000CA,0x989000CA,0x708C00CA,0x708C00CA,0x628C00CA,0x927C00A3,0x927C00A3,0x927C00A3,0x747C0002,0x747C0002,0x64800026,0x667C00A3,0x667C00A3,0x60780015,0x587800A5,0xEC02D3,0xEC02D3,0xEC02D3,0x7A5C00C9,0x7A5C00C9,0x627400C8,0x744400A2,0x744400A2,0x62540001,0x586000A4,0x1E402D3, -0x1E402D3,0x621C00C8,0x580800A4,0x500002D4,0xFE840046,0xF498018A,0xA002D3,0xCE780001,0x987C0002,0x827C0002,0x7C7C0005,0x70780002,0xF86C0032,0xC2680000,0x767400A3,0x62540001,0x15402D3,0xB400A2,0xB400A2,0xB400A2,0xB400A2,0x84A40001,0x84A40001,0x84A40001,0x6AA40001,0x6AA40001,0x62A00001,0x10C00A2,0x10C00A2,0x10C00A2,0x70840001,0x70840001, -0x62900000,0xBF800A2,0xBF800A2,0x62580000,0x580000A4,0x10C00A2,0x10C00A2,0x10C00A2,0x70840001,0x70840001,0x62900000,0xBF800A2,0xBF800A2,0x62580000,0x580000A4,0xBF800A2,0xBF800A2,0x62580000,0x580000A4,0x580000A4,0xFE900005,0xFCA80019,0xB400A2,0xCE780000,0x94800000,0x80800000,0x78840000,0x70780001,0xFA70000D,0xC2680000,0x17C00A2,0x62580000, -0x17C00A2,0xD800CA,0x9CC80001,0x80C40001,0x76C40001,0x14400C8,0x86A40001,0x76B00001,0x27F800C8,0x76740000,0x6C0000C8,0x14400C8,0x86A40001,0x76B00001,0x27F800C8,0x76740000,0x6C0000C8,0x27F800C8,0x76740000,0x6C0000C8,0x6C0000C8,0x14400C8,0x86A40001,0x76B00001,0x27F800C8,0x76740000,0x6C0000C8,0x27F800C8,0x76740000,0x6C0000C8,0x6C0000C8,0x27F800C8, -0x76740000,0x6C0000C8,0x6C0000C8,0x6C0000C8,0xF4A00029,0xE800C8,0xFECC003A,0xCA7C0000,0x9C780001,0x86740000,0x768C0000,0x76540000,0xF8840020,0xC2680000,0x78940001,0x6C0000C8,0x1D000C8,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x8C00CA,0x767C0001,0x767C0001,0x767C0001,0x767C0001,0x767C0001, -0x767C0001,0x5A780001,0x5A780001,0x5A780001,0x50780001,0x2D000C8,0x2D000C8,0x2D000C8,0x2D000C8,0x2D000C8,0x2D000C8,0x60580001,0x60580001,0x60580001,0x50640001,0x1AC00C8,0x1AC00C8,0x1AC00C8,0x50280000,0x460000C8,0xF8800022,0x8C00CA,0x8C00CA,0xC27C0001,0x9A7C0001,0x847C0001,0x847C0001,0x6C7C0001,0xFC640008,0xC0680000,0x64740000,0x60580001, -0x12C00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table76[] = { -0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0xD00000,0xD00000,0xD00000,0xD00000,0xD00000,0xD00000,0xD00000,0xD00000,0xD00000,0xD00000,0x1A40000, -0x1A40000,0x1A40000,0x1A40000,0x44000001,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x2940000,0x2940000,0x2940000,0xD00000,0x1280000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000, -0x10C0000,0xBF80000,0xBF80000,0xBF80000,0x58000001,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0xBF80000,0x58000001,0xBF80000,0xBF80000,0xBF80000,0x58000001,0x58000001,0xC00000,0xB40000,0xB40000,0xD00000,0x2E00000,0xF40000,0xF40000,0x32C0000,0xD00000,0x2E00000,0x17C0000,0xBF80000, -0x17C0000,0xD80000,0xD80000,0xD80000,0xD80000,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x6A000001,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x6A000001,0x25F80000,0x25F80000,0x6A000001,0x6A000001,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x6A000001,0x25F80000,0x25F80000,0x6A000001,0x6A000001,0x25F80000, -0x25F80000,0x6A000001,0x6A000001,0x6A000001,0xFC0000,0xAE40000,0xD80000,0x3240000,0x16C0000,0x1CC0000,0x9F80000,0x37FC0000,0x50C0000,0x1400000,0x1CC0000,0x6A000001,0x1CC0000,0x1000000,0x17C0000,0x43F80000,0x7E000001,0x17C0000,0x43F80000,0x7E000001,0x43F80000,0x7E000001,0x7E000001,0x17C0000,0x43F80000,0x7E000001,0x43F80000,0x7E000001, -0x7E000001,0x43F80000,0x7E000001,0x7E000001,0x7E000001,0x17C0000,0x43F80000,0x7E000001,0x43F80000,0x7E000001,0x7E000001,0x43F80000,0x7E000001,0x7E000001,0x7E000001,0x43F80000,0x7E000001,0x7E000001,0x7E000001,0x7E000001,0x1400000,0x1100000,0x1100000,0x3AC0000,0x29FC0000,0x61F00000,0x7E000001,0x7E000001,0x15C0000,0x1E00000,0x79C40000,0x7E000001, -0x11FC0000,0xC40738,0xCCB402D4,0x92B402D4,0x7EB402D5,0xC2A00190,0x9AA000D5,0x80A8013A,0x88A00190,0x7CA000D5,0x74A00192,0xBC8C02D3,0x9C8C00A2,0x849800FF,0x8C8C00D1,0x7E8C0002,0x749000D7,0x7E8C02D4,0x7A8400FD,0x7284013B,0x6C8C02D3,0x3240734,0xA46802D3,0x7E8C02D4,0x965C0192,0x807400CF,0x747C0192,0x904402D3,0x7E5400A3,0x745400D7,0x6C6402D4,0x17FC0734, -0x7E1402D4,0x74080192,0x6C0002DC,0x62000734,0xFEA000FE,0xF6BC04A0,0xF8C0053C,0xD48C0000,0xA68C0001,0x8C8C0002,0x80900012,0x7C8C0011,0xFE8800DC,0xC87C0002,0x828000A9,0x745400D7,0x1A40734,0xD802D4,0xB8C800A4,0x8CC800A4,0x7EC400A5,0xAEB400C8,0x90B40001,0x80B80015,0x82B400C8,0x7CB00026,0x74B400CA,0x14402D3,0x9A9000A2,0x7EAC00A3,0x8E8400C9,0x7E8C0002, -0x769800CA,0x27F802D3,0x7E5400A3,0x744400CA,0x6C0002D3,0x14402D3,0x9A9000A2,0x7EAC00A3,0x8E8400C9,0x7E8C0002,0x769800CA,0x27F802D3,0x7E5400A3,0x744400CA,0x6C0002D3,0x27F802D3,0x7E5400A3,0x744400CA,0x6C0002D3,0x6C0002D3,0xFAAC0065,0xFECC01A0,0xF2D401AD,0xD48C0000,0xA68C0001,0x8C8C0002,0x80980002,0x7E800005,0xFA900071,0xC87C0001,0x847800A2,0x744400CA, -0x1D002D3,0xB402D4,0xB402D4,0xB402D4,0xB402D4,0xA4A000C8,0xA4A000C8,0xA4A000C8,0x78A000C8,0x78A000C8,0x6AA000C9,0x9C8C00A2,0x9C8C00A2,0x9C8C00A2,0x7E8C0001,0x7E8C0001,0x6E900026,0x708C00A2,0x708C00A2,0x6A880015,0x628C00A2,0x10802D3,0x10802D3,0x10802D3,0x846C00C9,0x846C00C9,0x6C8400C9,0x7E5400A2,0x7E5400A2,0x6A680002,0x627000A2,0x9F802D3, -0x9F802D3,0x6A3000C9,0x621400A2,0x580002D3,0xFC9C005A,0xFEAC0189,0xB402D4,0xD48C0000,0xA28C0001,0x8C8C0001,0x86900006,0x788C0002,0xFE80003E,0xC87C0001,0x808400A2,0x6A680002,0x17802D3,0xC400A4,0xC400A4,0xC400A4,0xC400A4,0x90B40000,0x90B40000,0x90B40000,0x74B40000,0x74B40000,0x6AB40001,0x32400A2,0x32400A2,0x32400A2,0x7A940001,0x7A940001, -0x6AA40001,0x17FC00A2,0x17FC00A2,0x6A6C0001,0x620000A2,0x32400A2,0x32400A2,0x32400A2,0x7A940001,0x7A940001,0x6AA40001,0x17FC00A2,0x17FC00A2,0x6A6C0001,0x620000A2,0x17FC00A2,0x17FC00A2,0x6A6C0001,0x620000A2,0x620000A2,0xFEA0000A,0xF6BC0020,0xC400A4,0xD48C0000,0xA0900000,0x8A900000,0x80980001,0x7A880000,0xF8880012,0xC87C0000,0x1A400A2,0x6A6C0001, -0x1A400A2,0xEC00C8,0xA8D80000,0x88D80001,0x7ED80001,0x35C00C8,0x90B40001,0x7EC40001,0x33FC00C8,0x7E880001,0x740000CA,0x35C00C8,0x90B40001,0x7EC40001,0x33FC00C8,0x7E880001,0x740000CA,0x33FC00C8,0x7E880001,0x740000CA,0x740000CA,0x35C00C8,0x90B40001,0x7EC40001,0x33FC00C8,0x7E880001,0x740000CA,0x33FC00C8,0x7E880001,0x740000CA,0x740000CA,0x33FC00C8, -0x7E880001,0x740000CA,0x740000CA,0x740000CA,0xFEB40029,0xFC00C8,0xFAE4003D,0xD0900000,0xA6880001,0x8E880000,0x7EA00001,0x7E6C0001,0xFE980020,0xCA7C0000,0x82A40000,0x740000CA,0x1F400C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0xA000C8,0x828C0000,0x828C0000,0x828C0000,0x828C0000,0x828C0000, -0x828C0000,0x628C0001,0x628C0001,0x628C0001,0x588C0001,0xEC00C8,0xEC00C8,0xEC00C8,0xEC00C8,0xEC00C8,0xEC00C8,0x6A680001,0x6A680001,0x6A680001,0x58780001,0x1E400C8,0x1E400C8,0x1E400C8,0x583C0001,0x4E0000CA,0xF2940029,0xA000C8,0xA000C8,0xD08C0000,0xA68C0000,0x908C0000,0x908C0000,0x768C0000,0xF47C000D,0xC07C0001,0x6A880001,0x6A680001, -0x15400C8,}; -static const uint32_t g_etc1_to_bc7_m6_table77[] = { -0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0x1D80000, -0x1D80000,0x1D80000,0x1D80000,0x4C000001,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0xAA40000,0xAA40000,0xAA40000,0xE80000,0x14C0000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000, -0x1240000,0x17F80000,0x17F80000,0x17F80000,0x60000001,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x17F80000,0x17F80000,0x17F80000,0x60000001,0x17F80000,0x17F80000,0x17F80000,0x60000001,0x60000001,0xD00000,0xC40000,0xC40000,0xE40000,0x2F40000,0x3080000,0x3080000,0x1480000,0xE40000,0x2F40000,0x1A00000,0x17F80000, -0x1A00000,0xE80000,0xE80000,0xE80000,0xE80000,0x1580000,0x1580000,0x1580000,0x31F80000,0x31F80000,0x72000001,0x1580000,0x1580000,0x1580000,0x31F80000,0x31F80000,0x72000001,0x31F80000,0x31F80000,0x72000001,0x72000001,0x1580000,0x1580000,0x1580000,0x31F80000,0x31F80000,0x72000001,0x31F80000,0x31F80000,0x72000001,0x72000001,0x31F80000, -0x31F80000,0x72000001,0x72000001,0x72000001,0x30C0000,0xF80000,0xE80000,0x13C0000,0x1840000,0x1EC0000,0x15FC0000,0x43F40000,0x5200000,0x1580000,0x1EC0000,0x72000001,0x1EC0000,0x1100000,0x1940000,0x4FF80000,0x86000001,0x1940000,0x4FF80000,0x86000001,0x4FF80000,0x86000001,0x86000001,0x1940000,0x4FF80000,0x86000001,0x4FF80000,0x86000001, -0x86000001,0x4FF80000,0x86000001,0x86000001,0x86000001,0x1940000,0x4FF80000,0x86000001,0x4FF80000,0x86000001,0x86000001,0x4FF80000,0x86000001,0x86000001,0x86000001,0x4FF80000,0x86000001,0x86000001,0x86000001,0x86000001,0x1540000,0x9200000,0x9200000,0x1C80000,0x37FC0000,0x6BF00000,0x86000001,0x86000001,0x3700000,0x3FC0000,0x81D40000,0x86000001, -0x1FFC0000,0xD40738,0xD4C402D4,0x9AC402D4,0x86C402D5,0xCAB00190,0xA2B000D5,0x88B8013A,0x90B00190,0x84B000D5,0x7CB00192,0xC49C02D3,0xA49C00A2,0x8CA800FF,0x949C00D1,0x869C0002,0x7CA000D7,0x869C02D4,0x829400FD,0x7A94013B,0x749C02D3,0x33C0734,0xAC7802D3,0x869C02D4,0x9E6C0192,0x888400CF,0x7C8C0192,0x985402D3,0x866400A3,0x7C6400D7,0x747402D4,0x23FC0734, -0x862402D4,0x7C180192,0x740002D4,0x6A000734,0xFEB4012D,0xFECC04A0,0xFECC0554,0xDC9C0000,0xAE9C0001,0x949C0002,0x88A00012,0x849C0011,0xFE9800FA,0xD08C0002,0x8A9000A9,0x7C6400D7,0x1C80734,0xE802D4,0xC0D800A4,0x94D800A4,0x86D400A5,0xB6C400C8,0x98C40001,0x88C80015,0x8AC400C8,0x84C00026,0x7CC400CA,0x15C02D3,0xA2A000A2,0x86BC00A3,0x969400C9,0x869C0002, -0x7EA800CA,0x33F802D3,0x866400A3,0x7C5400CA,0x740002D3,0x15C02D3,0xA2A000A2,0x86BC00A3,0x969400C9,0x869C0002,0x7EA800CA,0x33F802D3,0x866400A3,0x7C5400CA,0x740002D3,0x33F802D3,0x866400A3,0x7C5400CA,0x740002D3,0x740002D3,0xFEBC0076,0xF6DC01BA,0xFAE401AD,0xDC9C0000,0xAE9C0001,0x949C0002,0x88A80002,0x86900005,0xFEA40081,0xD08C0001,0x8C8800A2,0x7C5400CA, -0x1F002D3,0xC402D4,0xC402D4,0xC402D4,0xC402D4,0xACB000C8,0xACB000C8,0xACB000C8,0x80B000C8,0x80B000C8,0x72B000C9,0xA49C00A2,0xA49C00A2,0xA49C00A2,0x869C0001,0x869C0001,0x76A00026,0x789C00A2,0x789C00A2,0x72980015,0x6A9C00A2,0x12002D3,0x12002D3,0x12002D3,0x8C7C00C9,0x8C7C00C9,0x749400C9,0x866400A2,0x866400A2,0x72780002,0x6A8000A2,0x15F802D3, -0x15F802D3,0x724000C9,0x6A2400A2,0x600002D3,0xFEAC0065,0xF6BC01A0,0xC402D4,0xDC9C0000,0xAA9C0001,0x949C0001,0x8EA00006,0x809C0002,0xFE90004A,0xD08C0001,0x889400A2,0x72780002,0x19C02D3,0xD400A4,0xD400A4,0xD400A4,0xD400A4,0x98C40000,0x98C40000,0x98C40000,0x7CC40000,0x7CC40000,0x72C40001,0x33C00A2,0x33C00A2,0x33C00A2,0x82A40001,0x82A40001, -0x72B40001,0x23FC00A2,0x23FC00A2,0x727C0001,0x6A0000A2,0x33C00A2,0x33C00A2,0x33C00A2,0x82A40001,0x82A40001,0x72B40001,0x23FC00A2,0x23FC00A2,0x727C0001,0x6A0000A2,0x23FC00A2,0x23FC00A2,0x727C0001,0x6A0000A2,0x6A0000A2,0xFAB4000D,0xFECC0020,0xD400A4,0xDC9C0000,0xA8A00000,0x92A00000,0x88A80001,0x82980000,0xF29C0019,0xD08C0000,0x1C800A2,0x727C0001, -0x1C800A2,0xFC00C8,0xB0E80000,0x90E80001,0x86E80001,0x37400C8,0x98C40001,0x86D40001,0x3FFC00C8,0x86980001,0x7C0000CA,0x37400C8,0x98C40001,0x86D40001,0x3FFC00C8,0x86980001,0x7C0000CA,0x3FFC00C8,0x86980001,0x7C0000CA,0x7C0000CA,0x37400C8,0x98C40001,0x86D40001,0x3FFC00C8,0x86980001,0x7C0000CA,0x3FFC00C8,0x86980001,0x7C0000CA,0x7C0000CA,0x3FFC00C8, -0x86980001,0x7C0000CA,0x7C0000CA,0x7C0000CA,0xFAC80032,0x10C00C8,0xF2F40048,0xD8A00000,0xAE980001,0x96980000,0x86B00001,0x867C0001,0xFEAC0029,0xD28C0000,0x8AB40000,0x7C0000CA,0xDFC00C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0xB000C8,0x8A9C0000,0x8A9C0000,0x8A9C0000,0x8A9C0000,0x8A9C0000, -0x8A9C0000,0x6A9C0001,0x6A9C0001,0x6A9C0001,0x609C0001,0x10400C8,0x10400C8,0x10400C8,0x10400C8,0x10400C8,0x10400C8,0x72780001,0x72780001,0x72780001,0x60880001,0x7FC00C8,0x7FC00C8,0x7FC00C8,0x604C0001,0x560000CA,0xFAA40029,0xB000C8,0xB000C8,0xD89C0000,0xAE9C0000,0x989C0000,0x989C0000,0x7E9C0000,0xFC8C000D,0xC88C0001,0x72980001,0x72780001, -0x17400C8,}; -static const uint32_t g_etc1_to_bc7_m6_table78[] = { -0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x5F80000, -0x5F80000,0x5F80000,0x5F80000,0x54000001,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xB80000,0xB80000,0xB80000,0x1000000,0x16C0000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000, -0x13C0000,0x21FC0000,0x21FC0000,0x21FC0000,0x68000001,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x21FC0000,0x21FC0000,0x21FC0000,0x68000001,0x21FC0000,0x21FC0000,0x21FC0000,0x68000001,0x68000001,0x8E00000,0xD40000,0xD40000,0x4F40000,0x3080000,0x1200000,0x1200000,0x1640000,0x4F40000,0x3080000,0x1C00000,0x21FC0000, -0x1C00000,0xF80000,0xF80000,0xF80000,0xF80000,0x1700000,0x1700000,0x1700000,0x3DF80000,0x3DF80000,0x7A000001,0x1700000,0x1700000,0x1700000,0x3DF80000,0x3DF80000,0x7A000001,0x3DF80000,0x3DF80000,0x7A000001,0x7A000001,0x1700000,0x1700000,0x1700000,0x3DF80000,0x3DF80000,0x7A000001,0x3DF80000,0x3DF80000,0x7A000001,0x7A000001,0x3DF80000, -0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x1200000,0x1080000,0xF80000,0x1500000,0x1A00000,0x9FC0000,0x23FC0000,0x4DFC0000,0x5340000,0x1700000,0x9FC0000,0x7A000001,0x9FC0000,0x1200000,0x1AC0000,0x5BF80000,0x8E000001,0x1AC0000,0x5BF80000,0x8E000001,0x5BF80000,0x8E000001,0x8E000001,0x1AC0000,0x5BF80000,0x8E000001,0x5BF80000,0x8E000001, -0x8E000001,0x5BF80000,0x8E000001,0x8E000001,0x8E000001,0x1AC0000,0x5BF80000,0x8E000001,0x5BF80000,0x8E000001,0x8E000001,0x5BF80000,0x8E000001,0x8E000001,0x8E000001,0x5BF80000,0x8E000001,0x8E000001,0x8E000001,0x8E000001,0x1680000,0x1340000,0x1340000,0x1E40000,0x45FC0000,0x75F00000,0x8E000001,0x8E000001,0x1880000,0x13FC0000,0x89E40000,0x8E000001, -0x2FFC0000,0xE40738,0xDCD402D4,0xA2D402D4,0x8ED402D5,0xD2C00190,0xAAC000D5,0x90C8013A,0x98C00190,0x8CC000D5,0x84C00192,0xCCAC02D3,0xACAC00A2,0x94B800FF,0x9CAC00D1,0x8EAC0002,0x84B000D7,0x8EAC02D4,0x8AA400FD,0x82A4013B,0x7CAC02D3,0x1540734,0xB48802D3,0x8EAC02D4,0xA67C0192,0x909400CF,0x849C0192,0xA06402D3,0x8E7400A3,0x847400D7,0x7C8402D4,0x2FFC0734, -0x8E3402D4,0x84280192,0x7C0C02D3,0x72000734,0xFEC40168,0xF6DC04DA,0xF8E00569,0xE4AC0000,0xB6AC0001,0x9CAC0002,0x90B00012,0x8CAC0011,0xFCB0013D,0xD89C0002,0x92A000A9,0x847400D7,0x1E80734,0xF802D4,0xC8E800A4,0x9CE800A4,0x8EE400A5,0xBED400C8,0xA0D40001,0x90D80015,0x92D400C8,0x8CD00026,0x84D400CA,0x17402D3,0xAAB000A2,0x8ECC00A3,0x9EA400C9,0x8EAC0002, -0x86B800CA,0x3FF802D3,0x8E7400A3,0x846400CA,0x7C0002D3,0x17402D3,0xAAB000A2,0x8ECC00A3,0x9EA400C9,0x8EAC0002,0x86B800CA,0x3FF802D3,0x8E7400A3,0x846400CA,0x7C0002D3,0x3FF802D3,0x8E7400A3,0x846400CA,0x7C0002D3,0x7C0002D3,0xFED00083,0xFEEC01BA,0xF2F401C8,0xE4AC0000,0xB6AC0001,0x9CAC0002,0x90B80002,0x8EA00005,0xFEB40095,0xD89C0001,0x949800A2,0x846400CA, -0xBFC02D3,0xD402D4,0xD402D4,0xD402D4,0xD402D4,0xB4C000C8,0xB4C000C8,0xB4C000C8,0x88C000C8,0x88C000C8,0x7AC000C9,0xACAC00A2,0xACAC00A2,0xACAC00A2,0x8EAC0001,0x8EAC0001,0x7EB00026,0x80AC00A2,0x80AC00A2,0x7AA80015,0x72AC00A2,0x13802D3,0x13802D3,0x13802D3,0x948C00C9,0x948C00C9,0x7CA400C9,0x8E7400A2,0x8E7400A2,0x7A880002,0x729000A2,0x21F802D3, -0x21F802D3,0x7A5000C9,0x723400A2,0x680002D3,0xFEBC0075,0xFECC01A0,0xD402D4,0xE4AC0000,0xB2AC0001,0x9CAC0001,0x96B00006,0x88AC0002,0xFEA0005A,0xD89C0001,0x90A400A2,0x7A880002,0x1BC02D3,0xE400A4,0xE400A4,0xE400A4,0xE400A4,0xA0D40000,0xA0D40000,0xA0D40000,0x84D40000,0x84D40000,0x7AD40001,0x15400A2,0x15400A2,0x15400A2,0x8AB40001,0x8AB40001, -0x7AC40001,0x2FFC00A2,0x2FFC00A2,0x7A8C0001,0x720000A2,0x15400A2,0x15400A2,0x15400A2,0x8AB40001,0x8AB40001,0x7AC40001,0x2FFC00A2,0x2FFC00A2,0x7A8C0001,0x720000A2,0x2FFC00A2,0x2FFC00A2,0x7A8C0001,0x720000A2,0x720000A2,0xF6C80012,0xF6DC0029,0xE400A4,0xE4AC0000,0xB0B00000,0x9AB00000,0x90B80001,0x8AA80000,0xFAAC0019,0xD89C0000,0x1E800A2,0x7A8C0001, -0x1E800A2,0x10C00C8,0xB8F80000,0x98F80001,0x8EF80001,0x38C00C8,0xA0D40001,0x8EE40001,0x4BFC00C8,0x8EA80001,0x840000CA,0x38C00C8,0xA0D40001,0x8EE40001,0x4BFC00C8,0x8EA80001,0x840000CA,0x4BFC00C8,0x8EA80001,0x840000CA,0x840000CA,0x38C00C8,0xA0D40001,0x8EE40001,0x4BFC00C8,0x8EA80001,0x840000CA,0x4BFC00C8,0x8EA80001,0x840000CA,0x840000CA,0x4BFC00C8, -0x8EA80001,0x840000CA,0x840000CA,0x840000CA,0xF2E0003D,0x71C00C8,0xFB040048,0xE0B00000,0xB6A80001,0x9EA80000,0x8EC00001,0x8E8C0001,0xF4C80032,0xDA9C0000,0x92C40000,0x840000CA,0x1DF800C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0xC000C8,0x92AC0000,0x92AC0000,0x92AC0000,0x92AC0000,0x92AC0000, -0x92AC0000,0x72AC0001,0x72AC0001,0x72AC0001,0x68AC0001,0x11C00C8,0x11C00C8,0x11C00C8,0x11C00C8,0x11C00C8,0x11C00C8,0x7A880001,0x7A880001,0x7A880001,0x68980001,0x13FC00C8,0x13FC00C8,0x13FC00C8,0x685C0001,0x5E0000CA,0xF2B40034,0xC000C8,0xC000C8,0xE0AC0000,0xB6AC0000,0xA0AC0000,0xA0AC0000,0x86AC0000,0xFC9C0012,0xD09C0001,0x7AA80001,0x7A880001, -0x19800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table79[] = { -0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x11F80000, -0x11F80000,0x11F80000,0x11F80000,0x5C000001,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xC80000,0xC80000,0xC80000,0x1180000,0x1900000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000, -0x3500000,0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0x70000001,0xF40000,0xE40000,0xE40000,0x1080000,0x31C0000,0x3340000,0x3340000,0x1800000,0x1080000,0x31C0000,0x1E40000,0x2DFC0000, -0x1E40000,0x1080000,0x1080000,0x1080000,0x1080000,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x82000001,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x82000001,0x49F80000,0x49F80000,0x82000001,0x82000001,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x82000001,0x49F80000,0x49F80000,0x82000001,0x82000001,0x49F80000, -0x49F80000,0x82000001,0x82000001,0x82000001,0x1340000,0x5180000,0x1080000,0x1680000,0x1BC0000,0x19FC0000,0x31FC0000,0x59F40000,0x14C0000,0x1880000,0x19FC0000,0x82000001,0x19FC0000,0x1300000,0x1C40000,0x67F80000,0x96000001,0x1C40000,0x67F80000,0x96000001,0x67F80000,0x96000001,0x96000001,0x1C40000,0x67F80000,0x96000001,0x67F80000,0x96000001, -0x96000001,0x67F80000,0x96000001,0x96000001,0x96000001,0x1C40000,0x67F80000,0x96000001,0x67F80000,0x96000001,0x96000001,0x67F80000,0x96000001,0x96000001,0x96000001,0x67F80000,0x96000001,0x96000001,0x96000001,0x96000001,0x17C0000,0x1440000,0x1440000,0x3FC0000,0x53F80000,0x7FF00000,0x96000001,0x96000001,0x19C0000,0x25FC0000,0x91F40000,0x96000001, -0x3FF80000,0xF40738,0xE4E402D4,0xAAE402D4,0x96E402D5,0xDAD00190,0xB2D000D5,0x98D8013A,0xA0D00190,0x94D000D5,0x8CD00192,0xD4BC02D3,0xB4BC00A2,0x9CC800FF,0xA4BC00D1,0x96BC0002,0x8CC000D7,0x96BC02D4,0x92B400FD,0x8AB4013B,0x84BC02D3,0x16C0734,0xBC9802D3,0x96BC02D4,0xAE8C0192,0x98A400CF,0x8CAC0192,0xA87402D3,0x968400A3,0x8C8400D7,0x849402D4,0x3BFC0734, -0x964402D4,0x8C380192,0x841C02D3,0x7A000734,0xFED8019A,0xFEEC04DA,0xFEEC0585,0xECBC0000,0xBEBC0001,0xA4BC0002,0x98C00012,0x94BC0011,0xFEBC0167,0xE0AC0002,0x9AB000A9,0x8C8400D7,0x7FC0734,0x10802D4,0xD0F800A4,0xA4F800A4,0x96F400A5,0xC6E400C8,0xA8E40001,0x98E80015,0x9AE400C8,0x94E00026,0x8CE400CA,0x18C02D3,0xB2C000A2,0x96DC00A3,0xA6B400C9,0x96BC0002, -0x8EC800CA,0x4BF802D3,0x968400A3,0x8C7400CA,0x840002D3,0x18C02D3,0xB2C000A2,0x96DC00A3,0xA6B400C9,0x96BC0002,0x8EC800CA,0x4BF802D3,0x968400A3,0x8C7400CA,0x840002D3,0x4BF802D3,0x968400A3,0x8C7400CA,0x840002D3,0x840002D3,0xFEE400A6,0xF90001D4,0xFB0401C8,0xECBC0000,0xBEBC0001,0xA4BC0002,0x98C80002,0x96B00005,0xFACC00B5,0xE0AC0001,0x9CA800A2,0x8C7400CA, -0x1BFC02D3,0xE402D4,0xE402D4,0xE402D4,0xE402D4,0xBCD000C8,0xBCD000C8,0xBCD000C8,0x90D000C8,0x90D000C8,0x82D000C9,0xB4BC00A2,0xB4BC00A2,0xB4BC00A2,0x96BC0001,0x96BC0001,0x86C00026,0x88BC00A2,0x88BC00A2,0x82B80015,0x7ABC00A2,0x15002D3,0x15002D3,0x15002D3,0x9C9C00C9,0x9C9C00C9,0x84B400C9,0x968400A2,0x968400A2,0x82980002,0x7AA000A2,0x2DF802D3, -0x2DF802D3,0x826000C9,0x7A4400A2,0x700002D3,0xFECC0084,0xF6DC01B9,0xE402D4,0xECBC0000,0xBABC0001,0xA4BC0001,0x9EC00006,0x90BC0002,0xFEB40065,0xE0AC0001,0x98B400A2,0x82980002,0x1E002D3,0xF400A4,0xF400A4,0xF400A4,0xF400A4,0xA8E40000,0xA8E40000,0xA8E40000,0x8CE40000,0x8CE40000,0x82E40001,0x16C00A2,0x16C00A2,0x16C00A2,0x92C40001,0x92C40001, -0x82D40001,0x3BFC00A2,0x3BFC00A2,0x829C0001,0x7A0000A2,0x16C00A2,0x16C00A2,0x16C00A2,0x92C40001,0x92C40001,0x82D40001,0x3BFC00A2,0x3BFC00A2,0x829C0001,0x7A0000A2,0x3BFC00A2,0x3BFC00A2,0x829C0001,0x7A0000A2,0x7A0000A2,0xFED80012,0xFEEC0029,0xF400A4,0xECBC0000,0xB8C00000,0xA2C00000,0x98C80001,0x92B80000,0xFCC00020,0xE0AC0000,0x7FC00A2,0x829C0001, -0x7FC00A2,0x11C00C8,0xC1080000,0xA1080001,0x97080001,0x3A400C8,0xA8E40001,0x96F40001,0x57FC00C8,0x96B80001,0x8C0000CA,0x3A400C8,0xA8E40001,0x96F40001,0x57FC00C8,0x96B80001,0x8C0000CA,0x57FC00C8,0x96B80001,0x8C0000CA,0x8C0000CA,0x3A400C8,0xA8E40001,0x96F40001,0x57FC00C8,0x96B80001,0x8C0000CA,0x57FC00C8,0x96B80001,0x8C0000CA,0x8C0000CA,0x57FC00C8, -0x96B80001,0x8C0000CA,0x8C0000CA,0x8C0000CA,0xFAF0003D,0xF2C00C8,0xF3140055,0xE8C00000,0xBEB80001,0xA6B80000,0x96D00001,0x969C0001,0xFCD80032,0xE2AC0000,0x9AD40000,0x8C0000CA,0x2BFC00C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0xD000C8,0x9ABC0000,0x9ABC0000,0x9ABC0000,0x9ABC0000,0x9ABC0000, -0x9ABC0000,0x7ABC0001,0x7ABC0001,0x7ABC0001,0x70BC0001,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x82980001,0x82980001,0x82980001,0x70A80001,0x1FF800C8,0x1FF800C8,0x1FF800C8,0x706C0001,0x660000CA,0xFAC40034,0xD000C8,0xD000C8,0xE8BC0000,0xBEBC0000,0xA8BC0000,0xA8BC0000,0x8EBC0000,0xF8B00019,0xD8AC0001,0x82B80001,0x82980001, -0x1B800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table80[] = { -0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0x3300000,0x3300000,0x3300000,0x3300000,0x3300000,0x3300000,0x3300000,0x3300000,0x3300000,0x3300000,0x1DFC0000, -0x1DFC0000,0x1DFC0000,0x1DFC0000,0x66000000,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0xDC0000,0xDC0000,0xDC0000,0x3300000,0x1B40000,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000, -0x16C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x7A000000,0xB040000,0xF40001,0xF40001,0x51C0000,0x1340000,0x34C0000,0x34C0000,0x19C0000,0x51C0000,0x1340000,0x7FC0000,0x3BFC0000, -0x7FC0000,0x1180001,0x1180001,0x1180001,0x1180001,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x8C000000,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x8C000000,0x57F80000,0x57F80000,0x8C000000,0x8C000000,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x8C000000,0x57F80000,0x57F80000,0x8C000000,0x8C000000,0x57F80000, -0x57F80000,0x8C000000,0x8C000000,0x8C000000,0x1480000,0x12C0000,0x1180001,0x1800000,0x1D80000,0x29FC0000,0x3FFC0000,0x65F40000,0x3600000,0x1A40000,0x29FC0000,0x8C000000,0x29FC0000,0x1400001,0x3DC0000,0x73FC0000,0xA0000000,0x3DC0000,0x73FC0000,0xA0000000,0x73FC0000,0xA0000000,0xA0000000,0x3DC0000,0x73FC0000,0xA0000000,0x73FC0000,0xA0000000, -0xA0000000,0x73FC0000,0xA0000000,0xA0000000,0xA0000000,0x3DC0000,0x73FC0000,0xA0000000,0x73FC0000,0xA0000000,0xA0000000,0x73FC0000,0xA0000000,0xA0000000,0xA0000000,0x73FC0000,0xA0000000,0xA0000000,0xA0000000,0xA0000000,0x1940000,0x1580000,0x1580000,0x19FC0000,0x61FC0000,0x89FC0000,0xA0000000,0xA0000000,0x3B40000,0x37FC0000,0x9BE80000,0xA0000000, -0x4FFC0000,0x1080734,0xF0F402D3,0xB2F402D4,0xA0F402D3,0xE2E40192,0xBAE400D7,0xA4E8013B,0xA8E40192,0x9EE000D7,0x96E00192,0xDAD002D4,0xBCD000A3,0xA4D800FD,0xACCC00CF,0xA0D00002,0x96D400D5,0xA0CC02D4,0x9AC400FF,0x92CC013A,0x8CCC02D5,0x1880734,0xC4AC02D3,0xA0D002D4,0xB89C0192,0xA0B400D1,0x96BC0190,0xB28402D3,0xA09400A2,0x969800D5,0x8CA802D4,0x49F80734, -0xA05402D3,0x96440190,0x8C3002D4,0x82000738,0xFEEC01E2,0xF9000514,0xFB040594,0xF4D00002,0xC6CC0003,0xAED00002,0xA0D40011,0x9EC80012,0xFED4019A,0xECBC0000,0xA2C400A9,0x969800D5,0x19FC0734,0x11C02D3,0xDB0800A2,0xAF0800A2,0xA10800A2,0xCCF800C9,0xB0F80002,0xA2F80015,0xA4F400C9,0x9EF00026,0x96F400C9,0x3A402D3,0xBCD000A2,0xA0EC00A2,0xB0C400C9,0xA0D00001, -0x96DC00C8,0x57FC02D3,0xA09000A2,0x968400C8,0x8C0002D4,0x3A402D3,0xBCD000A2,0xA0EC00A2,0xB0C400C9,0xA0D00001,0x96DC00C8,0x57FC02D3,0xA09000A2,0x968400C8,0x8C0002D4,0x57FC02D3,0xA09000A2,0x968400C8,0x8C0002D4,0x8C0002D4,0xFEF800B6,0xFF0C01E3,0xF51801E6,0xF4D00001,0xC6CC0002,0xAED00001,0xA0DC0002,0x9EC00006,0xFEDC00C5,0xECBC0000,0xA4BC00A2,0x968400C8, -0x2BFC02D3,0xF402D3,0xF402D3,0xF402D3,0xF402D3,0xC2E400CA,0xC2E400CA,0xC2E400CA,0x9AE000CA,0x9AE000CA,0x8CE000CA,0xBCD000A3,0xBCD000A3,0xBCD000A3,0x9ED00002,0x9ED00002,0x8ED40026,0x90D000A3,0x90D000A3,0x8ACC0015,0x82CC00A5,0x36802D3,0x36802D3,0x36802D3,0xA4B000C9,0xA4B000C9,0x8CC800C8,0x9E9800A2,0x9E9800A2,0x8CA80001,0x82B400A4,0x39FC02D3, -0x39FC02D3,0x8C7000C8,0x825C00A4,0x7A0002D4,0xFAE000A6,0xFEEC01BE,0xF402D3,0xF8CC0001,0xC2D00002,0xACD00002,0xA6D00005,0x9ACC0002,0xFCCC0080,0xECBC0000,0xA0C800A3,0x8CA80001,0x5FC02D3,0x10800A2,0x10800A2,0x10800A2,0x10800A2,0xAEF80001,0xAEF80001,0xAEF80001,0x94F80001,0x94F80001,0x8CF40001,0x18800A2,0x18800A2,0x18800A2,0x9AD80001,0x9AD80001, -0x8CE40000,0x49F800A2,0x49F800A2,0x8CAC0000,0x820000A4,0x18800A2,0x18800A2,0x18800A2,0x9AD80001,0x9AD80001,0x8CE40000,0x49F800A2,0x49F800A2,0x8CAC0000,0x820000A4,0x49F800A2,0x49F800A2,0x8CAC0000,0x820000A4,0x820000A4,0xFAEC0019,0xF9000032,0x10800A2,0xF8CC0000,0xBED40000,0xAAD40000,0xA2D80000,0x9ACC0001,0xFED00028,0xECBC0000,0x19FC00A2,0x8CAC0000, -0x19FC00A2,0x12C00CA,0xC71C0001,0xAB180001,0xA1180001,0x1C000C8,0xB0F80001,0xA1040001,0x65F800C8,0xA0C80000,0x960000C8,0x1C000C8,0xB0F80001,0xA1040001,0x65F800C8,0xA0C80000,0x960000C8,0x65F800C8,0xA0C80000,0x960000C8,0x960000C8,0x1C000C8,0xB0F80001,0xA1040001,0x65F800C8,0xA0C80000,0x960000C8,0x65F800C8,0xA0C80000,0x960000C8,0x960000C8,0x65F800C8, -0xA0C80000,0x960000C8,0x960000C8,0x960000C8,0xFB040048,0x94000C8,0xFD280055,0xF4D00000,0xC6CC0001,0xB0C80000,0xA0E00000,0xA0A80000,0xFEF0003D,0xECBC0000,0xA2E80001,0x960000C8,0x3DF800C8,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xE000CA,0xA0D00001,0xA0D00001,0xA0D00001,0xA0D00001,0xA0D00001, -0xA0D00001,0x84CC0001,0x84CC0001,0x84CC0001,0x7ACC0001,0x15000C8,0x15000C8,0x15000C8,0x15000C8,0x15000C8,0x15000C8,0x8AAC0001,0x8AAC0001,0x8AAC0001,0x7AB80001,0x2DF800C8,0x2DF800C8,0x2DF800C8,0x7A7C0000,0x700000C8,0xF4D8003D,0xE000CA,0xE000CA,0xECD00001,0xC4D00001,0xAED00001,0xAED00001,0x96D00001,0xF4C40020,0xEABC0000,0x8EC80000,0x8AAC0001, -0x1E000C8,}; -static const uint32_t g_etc1_to_bc7_m6_table81[] = { -0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x29FC0000, -0x29FC0000,0x29FC0000,0x29FC0000,0x6E000000,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xDC0001,0xEC0000,0xEC0000,0xEC0000,0x1480000,0x1D80000,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000, -0x1840000,0x47FC0000,0x47FC0000,0x47FC0000,0x82000000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x47FC0000,0x47FC0000,0x47FC0000,0x82000000,0x47FC0000,0x47FC0000,0x47FC0000,0x82000000,0x82000000,0x1180000,0x1040001,0x1040001,0x1300000,0x1480000,0x1640000,0x1640000,0x1B80000,0x1300000,0x1480000,0x17FC0000,0x47FC0000, -0x17FC0000,0x1280001,0x1280001,0x1280001,0x1280001,0x1BC0000,0x1BC0000,0x1BC0000,0x61FC0000,0x61FC0000,0x94000000,0x1BC0000,0x1BC0000,0x1BC0000,0x61FC0000,0x61FC0000,0x94000000,0x61FC0000,0x61FC0000,0x94000000,0x94000000,0x1BC0000,0x1BC0000,0x1BC0000,0x61FC0000,0x61FC0000,0x94000000,0x61FC0000,0x61FC0000,0x94000000,0x94000000,0x61FC0000, -0x61FC0000,0x94000000,0x94000000,0x94000000,0x5580000,0x73C0000,0x1280001,0x1940000,0x1F40000,0x39FC0000,0x4DFC0000,0x6FFC0000,0x3740000,0x1BC0000,0x39FC0000,0x94000000,0x39FC0000,0x1500001,0x3F40000,0x7FFC0000,0xA8000000,0x3F40000,0x7FFC0000,0xA8000000,0x7FFC0000,0xA8000000,0xA8000000,0x3F40000,0x7FFC0000,0xA8000000,0x7FFC0000,0xA8000000, -0xA8000000,0x7FFC0000,0xA8000000,0xA8000000,0xA8000000,0x3F40000,0x7FFC0000,0xA8000000,0x7FFC0000,0xA8000000,0xA8000000,0x7FFC0000,0xA8000000,0xA8000000,0xA8000000,0x7FFC0000,0xA8000000,0xA8000000,0xA8000000,0xA8000000,0x1A80000,0x1680000,0x1680000,0x2DFC0000,0x6FFC0000,0x93FC0000,0xA8000000,0xA8000000,0x1CC0000,0x49FC0000,0xA3F80000,0xA8000000, -0x5FF80000,0x1180734,0xF90402D3,0xBB0402D4,0xA90402D3,0xEAF40192,0xC2F400D7,0xACF8013B,0xB0F40192,0xA6F000D7,0x9EF00192,0xE2E002D4,0xC4E000A3,0xACE800FD,0xB4DC00CF,0xA8E00002,0x9EE400D5,0xA8DC02D4,0xA2D400FF,0x9ADC013A,0x94DC02D5,0x1A00734,0xCCBC02D3,0xA8E002D4,0xC0AC0192,0xA8C400D1,0x9ECC0190,0xBA9402D3,0xA8A400A2,0x9EA800D5,0x94B802D4,0x55F80734, -0xA86402D3,0x9E540190,0x944002D4,0x8A000738,0xFEF8021F,0xFF0C0524,0xF31405C3,0xFCE00002,0xCEDC0003,0xB6E00002,0xA8E40011,0xA6D80012,0xFCEC01F6,0xF4CC0000,0xAAD400A9,0x9EA800D5,0x27FC0734,0x12C02D3,0xE31800A2,0xB71800A2,0xA91800A2,0xD50800C9,0xB9080002,0xAB080015,0xAD0400C9,0xA7000026,0x9F0400C9,0x3BC02D3,0xC4E000A2,0xA8FC00A2,0xB8D400C9,0xA8E00001, -0x9EEC00C8,0x63FC02D3,0xA8A000A2,0x9E9400C8,0x940002D4,0x3BC02D3,0xC4E000A2,0xA8FC00A2,0xB8D400C9,0xA8E00001,0x9EEC00C8,0x63FC02D3,0xA8A000A2,0x9E9400C8,0x940002D4,0x63FC02D3,0xA8A000A2,0x9E9400C8,0x940002D4,0x940002D4,0xFB0C00DE,0xF92001F1,0xFD2801E6,0xFCE00001,0xCEDC0002,0xB6E00001,0xA8EC0002,0xA6D00006,0xFCF400E1,0xF4CC0000,0xACCC00A2,0x9E9400C8, -0x3BFC02D3,0x10402D3,0x10402D3,0x10402D3,0x10402D3,0xCAF400CA,0xCAF400CA,0xCAF400CA,0xA2F000CA,0xA2F000CA,0x94F000CA,0xC4E000A3,0xC4E000A3,0xC4E000A3,0xA6E00002,0xA6E00002,0x96E40026,0x98E000A3,0x98E000A3,0x92DC0015,0x8ADC00A5,0x38002D3,0x38002D3,0x38002D3,0xACC000C9,0xACC000C9,0x94D800C8,0xA6A800A2,0xA6A800A2,0x94B80001,0x8AC400A4,0x45FC02D3, -0x45FC02D3,0x948000C8,0x8A6C00A4,0x820002D4,0xFEF400BA,0xF90001D3,0x10402D3,0xF6E00002,0xCAE00002,0xB4E00002,0xAEE00005,0xA2DC0002,0xFED800A1,0xF4CC0000,0xA8D800A3,0x94B80001,0x15FC02D3,0x11800A2,0x11800A2,0x11800A2,0x11800A2,0xB7080001,0xB7080001,0xB7080001,0x9D080001,0x9D080001,0x95040001,0x1A000A2,0x1A000A2,0x1A000A2,0xA2E80001,0xA2E80001, -0x94F40000,0x55F800A2,0x55F800A2,0x94BC0000,0x8A0000A4,0x1A000A2,0x1A000A2,0x1A000A2,0xA2E80001,0xA2E80001,0x94F40000,0x55F800A2,0x55F800A2,0x94BC0000,0x8A0000A4,0x55F800A2,0x55F800A2,0x94BC0000,0x8A0000A4,0x8A0000A4,0xF7000020,0xFF0C003A,0x11800A2,0xF4E40001,0xC6E40000,0xB2E40000,0xAAE80000,0xA2DC0001,0xF8EC0029,0xF4CC0000,0x27FC00A2,0x94BC0000, -0x27FC00A2,0x13C00CA,0xCF2C0001,0xB3280001,0xA9280001,0x1D800C8,0xB9080001,0xA9140001,0x71F800C8,0xA8D80000,0x9E0000C8,0x1D800C8,0xB9080001,0xA9140001,0x71F800C8,0xA8D80000,0x9E0000C8,0x71F800C8,0xA8D80000,0x9E0000C8,0x9E0000C8,0x1D800C8,0xB9080001,0xA9140001,0x71F800C8,0xA8D80000,0x9E0000C8,0x71F800C8,0xA8D80000,0x9E0000C8,0x9E0000C8,0x71F800C8, -0xA8D80000,0x9E0000C8,0x9E0000C8,0x9E0000C8,0xFF14004A,0x15400C8,0xF5380062,0xFCE00000,0xCEDC0001,0xB8D80000,0xA8F00000,0xA8B80000,0xF7080048,0xF4CC0000,0xAAF80001,0x9E0000C8,0x4BFC00C8,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xF000CA,0xA8E00001,0xA8E00001,0xA8E00001,0xA8E00001,0xA8E00001, -0xA8E00001,0x8CDC0001,0x8CDC0001,0x8CDC0001,0x82DC0001,0x16800C8,0x16800C8,0x16800C8,0x16800C8,0x16800C8,0x16800C8,0x92BC0001,0x92BC0001,0x92BC0001,0x82C80001,0x39F800C8,0x39F800C8,0x39F800C8,0x828C0000,0x780000C8,0xFCE8003D,0xF000CA,0xF000CA,0xF4E00001,0xCCE00001,0xB6E00001,0xB6E00001,0x9EE00001,0xFCD40020,0xF2CC0000,0x96D80000,0x92BC0001, -0x3FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table82[] = { -0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x35FC0000, -0x35FC0000,0x35FC0000,0x35FC0000,0x76000000,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0x6FC0000,0x6FC0000,0x6FC0000,0x1600000,0x1F80000,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000, -0x19C0000,0x53FC0000,0x53FC0000,0x53FC0000,0x8A000000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x53FC0000,0x53FC0000,0x53FC0000,0x8A000000,0x53FC0000,0x53FC0000,0x53FC0000,0x8A000000,0x8A000000,0x1280000,0x1140001,0x1140001,0x1440000,0x15C0000,0x3780000,0x3780000,0x1D40000,0x1440000,0x15C0000,0x25FC0000,0x53FC0000, -0x25FC0000,0x1380001,0x1380001,0x1380001,0x1380001,0x3D00000,0x3D00000,0x3D00000,0x6DFC0000,0x6DFC0000,0x9C000000,0x3D00000,0x3D00000,0x3D00000,0x6DFC0000,0x6DFC0000,0x9C000000,0x6DFC0000,0x6DFC0000,0x9C000000,0x9C000000,0x3D00000,0x3D00000,0x3D00000,0x6DFC0000,0x6DFC0000,0x9C000000,0x6DFC0000,0x6DFC0000,0x9C000000,0x9C000000,0x6DFC0000, -0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x16C0000,0xF4C0000,0x1380001,0x1AC0000,0xFFC0000,0x47FC0000,0x5BFC0000,0x7BF40000,0x3880000,0x3D00000,0x47FC0000,0x9C000000,0x47FC0000,0x1600001,0x13FC0000,0x8BFC0000,0xB0000000,0x13FC0000,0x8BFC0000,0xB0000000,0x8BFC0000,0xB0000000,0xB0000000,0x13FC0000,0x8BFC0000,0xB0000000,0x8BFC0000,0xB0000000, -0xB0000000,0x8BFC0000,0xB0000000,0xB0000000,0xB0000000,0x13FC0000,0x8BFC0000,0xB0000000,0x8BFC0000,0xB0000000,0xB0000000,0x8BFC0000,0xB0000000,0xB0000000,0xB0000000,0x8BFC0000,0xB0000000,0xB0000000,0xB0000000,0xB0000000,0x1BC0000,0x5780000,0x5780000,0x41FC0000,0x7DF80000,0x9DFC0000,0xB0000000,0xB0000000,0x1E00000,0x59FC0000,0xADCC0000,0xB0000000, -0x6DFC0000,0x1280734,0xFD1402D4,0xC31402D4,0xB11402D3,0xF3040192,0xCB0400D7,0xB508013B,0xB9040192,0xAF0000D7,0xA7000192,0xEAF002D4,0xCCF000A3,0xB4F800FD,0xBCEC00CF,0xB0F00002,0xA6F400D5,0xB0EC02D4,0xAAE400FF,0xA2EC013A,0x9CEC02D5,0x1B80734,0xD4CC02D3,0xB0F002D4,0xC8BC0192,0xB0D400D1,0xA6DC0190,0xC2A402D3,0xB0B400A2,0xA6B800D5,0x9CC802D4,0x61F80734, -0xB07402D3,0xA6640190,0x9C5002D4,0x92000738,0xFF0C0252,0xF9200552,0xFB2405C3,0xFEF00006,0xD6EC0003,0xBEF00002,0xB0F40011,0xAEE80012,0xFEF8021A,0xFCDC0000,0xB2E400A9,0xA6B800D5,0x37FC0734,0x13C02D3,0xEB2800A2,0xBF2800A2,0xB12800A2,0xDD1800C9,0xC1180002,0xB3180015,0xB51400C9,0xAF100026,0xA71400C9,0x1D402D3,0xCCF000A2,0xB10C00A2,0xC0E400C9,0xB0F00001, -0xA6FC00C8,0x6FFC02D3,0xB0B000A2,0xA6A400C8,0x9C0002D4,0x1D402D3,0xCCF000A2,0xB10C00A2,0xC0E400C9,0xB0F00001,0xA6FC00C8,0x6FFC02D3,0xB0B000A2,0xA6A400C8,0x9C0002D4,0x6FFC02D3,0xB0B000A2,0xA6A400C8,0x9C0002D4,0x9C0002D4,0xFD1C00F5,0xFF2C0209,0xF5380203,0xFCF40005,0xD6EC0002,0xBEF00001,0xB0FC0002,0xAEE00006,0xFF0800F4,0xFCDC0000,0xB4DC00A2,0xA6A400C8, -0x49FC02D3,0x11402D3,0x11402D3,0x11402D3,0x11402D3,0xD30400CA,0xD30400CA,0xD30400CA,0xAB0000CA,0xAB0000CA,0x9D0000CA,0xCCF000A3,0xCCF000A3,0xCCF000A3,0xAEF00002,0xAEF00002,0x9EF40026,0xA0F000A3,0xA0F000A3,0x9AEC0015,0x92EC00A5,0x39802D3,0x39802D3,0x39802D3,0xB4D000C9,0xB4D000C9,0x9CE800C8,0xAEB800A2,0xAEB800A2,0x9CC80001,0x92D400A4,0x51FC02D3, -0x51FC02D3,0x9C9000C8,0x927C00A4,0x8A0002D4,0xFF0400CB,0xFF0C01DB,0x11402D3,0xFEF00002,0xD2F00002,0xBCF00002,0xB6F00005,0xAAEC0002,0xFCF000B5,0xFCDC0000,0xB0E800A3,0x9CC80001,0x23FC02D3,0x12800A2,0x12800A2,0x12800A2,0x12800A2,0xBF180001,0xBF180001,0xBF180001,0xA5180001,0xA5180001,0x9D140001,0x1B800A2,0x1B800A2,0x1B800A2,0xAAF80001,0xAAF80001, -0x9D040000,0x61F800A2,0x61F800A2,0x9CCC0000,0x920000A4,0x1B800A2,0x1B800A2,0x1B800A2,0xAAF80001,0xAAF80001,0x9D040000,0x61F800A2,0x61F800A2,0x9CCC0000,0x920000A4,0x61F800A2,0x61F800A2,0x9CCC0000,0x920000A4,0x920000A4,0xFF100020,0xF920003D,0x12800A2,0xFCF40001,0xCEF40000,0xBAF40000,0xB2F80000,0xAAEC0001,0xFEF8002D,0xFCDC0000,0x37FC00A2,0x9CCC0000, -0x37FC00A2,0x14C00CA,0xD73C0001,0xBB380001,0xB1380001,0x1F000C8,0xC1180001,0xB1240001,0x7DF800C8,0xB0E80000,0xA60000C8,0x1F000C8,0xC1180001,0xB1240001,0x7DF800C8,0xB0E80000,0xA60000C8,0x7DF800C8,0xB0E80000,0xA60000C8,0xA60000C8,0x1F000C8,0xC1180001,0xB1240001,0x7DF800C8,0xB0E80000,0xA60000C8,0x7DF800C8,0xB0E80000,0xA60000C8,0xA60000C8,0x7DF800C8, -0xB0E80000,0xA60000C8,0xA60000C8,0xA60000C8,0xFB2C0055,0x16400C8,0xFD480062,0xFEF40001,0xD6EC0001,0xC0E80000,0xB1000000,0xB0C80000,0xFF180048,0xFCDC0000,0xB3080001,0xA60000C8,0x5BFC00C8,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0x10000CA,0xB0F00001,0xB0F00001,0xB0F00001,0xB0F00001,0xB0F00001, -0xB0F00001,0x94EC0001,0x94EC0001,0x94EC0001,0x8AEC0001,0x18000C8,0x18000C8,0x18000C8,0x18000C8,0x18000C8,0x18000C8,0x9ACC0001,0x9ACC0001,0x9ACC0001,0x8AD80001,0x45F800C8,0x45F800C8,0x45F800C8,0x8A9C0000,0x800000C8,0xF4F8004A,0x10000CA,0x10000CA,0xFCF00001,0xD4F00001,0xBEF00001,0xBEF00001,0xA6F00001,0xF8E80029,0xFADC0000,0x9EE80000,0x9ACC0001, -0x13FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table83[] = { -0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x41FC0000, -0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xF0C0000,0xF0C0000,0xF0C0000,0x1780000,0xFFC0000,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000, -0x1B40000,0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x92000000,0x5380000,0x1240001,0x1240001,0x3540000,0x1700000,0x1900000,0x1900000,0x3EC0000,0x3540000,0x1700000,0x35FC0000,0x5FF80000, -0x35FC0000,0x1480001,0x1480001,0x1480001,0x1480001,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0xA4000000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0xA4000000,0x79FC0000,0x79FC0000,0xA4000000,0xA4000000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0xA4000000,0x79FC0000,0x79FC0000,0xA4000000,0xA4000000,0x79FC0000, -0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0x1800000,0x1600000,0x1480001,0x1C00000,0x23FC0000,0x57FC0000,0x69F80000,0x85F80000,0x39C0000,0x3E80000,0x57FC0000,0xA4000000,0x57FC0000,0x1700001,0x2BFC0000,0x97FC0000,0xB8000000,0x2BFC0000,0x97FC0000,0xB8000000,0x97FC0000,0xB8000000,0xB8000000,0x2BFC0000,0x97FC0000,0xB8000000,0x97FC0000,0xB8000000, -0xB8000000,0x97FC0000,0xB8000000,0xB8000000,0xB8000000,0x2BFC0000,0x97FC0000,0xB8000000,0x97FC0000,0xB8000000,0xB8000000,0x97FC0000,0xB8000000,0xB8000000,0xB8000000,0x97FC0000,0xB8000000,0xB8000000,0xB8000000,0xB8000000,0x1D00000,0xD880000,0xD880000,0x53FC0000,0x89FC0000,0xA7FC0000,0xB8000000,0xB8000000,0x1F80000,0x6BFC0000,0xB5DC0000,0xB8000000, -0x7DF80000,0x1380734,0xFF2402DC,0xCB2402D4,0xB92402D3,0xFB140192,0xD31400D7,0xBD18013B,0xC1140192,0xB71000D7,0xAF100192,0xF30002D4,0xD50000A3,0xBD0800FD,0xC4FC00CF,0xB9000002,0xAF0400D5,0xB8FC02D4,0xB2F400FF,0xAAFC013A,0xA4FC02D5,0x1D00734,0xDCDC02D3,0xB90002D4,0xD0CC0192,0xB8E400D1,0xAEEC0190,0xCAB402D3,0xB8C400A2,0xAEC800D5,0xA4D802D4,0x6DF80734, -0xB88402D3,0xAE740190,0xA46002D4,0x9A000738,0xFF20028E,0xFF2C056A,0xF33405F4,0xFF04001E,0xDEFC0003,0xC7000002,0xB9040011,0xB6F80012,0xFF10025E,0xFEF00006,0xBAF400A9,0xAEC800D5,0x45FC0734,0x14C02D3,0xF33800A2,0xC73800A2,0xB93800A2,0xE52800C9,0xC9280002,0xBB280015,0xBD2400C9,0xB7200026,0xAF2400C9,0x1EC02D3,0xD50000A2,0xB91C00A2,0xC8F400C9,0xB9000001, -0xAF0C00C8,0x7BFC02D3,0xB8C000A2,0xAEB400C8,0xA40002D4,0x1EC02D3,0xD50000A2,0xB91C00A2,0xC8F400C9,0xB9000001,0xAF0C00C8,0x7BFC02D3,0xB8C000A2,0xAEB400C8,0xA40002D4,0x7BFC02D3,0xB8C000A2,0xAEB400C8,0xA40002D4,0xA40002D4,0xFD30010A,0xFB44020B,0xFD480203,0xFF08000D,0xDEFC0002,0xC7000001,0xB90C0002,0xB6F00006,0xFF180119,0xFEF00005,0xBCEC00A2,0xAEB400C8, -0x59FC02D3,0x12402D3,0x12402D3,0x12402D3,0x12402D3,0xDB1400CA,0xDB1400CA,0xDB1400CA,0xB31000CA,0xB31000CA,0xA51000CA,0xD50000A3,0xD50000A3,0xD50000A3,0xB7000002,0xB7000002,0xA7040026,0xA90000A3,0xA90000A3,0xA2FC0015,0x9AFC00A5,0x3B002D3,0x3B002D3,0x3B002D3,0xBCE000C9,0xBCE000C9,0xA4F800C8,0xB6C800A2,0xB6C800A2,0xA4D80001,0x9AE400A4,0x5DFC02D3, -0x5DFC02D3,0xA4A000C8,0x9A8C00A4,0x920002D4,0xFF1000F1,0xF92001EE,0x12402D3,0xFF00000B,0xDB000002,0xC5000002,0xBF000005,0xB2FC0002,0xFF0000CB,0xFCF00002,0xB8F800A3,0xA4D80001,0x33FC02D3,0x13800A2,0x13800A2,0x13800A2,0x13800A2,0xC7280001,0xC7280001,0xC7280001,0xAD280001,0xAD280001,0xA5240001,0x1D000A2,0x1D000A2,0x1D000A2,0xB3080001,0xB3080001, -0xA5140000,0x6DF800A2,0x6DF800A2,0xA4DC0000,0x9A0000A4,0x1D000A2,0x1D000A2,0x1D000A2,0xB3080001,0xB3080001,0xA5140000,0x6DF800A2,0x6DF800A2,0xA4DC0000,0x9A0000A4,0x6DF800A2,0x6DF800A2,0xA4DC0000,0x9A0000A4,0x9A0000A4,0xFF200029,0xFF2C0049,0x13800A2,0xFD040004,0xD7040000,0xC3040000,0xBB080000,0xB2FC0001,0xFD100032,0xFCF00001,0x45FC00A2,0xA4DC0000, -0x45FC00A2,0x15C00CA,0xDF4C0001,0xC3480001,0xB9480001,0xDFC00C8,0xC9280001,0xB9340001,0x89F800C8,0xB8F80000,0xAE0000C8,0xDFC00C8,0xC9280001,0xB9340001,0x89F800C8,0xB8F80000,0xAE0000C8,0x89F800C8,0xB8F80000,0xAE0000C8,0xAE0000C8,0xDFC00C8,0xC9280001,0xB9340001,0x89F800C8,0xB8F80000,0xAE0000C8,0x89F800C8,0xB8F80000,0xAE0000C8,0xAE0000C8,0x89F800C8, -0xB8F80000,0xAE0000C8,0xAE0000C8,0xAE0000C8,0xF7400062,0x37400C8,0xF5580071,0xFD100005,0xDEFC0001,0xC8F80000,0xB9100000,0xB8D80000,0xFF2C0055,0xF8FC0002,0xBB180001,0xAE0000C8,0x69FC00C8,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0x11000CA,0xB9000001,0xB9000001,0xB9000001,0xB9000001,0xB9000001, -0xB9000001,0x9CFC0001,0x9CFC0001,0x9CFC0001,0x92FC0001,0x19800C8,0x19800C8,0x19800C8,0x19800C8,0x19800C8,0x19800C8,0xA2DC0001,0xA2DC0001,0xA2DC0001,0x92E80001,0x51F800C8,0x51F800C8,0x51F800C8,0x92AC0000,0x880000C8,0xFD08004A,0x11000CA,0x11000CA,0xFD000002,0xDD000001,0xC7000001,0xC7000001,0xAF000001,0xFEF4002D,0xFAF00001,0xA6F80000,0xA2DC0001, -0x21FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table84[] = { -0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x4FF80000, -0x4FF80000,0x4FF80000,0x4FF80000,0x86000001,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x9200000,0x9200000,0x9200000,0x1940000,0x1FFC0000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000, -0x1D00000,0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x9A000001,0x14C0000,0x1380000,0x1380000,0x7680000,0x1880000,0x1A80000,0x1A80000,0xDFC0000,0x7680000,0x1880000,0x45FC0000,0x6DF80000, -0x45FC0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x87FC0000,0x87FC0000,0xAC000001,0xAC000001,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x87FC0000,0x87FC0000,0xAC000001,0xAC000001,0x87FC0000, -0x87FC0000,0xAC000001,0xAC000001,0xAC000001,0x1940000,0x1740000,0x15C0000,0x1D80000,0x39FC0000,0x67FC0000,0x77FC0000,0x91FC0000,0x1B40000,0x9FC0000,0x67FC0000,0xAC000001,0x67FC0000,0x1840000,0x47FC0000,0xA5F80000,0xC0000001,0x47FC0000,0xA5F80000,0xC0000001,0xA5F80000,0xC0000001,0xC0000001,0x47FC0000,0xA5F80000,0xC0000001,0xA5F80000,0xC0000001, -0xC0000001,0xA5F80000,0xC0000001,0xC0000001,0xC0000001,0x47FC0000,0xA5F80000,0xC0000001,0xA5F80000,0xC0000001,0xC0000001,0xA5F80000,0xC0000001,0xC0000001,0xC0000001,0xA5F80000,0xC0000001,0xC0000001,0xC0000001,0xC0000001,0x5E40000,0x79C0000,0x79C0000,0x6BFC0000,0x99FC0000,0xB3F80000,0xC0000001,0xC0000001,0x1BFC0000,0x7DFC0000,0xBFD00000,0xC0000001, -0x8DFC0000,0x1480738,0xFD3802F8,0xD53802D4,0xC13802D5,0xFF240198,0xDD2400D5,0xC32C013A,0xCB240190,0xBF2400D5,0xB7240192,0xFF1002D3,0xDF1000A2,0xC71C00FF,0xCF1000D1,0xC1100002,0xB71400D7,0xC11002D4,0xBD0800FD,0xB508013B,0xAF1002D3,0x3E80734,0xE6EC02D3,0xC11002D4,0xD8E00192,0xC2F800CF,0xB7000192,0xD2C802D3,0xC0D800A3,0xB6D800D7,0xAEE802D4,0x79FC0734, -0xC09802D4,0xB68C0192,0xAE7002D3,0xA4000734,0xFF3402E1,0xFB440590,0xFD4805F4,0xFF18004A,0xE9100001,0xCF100002,0xC3140012,0xBF100011,0xFF2402C7,0xFF080025,0xC50400A9,0xB6D800D7,0x57FC0734,0x15C02D4,0xFB4C00A4,0xCF4C00A4,0xC14800A5,0xF13800C8,0xD3380001,0xC33C0015,0xC53800C8,0xBF340026,0xB73800CA,0xDFC02D3,0xDD1400A2,0xC13000A3,0xD10800C9,0xC1100002, -0xB91C00CA,0x89F802D3,0xC0D800A3,0xB6C800CA,0xAE0002D3,0xDFC02D3,0xDD1400A2,0xC13000A3,0xD10800C9,0xC1100002,0xB91C00CA,0x89F802D3,0xC0D800A3,0xB6C800CA,0xAE0002D3,0x89F802D3,0xC0D800A3,0xB6C800CA,0xAE0002D3,0xAE0002D3,0xFF44013A,0xF558022A,0xF5580225,0xFF20002A,0xE9100001,0xCF100002,0xC31C0002,0xC1040005,0xFF34013A,0xFF0C0012,0xC6FC00A2,0xB6C800CA, -0x69FC02D3,0x13802D4,0x13802D4,0x13802D4,0x13802D4,0xE72400C8,0xE72400C8,0xE72400C8,0xBB2400C8,0xBB2400C8,0xAD2400C9,0xDF1000A2,0xDF1000A2,0xDF1000A2,0xC1100001,0xC1100001,0xB1140026,0xB31000A2,0xB31000A2,0xAD0C0015,0xA51000A2,0x1CC02D3,0x1CC02D3,0x1CC02D3,0xC6F000C9,0xC6F000C9,0xAF0800C9,0xC0D800A2,0xC0D800A2,0xACEC0002,0xA4F400A2,0x6BF802D3, -0x6BF802D3,0xACB400C9,0xA49800A2,0x9A0002D3,0xFD28010A,0xFF2C0209,0x13802D4,0xFF180019,0xE5100001,0xCF100001,0xC9140006,0xBB100002,0xFF1400E5,0xFF04000E,0xC30800A2,0xACEC0002,0x43FC02D3,0x14800A4,0x14800A4,0x14800A4,0x14800A4,0xD3380000,0xD3380000,0xD3380000,0xB7380000,0xB7380000,0xAD380001,0x3E800A2,0x3E800A2,0x3E800A2,0xBD180001,0xBD180001, -0xAD280001,0x79FC00A2,0x79FC00A2,0xACF00001,0xA40000A2,0x3E800A2,0x3E800A2,0x3E800A2,0xBD180001,0xBD180001,0xAD280001,0x79FC00A2,0x79FC00A2,0xACF00001,0xA40000A2,0x79FC00A2,0x79FC00A2,0xACF00001,0xA40000A2,0xA40000A2,0xFB340034,0xFB440048,0x14800A4,0xFF1C0008,0xE3140000,0xCD140000,0xC31C0001,0xBD0C0000,0xF928003D,0xF90C0005,0x57FC00A2,0xACF00001, -0x57FC00A2,0x17000C8,0xEB5C0000,0xCB5C0001,0xC15C0001,0x29FC00C8,0xD3380001,0xC1480001,0x97F800C8,0xC10C0001,0xB60000CA,0x29FC00C8,0xD3380001,0xC1480001,0x97F800C8,0xC10C0001,0xB60000CA,0x97F800C8,0xC10C0001,0xB60000CA,0xB60000CA,0x29FC00C8,0xD3380001,0xC1480001,0x97F800C8,0xC10C0001,0xB60000CA,0x97F800C8,0xC10C0001,0xB60000CA,0xB60000CA,0x97F800C8, -0xC10C0001,0xB60000CA,0xB60000CA,0xB60000CA,0xFF500064,0x18800C8,0xFF6C0071,0xFD28000D,0xE90C0001,0xD10C0000,0xC1240001,0xC0F00001,0xF9480062,0xFF100005,0xC5280000,0xB60000CA,0x7BFC00C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0x12400C8,0xC5100000,0xC5100000,0xC5100000,0xC5100000,0xC5100000, -0xC5100000,0xA5100001,0xA5100001,0xA5100001,0x9B100001,0x3B000C8,0x3B000C8,0x3B000C8,0x3B000C8,0x3B000C8,0x3B000C8,0xACEC0001,0xACEC0001,0xACEC0001,0x9AFC0001,0x5DFC00C8,0x5DFC00C8,0x5DFC00C8,0x9AC00001,0x900000CA,0xF71C0055,0x12400C8,0x12400C8,0xF9140008,0xE9100000,0xD3100000,0xD3100000,0xB9100000,0xFD0C0032,0xFF000004,0xAD0C0001,0xACEC0001, -0x33FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table85[] = { -0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x5BF80000, -0x5BF80000,0x5BF80000,0x5BF80000,0x8E000001,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1340000,0x1340000,0x1340000,0x1AC0000,0x2FFC0000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000, -0x1E80000,0x79F80000,0x79F80000,0x79F80000,0xA2000001,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x79F80000,0x79F80000,0x79F80000,0xA2000001,0x79F80000,0x79F80000,0x79F80000,0xA2000001,0xA2000001,0x75C0000,0x1480000,0x1480000,0x37C0000,0x19C0000,0x3BC0000,0x3BC0000,0x21FC0000,0x37C0000,0x19C0000,0x55FC0000,0x79F80000, -0x55FC0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x23FC0000,0x23FC0000,0x23FC0000,0x93FC0000,0x93FC0000,0xB4000001,0x23FC0000,0x23FC0000,0x23FC0000,0x93FC0000,0x93FC0000,0xB4000001,0x93FC0000,0x93FC0000,0xB4000001,0xB4000001,0x23FC0000,0x23FC0000,0x23FC0000,0x93FC0000,0x93FC0000,0xB4000001,0x93FC0000,0x93FC0000,0xB4000001,0xB4000001,0x93FC0000, -0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0x1A80000,0x1840000,0x16C0000,0x1F00000,0x4DFC0000,0x77FC0000,0x85FC0000,0x9DF40000,0x1C80000,0x23FC0000,0x77FC0000,0xB4000001,0x77FC0000,0x1940000,0x5FFC0000,0xB1F80000,0xC8000001,0x5FFC0000,0xB1F80000,0xC8000001,0xB1F80000,0xC8000001,0xC8000001,0x5FFC0000,0xB1F80000,0xC8000001,0xB1F80000,0xC8000001, -0xC8000001,0xB1F80000,0xC8000001,0xC8000001,0xC8000001,0x5FFC0000,0xB1F80000,0xC8000001,0xB1F80000,0xC8000001,0xC8000001,0xB1F80000,0xC8000001,0xC8000001,0xC8000001,0xB1F80000,0xC8000001,0xC8000001,0xC8000001,0xC8000001,0x5F80000,0xFAC0000,0xFAC0000,0x7DFC0000,0xA7F80000,0xBDF80000,0xC8000001,0xC8000001,0x39FC0000,0x8FFC0000,0xC7E00000,0xC8000001, -0x9DF80000,0x1580738,0xFF480314,0xDD4802D4,0xC94802D5,0xFD3801B8,0xE53400D5,0xCB3C013A,0xD3340190,0xC73400D5,0xBF340192,0xFF2402D8,0xE72000A2,0xCF2C00FF,0xD72000D1,0xC9200002,0xBF2400D7,0xC92002D4,0xC51800FD,0xBD18013B,0xB72002D3,0x7FC0734,0xEEFC02D3,0xC92002D4,0xE0F00192,0xCB0800CF,0xBF100192,0xDAD802D3,0xC8E800A3,0xBEE800D7,0xB6F802D4,0x85FC0734, -0xC8A802D4,0xBE9C0192,0xB68002D3,0xAC000734,0xFF44033E,0xFF4C05D0,0xF5580625,0xFF2C0086,0xF1200001,0xD7200002,0xCB240012,0xC7200011,0xFF3402FA,0xFF1C0054,0xCD1400A9,0xBEE800D7,0x65FC0734,0x16C02D4,0xFF5C00A5,0xD75C00A4,0xC95800A5,0xF94800C8,0xDB480001,0xCB4C0015,0xCD4800C8,0xC7440026,0xBF4800CA,0x25FC02D3,0xE52400A2,0xC94000A3,0xD91800C9,0xC9200002, -0xC12C00CA,0x95F802D3,0xC8E800A3,0xBED800CA,0xB60002D3,0x25FC02D3,0xE52400A2,0xC94000A3,0xD91800C9,0xC9200002,0xC12C00CA,0x95F802D3,0xC8E800A3,0xBED800CA,0xB60002D3,0x95F802D3,0xC8E800A3,0xBED800CA,0xB60002D3,0xB60002D3,0xFF500155,0xFD68022A,0xFD680225,0xFF340042,0xF1200001,0xD7200002,0xCB2C0002,0xC9140005,0xFF44015B,0xFF240029,0xCF0C00A2,0xBED800CA, -0x79FC02D3,0x14802D4,0x14802D4,0x14802D4,0x14802D4,0xEF3400C8,0xEF3400C8,0xEF3400C8,0xC33400C8,0xC33400C8,0xB53400C9,0xE72000A2,0xE72000A2,0xE72000A2,0xC9200001,0xC9200001,0xB9240026,0xBB2000A2,0xBB2000A2,0xB51C0015,0xAD2000A2,0x1E402D3,0x1E402D3,0x1E402D3,0xCF0000C9,0xCF0000C9,0xB71800C9,0xC8E800A2,0xC8E800A2,0xB4FC0002,0xAD0400A2,0x77F802D3, -0x77F802D3,0xB4C400C9,0xACA800A2,0xA20002D3,0xFD380124,0xFB44020C,0x14802D4,0xFD280035,0xED200001,0xD7200001,0xD1240006,0xC3200002,0xFB2C0109,0xFF18001A,0xCB1800A2,0xB4FC0002,0x53FC02D3,0x15800A4,0x15800A4,0x15800A4,0x15800A4,0xDB480000,0xDB480000,0xDB480000,0xBF480000,0xBF480000,0xB5480001,0x7FC00A2,0x7FC00A2,0x7FC00A2,0xC5280001,0xC5280001, -0xB5380001,0x85FC00A2,0x85FC00A2,0xB5000001,0xAC0000A2,0x7FC00A2,0x7FC00A2,0x7FC00A2,0xC5280001,0xC5280001,0xB5380001,0x85FC00A2,0x85FC00A2,0xB5000001,0xAC0000A2,0x85FC00A2,0x85FC00A2,0xB5000001,0xAC0000A2,0xAC0000A2,0xF748003D,0xF3540055,0x15800A4,0xFD30000D,0xEB240000,0xD5240000,0xCB2C0001,0xC51C0000,0xFF340041,0xFD200008,0x65FC00A2,0xB5000001, -0x65FC00A2,0x18000C8,0xF36C0000,0xD36C0001,0xC96C0001,0x41FC00C8,0xDB480001,0xC9580001,0xA1FC00C8,0xC91C0001,0xBE0000CA,0x41FC00C8,0xDB480001,0xC9580001,0xA1FC00C8,0xC91C0001,0xBE0000CA,0xA1FC00C8,0xC91C0001,0xBE0000CA,0xBE0000CA,0x41FC00C8,0xDB480001,0xC9580001,0xA1FC00C8,0xC91C0001,0xBE0000CA,0xA1FC00C8,0xC91C0001,0xBE0000CA,0xBE0000CA,0xA1FC00C8, -0xC91C0001,0xBE0000CA,0xBE0000CA,0xBE0000CA,0xF7680071,0x59800C8,0xF77C0080,0xFF400012,0xF11C0001,0xD91C0000,0xC9340001,0xC9000001,0xFD580064,0xFF2C000D,0xCD380000,0xBE0000CA,0x89FC00C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0x13400C8,0xCD200000,0xCD200000,0xCD200000,0xCD200000,0xCD200000, -0xCD200000,0xAD200001,0xAD200001,0xAD200001,0xA3200001,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0xB4FC0001,0xB4FC0001,0xB4FC0001,0xA30C0001,0x69FC00C8,0x69FC00C8,0x69FC00C8,0xA2D00001,0x980000CA,0xFF2C0055,0x13400C8,0x13400C8,0xFB24000D,0xF1200000,0xDB200000,0xDB200000,0xC1200000,0xFD1C003D,0xFF140005,0xB51C0001,0xB4FC0001, -0x41FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table86[] = { -0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x67F80000, -0x67F80000,0x67F80000,0x67F80000,0x96000001,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1440000,0x1440000,0x1440000,0x1C40000,0x3FF80000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000, -0x3FC0000,0x85F80000,0x85F80000,0x85F80000,0xAA000001,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x85F80000,0x85F80000,0x85F80000,0xAA000001,0x85F80000,0x85F80000,0x85F80000,0xAA000001,0xAA000001,0xF6C0000,0x1580000,0x1580000,0x1900000,0x1B00000,0x1D40000,0x1D40000,0x33FC0000,0x1900000,0x1B00000,0x63FC0000,0x85F80000, -0x63FC0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x9FF80000,0x9FF80000,0xBC000001,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x9FF80000,0x9FF80000,0xBC000001,0x9FF80000,0x9FF80000,0xBC000001,0xBC000001,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x9FF80000,0x9FF80000,0xBC000001,0x9FF80000,0x9FF80000,0xBC000001,0xBC000001,0x9FF80000, -0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0x5B80000,0x3940000,0x17C0000,0xDFC0000,0x61FC0000,0x85FC0000,0x93F80000,0xA7F80000,0x1DC0000,0x3BFC0000,0x85FC0000,0xBC000001,0x85FC0000,0x1A40000,0x77FC0000,0xBDF80000,0xD0000001,0x77FC0000,0xBDF80000,0xD0000001,0xBDF80000,0xD0000001,0xD0000001,0x77FC0000,0xBDF80000,0xD0000001,0xBDF80000,0xD0000001, -0xD0000001,0xBDF80000,0xD0000001,0xD0000001,0xD0000001,0x77FC0000,0xBDF80000,0xD0000001,0xBDF80000,0xD0000001,0xD0000001,0xBDF80000,0xD0000001,0xD0000001,0xD0000001,0xBDF80000,0xD0000001,0xD0000001,0xD0000001,0xD0000001,0x23FC0000,0x1C00000,0x1C00000,0x91FC0000,0xB5F80000,0xC7F80000,0xD0000001,0xD0000001,0x57FC0000,0xA1FC0000,0xCFF00000,0xD0000001, -0xABFC0000,0x1680738,0xFF5C0339,0xE55802D4,0xD15802D5,0xFF4801E0,0xED4400D5,0xD34C013A,0xDB440190,0xCF4400D5,0xC7440192,0xFD3802F8,0xEF3000A2,0xD73C00FF,0xDF3000D1,0xD1300002,0xC73400D7,0xD13002D4,0xCD2800FD,0xC528013B,0xBF3002D3,0x1FFC0734,0xF70C02D3,0xD13002D4,0xE9000192,0xD31800CF,0xC7200192,0xE2E802D3,0xD0F800A3,0xC6F800D7,0xBF0802D4,0x91FC0734, -0xD0B802D4,0xC6AC0192,0xBE9002D3,0xB4000734,0xFF580386,0xFB6405D2,0xFD680625,0xFF4000D3,0xF9300001,0xDF300002,0xD3340012,0xCF300011,0xFD4C036A,0xFF300099,0xD52400A9,0xC6F800D7,0x75FC0734,0x17C02D4,0xFF6C00B4,0xDF6C00A4,0xD16800A5,0xFD5800CA,0xE3580001,0xD35C0015,0xD55800C8,0xCF540026,0xC75800CA,0x3DFC02D3,0xED3400A2,0xD15000A3,0xE12800C9,0xD1300002, -0xC93C00CA,0xA1F802D3,0xD0F800A3,0xC6E800CA,0xBE0002D3,0x3DFC02D3,0xED3400A2,0xD15000A3,0xE12800C9,0xD1300002,0xC93C00CA,0xA1F802D3,0xD0F800A3,0xC6E800CA,0xBE0002D3,0xA1F802D3,0xD0F800A3,0xC6E800CA,0xBE0002D3,0xBE0002D3,0xFF64017A,0xF5780248,0xF77C0244,0xFF48006E,0xF9300001,0xDF300002,0xD33C0002,0xD1240005,0xFF5C016D,0xFD3C004B,0xD71C00A2,0xC6E800CA, -0x87FC02D3,0x15802D4,0x15802D4,0x15802D4,0x15802D4,0xF74400C8,0xF74400C8,0xF74400C8,0xCB4400C8,0xCB4400C8,0xBD4400C9,0xEF3000A2,0xEF3000A2,0xEF3000A2,0xD1300001,0xD1300001,0xC1340026,0xC33000A2,0xC33000A2,0xBD2C0015,0xB53000A2,0x1FC02D3,0x1FC02D3,0x1FC02D3,0xD71000C9,0xD71000C9,0xBF2800C9,0xD0F800A2,0xD0F800A2,0xBD0C0002,0xB51400A2,0x83F802D3, -0x83F802D3,0xBCD400C9,0xB4B800A2,0xAA0002D3,0xFD48013D,0xF3540229,0x15802D4,0xFF3C0048,0xF5300001,0xDF300001,0xD9340006,0xCB300002,0xFF3C0120,0xFD2C0035,0xD32800A2,0xBD0C0002,0x61FC02D3,0x16800A4,0x16800A4,0x16800A4,0x16800A4,0xE3580000,0xE3580000,0xE3580000,0xC7580000,0xC7580000,0xBD580001,0x1FFC00A2,0x1FFC00A2,0x1FFC00A2,0xCD380001,0xCD380001, -0xBD480001,0x91FC00A2,0x91FC00A2,0xBD100001,0xB40000A2,0x1FFC00A2,0x1FFC00A2,0x1FFC00A2,0xCD380001,0xCD380001,0xBD480001,0x91FC00A2,0x91FC00A2,0xBD100001,0xB40000A2,0x91FC00A2,0x91FC00A2,0xBD100001,0xB40000A2,0xB40000A2,0xFF58003D,0xFB640055,0x16800A4,0xFF440012,0xF3340000,0xDD340000,0xD33C0001,0xCD2C0000,0xFD4C0048,0xFF300011,0x75FC00A2,0xBD100001, -0x75FC00A2,0x19000C8,0xFB7C0000,0xDB7C0001,0xD17C0001,0x59FC00C8,0xE3580001,0xD1680001,0xADFC00C8,0xD12C0001,0xC60000CA,0x59FC00C8,0xE3580001,0xD1680001,0xADFC00C8,0xD12C0001,0xC60000CA,0xADFC00C8,0xD12C0001,0xC60000CA,0xC60000CA,0x59FC00C8,0xE3580001,0xD1680001,0xADFC00C8,0xD12C0001,0xC60000CA,0xADFC00C8,0xD12C0001,0xC60000CA,0xC60000CA,0xADFC00C8, -0xD12C0001,0xC60000CA,0xC60000CA,0xC60000CA,0xFF780071,0xDA800C8,0xFF8C0080,0xFF580020,0xF92C0001,0xE12C0000,0xD1440001,0xD1100001,0xFF700071,0xFD480019,0xD5480000,0xC60000CA,0x99FC00C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0x14400C8,0xD5300000,0xD5300000,0xD5300000,0xD5300000,0xD5300000, -0xD5300000,0xB5300001,0xB5300001,0xB5300001,0xAB300001,0x1E000C8,0x1E000C8,0x1E000C8,0x1E000C8,0x1E000C8,0x1E000C8,0xBD0C0001,0xBD0C0001,0xBD0C0001,0xAB1C0001,0x75FC00C8,0x75FC00C8,0x75FC00C8,0xAAE00001,0xA00000CA,0xF73C0064,0x14400C8,0x14400C8,0xFB340014,0xF9300000,0xE3300000,0xE3300000,0xC9300000,0xF9300048,0xF928000D,0xBD2C0001,0xBD0C0001, -0x51FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table87[] = { -0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x73F80000, -0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x3540000,0x3540000,0x3540000,0x1DC0000,0x4DFC0000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000, -0x1BFC0000,0x91F80000,0x91F80000,0x91F80000,0xB2000001,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x91F80000,0x91F80000,0x91F80000,0xB2000001,0x91F80000,0x91F80000,0x91F80000,0xB2000001,0xB2000001,0x1800000,0x1680000,0x1680000,0x7A00000,0x1C40000,0x3E80000,0x3E80000,0x47FC0000,0x7A00000,0x1C40000,0x73FC0000,0x91F80000, -0x73FC0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xC4000001,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xC4000001,0xABF80000,0xABF80000,0xC4000001,0xC4000001,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xC4000001,0xABF80000,0xABF80000,0xC4000001,0xC4000001,0xABF80000, -0xABF80000,0xC4000001,0xC4000001,0xC4000001,0x1CC0000,0xBA40000,0x18C0000,0x2BFC0000,0x73FC0000,0x95FC0000,0x9FFC0000,0xB3F40000,0x1F00000,0x53FC0000,0x95FC0000,0xC4000001,0x95FC0000,0x1B40000,0x8FFC0000,0xC9F80000,0xD8000001,0x8FFC0000,0xC9F80000,0xD8000001,0xC9F80000,0xD8000001,0xD8000001,0x8FFC0000,0xC9F80000,0xD8000001,0xC9F80000,0xD8000001, -0xD8000001,0xC9F80000,0xD8000001,0xD8000001,0xD8000001,0x8FFC0000,0xC9F80000,0xD8000001,0xC9F80000,0xD8000001,0xD8000001,0xC9F80000,0xD8000001,0xD8000001,0xD8000001,0xC9F80000,0xD8000001,0xD8000001,0xD8000001,0xD8000001,0x4BFC0000,0x1D00000,0x1D00000,0xA5FC0000,0xC1FC0000,0xD1F80000,0xD8000001,0xD8000001,0x75FC0000,0xB1FC0000,0xD9C40000,0xD8000001, -0xBBFC0000,0x1780738,0xFF6C0378,0xED6802D4,0xD96802D5,0xFF5C0212,0xF55400D5,0xDB5C013A,0xE3540190,0xD75400D5,0xCF540192,0xFF50031B,0xF74000A2,0xDF4C00FF,0xE74000D1,0xD9400002,0xCF4400D7,0xD94002D4,0xD53800FD,0xCD38013B,0xC74002D3,0x37FC0734,0xFF1C02D3,0xD94002D4,0xF1100192,0xDB2800CF,0xCF300192,0xEAF802D3,0xD90800A3,0xCF0800D7,0xC71802D4,0x9DFC0734, -0xD8C802D4,0xCEBC0192,0xC6A002D3,0xBC000734,0xFF6403DE,0xF3740618,0xF5780658,0xFF54012A,0xFF400006,0xE7400002,0xDB440012,0xD7400011,0xFF5C03A6,0xFF4400EA,0xDD3400A9,0xCF0800D7,0x83FC0734,0x18C02D4,0xFF8000CD,0xE77C00A4,0xD97800A5,0xFF6C00D4,0xEB680001,0xDB6C0015,0xDD6800C8,0xD7640026,0xCF6800CA,0x55FC02D3,0xF54400A2,0xD96000A3,0xE93800C9,0xD9400002, -0xD14C00CA,0xADF802D3,0xD90800A3,0xCEF800CA,0xC60002D3,0x55FC02D3,0xF54400A2,0xD96000A3,0xE93800C9,0xD9400002,0xD14C00CA,0xADF802D3,0xD90800A3,0xCEF800CA,0xC60002D3,0xADF802D3,0xD90800A3,0xCEF800CA,0xC60002D3,0xC60002D3,0xFF780191,0xFD880248,0xFF8C0244,0xFF5C0096,0xFD440005,0xE7400002,0xDB4C0002,0xD9340005,0xFF7001A5,0xFF540071,0xDF2C00A2,0xCEF800CA, -0x97FC02D3,0x16802D4,0x16802D4,0x16802D4,0x16802D4,0xFF5400C8,0xFF5400C8,0xFF5400C8,0xD35400C8,0xD35400C8,0xC55400C9,0xF74000A2,0xF74000A2,0xF74000A2,0xD9400001,0xD9400001,0xC9440026,0xCB4000A2,0xCB4000A2,0xC53C0015,0xBD4000A2,0x19FC02D3,0x19FC02D3,0x19FC02D3,0xDF2000C9,0xDF2000C9,0xC73800C9,0xD90800A2,0xD90800A2,0xC51C0002,0xBD2400A2,0x8FF802D3, -0x8FF802D3,0xC4E400C9,0xBCC800A2,0xB20002D3,0xFF58015D,0xFB640229,0x16802D4,0xFF4C0065,0xFD400001,0xE7400001,0xE1440006,0xD3400002,0xFF500139,0xFF3C0054,0xDB3800A2,0xC51C0002,0x71FC02D3,0x17800A4,0x17800A4,0x17800A4,0x17800A4,0xEB680000,0xEB680000,0xEB680000,0xCF680000,0xCF680000,0xC5680001,0x37FC00A2,0x37FC00A2,0x37FC00A2,0xD5480001,0xD5480001, -0xC5580001,0x9DFC00A2,0x9DFC00A2,0xC5200001,0xBC0000A2,0x37FC00A2,0x37FC00A2,0x37FC00A2,0xD5480001,0xD5480001,0xC5580001,0x9DFC00A2,0x9DFC00A2,0xC5200001,0xBC0000A2,0x9DFC00A2,0x9DFC00A2,0xC5200001,0xBC0000A2,0xBC0000A2,0xFB6C0048,0xF3740064,0x17800A4,0xFD580019,0xFB440000,0xE5440000,0xDB4C0001,0xD53C0000,0xF5640055,0xFF480014,0x83FC00A2,0xC5200001, -0x83FC00A2,0x1A000C8,0xFF8C0001,0xE38C0001,0xD98C0001,0x71FC00C8,0xEB680001,0xD9780001,0xB9FC00C8,0xD93C0001,0xCE0000CA,0x71FC00C8,0xEB680001,0xD9780001,0xB9FC00C8,0xD93C0001,0xCE0000CA,0xB9FC00C8,0xD93C0001,0xCE0000CA,0xCE0000CA,0x71FC00C8,0xEB680001,0xD9780001,0xB9FC00C8,0xD93C0001,0xCE0000CA,0xB9FC00C8,0xD93C0001,0xCE0000CA,0xCE0000CA,0xB9FC00C8, -0xD93C0001,0xCE0000CA,0xCE0000CA,0xCE0000CA,0xFF8C0080,0x1BC00C8,0xF79C0091,0xFF6C002D,0xFB480005,0xE93C0000,0xD9540001,0xD9200001,0xF7880080,0xFF600029,0xDD580000,0xCE0000CA,0xA7FC00C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0x15400C8,0xDD400000,0xDD400000,0xDD400000,0xDD400000,0xDD400000, -0xDD400000,0xBD400001,0xBD400001,0xBD400001,0xB3400001,0x1F800C8,0x1F800C8,0x1F800C8,0x1F800C8,0x1F800C8,0x1F800C8,0xC51C0001,0xC51C0001,0xC51C0001,0xB32C0001,0x81FC00C8,0x81FC00C8,0x81FC00C8,0xB2F00001,0xA80000CA,0xFF4C0064,0x15400C8,0x15400C8,0xFD480019,0xFD400001,0xEB400000,0xEB400000,0xD1400000,0xFF3C0050,0xFD380014,0xC53C0001,0xC51C0001, -0x5FFC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table88[] = { -0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x3F40000,0x7FFC0000, -0x7FFC0000,0x7FFC0000,0x7FFC0000,0xA8000000,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1500001,0x1680000,0x1680000,0x1680000,0x3F40000,0x5FF80000,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000, -0x37FC0000,0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0xBC000000,0x1940000,0x1780001,0x1780001,0x1B80000,0x3D80000,0x9FC0000,0x9FC0000,0x5DFC0000,0x1B80000,0x3D80000,0x83FC0000,0x9DFC0000, -0x83FC0000,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xCE000000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xCE000000,0xB9F80000,0xB9F80000,0xCE000000,0xCE000000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xCE000000,0xB9F80000,0xB9F80000,0xCE000000,0xCE000000,0xB9F80000, -0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0x3E00000,0x5B80000,0x19C0001,0x4DFC0000,0x8BFC0000,0xA5FC0000,0xAFFC0000,0xBFF40000,0x15FC0000,0x6FFC0000,0xA5FC0000,0xCE000000,0xA5FC0000,0x1C40001,0xABFC0000,0xD7F80000,0xE2000000,0xABFC0000,0xD7F80000,0xE2000000,0xD7F80000,0xE2000000,0xE2000000,0xABFC0000,0xD7F80000,0xE2000000,0xD7F80000,0xE2000000, -0xE2000000,0xD7F80000,0xE2000000,0xE2000000,0xE2000000,0xABFC0000,0xD7F80000,0xE2000000,0xD7F80000,0xE2000000,0xE2000000,0xD7F80000,0xE2000000,0xE2000000,0xE2000000,0xD7F80000,0xE2000000,0xE2000000,0xE2000000,0xE2000000,0x77FC0000,0x1E40000,0x1E40000,0xBBFC0000,0xD1FC0000,0xDDF40000,0xE2000000,0xE2000000,0x97FC0000,0xC5FC0000,0xE1F40000,0xE2000000, -0xCBFC0000,0x18C0734,0xFF8003BF,0xF57802D4,0xE37802D3,0xFF740272,0xFD6800D7,0xE76C013B,0xEB680192,0xE16400D7,0xD9640192,0xFF680361,0xFF5400A3,0xE75C00FD,0xEF5000CF,0xE3540002,0xD95800D5,0xE35002D4,0xDD4800FF,0xD550013A,0xCF5002D5,0x53FC0734,0xFF3802E3,0xE35402D4,0xFB200192,0xE33800D1,0xD9400190,0xF50802D3,0xE31800A2,0xD91C00D5,0xCF2C02D4,0xABF80734, -0xE2D802D3,0xD8C80190,0xCEB402D4,0xC4000738,0xFF780447,0xFD880614,0xFD88065C,0xFF6C01B7,0xFF58002E,0xF1540002,0xE3580011,0xE14C0012,0xFF700413,0xFF5C016A,0xE54800A9,0xD91C00D5,0x95FC0734,0x1A002D3,0xFF9000FB,0xF18C00A2,0xE38C00A2,0xFF8000F1,0xF37C0002,0xE57C0015,0xE77800C9,0xE1740026,0xD97800C9,0x71FC02D3,0xFF5400A2,0xE37000A2,0xF34800C9,0xE3540001, -0xD96000C8,0xB9FC02D3,0xE31400A2,0xD90800C8,0xCE0002D4,0x71FC02D3,0xFF5400A2,0xE37000A2,0xF34800C9,0xE3540001,0xD96000C8,0xB9FC02D3,0xE31400A2,0xD90800C8,0xCE0002D4,0xB9FC02D3,0xE31400A2,0xD90800C8,0xCE0002D4,0xCE0002D4,0xFD9001C4,0xF79C0269,0xF79C0266,0xFF7800D1,0xFF5C001A,0xF1540001,0xE3600002,0xE1440006,0xFF8801C3,0xFF7000B5,0xE74000A2,0xD90800C8, -0xA7FC02D3,0x17802D3,0x17802D3,0x17802D3,0x17802D3,0xFF6800CE,0xFF6800CE,0xFF6800CE,0xDD6400CA,0xDD6400CA,0xCF6400CA,0xFF5400A3,0xFF5400A3,0xFF5400A3,0xE1540002,0xE1540002,0xD1580026,0xD35400A3,0xD35400A3,0xCD500015,0xC55000A5,0x35FC02D3,0x35FC02D3,0x35FC02D3,0xE73400C9,0xE73400C9,0xCF4C00C8,0xE11C00A2,0xE11C00A2,0xCF2C0001,0xC53800A4,0x9DF402D3, -0x9DF402D3,0xCEF400C8,0xC4E000A4,0xBC0002D4,0xFF680189,0xF374024B,0x17802D3,0xFF600099,0xFF540009,0xEF540002,0xE9540005,0xDD500002,0xFF64016D,0xFF540079,0xE34C00A3,0xCF2C0001,0x81FC02D3,0x18C00A2,0x18C00A2,0x18C00A2,0x18C00A2,0xF17C0001,0xF17C0001,0xF17C0001,0xD77C0001,0xD77C0001,0xCF780001,0x53FC00A2,0x53FC00A2,0x53FC00A2,0xDD5C0001,0xDD5C0001, -0xCF680000,0xABF800A2,0xABF800A2,0xCF300000,0xC40000A4,0x53FC00A2,0x53FC00A2,0x53FC00A2,0xDD5C0001,0xDD5C0001,0xCF680000,0xABF800A2,0xABF800A2,0xCF300000,0xC40000A4,0xABF800A2,0xABF800A2,0xCF300000,0xC40000A4,0xC40000A4,0xF7800055,0xFD880062,0x18C00A2,0xFB700029,0xFF580001,0xED580000,0xE55C0000,0xDD500001,0xFD740055,0xFD640020,0x95FC00A2,0xCF300000, -0x95FC00A2,0x1B000CA,0xFFA4000D,0xED9C0001,0xE39C0001,0x8DFC00C8,0xF37C0001,0xE3880001,0xC7FC00C8,0xE34C0000,0xD80000C8,0x8DFC00C8,0xF37C0001,0xE3880001,0xC7FC00C8,0xE34C0000,0xD80000C8,0xC7FC00C8,0xE34C0000,0xD80000C8,0xD80000C8,0x8DFC00C8,0xF37C0001,0xE3880001,0xC7FC00C8,0xE34C0000,0xD80000C8,0xC7FC00C8,0xE34C0000,0xD80000C8,0xD80000C8,0xC7FC00C8, -0xE34C0000,0xD80000C8,0xD80000C8,0xD80000C8,0xF7A40091,0xFCC00C8,0xFFAC0095,0xFF8C0048,0xFF64000D,0xF34C0000,0xE3640000,0xE32C0000,0xFF980082,0xFD80003D,0xE56C0001,0xD80000C8,0xB9FC00C8,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0x16400CA,0xE3540001,0xE3540001,0xE3540001,0xE3540001,0xE3540001, -0xE3540001,0xC7500001,0xC7500001,0xC7500001,0xBD500001,0x19FC00C8,0x19FC00C8,0x19FC00C8,0x19FC00C8,0x19FC00C8,0x19FC00C8,0xCD300001,0xCD300001,0xCD300001,0xBD3C0001,0x8FF800C8,0x8FF800C8,0x8FF800C8,0xBD000000,0xB20000C8,0xF9600071,0x16400CA,0x16400CA,0xFF580022,0xFD540005,0xF1540001,0xF1540001,0xD9540001,0xFD540055,0xFF500019,0xD14C0000,0xCD300001, -0x71FC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table89[] = { -0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x13FC0000,0x8BFC0000, -0x8BFC0000,0x8BFC0000,0x8BFC0000,0xB0000000,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x1600001,0x5780000,0x5780000,0x5780000,0x13FC0000,0x6DFC0000,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000, -0x4FFC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0xC4000000,0x1A40000,0x1880001,0x1880001,0x5C80000,0x3EC0000,0x27FC0000,0x27FC0000,0x71FC0000,0x5C80000,0x3EC0000,0x93FC0000,0xA9FC0000, -0x93FC0000,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x87FC0000,0x87FC0000,0x87FC0000,0xC5F80000,0xC5F80000,0xD6000000,0x87FC0000,0x87FC0000,0x87FC0000,0xC5F80000,0xC5F80000,0xD6000000,0xC5F80000,0xC5F80000,0xD6000000,0xD6000000,0x87FC0000,0x87FC0000,0x87FC0000,0xC5F80000,0xC5F80000,0xD6000000,0xC5F80000,0xC5F80000,0xD6000000,0xD6000000,0xC5F80000, -0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0x1F40000,0xDC80000,0x1AC0001,0x6BFC0000,0x9DFC0000,0xB5FC0000,0xBDF80000,0xC9F80000,0x3DFC0000,0x87FC0000,0xB5FC0000,0xD6000000,0xB5FC0000,0x1D40001,0xC3FC0000,0xE1FC0000,0xEA000000,0xC3FC0000,0xE1FC0000,0xEA000000,0xE1FC0000,0xEA000000,0xEA000000,0xC3FC0000,0xE1FC0000,0xEA000000,0xE1FC0000,0xEA000000, -0xEA000000,0xE1FC0000,0xEA000000,0xEA000000,0xEA000000,0xC3FC0000,0xE1FC0000,0xEA000000,0xE1FC0000,0xEA000000,0xEA000000,0xE1FC0000,0xEA000000,0xEA000000,0xEA000000,0xE1FC0000,0xEA000000,0xEA000000,0xEA000000,0xEA000000,0x9FFC0000,0x3F40000,0x3F40000,0xCFFC0000,0xDFF80000,0xE7F40000,0xEA000000,0xEA000000,0xB5FC0000,0xD5FC0000,0xEBC80000,0xEA000000, -0xDBFC0000,0x19C0734,0xFF90041C,0xFD8802D4,0xEB8802D3,0xFF8002E2,0xFF7800E7,0xEF7C013B,0xF3780192,0xE97400D7,0xE1740192,0xFF7403A9,0xFF6800C6,0xEF6C00FD,0xF76000CF,0xEB640002,0xE16800D5,0xEB6002D4,0xE55800FF,0xDD60013A,0xD76002D5,0x6BFC0734,0xFF580319,0xEB6402D4,0xFF38019A,0xEB4800D1,0xE1500190,0xFD1802D3,0xEB2800A2,0xE12C00D5,0xD73C02D4,0xB7F80734, -0xEAE802D3,0xE0D80190,0xD6C402D4,0xCC000738,0xFF8C0494,0xF598065A,0xF79C068F,0xFF800236,0xFF6C0086,0xF9640002,0xEB680011,0xE95C0012,0xFF800481,0xFF7401F7,0xED5800A9,0xE12C00D5,0xA3FC0734,0x1B002D3,0xFFA40126,0xF99C00A2,0xEB9C00A2,0xFF980119,0xFB8C0002,0xED8C0015,0xEF8800C9,0xE9840026,0xE18800C9,0x89FC02D3,0xFF7000AD,0xEB8000A2,0xFB5800C9,0xEB640001, -0xE17000C8,0xC5FC02D3,0xEB2400A2,0xE11800C8,0xD60002D4,0x89FC02D3,0xFF7000AD,0xEB8000A2,0xFB5800C9,0xEB640001,0xE17000C8,0xC5FC02D3,0xEB2400A2,0xE11800C8,0xD60002D4,0xC5FC02D3,0xEB2400A2,0xE11800C8,0xD60002D4,0xD60002D4,0xFFA001E5,0xFFAC0269,0xFFAC0266,0xFF94010A,0xFF7C0049,0xF9640001,0xEB700002,0xE9540006,0xFF9801E6,0xFF8400E2,0xEF5000A2,0xE11800C8, -0xB7FC02D3,0x18802D3,0x18802D3,0x18802D3,0x18802D3,0xFF7800E3,0xFF7800E3,0xFF7800E3,0xE57400CA,0xE57400CA,0xD77400CA,0xFF6800AD,0xFF6800AD,0xFF6800AD,0xE9640002,0xE9640002,0xD9680026,0xDB6400A3,0xDB6400A3,0xD5600015,0xCD6000A5,0x4DFC02D3,0x4DFC02D3,0x4DFC02D3,0xEF4400C9,0xEF4400C9,0xD75C00C8,0xE92C00A2,0xE92C00A2,0xD73C0001,0xCD4800A4,0xA7FC02D3, -0xA7FC02D3,0xD70400C8,0xCCF000A4,0xC40002D4,0xFD8001A6,0xFB84024B,0x18802D3,0xFF7000CA,0xFF6C0022,0xF7640002,0xF1640005,0xE5600002,0xFF78018A,0xFF6800A8,0xEB5C00A3,0xD73C0001,0x91FC02D3,0x19C00A2,0x19C00A2,0x19C00A2,0x19C00A2,0xF98C0001,0xF98C0001,0xF98C0001,0xDF8C0001,0xDF8C0001,0xD7880001,0x6BFC00A2,0x6BFC00A2,0x6BFC00A2,0xE56C0001,0xE56C0001, -0xD7780000,0xB7F800A2,0xB7F800A2,0xD7400000,0xCC0000A4,0x6BFC00A2,0x6BFC00A2,0x6BFC00A2,0xE56C0001,0xE56C0001,0xD7780000,0xB7F800A2,0xB7F800A2,0xD7400000,0xCC0000A4,0xB7F800A2,0xB7F800A2,0xD7400000,0xCC0000A4,0xCC0000A4,0xFF900055,0xF5980071,0x19C00A2,0xFD840032,0xFF700005,0xF5680000,0xED6C0000,0xE5600001,0xFD880062,0xFF74002D,0xA3FC00A2,0xD7400000, -0xA3FC00A2,0x1C000CA,0xFFB40022,0xF5AC0001,0xEBAC0001,0xA5FC00C8,0xFB8C0001,0xEB980001,0xD3FC00C8,0xEB5C0000,0xE00000C8,0xA5FC00C8,0xFB8C0001,0xEB980001,0xD3FC00C8,0xEB5C0000,0xE00000C8,0xD3FC00C8,0xEB5C0000,0xE00000C8,0xE00000C8,0xA5FC00C8,0xFB8C0001,0xEB980001,0xD3FC00C8,0xEB5C0000,0xE00000C8,0xD3FC00C8,0xEB5C0000,0xE00000C8,0xE00000C8,0xD3FC00C8, -0xEB5C0000,0xE00000C8,0xE00000C8,0xE00000C8,0xFFB40091,0x1E000C8,0xF9C000A2,0xFFA00059,0xFF7C0025,0xFB5C0000,0xEB740000,0xEB3C0000,0xFFAC0095,0xFF940050,0xED7C0001,0xE00000C8,0xC7FC00C8,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0x17400CA,0xEB640001,0xEB640001,0xEB640001,0xEB640001,0xEB640001, -0xEB640001,0xCF600001,0xCF600001,0xCF600001,0xC5600001,0x31FC00C8,0x31FC00C8,0x31FC00C8,0x31FC00C8,0x31FC00C8,0x31FC00C8,0xD5400001,0xD5400001,0xD5400001,0xC54C0001,0x9BF800C8,0x9BF800C8,0x9BF800C8,0xC5100000,0xBA0000C8,0xFF6C007D,0x17400CA,0x17400CA,0xFF68002D,0xFF64000A,0xF9640001,0xF9640001,0xE1640001,0xF9680062,0xFD600029,0xD95C0000,0xD5400001, -0x7FFC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table90[] = { -0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x97FC0000, -0x97FC0000,0x97FC0000,0x97FC0000,0xB8000000,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0xD880000,0xD880000,0xD880000,0x2BFC0000,0x7DF80000,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000, -0x69FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0xCC000000,0x3B40000,0x1980001,0x1980001,0x1DC0000,0xBFC0000,0x45FC0000,0x45FC0000,0x85FC0000,0x1DC0000,0xBFC0000,0xA1FC0000,0xB5FC0000, -0xA1FC0000,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x9FFC0000,0x9FFC0000,0x9FFC0000,0xD1F80000,0xD1F80000,0xDE000000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0xD1F80000,0xD1F80000,0xDE000000,0xD1F80000,0xD1F80000,0xDE000000,0xDE000000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0xD1F80000,0xD1F80000,0xDE000000,0xD1F80000,0xD1F80000,0xDE000000,0xDE000000,0xD1F80000, -0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0x1FFC0000,0x1DC0000,0x1BC0001,0x89FC0000,0xB1FC0000,0xC3FC0000,0xC9FC0000,0xD5F40000,0x63FC0000,0x9FFC0000,0xC3FC0000,0xDE000000,0xC3FC0000,0x1E40001,0xDBFC0000,0xEDFC0000,0xF2000000,0xDBFC0000,0xEDFC0000,0xF2000000,0xEDFC0000,0xF2000000,0xF2000000,0xDBFC0000,0xEDFC0000,0xF2000000,0xEDFC0000,0xF2000000, -0xF2000000,0xEDFC0000,0xF2000000,0xF2000000,0xF2000000,0xDBFC0000,0xEDFC0000,0xF2000000,0xEDFC0000,0xF2000000,0xF2000000,0xEDFC0000,0xF2000000,0xF2000000,0xF2000000,0xEDFC0000,0xF2000000,0xF2000000,0xF2000000,0xF2000000,0xC7FC0000,0x47FC0000,0x47FC0000,0xE3FC0000,0xEBFC0000,0xF1F40000,0xF2000000,0xF2000000,0xD3FC0000,0xE7FC0000,0xF3D80000,0xF2000000, -0xE9FC0000,0x1AC0734,0xFFA40477,0xFF9C02EB,0xF39802D3,0xFF980352,0xFF8C012F,0xF78C013B,0xFB880192,0xF18400D7,0xE9840192,0xFF8C0401,0xFF7C011E,0xF77C00FD,0xFF7000CF,0xF3740002,0xE97800D5,0xF37002D4,0xED6800FF,0xE570013A,0xDF7002D5,0x83FC0734,0xFF700361,0xF37402D4,0xFF5801E2,0xF35800D1,0xE9600190,0xFF3802DD,0xF33800A2,0xE93C00D5,0xDF4C02D4,0xC3F80734, -0xF2F802D3,0xE8E80190,0xDED402D4,0xD4000738,0xFFA004E6,0xFDA8065A,0xFFAC068F,0xFF9402CB,0xFF84010B,0xFF740006,0xF3780011,0xF16C0012,0xFF9804CA,0xFF84028B,0xF56800A9,0xE93C00D5,0xB3FC0734,0x1C002D3,0xFFB4016B,0xFFAC00A3,0xF3AC00A2,0xFFA8015B,0xFF9C0012,0xF59C0015,0xF79800C9,0xF1940026,0xE99800C9,0xA3FC02D3,0xFF8800D5,0xF39000A2,0xFF7000CE,0xF3740001, -0xE98000C8,0xD1FC02D3,0xF33400A2,0xE92800C8,0xDE0002D4,0xA3FC02D3,0xFF8800D5,0xF39000A2,0xFF7000CE,0xF3740001,0xE98000C8,0xD1FC02D3,0xF33400A2,0xE92800C8,0xDE0002D4,0xD1FC02D3,0xF33400A2,0xE92800C8,0xDE0002D4,0xDE0002D4,0xFFB40202,0xF7BC028B,0xF7BC028B,0xFFA4015B,0xFF900089,0xFF740005,0xF3800002,0xF1640006,0xFDB00222,0xFF980136,0xF76000A2,0xE92800C8, -0xC5FC02D3,0x19802D3,0x19802D3,0x19802D3,0x19802D3,0xFF8C00FE,0xFF8C00FE,0xFF8C00FE,0xED8400CA,0xED8400CA,0xDF8400CA,0xFF7800CB,0xFF7800CB,0xFF7800CB,0xF1740002,0xF1740002,0xE1780026,0xE37400A3,0xE37400A3,0xDD700015,0xD57000A5,0x65FC02D3,0x65FC02D3,0x65FC02D3,0xF75400C9,0xF75400C9,0xDF6C00C8,0xF13C00A2,0xF13C00A2,0xDF4C0001,0xD55800A4,0xB3FC02D3, -0xB3FC02D3,0xDF1400C8,0xD50000A4,0xCC0002D4,0xFF9001C6,0xF598026A,0x19802D3,0xFF8800F3,0xFF80004A,0xFF740002,0xF9740005,0xED700002,0xFD8801C3,0xFF8000DD,0xF36C00A3,0xDF4C0001,0x9FFC02D3,0x1AC00A2,0x1AC00A2,0x1AC00A2,0x1AC00A2,0xFF9C0002,0xFF9C0002,0xFF9C0002,0xE79C0001,0xE79C0001,0xDF980001,0x83FC00A2,0x83FC00A2,0x83FC00A2,0xED7C0001,0xED7C0001, -0xDF880000,0xC3F800A2,0xC3F800A2,0xDF500000,0xD40000A4,0x83FC00A2,0x83FC00A2,0x83FC00A2,0xED7C0001,0xED7C0001,0xDF880000,0xC3F800A2,0xC3F800A2,0xDF500000,0xD40000A4,0xC3F800A2,0xC3F800A2,0xDF500000,0xD40000A4,0xD40000A4,0xFFA00064,0xFDA80071,0x1AC00A2,0xFF98003D,0xFF840011,0xFD780000,0xF57C0000,0xED700001,0xF5A00071,0xFB90003D,0xB3FC00A2,0xDF500000, -0xB3FC00A2,0x1D000CA,0xFFC4003A,0xFDBC0001,0xF3BC0001,0xBDFC00C8,0xFFA00009,0xF3A80001,0xDFF800C8,0xF36C0000,0xE80000C8,0xBDFC00C8,0xFFA00009,0xF3A80001,0xDFF800C8,0xF36C0000,0xE80000C8,0xDFF800C8,0xF36C0000,0xE80000C8,0xE80000C8,0xBDFC00C8,0xFFA00009,0xF3A80001,0xDFF800C8,0xF36C0000,0xE80000C8,0xDFF800C8,0xF36C0000,0xE80000C8,0xE80000C8,0xDFF800C8, -0xF36C0000,0xE80000C8,0xE80000C8,0xE80000C8,0xFBC800A4,0x1F000C8,0xFFCC00AA,0xFDBC0071,0xFFA4003D,0xFF740004,0xF3840000,0xF34C0000,0xF9C800A2,0xFBB80071,0xF58C0001,0xE80000C8,0xD7FC00C8,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0x18400CA,0xF3740001,0xF3740001,0xF3740001,0xF3740001,0xF3740001, -0xF3740001,0xD7700001,0xD7700001,0xD7700001,0xCD700001,0x49FC00C8,0x49FC00C8,0x49FC00C8,0x49FC00C8,0x49FC00C8,0x49FC00C8,0xDD500001,0xDD500001,0xDD500001,0xCD5C0001,0xA7F800C8,0xA7F800C8,0xA7F800C8,0xCD200000,0xC20000C8,0xF9800082,0x18400CA,0x18400CA,0xFB7C003D,0xFF780012,0xFD740002,0xFD740002,0xE9740001,0xFF74006A,0xFD740032,0xE16C0000,0xDD500001, -0x8FFC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table91[] = { -0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0xA3FC0000, -0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x19C0000,0x19C0000,0x19C0000,0x43FC0000,0x8BFC0000,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000, -0x81FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0xD4000000,0xBC40000,0x1A80001,0x1A80001,0x1F00000,0x33FC0000,0x63FC0000,0x63FC0000,0x99FC0000,0x1F00000,0x33FC0000,0xB1FC0000,0xC1FC0000, -0xB1FC0000,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xE6000000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xE6000000,0xDDF40000,0xDDF40000,0xE6000000,0xE6000000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xE6000000,0xDDF40000,0xDDF40000,0xE6000000,0xE6000000,0xDDF40000, -0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0x57FC0000,0x1EC0000,0x1CC0001,0xA7FC0000,0xC5FC0000,0xD3FC0000,0xD7FC0000,0xDFF80000,0x8BFC0000,0xB7FC0000,0xD3FC0000,0xE6000000,0xD3FC0000,0x1F40001,0xF5FC0000,0xF9FC0000,0xFA000000,0xF5FC0000,0xF9FC0000,0xFA000000,0xF9FC0000,0xFA000000,0xFA000000,0xF5FC0000,0xF9FC0000,0xFA000000,0xF9FC0000,0xFA000000, -0xFA000000,0xF9FC0000,0xFA000000,0xFA000000,0xFA000000,0xF5FC0000,0xF9FC0000,0xFA000000,0xF9FC0000,0xFA000000,0xFA000000,0xF9FC0000,0xFA000000,0xFA000000,0xFA000000,0xF9FC0000,0xFA000000,0xFA000000,0xFA000000,0xFA000000,0xEDFC0000,0xC7FC0000,0xC7FC0000,0xF7FC0000,0xF9FC0000,0xFBF40000,0xFA000000,0xFA000000,0xF1FC0000,0xF7FC0000,0xFBE80000,0xFA000000, -0xF9FC0000,0x1BC0734,0xFFB004DF,0xFFAC032C,0xFBA802D3,0xFFA403F2,0xFFA001B3,0xFF9C013B,0xFF9401A4,0xF99400D7,0xF1940192,0xFFA40479,0xFF9401AE,0xFF8C00FD,0xFF880107,0xFB840002,0xF18800D5,0xFB8002D4,0xF57800FF,0xED80013A,0xE78002D5,0x9BFC0734,0xFF8803C9,0xFB8402D4,0xFF700252,0xFB6800D1,0xF1700190,0xFF58031F,0xFB4800A2,0xF14C00D5,0xE75C02D4,0xCFF80734, -0xFB0802D3,0xF0F80190,0xE6E402D4,0xDC000738,0xFFB40553,0xF5B806A4,0xF7BC06C4,0xFFA4038C,0xFF9801BF,0xFF88005A,0xFB880011,0xF97C0012,0xFDB00553,0xFF98033A,0xFD7800A9,0xF14C00D5,0xC1FC0734,0x1D002D3,0xFFC401A3,0xFFC000CE,0xFBBC00A2,0xFFBC0199,0xFFB4005A,0xFDAC0015,0xFFA800C9,0xF9A40026,0xF1A800C9,0xBBFC02D3,0xFFA0011D,0xFBA000A2,0xFF8800FE,0xFB840001, -0xF19000C8,0xDDFC02D3,0xFB4400A2,0xF13800C8,0xE60002D4,0xBBFC02D3,0xFFA0011D,0xFBA000A2,0xFF8800FE,0xFB840001,0xF19000C8,0xDDFC02D3,0xFB4400A2,0xF13800C8,0xE60002D4,0xDDFC02D3,0xFB4400A2,0xF13800C8,0xE60002D4,0xE60002D4,0xFBC80244,0xFFCC028B,0xFFCC028B,0xFFC001A6,0xFFA800ED,0xFF900039,0xFB900002,0xF9740006,0xFFC40243,0xFFB0019E,0xFF7000A2,0xF13800C8, -0xD5FC02D3,0x1A802D3,0x1A802D3,0x1A802D3,0x1A802D3,0xFF9C012B,0xFF9C012B,0xFF9C012B,0xF59400CA,0xF59400CA,0xE79400CA,0xFF8C00ED,0xFF8C00ED,0xFF8C00ED,0xF9840002,0xF9840002,0xE9880026,0xEB8400A3,0xEB8400A3,0xE5800015,0xDD8000A5,0x7DFC02D3,0x7DFC02D3,0x7DFC02D3,0xFF6400C9,0xFF6400C9,0xE77C00C8,0xF94C00A2,0xF94C00A2,0xE75C0001,0xDD6800A4,0xBFFC02D3, -0xBFFC02D3,0xE72400C8,0xDD1000A4,0xD40002D4,0xFFA001E5,0xFDA8026A,0x1A802D3,0xFF980126,0xFF940082,0xFF88001A,0xFF88000A,0xF5800002,0xFD9C01E1,0xFF900111,0xFB7C00A3,0xE75C0001,0xAFFC02D3,0x1BC00A2,0x1BC00A2,0x1BC00A2,0x1BC00A2,0xFFB0000D,0xFFB0000D,0xFFB0000D,0xEFAC0001,0xEFAC0001,0xE7A80001,0x9BFC00A2,0x9BFC00A2,0x9BFC00A2,0xF58C0001,0xF58C0001, -0xE7980000,0xCFF800A2,0xCFF800A2,0xE7600000,0xDC0000A4,0x9BFC00A2,0x9BFC00A2,0x9BFC00A2,0xF58C0001,0xF58C0001,0xE7980000,0xCFF800A2,0xCFF800A2,0xE7600000,0xDC0000A4,0xCFF800A2,0xCFF800A2,0xE7600000,0xDC0000A4,0xDC0000A4,0xFBB40071,0xF5B80082,0x1BC00A2,0xFBAC0055,0xFF9C0022,0xFF900008,0xFD8C0000,0xF5800001,0xFDB00071,0xFFA40048,0xC1FC00A2,0xE7600000, -0xC1FC00A2,0x1E000CA,0xFFDC0062,0xFFCC0011,0xFBCC0001,0xD5FC00C8,0xFFC0002D,0xFBB80001,0xEBF800C8,0xFB7C0000,0xF00000C8,0xD5FC00C8,0xFFC0002D,0xFBB80001,0xEBF800C8,0xFB7C0000,0xF00000C8,0xEBF800C8,0xFB7C0000,0xF00000C8,0xF00000C8,0xD5FC00C8,0xFFC0002D,0xFBB80001,0xEBF800C8,0xFB7C0000,0xF00000C8,0xEBF800C8,0xFB7C0000,0xF00000C8,0xF00000C8,0xEBF800C8, -0xFB7C0000,0xF00000C8,0xF00000C8,0xF00000C8,0xF3E000B5,0x27FC00C8,0xF9E000B5,0xFDD40091,0xFFBC0061,0xFFA40022,0xFB940000,0xFB5C0000,0xFDD800A4,0xFFCC0082,0xFD9C0001,0xF00000C8,0xE5FC00C8,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0x19400CA,0xFB840001,0xFB840001,0xFB840001,0xFB840001,0xFB840001, -0xFB840001,0xDF800001,0xDF800001,0xDF800001,0xD5800001,0x63FC00C8,0x63FC00C8,0x63FC00C8,0x63FC00C8,0x63FC00C8,0x63FC00C8,0xE5600001,0xE5600001,0xE5600001,0xD56C0001,0xB3F800C8,0xB3F800C8,0xB3F800C8,0xD5300000,0xCA0000C8,0xF3940091,0x19400CA,0x19400CA,0xFD8C004A,0xFD880022,0xFD84000A,0xFD84000A,0xF1840001,0xFD8C0071,0xF9880048,0xE97C0000,0xE5600001, -0x9FF800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table92[] = { -0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0xB1F80000, -0xB1F80000,0xB1F80000,0xB1F80000,0xC8000001,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0x1940000,0xFAC0000,0xFAC0000,0xFAC0000,0x5FFC0000,0x9DF80000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000, -0x9BFC0000,0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0xDC000001,0x5D80000,0x1BC0000,0x1BC0000,0x17FC0000,0x5FFC0000,0x85FC0000,0x85FC0000,0xAFFC0000,0x17FC0000,0x5FFC0000,0xC1FC0000,0xCFF80000, -0xC1FC0000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0xD3FC0000,0xD3FC0000,0xD3FC0000,0xE9FC0000,0xE9FC0000,0xEE000001,0xD3FC0000,0xD3FC0000,0xD3FC0000,0xE9FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xE9FC0000,0xEE000001,0xEE000001,0xD3FC0000,0xD3FC0000,0xD3FC0000,0xE9FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xE9FC0000,0xEE000001,0xEE000001,0xE9FC0000, -0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0x97FC0000,0x17FC0000,0x1E00000,0xC9FC0000,0xDBFC0000,0xE3FC0000,0xE7F80000,0xEBF80000,0xB7FC0000,0xD3FC0000,0xE3FC0000,0xEE000001,0xE3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1CC0625,0xFFC4047D,0xFFC0034C,0xFFBC02D4,0xFFBC03A5,0xFFB40204,0xFFB00161,0xFFAC017D,0xFFA800C9,0xF7A80139,0xFFB00412,0xFFAC01FB,0xFFA4012A,0xFFA00106,0xFF980009,0xF9980082,0xFF940225,0xFB9000C8,0xF59000C1,0xEF940222,0xB5FC0625,0xFFA003BC,0xFF9802D3,0xFF94024F,0xFF8400E9,0xF784013B,0xFF7C02BE,0xFF6400A5,0xF7640076,0xEF700222,0xDBF80625, -0xFF2C02D3,0xF7180139,0xEEFC0222,0xE4000627,0xFFC404D9,0xFDC8059D,0xFFCC05C5,0xFFB40375,0xFFA801FF,0xFFA400B5,0xFF9C0032,0xFF900004,0xFFBC04B6,0xFFB00336,0xFF9000B4,0xF7640076,0xD1FC0625,0x1DC0225,0xFFD40178,0xFFCC00E4,0xFFCC00A4,0xFFD00145,0xFFC8007E,0xFFC40020,0xFFC00081,0xFDB8000C,0xF7BC0071,0xCFFC0222,0xFFC00118,0xFFB800A2,0xFFAC00C6,0xFF9C0001, -0xF7A40071,0xE7FC0222,0xFF6C00A2,0xF7540071,0xEE000222,0xCFFC0222,0xFFC00118,0xFFB800A2,0xFFAC00C6,0xFF9C0001,0xF7A40071,0xE7FC0222,0xFF6C00A2,0xF7540071,0xEE000222,0xE7FC0222,0xFF6C00A2,0xF7540071,0xEE000222,0xEE000222,0xFFD801C3,0xF7DC0201,0xF7DC0204,0xFDD00171,0xFFC000F2,0xFFAC0059,0xFFA80005,0xFF900000,0xFDD801C5,0xFFC80146,0xFF9800AB,0xF7540071, -0xE1FC0222,0x1BC02D4,0x1BC02D4,0x1BC02D4,0x1BC02D4,0xFFB00161,0xFFB00161,0xFFB00161,0xFDA800C8,0xFDA800C8,0xEFA800C9,0xFFA4012A,0xFFA4012A,0xFFA4012A,0xFF980009,0xFF980009,0xF3980026,0xF59400A2,0xF59400A2,0xEF900015,0xE79400A2,0x99FC02D3,0x99FC02D3,0x99FC02D3,0xFF8400E9,0xFF8400E9,0xF18C00C9,0xFF6400A5,0xFF6400A5,0xEF700002,0xE77800A2,0xCDFC02D3, -0xCDFC02D3,0xEF3800C9,0xE71C00A2,0xDC0002D3,0xFBB40225,0xF5B8028C,0x1BC02D4,0xFFAC0175,0xFFA400D9,0xFF9C0059,0xFF9C0032,0xFD940002,0xFDB00201,0xFFA40163,0xFF9000AB,0xEF700002,0xBFFC02D3,0x1CC00A4,0x1CC00A4,0x1CC00A4,0x1CC00A4,0xFFC40020,0xFFC40020,0xFFC40020,0xF9BC0000,0xF9BC0000,0xEFBC0001,0xB7FC00A2,0xB7FC00A2,0xB7FC00A2,0xFF9C0001,0xFF9C0001, -0xEFAC0001,0xDDF400A2,0xDDF400A2,0xEF740001,0xE60000A2,0xB7FC00A2,0xB7FC00A2,0xB7FC00A2,0xFF9C0001,0xFF9C0001,0xEFAC0001,0xDDF400A2,0xDDF400A2,0xEF740001,0xE60000A2,0xDDF400A2,0xDDF400A2,0xEF740001,0xE60000A2,0xE60000A2,0xFDC80080,0xFFCC0080,0x1CC00A4,0xFDC00064,0xFDBC003D,0xFFAC0019,0xFFA80005,0xFF900000,0xFFC40080,0xFBC00062,0xD3FC00A2,0xEF740001, -0xD3FC00A2,0x1F00071,0xFFE80041,0xFFE40014,0xFFE00000,0xE9FC0071,0xFFD80028,0xFFD00000,0xF3FC0071,0xFFA00000,0xF6000071,0xE9FC0071,0xFFD80028,0xFFD00000,0xF3FC0071,0xFFA00000,0xF6000071,0xF3FC0071,0xFFA00000,0xF6000071,0xF6000071,0xE9FC0071,0xFFD80028,0xFFD00000,0xF3FC0071,0xFFA00000,0xF6000071,0xF3FC0071,0xFFA00000,0xF6000071,0xF6000071,0xF3FC0071, -0xFFA00000,0xF6000071,0xF6000071,0xF6000071,0xFFEC0062,0x87FC0071,0xFFEC0064,0xFDE80055,0xFDE40048,0xFFC8001D,0xFFB40000,0xFF8C0000,0xFDEC0062,0xFFE40055,0xFFBC0004,0xF6000071,0xF1FC0071,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0x1A800C8,0xFF980005,0xFF980005,0xFF980005,0xFF980005,0xFF980005, -0xFF980005,0xE7940001,0xE7940001,0xE7940001,0xDD940001,0x7DFC00C8,0x7DFC00C8,0x7DFC00C8,0x7DFC00C8,0x7DFC00C8,0x7DFC00C8,0xEF700001,0xEF700001,0xEF700001,0xDD800001,0xBFFC00C8,0xBFFC00C8,0xBFFC00C8,0xDD440001,0xD20000CA,0xFBA40091,0x1A800C8,0x1A800C8,0xFFA00055,0xFD9C0034,0xFF980014,0xFF980014,0xFB940000,0xFD9C0082,0xFD9C0055,0xEF900001,0xEF700001, -0xAFFC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table93[] = { -0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0x77FC0000,0xBDF80000, -0xBDF80000,0xBDF80000,0xBDF80000,0xD0000001,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1C00000,0x1C00000,0x1C00000,0x77FC0000,0xABFC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000, -0xB5FC0000,0xDBF80000,0xDBF80000,0xDBF80000,0xE4000001,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xDBF80000,0xDBF80000,0xDBF80000,0xE4000001,0xDBF80000,0xDBF80000,0xDBF80000,0xE4000001,0xE4000001,0xDE80000,0x1CC0000,0x1CC0000,0x51FC0000,0x87FC0000,0xA3FC0000,0xA3FC0000,0xC3FC0000,0x51FC0000,0x87FC0000,0xD1FC0000,0xDBF80000, -0xD1FC0000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0xEBFC0000,0xEBFC0000,0xEBFC0000,0xF5FC0000,0xF5FC0000,0xF6000001,0xEBFC0000,0xEBFC0000,0xEBFC0000,0xF5FC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF5FC0000,0xF6000001,0xF6000001,0xEBFC0000,0xEBFC0000,0xEBFC0000,0xF5FC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF5FC0000,0xF6000001,0xF6000001,0xF5FC0000, -0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xD1FC0000,0x97FC0000,0x1F00000,0xE7FC0000,0xEFFC0000,0xF3FC0000,0xF5F80000,0xF7F40000,0xDFFC0000,0xEBFC0000,0xF3FC0000,0xF6000001,0xF3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1D804C1,0xFFD003C9,0xFFCC0314,0xFFCC02D4,0xFFC80305,0xFFC40204,0xFFC401A0,0xFFB80151,0xFFB800D8,0xFBB800E1,0xFFC4031D,0xFFBC01F3,0xFFBC017A,0xFFAC00E6,0xFFAC003D,0xFBA80036,0xFFAC016D,0xFFA400A4,0xF9A40049,0xF5A4014E,0xC7FC04C1,0xFFB80354,0xFFB002D3,0xFFAC01F7,0xFFA0011A,0xFB9800E3,0xFF940216,0xFF8800CD,0xFB78001A,0xF580014F,0xE3FC04C1, -0xFF6002D3,0xFB3800E1,0xF514014E,0xEA0004C3,0xFFD003DA,0xF5D80485,0xF5D8049C,0xFFC402E5,0xFFBC01E3,0xFFB800E7,0xFFB40084,0xFFA80015,0xFFD003C4,0xFFC402B9,0xFFA800E4,0xFB78001A,0xDDF804C1,0x1E8014D,0xFDE40105,0xFFE000BD,0xFFDC00A4,0xFFDC00C9,0xFFD8006C,0xFFD40041,0xFFCC0041,0xFFCC0001,0xFBCC0019,0xDFFC014D,0xFFD800D8,0xFFCC00A4,0xFFC0007D,0xFFB80011, -0xFBB80019,0xEFFC014D,0xFF9C00A2,0xFB740019,0xF400014E,0xDFFC014D,0xFFD800D8,0xFFCC00A4,0xFFC0007D,0xFFB80011,0xFBB80019,0xEFFC014D,0xFF9C00A2,0xFB740019,0xF400014E,0xEFFC014D,0xFF9C00A2,0xFB740019,0xF400014E,0xF400014E,0xFFE4011D,0xFDE80131,0xFDE80138,0xFFDC00E1,0xFFD400AA,0xFFC80056,0xFFBC0025,0xFFB0000D,0xFFE00122,0xFFDC00DA,0xFFB800A6,0xFB740019, -0xEBFC014D,0x1CC02D4,0x1CC02D4,0x1CC02D4,0x1CC02D4,0xFFC401A0,0xFFC401A0,0xFFC401A0,0xFFB800D8,0xFFB800D8,0xF7B800C9,0xFFBC017A,0xFFBC017A,0xFFBC017A,0xFFAC003D,0xFFAC003D,0xFBA80026,0xFDA400A2,0xFDA400A2,0xF7A00015,0xEFA400A2,0xB1FC02D3,0xB1FC02D3,0xB1FC02D3,0xFFA0011A,0xFFA0011A,0xF99C00C9,0xFF8800CD,0xFF8800CD,0xF7800002,0xEF8800A2,0xD9FC02D3, -0xD9FC02D3,0xF74800C9,0xEF2C00A2,0xE40002D3,0xFDC80244,0xFDC8028C,0x1CC02D4,0xFFBC01BA,0xFFB40131,0xFFB400A8,0xFFB40084,0xFFA80015,0xFFBC0236,0xFFBC01A6,0xFFA800DB,0xF7800002,0xCFFC02D3,0x1DC00A4,0x1DC00A4,0x1DC00A4,0x1DC00A4,0xFFD40041,0xFFD40041,0xFFD40041,0xFFCC0001,0xFFCC0001,0xF7CC0001,0xCFFC00A2,0xCFFC00A2,0xCFFC00A2,0xFFB80011,0xFFB80011, -0xF7BC0001,0xE7FC00A2,0xE7FC00A2,0xF7840001,0xEE0000A2,0xCFFC00A2,0xCFFC00A2,0xCFFC00A2,0xFFB80011,0xFFB80011,0xF7BC0001,0xE7FC00A2,0xE7FC00A2,0xF7840001,0xEE0000A2,0xE7FC00A2,0xE7FC00A2,0xF7840001,0xEE0000A2,0xEE0000A2,0xFFD80082,0xF7DC0091,0x1DC00A4,0xFDD80071,0xFDD00055,0xFFC8003D,0xFFBC0025,0xFFB0000D,0xF1DC0091,0xFBD40071,0xE1FC00A2,0xF7840001, -0xE1FC00A2,0x1F80019,0xFFF4000D,0xFFF00004,0xFFF00000,0xF5FC0019,0xFFF00008,0xFFE80000,0xF9FC0019,0xFFD40000,0xFA000019,0xF5FC0019,0xFFF00008,0xFFE80000,0xF9FC0019,0xFFD40000,0xFA000019,0xF9FC0019,0xFFD40000,0xFA000019,0xFA000019,0xF5FC0019,0xFFF00008,0xFFE80000,0xF9FC0019,0xFFD40000,0xFA000019,0xF9FC0019,0xFFD40000,0xFA000019,0xFA000019,0xF9FC0019, -0xFFD40000,0xFA000019,0xFA000019,0xFA000019,0xFDF40014,0xC7FC0019,0xF5F80019,0xFFF40012,0xFFE80010,0xFFE80008,0xFFDC0000,0xFFC80000,0xF1FC0019,0xFFF00014,0xFFE00001,0xFA000019,0xF9FC0019,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0x1B800C8,0xFFA80014,0xFFA80014,0xFFA80014,0xFFA80014,0xFFA80014, -0xFFA80014,0xEFA40001,0xEFA40001,0xEFA40001,0xE5A40001,0x95FC00C8,0x95FC00C8,0x95FC00C8,0x95FC00C8,0x95FC00C8,0x95FC00C8,0xF7800001,0xF7800001,0xF7800001,0xE5900001,0xCBFC00C8,0xCBFC00C8,0xCBFC00C8,0xE5540001,0xDA0000CA,0xF3B400A4,0x1B800C8,0x1B800C8,0xFBB40071,0xFDB00048,0xFFAC0029,0xFFAC0029,0xFFA40004,0xF9B00091,0xFBAC0064,0xF7A00001,0xF7800001, -0xBFF800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table94[] = { -0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0xC9F80000, -0xC9F80000,0xC9F80000,0xC9F80000,0xD8000001,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1D00000,0x1D00000,0x1D00000,0x8FFC0000,0xBBFC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000, -0xCDFC0000,0xE7F80000,0xE7F80000,0xE7F80000,0xEC000001,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xE7F80000,0xE7F80000,0xE7F80000,0xEC000001,0xE7F80000,0xE7F80000,0xE7F80000,0xEC000001,0xEC000001,0x1FC0000,0x1DC0000,0x1DC0000,0x89FC0000,0xADFC0000,0xC1FC0000,0xC1FC0000,0xD7FC0000,0x89FC0000,0xADFC0000,0xDFFC0000,0xE7F80000, -0xDFFC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1E403A2,0xFFDC032A,0xFFD802D5,0xFFD802B1,0xFFDC0282,0xFFD40205,0xFFD001C9,0xFFCC0150,0xFFCC0110,0xFFC800C8,0xFFD0028A,0xFFD001E9,0xFFC801A9,0xFFC000FC,0xFFC00098,0xFFBC0029,0xFFB8011A,0xFFB800A1,0xFFB00014,0xF9B400C1,0xD5FC03A2,0xFFCC02F1,0xFFC802AE,0xFFB801CC,0xFFB80153,0xFFAC00CA,0xFFAC01B3,0xFFA000FE,0xFF900001,0xF99400C2,0xEBF803A2, -0xFF9002AE,0xFF5800C8,0xF93400C1,0xF00003A2,0xFDE00326,0xF9E00370,0xFBE40389,0xFFD40272,0xFFD001DA,0xFFC8012F,0xFFC400E0,0xFFB80065,0xFFD8030F,0xFFD00253,0xFFBC010D,0xFF900001,0xE5FC03A2,0x1F400C2,0xFDF000AE,0xFFF00099,0xFFEC0091,0xFFE80086,0xFFE80065,0xFFE80055,0xFFE40030,0xFFE0001D,0xFFDC0000,0xEFFC00C1,0xFFE400A1,0xFFE40091,0xFFD80058,0xFFD80034, -0xFFCC0000,0xF7F800C1,0xFFC80091,0xFF940000,0xF80000C1,0xEFFC00C1,0xFFE400A1,0xFFE40091,0xFFD80058,0xFFD80034,0xFFCC0000,0xF7F800C1,0xFFC80091,0xFF940000,0xF80000C1,0xF7F800C1,0xFFC80091,0xFF940000,0xF80000C1,0xF80000C1,0xFDF000AC,0xFFEC00C0,0xF3F400C2,0xFFEC009B,0xFFE80081,0xFFE0005E,0xFFE00048,0xFFD0002D,0xFBF000AC,0xFFE80095,0xFFD80092,0xFF940000, -0xF5FC00C1,0x1D802B1,0x1D802B1,0x1D802B1,0x1D802B1,0xFFD001C9,0xFFD001C9,0xFFD001C9,0xFFCC0110,0xFFCC0110,0xFFC800C8,0xFFC801A9,0xFFC801A9,0xFFC801A9,0xFFC00098,0xFFC00098,0xFFBC0029,0xFFB800A1,0xFFB800A1,0xFDB00011,0xF7B40091,0xC9FC02AE,0xC9FC02AE,0xC9FC02AE,0xFFB80153,0xFFB80153,0xFFAC00CA,0xFFA000FE,0xFFA000FE,0xFF900001,0xF7980091,0xE5F802AE, -0xE5F802AE,0xFF5800C8,0xF73C0091,0xEC0002AE,0xFFD80245,0xF5D8028C,0x1D802B1,0xFFD401E2,0xFFCC017A,0xFFC40114,0xFFC400E0,0xFFB80065,0xFFD0022E,0xFFD001C3,0xFFBC0109,0xFF900001,0xDFF802AE,0x1EC0091,0x1EC0091,0x1EC0091,0x1EC0091,0xFFE80055,0xFFE80055,0xFFE80055,0xFFE0001D,0xFFE0001D,0xFFDC0000,0xE5FC0091,0xE5FC0091,0xE5FC0091,0xFFD80034,0xFFD80034, -0xFFCC0000,0xF3F80091,0xF3F80091,0xFF940000,0xF6000091,0xE5FC0091,0xE5FC0091,0xE5FC0091,0xFFD80034,0xFFD80034,0xFFCC0000,0xF3F80091,0xF3F80091,0xFF940000,0xF6000091,0xF3F80091,0xF3F80091,0xFF940000,0xF6000091,0xF6000091,0xFBEC0080,0xFFEC0080,0x1EC0091,0xF9EC0080,0xFFE0006A,0xFFE00055,0xFFE00048,0xFFD0002D,0xF9EC0080,0xFFE80071,0xEFFC0091,0xFF940000, -0xEFFC0091,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0x1C800C8,0xFFBC0029,0xFFBC0029,0xFFBC0029,0xFFBC0029,0xFFBC0029, -0xFFBC0029,0xF7B40001,0xF7B40001,0xF7B40001,0xEDB40001,0xAFFC00C8,0xAFFC00C8,0xAFFC00C8,0xAFFC00C8,0xAFFC00C8,0xAFFC00C8,0xFF900001,0xFF900001,0xFF900001,0xEDA00001,0xD7FC00C8,0xD7FC00C8,0xD7FC00C8,0xED640001,0xE20000CA,0xFBC400A4,0x1C800C8,0x1C800C8,0xFBC40080,0xFFBC0061,0xFFBC0041,0xFFBC0041,0xFFB80014,0xFFBC009D,0xFFBC0075,0xFFB00001,0xFF900001, -0xCDFC00C8,}; -static const uint32_t g_etc1_to_bc7_m6_table95[] = { -0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xD5F80000, -0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x9E00000,0x9E00000,0x9E00000,0xA9FC0000,0xC9FC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000, -0xE5FC0000,0xF3F80000,0xF3F80000,0xF3F80000,0xF4000001,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xF3F80000,0xF3F80000,0xF3F80000,0xF4000001,0xF3F80000,0xF3F80000,0xF3F80000,0xF4000001,0xF4000001,0x77FC0000,0x1EC0000,0x1EC0000,0xC3FC0000,0xD5FC0000,0xDFFC0000,0xDFFC0000,0xEBFC0000,0xC3FC0000,0xD5FC0000,0xEFFC0000,0xF3F80000, -0xEFFC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1EC0232,0xFFE801F2,0xFFE401C9,0xFFE401B9,0xFFE801AA,0xFFE00165,0xFFDC0149,0xFFD80110,0xFFD800EC,0xFFD800C8,0xFFDC0186,0xFFDC0131,0xFFDC010D,0xFFD400BB,0xFFD00088,0xFFD00048,0xFFCC0091,0xFFCC0051,0xFFC40001,0xFBC40039,0xE3FC0232,0xFFD801DD,0xFFD801B9,0xFFCC0150,0xFFCC0110,0xFFC400C8,0xFFC00109,0xFFB80096,0xFFAC0011,0xFBAC0039,0xF1F80232, -0xFFAC01B9,0xFF8800C8,0xFB5C0039,0xF4000232,0xFFE401E6,0xFDE80210,0xFFEC0221,0xFFE0019E,0xFFDC013E,0xFFD400D8,0xFFD000B5,0xFFD00061,0xFFE401ED,0xFFDC018C,0xFFD000AF,0xFFAC0011,0xEDFC0232,0x1F80036,0xFFF80031,0xFFF4002D,0xFFF40029,0xFFF40022,0xFFF4001D,0xFFF40019,0xFFF0000C,0xFFF00008,0xFFEC0000,0xF7FC0036,0xFFF0002D,0xFFF00029,0xFFF00018,0xFFE40010, -0xFFE40000,0xFBFC0036,0xFFE00029,0xFFC80000,0xFA000039,0xF7FC0036,0xFFF0002D,0xFFF00029,0xFFF00018,0xFFE40010,0xFFE40000,0xFBFC0036,0xFFE00029,0xFFC80000,0xFA000039,0xFBFC0036,0xFFE00029,0xFFC80000,0xFA000039,0xFA000039,0xFFF40030,0xF5F80036,0xF5F80036,0xFFF8002C,0xFFF00022,0xFFEC0018,0xFFE80011,0xFFE4000A,0xFFF8002C,0xFFF4002B,0xFFE8002A,0xFFC80000, -0xFBFC0036,0x1E401B9,0x1E401B9,0x1E401B9,0x1E401B9,0xFFDC0149,0xFFDC0149,0xFFDC0149,0xFFD800EC,0xFFD800EC,0xFFD800C8,0xFFDC010D,0xFFDC010D,0xFFDC010D,0xFFD00088,0xFFD00088,0xFFD00048,0xFFCC0051,0xFFCC0051,0xFFC40001,0xFBC40029,0xD9FC01B9,0xD9FC01B9,0xD9FC01B9,0xFFCC0110,0xFFCC0110,0xFFC400C8,0xFFB80096,0xFFB80096,0xFFAC0011,0xFBAC0029,0xEDF801B9, -0xEDF801B9,0xFF8800C8,0xFB5C0029,0xF20001BA,0xFDE40182,0xFBE401A0,0x1E401B9,0xFFDC0144,0xFFD80101,0xFFD400C8,0xFFD000B5,0xFFD00061,0xFDE00181,0xFFDC013B,0xFFD000AE,0xFFAC0011,0xE7FC01B9,0x1F40029,0x1F40029,0x1F40029,0x1F40029,0xFFF40019,0xFFF40019,0xFFF40019,0xFFF00008,0xFFF00008,0xFFEC0000,0xF1FC0029,0xF1FC0029,0xF1FC0029,0xFFE40010,0xFFE40010, -0xFFE40000,0xF9F80029,0xF9F80029,0xFFC80000,0xFA000029,0xF1FC0029,0xF1FC0029,0xF1FC0029,0xFFE40010,0xFFE40010,0xFFE40000,0xF9F80029,0xF9F80029,0xFFC80000,0xFA000029,0xF9F80029,0xF9F80029,0xFFC80000,0xFA000029,0xFA000029,0xFFF40020,0xF3F40029,0x1F40029,0xFDF40020,0xFFF00019,0xFFEC0014,0xFFE80011,0xFFE4000A,0xFDF40020,0xFDF00022,0xF7FC0029,0xFFC80000, -0xF7FC0029,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0x1D800C8,0xFFD00048,0xFFD00048,0xFFD00048,0xFFD00048,0xFFD00048, -0xFFD00048,0xFFC40001,0xFFC40001,0xFFC40001,0xF5C40001,0xC7FC00C8,0xC7FC00C8,0xC7FC00C8,0xC7FC00C8,0xC7FC00C8,0xC7FC00C8,0xFFAC0011,0xFFAC0011,0xFFAC0011,0xF5B00001,0xE3FC00C8,0xE3FC00C8,0xE3FC00C8,0xF5740001,0xEA0000CA,0xF5D800B5,0x1D800C8,0x1D800C8,0xFDD40091,0xFFD00075,0xFFCC0061,0xFFCC0061,0xFFCC0034,0xFDD400A2,0xFFD00082,0xFFC4001D,0xFFAC0011, -0xDDF800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table96[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x180001,0x180001,0x180001,0x180001,0x2240000,0x2240000,0x2240000,0x4C0000,0x4C0000,0xC000000,0x2240000,0x2240000,0x2240000,0x4C0000,0x4C0000,0xC000000,0x4C0000,0x4C0000,0xC000000,0xC000000,0x2240000,0x2240000,0x2240000,0x4C0000,0x4C0000,0xC000000,0x4C0000,0x4C0000,0xC000000,0xC000000,0x4C0000, -0x4C0000,0xC000000,0xC000000,0xC000000,0x41C0000,0x1C0000,0x180001,0x240000,0x2C0000,0x340000,0x3C0000,0x5C0000,0x200000,0x2240000,0x340000,0xC000000,0x340000,0x540000,0x7C0000,0xFC0000,0x28000001,0x7C0000,0xFC0000,0x28000001,0xFC0000,0x28000001,0x28000001,0x7C0000,0xFC0000,0x28000001,0xFC0000,0x28000001, -0x28000001,0xFC0000,0x28000001,0x28000001,0x28000001,0x7C0000,0xFC0000,0x28000001,0xFC0000,0x28000001,0x28000001,0xFC0000,0x28000001,0x28000001,0x28000001,0xFC0000,0x28000001,0x28000001,0x28000001,0x28000001,0x680000,0x4580000,0x4580000,0x8C0000,0xCC0000,0x1940000,0x28000001,0x28000001,0x2700000,0x9C0000,0x1DCC0000,0x28000001, -0xB00000,0x1C0499,0x76080071,0x3C080071,0x28080072,0x500001A5,0x3A000028,0x28000001,0x280001A5,0x200000A2,0x1A0001A5,0x3600039D,0x2E000149,0x240000AA,0x22000236,0x2000011B,0x180001F1,0x1A00039D,0x1C000236,0x160002AE,0x1200039E,0x280499,0x28000216,0x22000127,0x220002AF,0x1E000181,0x18000231,0x180003E2,0x1600028E,0x140002EE,0x120003C2,0x500499, -0x1600032F,0x10000373,0x1000041B,0xC00049B,0xA4000108,0xFE0C0229,0xF21401F2,0x48000118,0x3600011B,0x2800011B,0x220000C2,0x20000173,0x64000209,0x3C00017A,0x1E0001B6,0x140002EE,0x380499,0x24039D,0x720C0055,0x3A0C0055,0x280C0056,0x500001A5,0x3A000028,0x28000001,0x280001A5,0x200000A2,0x1A0001A5,0x34039D,0x2E000149,0x240000AA,0x22000236,0x2000011B, -0x180001F1,0x68039D,0x1C000236,0x160002AE,0x1200039E,0x34039D,0x2E000149,0x240000AA,0x22000236,0x2000011B,0x180001F1,0x68039D,0x1C000236,0x160002AE,0x1200039E,0x68039D,0x1C000236,0x160002AE,0x1200039E,0x1200039E,0xA4000108,0xFE0C0205,0xF61C016E,0x48000118,0x3600011B,0x2800011B,0x220000C2,0x20000173,0x6C0001DB,0x3C00016A,0x1E0001B2,0x160002AE, -0x4C039D,0x80071,0x80071,0x80071,0x80071,0x26000000,0x26000000,0x26000000,0x12000000,0x12000000,0xC000000,0x10000055,0x10000055,0x10000055,0xC000020,0xC000020,0xC000010,0x8000055,0x8000055,0x8000034,0x6000055,0xC0071,0xC0071,0xC0071,0xC000030,0xC000030,0xC000020,0x600005D,0x600005D,0x800003D,0x6000059,0x140071, -0x140071,0x4000052,0x4000062,0x4000072,0x44000019,0xC8000000,0x80071,0x24000022,0x1A00001D,0x12000022,0x1200001D,0xC000022,0x24000036,0x1A00002D,0xA000056,0x800003D,0x100071,0xC0055,0xC0055,0xC0055,0xC0055,0x26000000,0x26000000,0x26000000,0x12000000,0x12000000,0xC000000,0x100055,0x100055,0x100055,0xC000020,0xC000020, -0xC000010,0x200055,0x200055,0x8000034,0x6000055,0x100055,0x100055,0x100055,0xC000020,0xC000020,0xC000010,0x200055,0x200055,0x8000034,0x6000055,0x200055,0x200055,0x8000034,0x6000055,0x6000055,0x44000019,0xC8000000,0xC0055,0x24000022,0x1A00001D,0x12000022,0x1200001D,0xC000022,0x24000032,0x1A000029,0x180055,0x8000034, -0x180055,0x3801A5,0x621C0001,0x361C0001,0x28180002,0x5001A5,0x3A000028,0x28000001,0xA001A5,0x200000A2,0x1A0001A5,0x5001A5,0x3A000028,0x28000001,0xA001A5,0x200000A2,0x1A0001A5,0xA001A5,0x200000A2,0x1A0001A5,0x1A0001A5,0x5001A5,0x3A000028,0x28000001,0xA001A5,0x200000A2,0x1A0001A5,0xA001A5,0x200000A2,0x1A0001A5,0x1A0001A5,0xA001A5, -0x200000A2,0x1A0001A5,0x1A0001A5,0x1A0001A5,0xA40000A4,0x3C01A5,0xFC280062,0x52000091,0x360000A2,0x2C00009D,0x2400006A,0x200000CA,0x720000DD,0x4C0000B4,0x26000059,0x1A0001A5,0x7001A5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table97[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x280001,0x280001,0x280001,0x280001,0x23C0000,0x23C0000,0x23C0000,0x7C0000,0x7C0000,0x14000000,0x23C0000,0x23C0000,0x23C0000,0x7C0000,0x7C0000,0x14000000,0x7C0000,0x7C0000,0x14000000,0x14000000,0x23C0000,0x23C0000,0x23C0000,0x7C0000,0x7C0000,0x14000000,0x7C0000,0x7C0000,0x14000000,0x14000000,0x7C0000, -0x7C0000,0x14000000,0x14000000,0x14000000,0x300000,0x2C0000,0x280001,0x380000,0x440000,0x580000,0x640000,0x980000,0x340000,0x23C0000,0x580000,0x14000000,0x580000,0x640000,0x940000,0x12C0000,0x30000001,0x940000,0x12C0000,0x30000001,0x12C0000,0x30000001,0x30000001,0x940000,0x12C0000,0x30000001,0x12C0000,0x30000001, -0x30000001,0x12C0000,0x30000001,0x30000001,0x30000001,0x940000,0x12C0000,0x30000001,0x12C0000,0x30000001,0x30000001,0x12C0000,0x30000001,0x30000001,0x30000001,0x12C0000,0x30000001,0x30000001,0x30000001,0x30000001,0x7C0000,0xC680000,0xC680000,0xA80000,0xF40000,0x1E00000,0x30000001,0x30000001,0x880000,0xBC0000,0x25DC0000,0x30000001, -0xD40000,0x240691,0x86100129,0x460C0129,0x300C012A,0x6A0001A5,0x46000008,0x32000011,0x340001A5,0x2C00006A,0x220001A5,0x480004ED,0x3A0001D1,0x2E00010E,0x2E00029E,0x2800012B,0x2200021E,0x220004ED,0x20000306,0x1C000362,0x160004EE,0x340691,0x34000316,0x280001E3,0x28000367,0x280001D4,0x1E000295,0x1E000566,0x2000037F,0x1C0003C6,0x1600052E,0x680691, -0x1C00048F,0x1600049F,0x140005C6,0x10000693,0xC2000118,0xF2140349,0xF61C0372,0x66000128,0x4000013B,0x34000135,0x2A0000C3,0x240001AE,0x82000289,0x500001CD,0x26000266,0x1C0003C6,0x4C0691,0x3004ED,0x821400DD,0x441400DD,0x301400DE,0x6A0001A5,0x46000008,0x3204000E,0x340001A5,0x2C00006A,0x220001A5,0x24404ED,0x3A0001D1,0x2E00010E,0x2E00029E,0x2800012B, -0x2200021E,0x8C04ED,0x20000306,0x1C000362,0x160004EE,0x24404ED,0x3A0001D1,0x2E00010E,0x2E00029E,0x2800012B,0x2200021E,0x8C04ED,0x20000306,0x1C000362,0x160004EE,0x8C04ED,0x20000306,0x1C000362,0x160004EE,0x160004EE,0xC2000118,0xF61C02BD,0xFA24026E,0x66000128,0x4000013B,0x34000135,0x2A0000C3,0x240001AE,0x82000249,0x500001B4,0x26000262,0x1C000362, -0x6404ED,0xC0129,0xC0129,0xC0129,0xC0129,0x3E000000,0x3E000000,0x3E000000,0x1E000000,0x1E000000,0x14000000,0x1C0000DD,0x1C0000DD,0x1C0000DD,0x18000050,0x18000050,0x12000028,0xE0000DD,0xE0000DD,0xE000088,0xA0000DD,0x140126,0x140126,0x140126,0x12000088,0x12000088,0x1200004C,0xC0000F1,0xC0000F1,0xC0000A1,0x80000EA,0x240126, -0x240126,0xA0000C6,0x8000105,0x6000126,0x76000041,0xFA040011,0xC0129,0x3A000059,0x28000050,0x22000055,0x1E000049,0x16000061,0x42000092,0x3200007D,0x120000DE,0xC0000A1,0x1C0126,0x1400DD,0x1400DD,0x1400DD,0x1400DD,0x3E000000,0x3E000000,0x3E000000,0x1E000000,0x1E000000,0x14000000,0x1C00DD,0x1C00DD,0x1C00DD,0x18000050,0x18000050, -0x12000028,0x3800DD,0x3800DD,0xE000088,0xA0000DD,0x1C00DD,0x1C00DD,0x1C00DD,0x18000050,0x18000050,0x12000028,0x3800DD,0x3800DD,0xE000088,0xA0000DD,0x3800DD,0x3800DD,0xE000088,0xA0000DD,0xA0000DD,0x76000041,0xFA04000D,0x1400DD,0x3A000059,0x28000050,0x22000055,0x1E000049,0x16000061,0x42000082,0x32000074,0x2800DD,0xE000088, -0x2800DD,0x4801A5,0x6A2C0001,0x3E2C0001,0x30280002,0x6801A5,0x46000008,0x30100001,0xD001A5,0x2C00006A,0x220001A5,0x6801A5,0x46000008,0x30100001,0xD001A5,0x2C00006A,0x220001A5,0xD001A5,0x2C00006A,0x220001A5,0x220001A5,0x6801A5,0x46000008,0x30100001,0xD001A5,0x2C00006A,0x220001A5,0xD001A5,0x2C00006A,0x220001A5,0x220001A5,0xD001A5, -0x2C00006A,0x220001A5,0x220001A5,0x220001A5,0xD6000075,0x4C01A5,0xF4380071,0x6E000059,0x4A00006A,0x36000064,0x2E00003A,0x280000A2,0x920400B5,0x5E00007D,0x32000028,0x220001A5,0x9401A5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table98[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x40001,0x80000,0x80000,0x80000,0x80000,0x80000, -0x80000,0xC0000,0xC0000,0xC0000,0x2000000,0x80000,0x80000,0x80000,0x80000,0x80000,0x80000,0xC0000,0xC0000,0xC0000,0x2000000,0xC0000,0xC0000,0xC0000,0x2000000,0x2000000,0xA040000,0x40001,0x40001,0x6040000,0x80000,0x80000,0x80000,0x80000,0x6040000,0x80000,0xC0000,0xC0000, -0xC0000,0x380001,0x380001,0x380001,0x380001,0x540000,0x540000,0x540000,0xAC0000,0xAC0000,0x1C000000,0x540000,0x540000,0x540000,0xAC0000,0xAC0000,0x1C000000,0xAC0000,0xAC0000,0x1C000000,0x1C000000,0x540000,0x540000,0x540000,0xAC0000,0xAC0000,0x1C000000,0xAC0000,0xAC0000,0x1C000000,0x1C000000,0xAC0000, -0xAC0000,0x1C000000,0x1C000000,0x1C000000,0x440000,0x63C0000,0x380001,0x24C0000,0x600000,0x780000,0x8C0000,0xD40000,0x480000,0x540000,0x780000,0x1C000000,0x780000,0x740000,0xAC0000,0x15C0000,0x38000001,0xAC0000,0x15C0000,0x38000001,0x15C0000,0x38000001,0x38000001,0xAC0000,0x15C0000,0x38000001,0x15C0000,0x38000001, -0x38000001,0x15C0000,0x38000001,0x38000001,0x38000001,0xAC0000,0x15C0000,0x38000001,0x15C0000,0x38000001,0x38000001,0x15C0000,0x38000001,0x38000001,0x38000001,0x15C0000,0x38000001,0x38000001,0x38000001,0x38000001,0x900000,0x7C0000,0x7C0000,0x2C00000,0x11C0000,0x9F00000,0x38000001,0x38000001,0x9C0000,0xD80000,0x2DEC0000,0x38000001, -0xF40000,0x2C088E,0x9A1401FE,0x501401FE,0x381401FF,0x7E0401AA,0x54040005,0x3C08003E,0x3E0401AA,0x3404004F,0x2A0401AA,0x5A0005EA,0x46000218,0x36000163,0x3A0002BD,0x3000010A,0x28000215,0x2C0005EA,0x26000383,0x240003DD,0x1C0005ED,0x40088E,0x40000401,0x3400028E,0x340003FA,0x2E0001F3,0x280002BE,0x2800069F,0x2600042C,0x20000463,0x1C000651,0x80088E, -0x200005EF,0x1C0005B2,0x1A000749,0x1600088E,0xF40000E9,0xF61C0486,0xFA24050F,0x74000111,0x5000011D,0x3C000103,0x34000096,0x2C00019A,0xA40002D1,0x5E0001D1,0x320002B1,0x20000463,0x5C088E,0x3C05EA,0x8E200152,0x4E200152,0x38200153,0x7A0801A6,0x54040001,0x3A10002A,0x3E0401A6,0x3404004B,0x2A0401A6,0x5805EA,0x46000218,0x36000163,0x3A0002BD,0x3000010A, -0x28000215,0xB005EA,0x26000383,0x240003DD,0x1C0005ED,0x5805EA,0x46000218,0x36000163,0x3A0002BD,0x3000010A,0x28000215,0xB005EA,0x26000383,0x240003DD,0x1C0005ED,0xB005EA,0x26000383,0x240003DD,0x1C0005ED,0x1C0005ED,0xF40000E9,0xFC280356,0xFE2C0353,0x74000111,0x5000011D,0x3C000103,0x34000096,0x2C00019A,0xA400026D,0x5E0001AD,0x320002A8,0x240003DD, -0x7C05EA,0x1401FE,0x1401FE,0x1401FE,0x1401FE,0x52040005,0x52040005,0x52040005,0x28040006,0x28040006,0x1C040005,0x30000152,0x30000152,0x30000152,0x22000059,0x22000059,0x1A000028,0x16000154,0x16000154,0x160000B4,0xE000154,0x2001FD,0x2001FD,0x2001FD,0x220000D2,0x220000D2,0x18000069,0x12000188,0x12000188,0x140000EA,0xE00016D,0x3C01FD, -0x3C01FD,0x10000149,0xA0001B5,0xA0001FD,0xB6000049,0xFE0C005E,0x1401FE,0x50000071,0x3C000061,0x2E000061,0x2A000049,0x2000007D,0x640000DD,0x440000AD,0x1E000156,0x140000EA,0x2C01FD,0x200152,0x200152,0x200152,0x200152,0x4E080001,0x4E080001,0x4E080001,0x28080001,0x28080001,0x1C040001,0x300152,0x300152,0x300152,0x22000059,0x22000059, -0x1A000028,0x5C0152,0x5C0152,0x160000B4,0xE000154,0x300152,0x300152,0x300152,0x22000059,0x22000059,0x1A000028,0x5C0152,0x5C0152,0x160000B4,0xE000154,0x5C0152,0x5C0152,0x160000B4,0xE000154,0xE000154,0xB6000049,0xFE0C003A,0x200152,0x50000071,0x3C000061,0x2E000061,0x2A000049,0x2000007D,0x640000B9,0x4400009D,0x400152,0x160000B4, -0x400152,0x5801A5,0x723C0001,0x463C0001,0x38380002,0x8001A5,0x54040000,0x38200001,0x10001A5,0x36000049,0x2A0001A5,0x8001A5,0x54040000,0x38200001,0x10001A5,0x36000049,0x2A0001A5,0x10001A5,0x36000049,0x2A0001A5,0x2A0001A5,0x8001A5,0x54040000,0x38200001,0x10001A5,0x36000049,0x2A0001A5,0x10001A5,0x36000049,0x2A0001A5,0x2A0001A5,0x10001A5, -0x36000049,0x2A0001A5,0x2A0001A5,0x2A0001A5,0xF6040055,0x5C01A5,0xFC480071,0x84000034,0x56000048,0x40000048,0x36000019,0x32000071,0xB4040091,0x6E000055,0x3C00000A,0x2A0001A5,0xB401A5,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x8000000,0x8000000,0x8000000,0x8000000,0x8000000, -0x8000000,0x4000000,0x4000000,0x4000000,0x2000000,0x40005,0x40005,0x40005,0x40005,0x40005,0x40005,0x2000002,0x2000002,0x2000002,0x2000001,0x5,0x5,0x5,0x2000004,0x5,0x28000000,0x40005,0x40005,0x12000000,0xC000000,0xA000000,0xA000000,0x6000000,0x12000001,0xC000001,0x4000000,0x2000002, -0x5,}; -static const uint32_t g_etc1_to_bc7_m6_table99[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x140001,0x200000,0x200000,0x200000,0x200000,0x200000, -0x200000,0x3C0000,0x3C0000,0x3C0000,0xA000000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x3C0000,0x3C0000,0x3C0000,0xA000000,0x3C0000,0x3C0000,0x3C0000,0xA000000,0xA000000,0x180000,0x140001,0x140001,0x2180000,0x1C0000,0x1C0000,0x1C0000,0x240000,0x2180000,0x1C0000,0x2C0000,0x3C0000, -0x2C0000,0x480001,0x480001,0x480001,0x480001,0x6C0000,0x6C0000,0x6C0000,0xDC0000,0xDC0000,0x24000000,0x6C0000,0x6C0000,0x6C0000,0xDC0000,0xDC0000,0x24000000,0xDC0000,0xDC0000,0x24000000,0x24000000,0x6C0000,0x6C0000,0x6C0000,0xDC0000,0xDC0000,0x24000000,0xDC0000,0xDC0000,0x24000000,0x24000000,0xDC0000, -0xDC0000,0x24000000,0x24000000,0x24000000,0x2540000,0xE4C0000,0x480001,0x640000,0x7C0000,0x9C0000,0xB40000,0x1100000,0x5C0000,0x6C0000,0x9C0000,0x24000000,0x9C0000,0x840000,0xC40000,0x18C0000,0x40000001,0xC40000,0x18C0000,0x40000001,0x18C0000,0x40000001,0x40000001,0xC40000,0x18C0000,0x40000001,0x18C0000,0x40000001, -0x40000001,0x18C0000,0x40000001,0x40000001,0x40000001,0xC40000,0x18C0000,0x40000001,0x18C0000,0x40000001,0x40000001,0x18C0000,0x40000001,0x40000001,0x40000001,0x18C0000,0x40000001,0x40000001,0x40000001,0x40000001,0xA40000,0x8C0000,0x8C0000,0xDC0000,0x1400000,0x13F00000,0x40000001,0x40000001,0xB40000,0xF80000,0x35FC0000,0x40000001, -0x1180000,0x380A26,0xA62002D2,0x5A2002D2,0x402002D3,0x8E0C01E2,0x600C003F,0x461000A2,0x480C01E2,0x3C080073,0x320C01E2,0x720005EA,0x580001A8,0x40040159,0x4600024D,0x3A00007A,0x320001C9,0x380005EA,0x320002FB,0x2C000362,0x240005ED,0x540A26,0x4C000489,0x3C00031B,0x40000432,0x3A0001E3,0x2E0002BE,0x34000717,0x30000415,0x2A00043D,0x2400067D,0xA40A26, -0x260006D7,0x26000662,0x20000819,0x1C000A26,0xFA0400DE,0xFC2805A6,0xFE2C0687,0x90000086,0x6200008B,0x4C00007A,0x40000029,0x380000FA,0xC200025D,0x76000142,0x3C000233,0x2A00043D,0x740A26,0x4C05EA,0x96300152,0x56300152,0x40300153,0x821801A6,0x5C140001,0x4220002A,0x461401A6,0x3C14004B,0x321401A6,0x7005EA,0x580001A8,0x40080153,0x4600024D,0x3A00007A, -0x320001C9,0xE405EA,0x320002FB,0x2C000362,0x240005ED,0x7005EA,0x580001A8,0x40080153,0x4600024D,0x3A00007A,0x320001C9,0xE405EA,0x320002FB,0x2C000362,0x240005ED,0xE405EA,0x320002FB,0x2C000362,0x240005ED,0x240005ED,0xFC0800CE,0xF438037A,0xFA44035E,0x90000086,0x6200008B,0x4C00007A,0x40000029,0x380000FA,0xD00001C1,0x7C000105,0x3C000223,0x2C000362, -0xA005EA,0x2002D2,0x2002D2,0x2002D2,0x2002D2,0x620C003D,0x620C003D,0x620C003D,0x320C003E,0x320C003E,0x240C003D,0x48000152,0x48000152,0x48000152,0x34000025,0x34000025,0x24000001,0x22000152,0x22000152,0x1C000080,0x16000154,0x3002D2,0x3002D2,0x3002D2,0x280000FE,0x280000FE,0x2200007D,0x1E0001C8,0x1E0001C8,0x1C0000E4,0x16000194,0x5C02D2, -0x5C02D2,0x160001B5,0x14000228,0xE0002D5,0xF6000014,0xF21400F5,0x2002D2,0x7A000034,0x54000028,0x40000028,0x38000019,0x2A00003D,0x820000D5,0x5A000086,0x2C00015B,0x1C0000E4,0x4002D2,0x300152,0x300152,0x300152,0x300152,0x56180001,0x56180001,0x56180001,0x30180001,0x30180001,0x24140001,0x2440152,0x2440152,0x2440152,0x34000025,0x34000025, -0x24000001,0x8C0152,0x8C0152,0x1C000080,0x16000154,0x2440152,0x2440152,0x2440152,0x34000025,0x34000025,0x24000001,0x8C0152,0x8C0152,0x1C000080,0x16000154,0x8C0152,0x8C0152,0x1C000080,0x16000154,0x16000154,0xF6000014,0xF820003D,0x300152,0x7A000034,0x54000028,0x40000028,0x38000019,0x2A00003D,0x96000088,0x5A000062,0x640152,0x1C000080, -0x640152,0x6801A5,0x7A4C0001,0x4E4C0001,0x40480002,0x9801A5,0x5C140000,0x40300001,0x13001A5,0x3E000022,0x320001A5,0x9801A5,0x5C140000,0x40300001,0x13001A5,0x3E000022,0x320001A5,0x13001A5,0x3E000022,0x320001A5,0x320001A5,0x9801A5,0x5C140000,0x40300001,0x13001A5,0x3E000022,0x320001A5,0x13001A5,0x3E000022,0x320001A5,0x320001A5,0x13001A5, -0x3E000022,0x320001A5,0x320001A5,0x320001A5,0xFE140055,0x6C01A5,0xF4580082,0x9A000019,0x6A000028,0x4E000022,0x40000005,0x3A000055,0xD2040071,0x8600003A,0x44000001,0x320001A5,0xD801A5,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0xC003D,0x20000000,0x20000000,0x20000000,0x20000000,0x20000000, -0x20000000,0x10000000,0x10000000,0x10000000,0xA000000,0x10003D,0x10003D,0x10003D,0x10003D,0x10003D,0x10003D,0xC000014,0xC000014,0xC000014,0x800000D,0x18003D,0x18003D,0x18003D,0x8000028,0x400003D,0xA8000000,0xC003D,0xC003D,0x4A000000,0x34000000,0x28000000,0x28000000,0x1A000000,0x44000011,0x34000009,0x14000001,0xC000014, -0x14003D,}; -static const uint32_t g_etc1_to_bc7_m6_table100[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000, -0x3C0000,0x740000,0x740000,0x740000,0x12000001,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x740000,0x740000,0x740000,0x12000001,0x740000,0x740000,0x740000,0x12000001,0x12000001,0xC280000,0x280000,0x280000,0x42C0000,0x2300000,0x2340000,0x2340000,0x2400000,0x42C0000,0x2300000,0x540000,0x740000, -0x540000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x880000,0x880000,0x880000,0x1140000,0x1140000,0x2C000001,0x880000,0x880000,0x880000,0x1140000,0x1140000,0x2C000001,0x1140000,0x1140000,0x2C000001,0x2C000001,0x880000,0x880000,0x880000,0x1140000,0x1140000,0x2C000001,0x1140000,0x1140000,0x2C000001,0x2C000001,0x1140000, -0x1140000,0x2C000001,0x2C000001,0x2C000001,0x6680000,0x8600000,0x5C0000,0x7C0000,0x980000,0xC00000,0xE00000,0x1540000,0x740000,0x880000,0xC00000,0x2C000001,0xC00000,0x940001,0x2DC0000,0x1C40000,0x4A000000,0x2DC0000,0x1C40000,0x4A000000,0x1C40000,0x4A000000,0x4A000000,0x2DC0000,0x1C40000,0x4A000000,0x1C40000,0x4A000000, -0x4A000000,0x1C40000,0x4A000000,0x4A000000,0x4A000000,0x2DC0000,0x1C40000,0x4A000000,0x1C40000,0x4A000000,0x4A000000,0x1C40000,0x4A000000,0x4A000000,0x4A000000,0x1C40000,0x4A000000,0x4A000000,0x4A000000,0x4A000000,0xBC0000,0xA00000,0xA00000,0xFC0000,0x16C0000,0x1DFC0000,0x4A000000,0x4A000000,0xCC0000,0x1180000,0x3FF00000,0x4A000000, -0x13C0000,0x480C65,0xB62C0428,0x642C0428,0x4A2C0428,0xA014026D,0x6A1400D8,0x4C1C0165,0x5414026D,0x461000F0,0x3C14026D,0x8E0005EA,0x6A000163,0x4E080192,0x580001F6,0x4600001D,0x3C0001A5,0x440005ED,0x3E000284,0x38000301,0x2E0005EA,0x680C63,0x5E000594,0x48000438,0x4C0004BF,0x40000222,0x3A000313,0x400007BE,0x3A00041D,0x34000436,0x2E0006CB,0xD00C63, -0x32000818,0x2C00076D,0x2600094E,0x22000C63,0xFE140162,0xF43807A1,0xF840089D,0xB400001E,0x76000024,0x5A000018,0x4A000001,0x4200007A,0xF2000212,0x900000D7,0x460001D4,0x34000436,0x940C63,0x5C05ED,0x9E440154,0x5E440154,0x4A400154,0x8C2801A5,0x64280002,0x4A300029,0x4E2801A5,0x4424004C,0x3C2801A5,0x8C05EA,0x6A000163,0x4A180152,0x580001F6,0x4600001D, -0x3C0001A5,0x11805EA,0x3E000284,0x38000301,0x2E0005EA,0x8C05EA,0x6A000163,0x4A180152,0x580001F6,0x4600001D,0x3C0001A5,0x11805EA,0x3E000284,0x38000301,0x2E0005EA,0x11805EA,0x3E000284,0x38000301,0x2E0005EA,0x2E0005EA,0xFC1C00E5,0xFE4C0379,0xF2540384,0xB400001E,0x76000024,0x5A000018,0x4A000001,0x4200007A,0xF2000131,0x90000086,0x460001C4,0x38000301, -0xC805EA,0x2C0428,0x2C0428,0x2C0428,0x2C0428,0x761400C8,0x761400C8,0x761400C8,0x3E1400C8,0x3E1400C8,0x2C1400C9,0x64000152,0x64000152,0x64000152,0x40000005,0x40000005,0x2E04000E,0x30000152,0x30000152,0x26000055,0x20000152,0x400428,0x400428,0x400428,0x3400018E,0x3400018E,0x2A0000F1,0x2800022D,0x2800022D,0x240000FA,0x1E0001BE,0x800428, -0x800428,0x1C00028B,0x1C0002DB,0x1400042B,0xFC0C003E,0xF82001F1,0x2C0428,0xA400000D,0x6C000008,0x52000008,0x4C000000,0x38000019,0xB40000E3,0x76000072,0x3E000162,0x240000FA,0x5C0428,0x400154,0x400154,0x400154,0x400154,0x62280000,0x62280000,0x62280000,0x3A280000,0x3A280000,0x2C280001,0x600152,0x600152,0x600152,0x40000005,0x40000005, -0x2C100001,0xC40152,0xC40152,0x26000055,0x20000152,0x600152,0x600152,0x600152,0x40000005,0x40000005,0x2C100001,0xC40152,0xC40152,0x26000055,0x20000152,0xC40152,0xC40152,0x26000055,0x20000152,0x20000152,0xFE100012,0xF2340048,0x400154,0xA400000D,0x6C000008,0x52000008,0x4C000000,0x38000019,0xC2000055,0x7C000032,0x8C0152,0x26000055, -0x8C0152,0x7801A5,0x845C0000,0x585C0000,0x4A5C0000,0xB401A5,0x66240000,0x4A400000,0x16801A5,0x4800000D,0x3C0001A5,0xB401A5,0x66240000,0x4A400000,0x16801A5,0x4800000D,0x3C0001A5,0x16801A5,0x4800000D,0x3C0001A5,0x3C0001A5,0xB401A5,0x66240000,0x4A400000,0x16801A5,0x4800000D,0x3C0001A5,0x16801A5,0x4800000D,0x3C0001A5,0x3C0001A5,0x16801A5, -0x4800000D,0x3C0001A5,0x3C0001A5,0x3C0001A5,0xFE280062,0x8001A5,0xFE6C0080,0xB4000005,0x78000012,0x5A000008,0x4A080000,0x46000034,0xF6080055,0x98000019,0x4E100000,0x3C0001A5,0xFC01A5,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x1400C8,0x3C000000,0x3C000000,0x3C000000,0x3C000000,0x3C000000, -0x3C000000,0x1C000001,0x1C000001,0x1C000001,0x12000001,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x1C00C8,0x18000049,0x18000049,0x18000049,0x12000025,0x3800C8,0x3800C8,0x3800C8,0xE00007D,0x80000CA,0xFA040008,0x1400C8,0x1400C8,0x8A000000,0x60000000,0x4A000000,0x4A000000,0x30000000,0x7600003A,0x5600001D,0x24000004,0x18000049, -0x2800C8,}; -static const uint32_t g_etc1_to_bc7_m6_table101[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000, -0x2500000,0xA40000,0xA40000,0xA40000,0x1A000001,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0x2500000,0xA40000,0xA40000,0xA40000,0x1A000001,0xA40000,0xA40000,0xA40000,0x1A000001,0x1A000001,0x3C0000,0x380000,0x380000,0x400000,0x2440000,0x4C0000,0x4C0000,0x5C0000,0x400000,0x2440000,0x740000,0xA40000, -0x740000,0x6C0000,0x6C0000,0x6C0000,0x6C0000,0xA00000,0xA00000,0xA00000,0x1440000,0x1440000,0x34000001,0xA00000,0xA00000,0xA00000,0x1440000,0x1440000,0x34000001,0x1440000,0x1440000,0x34000001,0x34000001,0xA00000,0xA00000,0xA00000,0x1440000,0x1440000,0x34000001,0x1440000,0x1440000,0x34000001,0x34000001,0x1440000, -0x1440000,0x34000001,0x34000001,0x34000001,0x27C0000,0x740000,0x6C0000,0x2900000,0xB40000,0xE40000,0x1080000,0x1900000,0x880000,0xA00000,0xE40000,0x34000001,0xE40000,0xA40001,0x2F40000,0x1F40000,0x52000000,0x2F40000,0x1F40000,0x52000000,0x1F40000,0x52000000,0x52000000,0x2F40000,0x1F40000,0x52000000,0x1F40000,0x52000000, -0x52000000,0x1F40000,0x52000000,0x52000000,0x52000000,0x2F40000,0x1F40000,0x52000000,0x1F40000,0x52000000,0x52000000,0x1F40000,0x52000000,0x52000000,0x52000000,0x1F40000,0x52000000,0x52000000,0x52000000,0x52000000,0xD00000,0xB00000,0xB00000,0x3140000,0x1940000,0x27FC0000,0x52000000,0x52000000,0xE00000,0x1380000,0x49C40000,0x52000000, -0x1600000,0x540EC9,0xC23805B4,0x6C3805B5,0x523805B4,0xB21C032D,0x762001A4,0x56240261,0x5E1C032D,0x501801A4,0x441C032D,0xA60005EA,0x7C000153,0x581001FE,0x620001B9,0x50000005,0x440401B9,0x500005ED,0x4A000234,0x3E0002A5,0x360005EA,0x780EC7,0x680006C8,0x520005B3,0x5800057F,0x4C0002A2,0x400003A7,0x4C000876,0x46000455,0x3C00044E,0x34000717,0xF40EC7, -0x380009AC,0x320008B1,0x30000A97,0x28000EC7,0xFE20025D,0xFA440995,0xFE4C0AC9,0xCC000001,0x8A000004,0x66000003,0x5408001C,0x4E000030,0xFE000225,0xA60000A2,0x54000194,0x3C00044E,0xAC0EC7,0x6C05ED,0xA6540154,0x66540154,0x52500154,0x943801A5,0x6C380002,0x52400029,0x563801A5,0x4C34004C,0x443801A5,0xA405EA,0x78040153,0x52280152,0x620001B9,0x50000005, -0x441001A5,0x14C05EA,0x4A000234,0x3E0002A5,0x360005EA,0xA405EA,0x78040153,0x52280152,0x620001B9,0x50000005,0x441001A5,0x14C05EA,0x4A000234,0x3E0002A5,0x360005EA,0x14C05EA,0x4A000234,0x3E0002A5,0x360005EA,0x360005EA,0xFC3000F8,0xF65C039D,0xFA640384,0xCC000001,0x8A000004,0x66000003,0x52100001,0x4E000030,0xFE08010A,0xA8000035,0x5400017B,0x3E0002A5, -0xE805EA,0x3805B4,0x3805B4,0x3805B4,0x3805B4,0x861C0188,0x861C0188,0x861C0188,0x481C0188,0x481C0188,0x341C0189,0x7C000152,0x7C000152,0x7C000152,0x50000001,0x50000001,0x36080042,0x3C000152,0x3C000152,0x3200002D,0x28000152,0x5005B3,0x5005B3,0x5005B3,0x4000024E,0x4000024E,0x3400019B,0x340002A5,0x340002A5,0x2E000122,0x280001FB,0xA005B3, -0xA005B3,0x26000389,0x200003B6,0x1A0005B3,0xF81400D1,0xFE2C0329,0x3805B4,0xC6000001,0x84000001,0x64000001,0x5A040009,0x48000004,0xE4000105,0x9600006A,0x4C00016B,0x2E000122,0x7005B3,0x500154,0x500154,0x500154,0x500154,0x6A380000,0x6A380000,0x6A380000,0x42380000,0x42380000,0x34380001,0x780152,0x780152,0x780152,0x4C080001,0x4C080001, -0x34200001,0xF40152,0xF40152,0x3200002D,0x28000152,0x780152,0x780152,0x780152,0x4C080001,0x4C080001,0x34200001,0xF40152,0xF40152,0x3200002D,0x28000152,0xF40152,0xF40152,0x3200002D,0x28000152,0x28000152,0xFE200019,0xFA440048,0x500154,0xC4040001,0x80040000,0x62040000,0x54100000,0x48000004,0xF4000034,0x9A000012,0xAC0152,0x3200002D, -0xAC0152,0x8801A5,0x8C6C0000,0x606C0000,0x526C0000,0xC801A5,0x6E340000,0x52500000,0x19801A5,0x50000004,0x440001A5,0xC801A5,0x6E340000,0x52500000,0x19801A5,0x50000004,0x440001A5,0x19801A5,0x50000004,0x440001A5,0x440001A5,0xC801A5,0x6E340000,0x52500000,0x19801A5,0x50000004,0x440001A5,0x19801A5,0x50000004,0x440001A5,0x440001A5,0x19801A5, -0x50000004,0x440001A5,0x440001A5,0x440001A5,0xF6400071,0x9001A5,0xF67C0091,0xCC000000,0x8A000004,0x66000002,0x52180000,0x5000001D,0xFE180055,0xAE00000A,0x56200000,0x440001A5,0x12001A5,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x1C0188,0x54000000,0x54000000,0x54000000,0x54000000,0x54000000, -0x54000000,0x28000000,0x28000000,0x28000000,0x1A000001,0x280188,0x280188,0x280188,0x280188,0x280188,0x280188,0x22000089,0x22000089,0x22000089,0x18000049,0x500188,0x500188,0x500188,0x100000F2,0xC00018A,0xFE0C0048,0x1C0188,0x1C0188,0xC4000000,0x88000000,0x68000000,0x68000000,0x44000000,0xA000007D,0x74000041,0x34000009,0x22000089, -0x380188,}; -static const uint32_t g_etc1_to_bc7_m6_table102[] = { -0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x240000, -0x240000,0x240000,0x240000,0x6000000,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xC0001,0xE0C0000,0xE0C0000,0xE0C0000,0x140000,0x1C0000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x2680000,0x2680000,0x2680000,0x2680000,0x2680000, -0x2680000,0xD80000,0xD80000,0xD80000,0x22000001,0x2680000,0x2680000,0x2680000,0x2680000,0x2680000,0x2680000,0xD80000,0xD80000,0xD80000,0x22000001,0xD80000,0xD80000,0xD80000,0x22000001,0x22000001,0x4C0000,0x480000,0x480000,0x540000,0x2580000,0x600000,0x600000,0x780000,0x540000,0x2580000,0x980000,0xD80000, -0x980000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0xB80000,0xB80000,0xB80000,0x1740000,0x1740000,0x3C000001,0xB80000,0xB80000,0xB80000,0x1740000,0x1740000,0x3C000001,0x1740000,0x1740000,0x3C000001,0x3C000001,0xB80000,0xB80000,0xB80000,0x1740000,0x1740000,0x3C000001,0x1740000,0x1740000,0x3C000001,0x3C000001,0x1740000, -0x1740000,0x3C000001,0x3C000001,0x3C000001,0x900000,0x840000,0x7C0000,0xA80000,0xD00000,0x1080000,0x12C0000,0x1CC0000,0x9C0000,0xB80000,0x1080000,0x3C000001,0x1080000,0xB40001,0x30C0000,0xBFC0000,0x5A000000,0x30C0000,0xBFC0000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x30C0000,0xBFC0000,0x5A000000,0xBFC0000,0x5A000000, -0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0x30C0000,0xBFC0000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0xBFC0000,0x5A000000,0x5A000000,0x5A000000,0x5A000000,0xE40000,0x8C00000,0x8C00000,0x1300000,0x1BC0000,0x31FC0000,0x5A000000,0x5A000000,0xF80000,0x1540000,0x51D40000,0x5A000000, -0x1800000,0x600F1E,0xCA4805ED,0x764405ED,0x5A4405ED,0xBA2C034A,0x7E3001C5,0x5E340286,0x662C034A,0x582801BD,0x4C2C034A,0xAE1005EB,0x84100154,0x6020020F,0x6C0801B6,0x58100006,0x4C1401BE,0x5A0C05EB,0x5204020D,0x4604028A,0x3E0C05EB,0x900F1A,0x7A000675,0x5A1005EA,0x680004BE,0x5800021D,0x4C000362,0x580007E9,0x4E00036B,0x46000371,0x3C00069F,0x1240F1A, -0x44000939,0x3E0007FE,0x38000A17,0x30000F1A,0xFE3402CD,0xFE4C0A1A,0xF65C0B55,0xD4100002,0x920C0004,0x6E100004,0x5C180025,0x560C0023,0xFE100262,0xBC000021,0x5E000159,0x46000371,0xD00F1A,0x7C05ED,0xAE640154,0x6E640154,0x5A600154,0x9C4801A5,0x74480002,0x5A500029,0x5E4801A5,0x5444004C,0x4C4801A5,0xBC05EA,0x80140153,0x5A380152,0x700001A6,0x58100005, -0x4C2001A5,0x17C05EA,0x500001E8,0x48000266,0x3E0005EA,0xBC05EA,0x80140153,0x5A380152,0x700001A6,0x58100005,0x4C2001A5,0x17C05EA,0x500001E8,0x48000266,0x3E0005EA,0x17C05EA,0x500001E8,0x48000266,0x3E0005EA,0x3E0005EA,0xFE3C0121,0xFE6C039D,0xF27403AD,0xD4100001,0x920C0003,0x6E100003,0x5A200001,0x5800000D,0xFE180129,0xBC000008,0x5E000158,0x48000266, -0x10C05EA,0x4405ED,0x4405ED,0x4405ED,0x4405ED,0x8E2C01A5,0x8E2C01A5,0x8E2C01A5,0x502C01A5,0x502C01A5,0x3C2C01A6,0x84100153,0x84100153,0x84100153,0x58100002,0x58100002,0x3E18004B,0x44100153,0x44100153,0x380C002A,0x300C0153,0x6805EA,0x6805EA,0x6805EA,0x52000205,0x52000205,0x3C0401A6,0x40000248,0x40000248,0x3A0000A9,0x2E00019A,0xD005EA, -0xD005EA,0x2C000356,0x2A00037E,0x220005EA,0xFE2000FA,0xF63C0379,0x4405ED,0xD80C0001,0x8C100002,0x6C100002,0x6410000B,0x500C0002,0xFE0000B5,0xB6000015,0x5A040153,0x3A0000A9,0x9405EA,0x600154,0x600154,0x600154,0x600154,0x72480000,0x72480000,0x72480000,0x4A480000,0x4A480000,0x3C480001,0x900152,0x900152,0x900152,0x54180001,0x54180001, -0x3C300001,0x1240152,0x1240152,0x3A000019,0x30000152,0x900152,0x900152,0x900152,0x54180001,0x54180001,0x3C300001,0x1240152,0x1240152,0x3A000019,0x30000152,0x1240152,0x1240152,0x3A000019,0x30000152,0x30000152,0xFA340020,0xF2540055,0x600154,0xD80C0000,0x88140000,0x6A140000,0x5C200000,0x52080000,0xFE0C0032,0xBC000004,0xD00152,0x3A000019, -0xD00152,0x9801A5,0x947C0000,0x687C0000,0x5A7C0000,0xE001A5,0x76440000,0x5A600000,0x1CC01A5,0x5A040000,0x4C0001A5,0xE001A5,0x76440000,0x5A600000,0x1CC01A5,0x5A040000,0x4C0001A5,0x1CC01A5,0x5A040000,0x4C0001A5,0x4C0001A5,0xE001A5,0x76440000,0x5A600000,0x1CC01A5,0x5A040000,0x4C0001A5,0x1CC01A5,0x5A040000,0x4C0001A5,0x4C0001A5,0x1CC01A5, -0x5A040000,0x4C0001A5,0x4C0001A5,0x4C0001A5,0xFE500071,0xA401A5,0xFE8C0091,0xD4100000,0x98000000,0x70080000,0x5A280000,0x5800000D,0xFE2C0062,0xBC040002,0x5E300000,0x4C0001A5,0x14001A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x2C01A5,0x5C100001,0x5C100001,0x5C100001,0x5C100001,0x5C100001, -0x5C100001,0x30100001,0x30100001,0x30100001,0x220C0002,0x4001A5,0x4001A5,0x4001A5,0x4001A5,0x4001A5,0x4001A5,0x2E000050,0x2E000050,0x2E000050,0x22000011,0x7C01A5,0x7C01A5,0x7C01A5,0x1C0000C1,0x140001A5,0xF61C0062,0x2C01A5,0x2C01A5,0xCC100001,0x90100001,0x70100001,0x70100001,0x4C100001,0xE0000041,0xA400000D,0x40080001,0x2E000050, -0x5801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table103[] = { -0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x580000, -0x580000,0x580000,0x580000,0xE000000,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x200000,0x200000,0x200000,0x2C0000,0x3C0000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x2800000,0x2800000,0x2800000,0x2800000,0x2800000, -0x2800000,0x1080000,0x1080000,0x1080000,0x2A000001,0x2800000,0x2800000,0x2800000,0x2800000,0x2800000,0x2800000,0x1080000,0x1080000,0x1080000,0x2A000001,0x1080000,0x1080000,0x1080000,0x2A000001,0x2A000001,0x65C0000,0x580000,0x580000,0x4640000,0x26C0000,0x780000,0x780000,0x940000,0x4640000,0x26C0000,0xB80000,0x1080000, -0xB80000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0xD00000,0xD00000,0xD00000,0x1A40000,0x1A40000,0x44000001,0xD00000,0xD00000,0xD00000,0x1A40000,0x1A40000,0x44000001,0x1A40000,0x1A40000,0x44000001,0x44000001,0xD00000,0xD00000,0xD00000,0x1A40000,0x1A40000,0x44000001,0x1A40000,0x1A40000,0x44000001,0x44000001,0x1A40000, -0x1A40000,0x44000001,0x44000001,0x44000001,0x6A00000,0x2940000,0x8C0000,0x2BC0000,0xEC0000,0x1280000,0x1540000,0x3FC0000,0xB00000,0xD00000,0x1280000,0x44000001,0x1280000,0xC40001,0x3240000,0x17FC0000,0x62000000,0x3240000,0x17FC0000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x3240000,0x17FC0000,0x62000000,0x17FC0000,0x62000000, -0x62000000,0x17FC0000,0x62000000,0x62000000,0x62000000,0x3240000,0x17FC0000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x62000000,0x17FC0000,0x62000000,0x62000000,0x62000000,0x62000000,0xF80000,0xD40000,0xD40000,0x14C0000,0x1E40000,0x3BFC0000,0x62000000,0x62000000,0x10C0000,0x1740000,0x59E40000,0x62000000, -0x1A40000,0x700F1E,0xD25805ED,0x7E5405ED,0x625405ED,0xC23C034A,0x864001C5,0x66440286,0x6E3C034A,0x603801BD,0x543C034A,0xB62005EB,0x8C200154,0x6830020F,0x741801B6,0x60200006,0x542401BE,0x621C05EB,0x5A14020D,0x4E14028A,0x461C05EB,0xA80F1A,0x8C000615,0x622005EA,0x74000416,0x620001BA,0x5404034A,0x6200073B,0x5800028C,0x4E0002AB,0x4600062A,0x1580F1A, -0x50000899,0x4A000746,0x3E000983,0x38000F1A,0xFE440322,0xFA640A2E,0xFE6C0B55,0xDC200002,0x9A1C0004,0x76200004,0x64280025,0x5E1C0023,0xFE1C02BE,0xD0040000,0x66100159,0x4E0002AB,0xF00F1A,0x8C05ED,0xB6740154,0x76740154,0x62700154,0xA45801A5,0x7C580002,0x62600029,0x665801A5,0x5C54004C,0x545801A5,0x2D005EA,0x88240153,0x62480152,0x7A0C01A5,0x60200005, -0x543001A5,0x1AC05EA,0x5C0001A8,0x50000221,0x460005EA,0x2D005EA,0x88240153,0x62480152,0x7A0C01A5,0x60200005,0x543001A5,0x1AC05EA,0x5C0001A8,0x50000221,0x460005EA,0x1AC05EA,0x5C0001A8,0x50000221,0x460005EA,0x460005EA,0xFE500132,0xF67C03C5,0xFA8403AD,0xDC200001,0x9A1C0003,0x76200003,0x62300001,0x6008000C,0xFC300155,0xD0040000,0x68040152,0x50000221, -0x12C05EA,0x5405ED,0x5405ED,0x5405ED,0x5405ED,0x963C01A5,0x963C01A5,0x963C01A5,0x583C01A5,0x583C01A5,0x443C01A6,0x8C200153,0x8C200153,0x8C200153,0x60200002,0x60200002,0x4628004B,0x4C200153,0x4C200153,0x401C002A,0x381C0153,0x8005EA,0x8005EA,0x8005EA,0x620001BA,0x620001BA,0x441401A6,0x520001E4,0x520001E4,0x4200003B,0x38000162,0x10005EA, -0x10005EA,0x380002DE,0x32000303,0x2A0005EA,0xFC380111,0xFE4C0379,0x5405ED,0xE01C0001,0x94200002,0x74200002,0x6C20000B,0x581C0002,0xFE1400C8,0xD0040000,0x62140153,0x4200003B,0xB405EA,0x700154,0x700154,0x700154,0x700154,0x7A580000,0x7A580000,0x7A580000,0x52580000,0x52580000,0x44580001,0xA80152,0xA80152,0xA80152,0x5C280001,0x5C280001, -0x44400001,0x1580152,0x1580152,0x44000005,0x38000152,0xA80152,0xA80152,0xA80152,0x5C280001,0x5C280001,0x44400001,0x1580152,0x1580152,0x44000005,0x38000152,0x1580152,0x1580152,0x44000005,0x38000152,0x38000152,0xF6480029,0xFA640055,0x700154,0xE01C0000,0x90240000,0x72240000,0x64300000,0x5A180000,0xF624003D,0xD0040000,0xF00152,0x44000005, -0xF00152,0xA801A5,0x9C8C0000,0x708C0000,0x628C0000,0xF801A5,0x7E540000,0x62700000,0x1FC01A5,0x62140000,0x540001A5,0xF801A5,0x7E540000,0x62700000,0x1FC01A5,0x62140000,0x540001A5,0x1FC01A5,0x62140000,0x540001A5,0x540001A5,0xF801A5,0x7E540000,0x62700000,0x1FC01A5,0x62140000,0x540001A5,0x1FC01A5,0x62140000,0x540001A5,0x540001A5,0x1FC01A5, -0x62140000,0x540001A5,0x540001A5,0x540001A5,0xFA640080,0xB401A5,0xF69C00A4,0xDC200000,0xA0100000,0x78180000,0x62380000,0x60000005,0xF4480071,0xD0040000,0x66400000,0x540001A5,0x16401A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x3C01A5,0x64200001,0x64200001,0x64200001,0x64200001,0x64200001, -0x64200001,0x38200001,0x38200001,0x38200001,0x2A1C0002,0x5401A5,0x5401A5,0x5401A5,0x5401A5,0x5401A5,0x5401A5,0x3A000020,0x3A000020,0x3A000020,0x2A040001,0xAC01A5,0xAC01A5,0xAC01A5,0x26000092,0x1C0001A5,0xFE2C0062,0x3C01A5,0x3C01A5,0xD4200001,0x98200001,0x78200001,0x78200001,0x54200001,0xFA080029,0xCE040000,0x48180001,0x3A000020, -0x7801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table104[] = { -0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x8C0000, -0x8C0000,0x8C0000,0x8C0000,0x16000001,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x340000,0x340000,0x340000,0x2440000,0x640000,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x680001,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000, -0x9C0000,0x13C0000,0x13C0000,0x13C0000,0x34000000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x9C0000,0x13C0000,0x13C0000,0x13C0000,0x34000000,0x13C0000,0x13C0000,0x13C0000,0x34000000,0x34000000,0x700000,0x680001,0x680001,0x7C0000,0x840000,0x900000,0x900000,0xB00000,0x7C0000,0x840000,0xE00000,0x13C0000, -0xE00000,0x9C0001,0x9C0001,0x9C0001,0x9C0001,0x2E80000,0x2E80000,0x2E80000,0x1DC0000,0x1DC0000,0x4E000000,0x2E80000,0x2E80000,0x2E80000,0x1DC0000,0x1DC0000,0x4E000000,0x1DC0000,0x1DC0000,0x4E000000,0x4E000000,0x2E80000,0x2E80000,0x2E80000,0x1DC0000,0x1DC0000,0x4E000000,0x1DC0000,0x1DC0000,0x4E000000,0x4E000000,0x1DC0000, -0x1DC0000,0x4E000000,0x4E000000,0x4E000000,0xB80000,0xA80000,0x9C0001,0x2D40000,0x1080000,0x1500000,0x1800000,0x11F40000,0x2C40000,0x2E80000,0x1500000,0x4E000000,0x1500000,0xD80000,0x1400000,0x25F80000,0x6A000001,0x1400000,0x25F80000,0x6A000001,0x25F80000,0x6A000001,0x6A000001,0x1400000,0x25F80000,0x6A000001,0x25F80000,0x6A000001, -0x6A000001,0x25F80000,0x6A000001,0x6A000001,0x6A000001,0x1400000,0x25F80000,0x6A000001,0x25F80000,0x6A000001,0x6A000001,0x25F80000,0x6A000001,0x6A000001,0x6A000001,0x25F80000,0x6A000001,0x6A000001,0x6A000001,0x6A000001,0x50C0000,0xAE40000,0xAE40000,0x16C0000,0x9F80000,0x47F80000,0x6A000001,0x6A000001,0x3240000,0x1940000,0x63D80000,0x6A000001, -0x1CC0000,0x840F1A,0xDE6805EA,0x866805EA,0x6A6805EB,0xCC4C034A,0x8E5001C3,0x6E54028A,0x784C034A,0x684C01BE,0x5C4C034A,0xC23005EA,0x96300153,0x7040020D,0x7E2C01B2,0x6A300006,0x5E3401BD,0x6A3005EA,0x6224020F,0x58280286,0x4E3005ED,0xC40F1A,0x9E0005EB,0x6C3005EB,0x86000392,0x6C0801B6,0x5C18034A,0x740006B1,0x640001DC,0x5A000215,0x4E0005F1,0x18C0F1A, -0x5C0007F7,0x50000662,0x4A0008D9,0x40000F1E,0xFE580372,0xF4780A82,0xF67C0B9A,0xE6300000,0xA2300003,0x80300002,0x6C380023,0x662C0025,0xFE3402F6,0xD6180002,0x7024015B,0x5A000215,0x1180F1A,0xA005EA,0xC0840152,0x80840152,0x6A840153,0xAC6C01A6,0x86680001,0x6C74002A,0x706801A6,0x6668004B,0x5C6801A6,0xEC05EA,0x90380153,0x6A5C0153,0x841C01A5,0x6A340002, -0x5C4401A5,0x1E405EA,0x6600017D,0x5A0001F1,0x4E0005ED,0xEC05EA,0x90380153,0x6A5C0153,0x841C01A5,0x6A340002,0x5C4401A5,0x1E405EA,0x6600017D,0x5A0001F1,0x4E0005ED,0x1E405EA,0x6600017D,0x5A0001F1,0x4E0005ED,0x4E0005ED,0xFE640164,0xFE8C03CE,0xF49803D3,0xE6300000,0xA2300003,0x80300002,0x6C440002,0x6A1C000B,0xFE440171,0xD6180001,0x72140152,0x5A0001F1, -0x15405EA,0x6805EA,0x6805EA,0x6805EA,0x6805EA,0xA24C01A5,0xA24C01A5,0xA24C01A5,0x624C01A5,0x624C01A5,0x4E4C01A5,0x96300152,0x96300152,0x96300152,0x68300005,0x68300005,0x503C004C,0x56300152,0x56300152,0x4A300029,0x40300154,0x29805EA,0x29805EA,0x29805EA,0x740001A5,0x740001A5,0x4E2401A5,0x5E00018B,0x5E00018B,0x4E000004,0x40080154,0x13805EA, -0x13805EA,0x44000279,0x3C0002A5,0x320005ED,0xFC480129,0xF860039D,0x6805EA,0xE6300000,0xA0300002,0x80300002,0x7634000C,0x62300001,0xFE2800F2,0xD6180001,0x6C240152,0x4E000004,0xDC05EA,0x840152,0x840152,0x840152,0x840152,0x806C0001,0x806C0001,0x806C0001,0x5A6C0001,0x5A6C0001,0x4E680001,0xC40152,0xC40152,0xC40152,0x643C0001,0x643C0001, -0x4E500000,0x18C0152,0x18C0152,0x4E000000,0x40000154,0xC40152,0xC40152,0xC40152,0x643C0001,0x643C0001,0x4E500000,0x18C0152,0x18C0152,0x4E000000,0x40000154,0x18C0152,0x18C0152,0x4E000000,0x40000154,0x40000154,0xFE580029,0xF4780062,0x840152,0xE6300000,0x98380000,0x7A380001,0x6E400000,0x622C0000,0xFE34003D,0xD6180000,0x1180152,0x4E000000, -0x1180152,0xBC01A5,0xA4A00001,0x78A00001,0x6A9C0002,0x11401A5,0x86680000,0x6A840001,0xFF801A5,0x6A2C0001,0x5C0001A5,0x11401A5,0x86680000,0x6A840001,0xFF801A5,0x6A2C0001,0x5C0001A5,0xFF801A5,0x6A2C0001,0x5C0001A5,0x5C0001A5,0x11401A5,0x86680000,0x6A840001,0xFF801A5,0x6A2C0001,0x5C0001A5,0xFF801A5,0x6A2C0001,0x5C0001A5,0x5C0001A5,0xFF801A5, -0x6A2C0001,0x5C0001A5,0x5C0001A5,0x5C0001A5,0xFE780080,0xC801A5,0xFEAC00AA,0xE2340000,0xA8240000,0x82280000,0x6A4C0001,0x6A000001,0xFC580071,0xD8180000,0x70500000,0x5C0001A5,0x18C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x4C01A5,0x6E300000,0x6E300000,0x6E300000,0x6E300000,0x6E300000, -0x6E300000,0x42300000,0x42300000,0x42300000,0x34300000,0x7001A5,0x7001A5,0x7001A5,0x7001A5,0x7001A5,0x7001A5,0x4C000002,0x4C000002,0x4C000002,0x34140000,0xE401A5,0xE401A5,0xE401A5,0x30000061,0x260001A5,0xF8400071,0x4C01A5,0x4C01A5,0xE2300000,0xA4300000,0x84300000,0x84300000,0x5E300000,0xFC1C0032,0xCE180001,0x52280000,0x4C000002, -0xA001A5,}; -static const uint32_t g_etc1_to_bc7_m6_table105[] = { -0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0x25C0000,0xBC0000, -0xBC0000,0xBC0000,0xBC0000,0x1E000001,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x440000,0x440000,0x440000,0x25C0000,0x880000,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0x780001,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000, -0xB40000,0x1700000,0x1700000,0x1700000,0x3C000000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x1700000,0x1700000,0x1700000,0x3C000000,0x1700000,0x1700000,0x1700000,0x3C000000,0x3C000000,0x8800000,0x780001,0x780001,0x28C0000,0x980000,0x2A40000,0x2A40000,0xCC0000,0x28C0000,0x980000,0x1000000,0x1700000, -0x1000000,0xAC0001,0xAC0001,0xAC0001,0xAC0001,0x3000000,0x3000000,0x3000000,0x5FC0000,0x5FC0000,0x56000000,0x3000000,0x3000000,0x3000000,0x5FC0000,0x5FC0000,0x56000000,0x5FC0000,0x5FC0000,0x56000000,0x56000000,0x3000000,0x3000000,0x3000000,0x5FC0000,0x5FC0000,0x56000000,0x5FC0000,0x5FC0000,0x56000000,0x56000000,0x5FC0000, -0x5FC0000,0x56000000,0x56000000,0x56000000,0x4C80000,0x4B80000,0xAC0001,0xEC0000,0x1240000,0x1700000,0x1A80000,0x1BF80000,0x2D80000,0x3000000,0x1700000,0x56000000,0x1700000,0xE80000,0x1580000,0x31F80000,0x72000001,0x1580000,0x31F80000,0x72000001,0x31F80000,0x72000001,0x72000001,0x1580000,0x31F80000,0x72000001,0x31F80000,0x72000001, -0x72000001,0x31F80000,0x72000001,0x72000001,0x72000001,0x1580000,0x31F80000,0x72000001,0x31F80000,0x72000001,0x72000001,0x31F80000,0x72000001,0x72000001,0x72000001,0x31F80000,0x72000001,0x72000001,0x72000001,0x72000001,0x5200000,0xF80000,0xF80000,0x1840000,0x15FC0000,0x51F80000,0x72000001,0x72000001,0x13C0000,0x1B40000,0x6BE80000,0x72000001, -0x1EC0000,0x940F1A,0xE67805EA,0x8E7805EA,0x727805EB,0xD45C034A,0x966001C3,0x7664028A,0x805C034A,0x705C01BE,0x645C034A,0xCA4005EA,0x9E400153,0x7850020D,0x863C01B2,0x72400006,0x664401BD,0x724005EA,0x6A34020F,0x60380286,0x564005ED,0xDC0F1A,0xA61005EB,0x744005EB,0x9200035A,0x741801B6,0x6428034A,0x80000651,0x7000017C,0x620001D5,0x580805ED,0x1BC0F1A, -0x66000786,0x5C0005BA,0x50000861,0x48000F1E,0xFE6403C8,0xFC880A82,0xFE8C0B9A,0xEE400000,0xAA400003,0x88400002,0x74480023,0x6E3C0025,0xFE440361,0xDE280002,0x7834015B,0x620001D5,0x1380F1A,0xB005EA,0xC8940152,0x88940152,0x72940153,0xB47C01A6,0x8E780001,0x7484002A,0x787801A6,0x6E78004B,0x647801A6,0x10405EA,0x98480153,0x726C0153,0x8C2C01A5,0x72440002, -0x645401A5,0x7FC05EA,0x70000163,0x620001D5,0x560005ED,0x10405EA,0x98480153,0x726C0153,0x8C2C01A5,0x72440002,0x645401A5,0x7FC05EA,0x70000163,0x620001D5,0x560005ED,0x7FC05EA,0x70000163,0x620001D5,0x560005ED,0x560005ED,0xFE780179,0xF8A003EA,0xFCA803D3,0xEE400000,0xAA400003,0x88400002,0x74540002,0x722C000B,0xFE5C0189,0xDE280001,0x7A240152,0x620001D5, -0x17405EA,0x7805EA,0x7805EA,0x7805EA,0x7805EA,0xAA5C01A5,0xAA5C01A5,0xAA5C01A5,0x6A5C01A5,0x6A5C01A5,0x565C01A5,0x9E400152,0x9E400152,0x9E400152,0x70400005,0x70400005,0x584C004C,0x5E400152,0x5E400152,0x52400029,0x48400154,0x2B005EA,0x2B005EA,0x2B005EA,0x7C1001A5,0x7C1001A5,0x563401A5,0x6A000163,0x6A000163,0x56080002,0x48180154,0x16805EA, -0x16805EA,0x4E000239,0x44000248,0x3A0005ED,0xFE580149,0xFE6C03A5,0x7805EA,0xEE400000,0xA8400002,0x88400002,0x7E44000C,0x6A400001,0xFE3C010A,0xDE280001,0x74340152,0x56080002,0xFC05EA,0x940152,0x940152,0x940152,0x940152,0x887C0001,0x887C0001,0x887C0001,0x627C0001,0x627C0001,0x56780001,0xDC0152,0xDC0152,0xDC0152,0x6C4C0001,0x6C4C0001, -0x56600000,0x1BC0152,0x1BC0152,0x56100000,0x48000154,0xDC0152,0xDC0152,0xDC0152,0x6C4C0001,0x6C4C0001,0x56600000,0x1BC0152,0x1BC0152,0x56100000,0x48000154,0x1BC0152,0x1BC0152,0x56100000,0x48000154,0x48000154,0xFA6C0032,0xFC880062,0x940152,0xEE400000,0xA0480000,0x82480001,0x76500000,0x6A3C0000,0xFA48004A,0xDE280000,0x1380152,0x56100000, -0x1380152,0xCC01A5,0xACB00001,0x80B00001,0x72AC0002,0x12C01A5,0x8E780000,0x72940001,0x1BF801A5,0x723C0001,0x640001A5,0x12C01A5,0x8E780000,0x72940001,0x1BF801A5,0x723C0001,0x640001A5,0x1BF801A5,0x723C0001,0x640001A5,0x640001A5,0x12C01A5,0x8E780000,0x72940001,0x1BF801A5,0x723C0001,0x640001A5,0x1BF801A5,0x723C0001,0x640001A5,0x640001A5,0x1BF801A5, -0x723C0001,0x640001A5,0x640001A5,0x640001A5,0xFA8C0091,0xD801A5,0xF8C000B5,0xEA440000,0xB0340000,0x8A380000,0x725C0001,0x72100001,0xFC6C0082,0xE0280000,0x78600000,0x640001A5,0x1AC01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x5C01A5,0x76400000,0x76400000,0x76400000,0x76400000,0x76400000, -0x76400000,0x4A400000,0x4A400000,0x4A400000,0x3C400000,0x8801A5,0x8801A5,0x8801A5,0x8801A5,0x8801A5,0x8801A5,0x58080000,0x58080000,0x58080000,0x3C240000,0x11401A5,0x11401A5,0x11401A5,0x38000034,0x2E0001A5,0xFE4C0075,0x5C01A5,0x5C01A5,0xEA400000,0xAC400000,0x8C400000,0x8C400000,0x66400000,0xF830003D,0xD6280001,0x5A380000,0x58080000, -0xC001A5,}; -static const uint32_t g_etc1_to_bc7_m6_table106[] = { -0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0x2740000,0xF00000, -0xF00000,0xF00000,0xF00000,0x26000001,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x2540000,0x2540000,0x2540000,0x2740000,0xA80000,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0x880001,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000, -0xCC0000,0x1A00000,0x1A00000,0x1A00000,0x44000000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0x1A00000,0x1A00000,0x1A00000,0x44000000,0x1A00000,0x1A00000,0x1A00000,0x44000000,0x44000000,0x940000,0x880001,0x880001,0xA00000,0xAC0000,0xBC0000,0xBC0000,0xE80000,0xA00000,0xAC0000,0x1240000,0x1A00000, -0x1240000,0xBC0001,0xBC0001,0xBC0001,0xBC0001,0x3180000,0x3180000,0x3180000,0x11FC0000,0x11FC0000,0x5E000000,0x3180000,0x3180000,0x3180000,0x11FC0000,0x11FC0000,0x5E000000,0x11FC0000,0x11FC0000,0x5E000000,0x5E000000,0x3180000,0x3180000,0x3180000,0x11FC0000,0x11FC0000,0x5E000000,0x11FC0000,0x11FC0000,0x5E000000,0x5E000000,0x11FC0000, -0x11FC0000,0x5E000000,0x5E000000,0x5E000000,0xDC0000,0xCC80000,0xBC0001,0x3000000,0x1400000,0x1940000,0x1D00000,0x25FC0000,0x2EC0000,0x3180000,0x1940000,0x5E000000,0x1940000,0xF80000,0x1700000,0x3DF80000,0x7A000001,0x1700000,0x3DF80000,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x1700000,0x3DF80000,0x7A000001,0x3DF80000,0x7A000001, -0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x1700000,0x3DF80000,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x3DF80000,0x7A000001,0x7A000001,0x7A000001,0x7A000001,0x5340000,0x1080000,0x1080000,0x1A00000,0x23FC0000,0x5BF80000,0x7A000001,0x7A000001,0x1500000,0x1D00000,0x73F80000,0x7A000001, -0x9FC0000,0xA40F1A,0xEE8805EA,0x968805EA,0x7A8805EB,0xDC6C034A,0x9E7001C3,0x7E74028A,0x886C034A,0x786C01BE,0x6C6C034A,0xD25005EA,0xA6500153,0x8060020D,0x8E4C01B2,0x7A500006,0x6E5401BD,0x7A5005EA,0x7244020F,0x68480286,0x5E5005ED,0xF40F1A,0xAE2005EB,0x7C5005EB,0xA004034A,0x7C2801B6,0x6C38034A,0x8C000611,0x7A000155,0x6A0801C5,0x601805ED,0x1F00F1A, -0x6C000716,0x66000542,0x5C0007E9,0x50000F1E,0xFE780419,0xF4980ADA,0xF8A00BDB,0xF6500000,0xB2500003,0x90500002,0x7C580023,0x764C0025,0xFE5C03A2,0xE6380002,0x8044015B,0x6A0801C5,0x15C0F1A,0xC005EA,0xD0A40152,0x90A40152,0x7AA40153,0xBC8C01A6,0x96880001,0x7C94002A,0x808801A6,0x7688004B,0x6C8801A6,0x11C05EA,0xA0580153,0x7A7C0153,0x943C01A5,0x7A540002, -0x6C6401A5,0x13FC05EA,0x7A000155,0x6C0001B5,0x5E0005ED,0x11C05EA,0xA0580153,0x7A7C0153,0x943C01A5,0x7A540002,0x6C6401A5,0x13FC05EA,0x7A000155,0x6C0001B5,0x5E0005ED,0x13FC05EA,0x7A000155,0x6C0001B5,0x5E0005ED,0x5E0005ED,0xFC9001A9,0xFEAC03FE,0xF4B803FE,0xF6500000,0xB2500003,0x90500002,0x7C640002,0x7A3C000B,0xFE7001C3,0xE6380001,0x82340152,0x6C0001B5, -0x19805EA,0x8805EA,0x8805EA,0x8805EA,0x8805EA,0xB26C01A5,0xB26C01A5,0xB26C01A5,0x726C01A5,0x726C01A5,0x5E6C01A5,0xA6500152,0xA6500152,0xA6500152,0x78500005,0x78500005,0x605C004C,0x66500152,0x66500152,0x5A500029,0x50500154,0xC805EA,0xC805EA,0xC805EA,0x842001A5,0x842001A5,0x5E4401A5,0x78040153,0x78040153,0x5E180002,0x50280154,0x19805EA, -0x19805EA,0x560001FD,0x4E00020D,0x420005ED,0xFE680164,0xF88003C2,0x8805EA,0xF6500000,0xB0500002,0x90500002,0x8654000C,0x72500001,0xFC4C0123,0xE6380001,0x7C440152,0x5E180002,0x12005EA,0xA40152,0xA40152,0xA40152,0xA40152,0x908C0001,0x908C0001,0x908C0001,0x6A8C0001,0x6A8C0001,0x5E880001,0xF40152,0xF40152,0xF40152,0x745C0001,0x745C0001, -0x5E700000,0x1F00152,0x1F00152,0x5E200000,0x50000154,0xF40152,0xF40152,0xF40152,0x745C0001,0x745C0001,0x5E700000,0x1F00152,0x1F00152,0x5E200000,0x50000154,0x1F00152,0x1F00152,0x5E200000,0x50000154,0x50000154,0xF680003D,0xF4980071,0xA40152,0xF6500000,0xA8580000,0x8A580001,0x7E600000,0x724C0000,0xF2600055,0xE6380000,0x15C0152,0x5E200000, -0x15C0152,0xDC01A5,0xB4C00001,0x88C00001,0x7ABC0002,0x14401A5,0x96880000,0x7AA40001,0x27F801A5,0x7A4C0001,0x6C0001A5,0x14401A5,0x96880000,0x7AA40001,0x27F801A5,0x7A4C0001,0x6C0001A5,0x27F801A5,0x7A4C0001,0x6C0001A5,0x6C0001A5,0x14401A5,0x96880000,0x7AA40001,0x27F801A5,0x7A4C0001,0x6C0001A5,0x27F801A5,0x7A4C0001,0x6C0001A5,0x6C0001A5,0x27F801A5, -0x7A4C0001,0x6C0001A5,0x6C0001A5,0x6C0001A5,0xFAA000A2,0xE801A5,0xFECC00C1,0xF2540000,0xB8440000,0x92480000,0x7A6C0001,0x7A200001,0xF6880091,0xE8380000,0x80700000,0x6C0001A5,0x1D001A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x6C01A5,0x7E500000,0x7E500000,0x7E500000,0x7E500000,0x7E500000, -0x7E500000,0x52500000,0x52500000,0x52500000,0x44500000,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0x60180000,0x60180000,0x60180000,0x44340000,0x14401A5,0x14401A5,0x14401A5,0x4200001D,0x360001A5,0xF8600080,0x6C01A5,0x6C01A5,0xF2500000,0xB4500000,0x94500000,0x94500000,0x6E500000,0xFE3C0041,0xDE380001,0x62480000,0x60180000, -0xE401A5,}; -static const uint32_t g_etc1_to_bc7_m6_table107[] = { -0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x1200000, -0x1200000,0x1200000,0x1200000,0x2E000001,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0xA640000,0xA640000,0xA640000,0x28C0000,0xCC0000,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0x980001,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000, -0xE40000,0x1D00000,0x1D00000,0x1D00000,0x4C000000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0x1D00000,0x1D00000,0x1D00000,0x4C000000,0x1D00000,0x1D00000,0x1D00000,0x4C000000,0x4C000000,0xA40000,0x980001,0x980001,0xB40000,0xC00000,0xD00000,0xD00000,0x3000000,0xB40000,0xC00000,0x1480000,0x1D00000, -0x1480000,0xCC0001,0xCC0001,0xCC0001,0xCC0001,0x3300000,0x3300000,0x3300000,0x1DFC0000,0x1DFC0000,0x66000000,0x3300000,0x3300000,0x3300000,0x1DFC0000,0x1DFC0000,0x66000000,0x1DFC0000,0x1DFC0000,0x66000000,0x66000000,0x3300000,0x3300000,0x3300000,0x1DFC0000,0x1DFC0000,0x66000000,0x1DFC0000,0x1DFC0000,0x66000000,0x66000000,0x1DFC0000, -0x1DFC0000,0x66000000,0x66000000,0x66000000,0xF00000,0xDC0000,0xCC0001,0x1180000,0x1580000,0x1B40000,0x1F80000,0x31F80000,0x3000000,0x3300000,0x1B40000,0x66000000,0x1B40000,0x1080000,0x1880000,0x49F80000,0x82000001,0x1880000,0x49F80000,0x82000001,0x49F80000,0x82000001,0x82000001,0x1880000,0x49F80000,0x82000001,0x49F80000,0x82000001, -0x82000001,0x49F80000,0x82000001,0x82000001,0x82000001,0x1880000,0x49F80000,0x82000001,0x49F80000,0x82000001,0x82000001,0x49F80000,0x82000001,0x82000001,0x82000001,0x49F80000,0x82000001,0x82000001,0x82000001,0x82000001,0x14C0000,0x5180000,0x5180000,0x1BC0000,0x31FC0000,0x65F80000,0x82000001,0x82000001,0x1680000,0x1F00000,0x7DCC0000,0x82000001, -0x19FC0000,0xB40F1A,0xF69805EA,0x9E9805EA,0x829805EB,0xE47C034A,0xA68001C3,0x8684028A,0x907C034A,0x807C01BE,0x747C034A,0xDA6005EA,0xAE600153,0x8870020D,0x965C01B2,0x82600006,0x766401BD,0x826005EA,0x7A54020F,0x70580286,0x666005ED,0x10C0F1A,0xB63005EB,0x846005EB,0xA814034A,0x843801B6,0x7448034A,0x980005F1,0x820C0154,0x721801C5,0x682805ED,0xBF80F1A, -0x780006AE,0x6C0004B6,0x64000795,0x58000F1E,0xFE8C046E,0xFCA80ADA,0xFEAC0BDF,0xFE600000,0xBA600003,0x98600002,0x84680023,0x7E5C0025,0xFE700403,0xEE480002,0x8854015B,0x721801C5,0x17C0F1A,0xD005EA,0xD8B40152,0x98B40152,0x82B40153,0xC49C01A6,0x9E980001,0x84A4002A,0x889801A6,0x7E98004B,0x749801A6,0x13405EA,0xA8680153,0x828C0153,0x9C4C01A5,0x82640002, -0x747401A5,0x1FF805EA,0x820C0153,0x740001A9,0x660005ED,0x13405EA,0xA8680153,0x828C0153,0x9C4C01A5,0x82640002,0x747401A5,0x1FF805EA,0x820C0153,0x740001A9,0x660005ED,0x1FF805EA,0x820C0153,0x740001A9,0x660005ED,0x660005ED,0xFEA001C8,0xFAC40412,0xFCC803FE,0xFE600000,0xBA600003,0x98600002,0x84740002,0x824C000B,0xFC8401E2,0xEE480001,0x8A440152,0x740001A9, -0x1B805EA,0x9805EA,0x9805EA,0x9805EA,0x9805EA,0xBA7C01A5,0xBA7C01A5,0xBA7C01A5,0x7A7C01A5,0x7A7C01A5,0x667C01A5,0xAE600152,0xAE600152,0xAE600152,0x80600005,0x80600005,0x686C004C,0x6E600152,0x6E600152,0x62600029,0x58600154,0xE005EA,0xE005EA,0xE005EA,0x8C3001A5,0x8C3001A5,0x665401A5,0x80140153,0x80140153,0x66280002,0x58380154,0x1CC05EA, -0x1CC05EA,0x600001D5,0x560001C8,0x4A0005ED,0xFA7C0191,0xFE8C03CE,0x9805EA,0xFE600000,0xB8600002,0x98600002,0x8E64000C,0x7A600001,0xFC600152,0xEE480001,0x84540152,0x66280002,0x14005EA,0xB40152,0xB40152,0xB40152,0xB40152,0x989C0001,0x989C0001,0x989C0001,0x729C0001,0x729C0001,0x66980001,0x10C0152,0x10C0152,0x10C0152,0x7C6C0001,0x7C6C0001, -0x66800000,0xBF80152,0xBF80152,0x66300000,0x58000154,0x10C0152,0x10C0152,0x10C0152,0x7C6C0001,0x7C6C0001,0x66800000,0xBF80152,0xBF80152,0x66300000,0x58000154,0xBF80152,0xBF80152,0x66300000,0x58000154,0x58000154,0xFE90003D,0xFCA80071,0xB40152,0xFE600000,0xB0680000,0x92680001,0x86700000,0x7A5C0000,0xFA700055,0xEE480000,0x17C0152,0x66300000, -0x17C0152,0xEC01A5,0xBCD00001,0x90D00001,0x82CC0002,0x15C01A5,0x9E980000,0x82B40001,0x33F801A5,0x825C0001,0x740001A5,0x15C01A5,0x9E980000,0x82B40001,0x33F801A5,0x825C0001,0x740001A5,0x33F801A5,0x825C0001,0x740001A5,0x740001A5,0x15C01A5,0x9E980000,0x82B40001,0x33F801A5,0x825C0001,0x740001A5,0x33F801A5,0x825C0001,0x740001A5,0x740001A5,0x33F801A5, -0x825C0001,0x740001A5,0x740001A5,0x740001A5,0xFCB000A4,0xFC01A5,0xF8E000CA,0xFA640000,0xC0540000,0x9A580000,0x827C0001,0x82300001,0xFE980091,0xF0480000,0x88800000,0x740001A5,0x1F001A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x7C01A5,0x86600000,0x86600000,0x86600000,0x86600000,0x86600000, -0x86600000,0x5A600000,0x5A600000,0x5A600000,0x4C600000,0xB801A5,0xB801A5,0xB801A5,0xB801A5,0xB801A5,0xB801A5,0x68280000,0x68280000,0x68280000,0x4C440000,0x17401A5,0x17401A5,0x17401A5,0x4A000008,0x3E0001A5,0xFE6C0088,0x7C01A5,0x7C01A5,0xFA600000,0xBC600000,0x9C600000,0x9C600000,0x76600000,0xFA50004A,0xE6480001,0x6A580000,0x68280000, -0x10801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table108[] = { -0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0x1580000, -0x1580000,0x1580000,0x1580000,0x38000000,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x4780000,0x4780000,0x4780000,0xA80000,0xF00000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000, -0x1000000,0x5F80000,0x5F80000,0x5F80000,0x54000001,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x1000000,0x5F80000,0x5F80000,0x5F80000,0x54000001,0x5F80000,0x5F80000,0x5F80000,0x54000001,0x54000001,0xB80000,0xAC0000,0xAC0000,0xC80000,0xD80000,0x2E80000,0x2E80000,0x1200000,0xC80000,0xD80000,0x16C0000,0x5F80000, -0x16C0000,0xE00000,0xE00000,0xE00000,0xE00000,0x14C0000,0x14C0000,0x14C0000,0x2BF80000,0x2BF80000,0x6E000001,0x14C0000,0x14C0000,0x14C0000,0x2BF80000,0x2BF80000,0x6E000001,0x2BF80000,0x2BF80000,0x6E000001,0x6E000001,0x14C0000,0x14C0000,0x14C0000,0x2BF80000,0x2BF80000,0x6E000001,0x2BF80000,0x2BF80000,0x6E000001,0x6E000001,0x2BF80000, -0x2BF80000,0x6E000001,0x6E000001,0x6E000001,0x1040000,0xEEC0000,0xE00000,0x1300000,0x1780000,0x1DC0000,0xFFC0000,0x3DF80000,0x1180000,0x14C0000,0x1DC0000,0x6E000001,0x1DC0000,0x1180001,0x1A40000,0x57F80000,0x8C000000,0x1A40000,0x57F80000,0x8C000000,0x57F80000,0x8C000000,0x8C000000,0x1A40000,0x57F80000,0x8C000000,0x57F80000,0x8C000000, -0x8C000000,0x57F80000,0x8C000000,0x8C000000,0x8C000000,0x1A40000,0x57F80000,0x8C000000,0x57F80000,0x8C000000,0x8C000000,0x57F80000,0x8C000000,0x8C000000,0x8C000000,0x57F80000,0x8C000000,0x8C000000,0x8C000000,0x8C000000,0x3600000,0x12C0000,0x12C0000,0x1D80000,0x3FFC0000,0x71F40000,0x8C000000,0x8C000000,0x1800000,0xDFC0000,0x85FC0000,0x8C000000, -0x29FC0000,0xC40F1E,0xFCAC05ED,0xA8A805ED,0x8CA805ED,0xEC90034A,0xB09401C5,0x90980286,0x9890034A,0x8A8C01BD,0x7E90034A,0xE07405EB,0xB6740154,0x9284020F,0x9E6C01B6,0x8A740006,0x7E7801BE,0x8C7005EB,0x8468020D,0x7868028A,0x707005EB,0x3240F1A,0xC04005EB,0x8C7405EA,0xB224034A,0x8E4C01B2,0x7E58034A,0xA40C05EB,0x8C1C0153,0x7C2C01C3,0x703C05EA,0x17FC0F1A, -0x8400065A,0x7800043A,0x6C00071A,0x62000F1A,0xFEA004CC,0xF6BC0B32,0xF8C00C1E,0xFE74000E,0xC4700004,0xA0740004,0x8E7C0025,0x88700023,0xFE800477,0xFA580000,0x90640159,0x7C2C01C3,0x1A40F1A,0xE005ED,0xE0C80154,0xA0C80154,0x8CC40154,0xCEAC01A5,0xA6AC0002,0x8CB40029,0x90AC01A5,0x86A8004C,0x7EAC01A5,0x15005EA,0xB2780153,0x8C9C0152,0xA46001A5,0x8A740005, -0x7E8401A5,0x2DF805EA,0x8C180152,0x7E0401A5,0x700005EA,0x15005EA,0xB2780153,0x8C9C0152,0xA46001A5,0x8A740005,0x7E8401A5,0x2DF805EA,0x8C180152,0x7E0401A5,0x700005EA,0x2DF805EA,0x8C180152,0x7E0401A5,0x700005EA,0x700005EA,0xFEB401E6,0xF2D4043D,0xF6DC0428,0xFE780005,0xC4700003,0xA0740003,0x8C840001,0x8A5C000C,0xFE980202,0xFA580000,0x92580152,0x7E0401A5, -0x1E005EA,0xA805ED,0xA805ED,0xA805ED,0xA805ED,0xC09001A5,0xC09001A5,0xC09001A5,0x829001A5,0x829001A5,0x6E9001A6,0xB6740153,0xB6740153,0xB6740153,0x8A740002,0x8A740002,0x707C004B,0x76740153,0x76740153,0x6A70002A,0x62700153,0xFC05EA,0xFC05EA,0xFC05EA,0x964001A5,0x964001A5,0x6E6801A6,0x88280153,0x88280153,0x703C0001,0x62480152,0x3F805EA, -0x3F805EA,0x6C0001B2,0x6000019A,0x540005EA,0xFE9001AE,0xFAA403EA,0xA805ED,0xFE740005,0xBE740002,0x9E740002,0x9674000B,0x82700002,0xFE74016D,0xFA580000,0x8C680153,0x703C0001,0x16805EA,0xC40154,0xC40154,0xC40154,0xC40154,0xA4AC0000,0xA4AC0000,0xA4AC0000,0x7CAC0000,0x7CAC0000,0x6EAC0001,0x3240152,0x3240152,0x3240152,0x867C0001,0x867C0001, -0x6E940001,0x17FC0152,0x17FC0152,0x6E440001,0x62000152,0x3240152,0x3240152,0x3240152,0x867C0001,0x867C0001,0x6E940001,0x17FC0152,0x17FC0152,0x6E440001,0x62000152,0x17FC0152,0x17FC0152,0x6E440001,0x62000152,0x62000152,0xFEA0004A,0xF6BC0080,0xC40154,0xFE780001,0xBA780000,0x9C780000,0x8E840000,0x846C0000,0xF8880062,0xFA580000,0x1A40152,0x6E440001, -0x1A40152,0xFC01A5,0xC6E00000,0x9AE00000,0x8CE00000,0x17801A5,0xA8A80000,0x8CC40000,0x3FFC01A5,0x8C680000,0x7E0001A5,0x17801A5,0xA8A80000,0x8CC40000,0x3FFC01A5,0x8C680000,0x7E0001A5,0x3FFC01A5,0x8C680000,0x7E0001A5,0x7E0001A5,0x17801A5,0xA8A80000,0x8CC40000,0x3FFC01A5,0x8C680000,0x7E0001A5,0x3FFC01A5,0x8C680000,0x7E0001A5,0x7E0001A5,0x3FFC01A5, -0x8C680000,0x7E0001A5,0x7E0001A5,0x7E0001A5,0xFAC800B5,0x10C01A5,0xF2F400DD,0xFC7C0002,0xCA640000,0xA26C0000,0x8C8C0000,0x8C3C0000,0xFEAC00A4,0xFA580000,0x90940000,0x7E0001A5,0xDFC01A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x9001A5,0x8E740001,0x8E740001,0x8E740001,0x8E740001,0x8E740001, -0x8E740001,0x62740001,0x62740001,0x62740001,0x54700002,0xD401A5,0xD401A5,0xD401A5,0xD401A5,0xD401A5,0xD401A5,0x703C0000,0x703C0000,0x703C0000,0x54580001,0x1AC01A5,0x1AC01A5,0x1AC01A5,0x54000001,0x460001A5,0xFA840091,0x9001A5,0x9001A5,0xFE740001,0xC2740001,0xA2740001,0xA2740001,0x7E740001,0xF8680055,0xF8580000,0x726C0001,0x703C0000, -0x12C01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table109[] = { -0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0x1880000, -0x1880000,0x1880000,0x1880000,0x40000000,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0x800001,0xC880000,0xC880000,0xC880000,0xC00000,0x1140000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000, -0x1180000,0x11F80000,0x11F80000,0x11F80000,0x5C000001,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x11F80000,0x11F80000,0x11F80000,0x5C000001,0x11F80000,0x11F80000,0x11F80000,0x5C000001,0x5C000001,0xC80000,0xBC0000,0xBC0000,0x4D80000,0xEC0000,0x1000000,0x1000000,0x13C0000,0x4D80000,0xEC0000,0x1900000,0x11F80000, -0x1900000,0xF00000,0xF00000,0xF00000,0xF00000,0x1640000,0x1640000,0x1640000,0x37F80000,0x37F80000,0x76000001,0x1640000,0x1640000,0x1640000,0x37F80000,0x37F80000,0x76000001,0x37F80000,0x37F80000,0x76000001,0x76000001,0x1640000,0x1640000,0x1640000,0x37F80000,0x37F80000,0x76000001,0x37F80000,0x37F80000,0x76000001,0x76000001,0x37F80000, -0x37F80000,0x76000001,0x76000001,0x76000001,0x1180000,0x1000000,0xF00000,0x3440000,0x1940000,0x1FC0000,0x1DF80000,0x47FC0000,0x12C0000,0x1640000,0x1FC0000,0x76000001,0x1FC0000,0x1280001,0x1BC0000,0x61FC0000,0x94000000,0x1BC0000,0x61FC0000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x1BC0000,0x61FC0000,0x94000000,0x61FC0000,0x94000000, -0x94000000,0x61FC0000,0x94000000,0x94000000,0x94000000,0x1BC0000,0x61FC0000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x94000000,0x61FC0000,0x94000000,0x94000000,0x94000000,0x94000000,0x3740000,0x73C0000,0x73C0000,0x1F40000,0x4DFC0000,0x7BF40000,0x94000000,0x94000000,0x1940000,0x1DFC0000,0x8FD00000,0x94000000, -0x39FC0000,0xD40F1E,0xFEBC05F1,0xB0B805ED,0x94B805ED,0xF4A0034A,0xB8A401C5,0x98A80286,0xA0A0034A,0x929C01BD,0x86A0034A,0xE88405EB,0xBE840154,0x9A94020F,0xA67C01B6,0x92840006,0x868801BE,0x948005EB,0x8C78020D,0x8078028A,0x788005EB,0x33C0F1A,0xC85005EB,0x948405EA,0xBA34034A,0x965C01B2,0x8668034A,0xAC1C05EB,0x942C0153,0x843C01C3,0x784C05EA,0x23FC0F1A, -0x8E000629,0x820003F2,0x760006D7,0x6A000F1A,0xFEB40537,0xFECC0B32,0xFECC0C36,0xFE880026,0xCC800004,0xA8840004,0x968C0025,0x90800023,0xFE9804C6,0xFC6C0006,0x98740159,0x843C01C3,0x1C80F1A,0xF005ED,0xE8D80154,0xA8D80154,0x94D40154,0xD6BC01A5,0xAEBC0002,0x94C40029,0x98BC01A5,0x8EB8004C,0x86BC01A5,0x16805EA,0xBA880153,0x94AC0152,0xAC7001A5,0x92840005, -0x869401A5,0x39F805EA,0x94280152,0x861401A5,0x780005EA,0x16805EA,0xBA880153,0x94AC0152,0xAC7001A5,0x92840005,0x869401A5,0x39F805EA,0x94280152,0x861401A5,0x780005EA,0x39F805EA,0x94280152,0x861401A5,0x780005EA,0x780005EA,0xFAC80226,0xFAE4043D,0xFEEC0428,0xFC900012,0xCC800003,0xA8840003,0x94940001,0x926C000C,0xFEAC0244,0xFE6C0002,0x9A680152,0x861401A5, -0x3FC05EA,0xB805ED,0xB805ED,0xB805ED,0xB805ED,0xC8A001A5,0xC8A001A5,0xC8A001A5,0x8AA001A5,0x8AA001A5,0x76A001A6,0xBE840153,0xBE840153,0xBE840153,0x92840002,0x92840002,0x788C004B,0x7E840153,0x7E840153,0x7280002A,0x6A800153,0x11405EA,0x11405EA,0x11405EA,0x9E5001A5,0x9E5001A5,0x767801A6,0x90380153,0x90380153,0x784C0001,0x6A580152,0xFF805EA, -0xFF805EA,0x760001A6,0x6800017E,0x5C0005EA,0xFEA001CB,0xFEAC040A,0xB805ED,0xFE88000D,0xC6840002,0xA6840002,0x9E84000B,0x8A800002,0xFE8001A3,0xFA6C0002,0x94780153,0x784C0001,0x18C05EA,0xD40154,0xD40154,0xD40154,0xD40154,0xACBC0000,0xACBC0000,0xACBC0000,0x84BC0000,0x84BC0000,0x76BC0001,0x33C0152,0x33C0152,0x33C0152,0x8E8C0001,0x8E8C0001, -0x76A40001,0x23FC0152,0x23FC0152,0x76540001,0x6A000152,0x33C0152,0x33C0152,0x33C0152,0x8E8C0001,0x8E8C0001,0x76A40001,0x23FC0152,0x23FC0152,0x76540001,0x6A000152,0x23FC0152,0x23FC0152,0x76540001,0x6A000152,0x6A000152,0xFAB40055,0xFECC0080,0xD40154,0xFE880004,0xC2880000,0xA4880000,0x96940000,0x8C7C0000,0xFE94006A,0xFA6C0001,0x1C80152,0x76540001, -0x1C80152,0x10C01A5,0xCEF00000,0xA2F00000,0x94F00000,0x19001A5,0xB0B80000,0x94D40000,0x4BFC01A5,0x94780000,0x860001A5,0x19001A5,0xB0B80000,0x94D40000,0x4BFC01A5,0x94780000,0x860001A5,0x4BFC01A5,0x94780000,0x860001A5,0x860001A5,0x19001A5,0xB0B80000,0x94D40000,0x4BFC01A5,0x94780000,0x860001A5,0x4BFC01A5,0x94780000,0x860001A5,0x860001A5,0x4BFC01A5, -0x94780000,0x860001A5,0x860001A5,0x860001A5,0xF2E000C8,0x12001A5,0xFB0400DD,0xFE940005,0xD2740000,0xAA7C0000,0x949C0000,0x944C0000,0xF4C800B5,0xFE6C0001,0x98A40000,0x860001A5,0x1DF801A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0xA001A5,0x96840001,0x96840001,0x96840001,0x96840001,0x96840001, -0x96840001,0x6A840001,0x6A840001,0x6A840001,0x5C800002,0xEC01A5,0xEC01A5,0xEC01A5,0xEC01A5,0xEC01A5,0xEC01A5,0x784C0000,0x784C0000,0x784C0000,0x5C680001,0x1DC01A5,0x1DC01A5,0x1DC01A5,0x5C100001,0x4E0001A5,0xF29400A2,0xA001A5,0xA001A5,0xFE840002,0xCA840001,0xAA840001,0xAA840001,0x86840001,0xFE740059,0xF86C0001,0x7A7C0001,0x784C0000, -0x15001A5,}; -static const uint32_t g_etc1_to_bc7_m6_table110[] = { -0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0x1B80000, -0x1B80000,0x1B80000,0x1B80000,0x48000000,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x900001,0x9C0000,0x9C0000,0x9C0000,0xD80000,0x1340000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0xCC0000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000, -0x1300000,0x1DF40000,0x1DF40000,0x1DF40000,0x64000001,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1DF40000,0x1DF40000,0x1DF40000,0x64000001,0x1DF40000,0x1DF40000,0x1DF40000,0x64000001,0x64000001,0x4D80000,0xCC0000,0xCC0000,0xEC0000,0x1000000,0x1140000,0x1140000,0x3540000,0xEC0000,0x1000000,0x1B00000,0x1DF40000, -0x1B00000,0x1000000,0x1000000,0x1000000,0x1000000,0x17C0000,0x17C0000,0x17C0000,0x43F80000,0x43F80000,0x7E000001,0x17C0000,0x17C0000,0x17C0000,0x43F80000,0x43F80000,0x7E000001,0x43F80000,0x43F80000,0x7E000001,0x7E000001,0x17C0000,0x17C0000,0x17C0000,0x43F80000,0x43F80000,0x7E000001,0x43F80000,0x43F80000,0x7E000001,0x7E000001,0x43F80000, -0x43F80000,0x7E000001,0x7E000001,0x7E000001,0x3280000,0x1100000,0x1000000,0x15C0000,0x3AC0000,0x11FC0000,0x29FC0000,0x53F80000,0x1400000,0x17C0000,0x11FC0000,0x7E000001,0x11FC0000,0x1380001,0x3D00000,0x6DFC0000,0x9C000000,0x3D00000,0x6DFC0000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x3D00000,0x6DFC0000,0x9C000000,0x6DFC0000,0x9C000000, -0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x3D00000,0x6DFC0000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x6DFC0000,0x9C000000,0x9C000000,0x9C000000,0x9C000000,0x3880000,0xF4C0000,0xF4C0000,0xFFC0000,0x5BFC0000,0x85F40000,0x9C000000,0x9C000000,0x1AC0000,0x2FFC0000,0x97E00000,0x9C000000, -0x47FC0000,0xE40F1E,0xFCCC0606,0xB8C805ED,0x9CC805ED,0xFCB0034A,0xC0B401C5,0xA0B80286,0xA8B0034A,0x9AAC01BD,0x8EB0034A,0xF09405EB,0xC6940154,0xA2A4020F,0xAE8C01B6,0x9A940006,0x8E9801BE,0x9C9005EB,0x9488020D,0x8888028A,0x809005EB,0x1540F1A,0xD06005EB,0x9C9405EA,0xC244034A,0x9E6C01B2,0x8E78034A,0xB42C05EB,0x9C3C0153,0x8C4C01C3,0x805C05EA,0x2FFC0F1A, -0x98000606,0x8A00039E,0x7E000686,0x72000F1A,0xFEC405AE,0xF6DC0B8E,0xF8E00C65,0xFE9C0054,0xD4900004,0xB0940004,0x9E9C0025,0x98900023,0xFCB00557,0xFE800014,0xA0840159,0x8C4C01C3,0x1E80F1A,0x10005ED,0xF0E80154,0xB0E80154,0x9CE40154,0xDECC01A5,0xB6CC0002,0x9CD40029,0xA0CC01A5,0x96C8004C,0x8ECC01A5,0x18005EA,0xC2980153,0x9CBC0152,0xB48001A5,0x9A940005, -0x8EA401A5,0x45F805EA,0x9C380152,0x8E2401A5,0x800005EA,0x18005EA,0xC2980153,0x9CBC0152,0xB48001A5,0x9A940005,0x8EA401A5,0x45F805EA,0x9C380152,0x8E2401A5,0x800005EA,0x45F805EA,0x9C380152,0x8E2401A5,0x800005EA,0x800005EA,0xFED8024B,0xF4F80465,0xF6FC0455,0xFEA40029,0xD4900003,0xB0940003,0x9CA40001,0x9A7C000C,0xFCC00269,0xFE840008,0xA2780152,0x8E2401A5, -0x13FC05EA,0xC805ED,0xC805ED,0xC805ED,0xC805ED,0xD0B001A5,0xD0B001A5,0xD0B001A5,0x92B001A5,0x92B001A5,0x7EB001A6,0xC6940153,0xC6940153,0xC6940153,0x9A940002,0x9A940002,0x809C004B,0x86940153,0x86940153,0x7A90002A,0x72900153,0x12C05EA,0x12C05EA,0x12C05EA,0xA66001A5,0xA66001A5,0x7E8801A6,0x98480153,0x98480153,0x805C0001,0x72680152,0x1BF805EA, -0x1BF805EA,0x7E0801A6,0x72000162,0x640005EA,0xFAB40206,0xFAC40411,0xC805ED,0xFE98001A,0xCE940002,0xAE940002,0xA694000B,0x92900002,0xFE9401BA,0xFC7C000B,0x9C880153,0x805C0001,0x1AC05EA,0xE40154,0xE40154,0xE40154,0xE40154,0xB4CC0000,0xB4CC0000,0xB4CC0000,0x8CCC0000,0x8CCC0000,0x7ECC0001,0x1540152,0x1540152,0x1540152,0x969C0001,0x969C0001, -0x7EB40001,0x2FFC0152,0x2FFC0152,0x7E640001,0x72000152,0x1540152,0x1540152,0x1540152,0x969C0001,0x969C0001,0x7EB40001,0x2FFC0152,0x2FFC0152,0x7E640001,0x72000152,0x2FFC0152,0x2FFC0152,0x7E640001,0x72000152,0x72000152,0xF6C80062,0xF6DC0091,0xE40154,0xFCA00008,0xCA980000,0xAC980000,0x9EA40000,0x948C0000,0xFAAC0071,0xFE800002,0x1E80152,0x7E640001, -0x1E80152,0x11C01A5,0xD7000000,0xAB000000,0x9D000000,0x1A801A5,0xB8C80000,0x9CE40000,0x57FC01A5,0x9C880000,0x8E0001A5,0x1A801A5,0xB8C80000,0x9CE40000,0x57FC01A5,0x9C880000,0x8E0001A5,0x57FC01A5,0x9C880000,0x8E0001A5,0x8E0001A5,0x1A801A5,0xB8C80000,0x9CE40000,0x57FC01A5,0x9C880000,0x8E0001A5,0x57FC01A5,0x9C880000,0x8E0001A5,0x8E0001A5,0x57FC01A5, -0x9C880000,0x8E0001A5,0x8E0001A5,0x8E0001A5,0xFAF000C8,0x13001A5,0xF31400F4,0xFCAC000D,0xDA840000,0xB28C0000,0x9CAC0000,0x9C5C0000,0xFCD800B5,0xFE880002,0xA0B40000,0x8E0001A5,0x2BFC01A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0xB001A5,0x9E940001,0x9E940001,0x9E940001,0x9E940001,0x9E940001, -0x9E940001,0x72940001,0x72940001,0x72940001,0x64900002,0x10401A5,0x10401A5,0x10401A5,0x10401A5,0x10401A5,0x10401A5,0x805C0000,0x805C0000,0x805C0000,0x64780001,0x5FC01A5,0x5FC01A5,0x5FC01A5,0x64200001,0x560001A5,0xFAA400A2,0xB001A5,0xB001A5,0xF894000A,0xD2940001,0xB2940001,0xB2940001,0x8E940001,0xFA880064,0xFC7C0002,0x828C0001,0x805C0000, -0x17001A5,}; -static const uint32_t g_etc1_to_bc7_m6_table111[] = { -0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0x1E80000, -0x1E80000,0x1E80000,0x1E80000,0x50000000,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xAC0000,0xAC0000,0xAC0000,0xF00000,0x1580000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0x3440000,0x3440000,0x3440000,0x3440000,0x3440000, -0x3440000,0x27FC0000,0x27FC0000,0x27FC0000,0x6C000001,0x3440000,0x3440000,0x3440000,0x3440000,0x3440000,0x3440000,0x27FC0000,0x27FC0000,0x27FC0000,0x6C000001,0x27FC0000,0x27FC0000,0x27FC0000,0x6C000001,0x6C000001,0xCE80000,0xDC0000,0xDC0000,0x1000000,0x1140000,0x12C0000,0x12C0000,0x1700000,0x1000000,0x1140000,0x1D40000,0x27FC0000, -0x1D40000,0x1100000,0x1100000,0x1100000,0x1100000,0x1940000,0x1940000,0x1940000,0x4FF80000,0x4FF80000,0x86000001,0x1940000,0x1940000,0x1940000,0x4FF80000,0x4FF80000,0x86000001,0x4FF80000,0x4FF80000,0x86000001,0x86000001,0x1940000,0x1940000,0x1940000,0x4FF80000,0x4FF80000,0x86000001,0x4FF80000,0x4FF80000,0x86000001,0x86000001,0x4FF80000, -0x4FF80000,0x86000001,0x86000001,0x86000001,0x13C0000,0x9200000,0x1100000,0x3700000,0x1C80000,0x1FFC0000,0x37FC0000,0x5DFC0000,0x1540000,0x1940000,0x1FFC0000,0x86000001,0x1FFC0000,0x1480001,0x3E80000,0x79FC0000,0xA4000000,0x3E80000,0x79FC0000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0x3E80000,0x79FC0000,0xA4000000,0x79FC0000,0xA4000000, -0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0x3E80000,0x79FC0000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0xA4000000,0x39C0000,0x1600000,0x1600000,0x23FC0000,0x69F80000,0x8FF40000,0xA4000000,0xA4000000,0x1C00000,0x41FC0000,0x9FF00000,0xA4000000, -0x57FC0000,0xF40F1E,0xFEDC061E,0xC0D805ED,0xA4D805ED,0xFCC00356,0xC8C401C5,0xA8C80286,0xB0C0034A,0xA2BC01BD,0x96C0034A,0xF8A405EB,0xCEA40154,0xAAB4020F,0xB69C01B6,0xA2A40006,0x96A801BE,0xA4A005EB,0x9C98020D,0x9098028A,0x88A005EB,0x16C0F1A,0xD87005EB,0xA4A405EA,0xCA54034A,0xA67C01B2,0x9688034A,0xBC3C05EB,0xA44C0153,0x945C01C3,0x886C05EA,0x3BFC0F1A, -0xA20005F1,0x94000376,0x8400065A,0x7A000F1A,0xFED80614,0xFEEC0B8E,0xFEEC0C81,0xFEB00093,0xDCA00004,0xB8A40004,0xA6AC0025,0xA0A00023,0xFEBC05A3,0xFE94003E,0xA8940159,0x945C01C3,0x7FC0F1A,0x11005ED,0xF8F80154,0xB8F80154,0xA4F40154,0xE6DC01A5,0xBEDC0002,0xA4E40029,0xA8DC01A5,0x9ED8004C,0x96DC01A5,0x19805EA,0xCAA80153,0xA4CC0152,0xBC9001A5,0xA2A40005, -0x96B401A5,0x51F805EA,0xA4480152,0x963401A5,0x880005EA,0x19805EA,0xCAA80153,0xA4CC0152,0xBC9001A5,0xA2A40005,0x96B401A5,0x51F805EA,0xA4480152,0x963401A5,0x880005EA,0x51F805EA,0xA4480152,0x963401A5,0x880005EA,0x880005EA,0xFEEC028B,0xFD080465,0xFF0C0455,0xFCBC0048,0xDCA00003,0xB8A40003,0xA4B40001,0xA28C000C,0xFCD80289,0xFE98001E,0xAA880152,0x963401A5, -0x21FC05EA,0xD805ED,0xD805ED,0xD805ED,0xD805ED,0xD8C001A5,0xD8C001A5,0xD8C001A5,0x9AC001A5,0x9AC001A5,0x86C001A6,0xCEA40153,0xCEA40153,0xCEA40153,0xA2A40002,0xA2A40002,0x88AC004B,0x8EA40153,0x8EA40153,0x82A0002A,0x7AA00153,0x14405EA,0x14405EA,0x14405EA,0xAE7001A5,0xAE7001A5,0x869801A6,0xA0580153,0xA0580153,0x886C0001,0x7A780152,0x27F805EA, -0x27F805EA,0x861801A6,0x7A000156,0x6C0005EA,0xFAC40225,0xFECC0439,0xD805ED,0xFEAC0032,0xD6A40002,0xB6A40002,0xAEA4000B,0x9AA00002,0xFAAC01E2,0xFE900015,0xA4980153,0x886C0001,0x1D005EA,0xF40154,0xF40154,0xF40154,0xF40154,0xBCDC0000,0xBCDC0000,0xBCDC0000,0x94DC0000,0x94DC0000,0x86DC0001,0x16C0152,0x16C0152,0x16C0152,0x9EAC0001,0x9EAC0001, -0x86C40001,0x3BFC0152,0x3BFC0152,0x86740001,0x7A000152,0x16C0152,0x16C0152,0x16C0152,0x9EAC0001,0x9EAC0001,0x86C40001,0x3BFC0152,0x3BFC0152,0x86740001,0x7A000152,0x3BFC0152,0x3BFC0152,0x86740001,0x7A000152,0x7A000152,0xFED80062,0xFEEC0091,0xF40154,0xFEB4000D,0xD2A80000,0xB4A80000,0xA6B40000,0x9C9C0000,0xFCC00080,0xFE980005,0x7FC0152,0x86740001, -0x7FC0152,0x12C01A5,0xDF100000,0xB3100000,0xA5100000,0x1C001A5,0xC0D80000,0xA4F40000,0x63FC01A5,0xA4980000,0x960001A5,0x1C001A5,0xC0D80000,0xA4F40000,0x63FC01A5,0xA4980000,0x960001A5,0x63FC01A5,0xA4980000,0x960001A5,0x960001A5,0x1C001A5,0xC0D80000,0xA4F40000,0x63FC01A5,0xA4980000,0x960001A5,0x63FC01A5,0xA4980000,0x960001A5,0x960001A5,0x63FC01A5, -0xA4980000,0x960001A5,0x960001A5,0x960001A5,0xF70400DD,0x14001A5,0xFB2400F4,0xFEC00014,0xE2940000,0xBA9C0000,0xA4BC0000,0xA46C0000,0xFCEC00CA,0xFEA0000A,0xA8C40000,0x960001A5,0x3BFC01A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xC001A5,0xA6A40001,0xA6A40001,0xA6A40001,0xA6A40001,0xA6A40001, -0xA6A40001,0x7AA40001,0x7AA40001,0x7AA40001,0x6CA00002,0x11C01A5,0x11C01A5,0x11C01A5,0x11C01A5,0x11C01A5,0x11C01A5,0x886C0000,0x886C0000,0x886C0000,0x6C880001,0x11FC01A5,0x11FC01A5,0x11FC01A5,0x6C300001,0x5E0001A5,0xF2B400B5,0xC001A5,0xC001A5,0xFCA8000D,0xDAA40001,0xBAA40001,0xBAA40001,0x96A40001,0xFC9C0071,0xFC900005,0x8A9C0001,0x886C0000, -0x19401A5,}; -static const uint32_t g_etc1_to_bc7_m6_table112[] = { -0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0xBF80000, -0xBF80000,0xBF80000,0xBF80000,0x58000001,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xC00000,0xC00000,0xC00000,0x10C0000,0x17C0000,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0xEC0001,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000, -0x1600000,0x35FC0000,0x35FC0000,0x35FC0000,0x76000000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x35FC0000,0x35FC0000,0x35FC0000,0x76000000,0x35FC0000,0x35FC0000,0x35FC0000,0x76000000,0x76000000,0x6FC0000,0xEC0001,0xEC0001,0x1140000,0x3280000,0x1440000,0x1440000,0x1900000,0x1140000,0x3280000,0x1F80000,0x35FC0000, -0x1F80000,0x1200001,0x1200001,0x1200001,0x1200001,0x1B00000,0x1B00000,0x1B00000,0x5DF40000,0x5DF40000,0x90000000,0x1B00000,0x1B00000,0x1B00000,0x5DF40000,0x5DF40000,0x90000000,0x5DF40000,0x5DF40000,0x90000000,0x90000000,0x1B00000,0x1B00000,0x1B00000,0x5DF40000,0x5DF40000,0x90000000,0x5DF40000,0x5DF40000,0x90000000,0x90000000,0x5DF40000, -0x5DF40000,0x90000000,0x90000000,0x90000000,0x1500000,0x3340000,0x1200001,0x3880000,0x1E80000,0x31FC0000,0x47F80000,0x69FC0000,0x16C0000,0x1B00000,0x31FC0000,0x90000000,0x31FC0000,0x15C0000,0x9FC0000,0x87FC0000,0xAC000001,0x9FC0000,0x87FC0000,0xAC000001,0x87FC0000,0xAC000001,0xAC000001,0x9FC0000,0x87FC0000,0xAC000001,0x87FC0000,0xAC000001, -0xAC000001,0x87FC0000,0xAC000001,0xAC000001,0xAC000001,0x9FC0000,0x87FC0000,0xAC000001,0x87FC0000,0xAC000001,0xAC000001,0x87FC0000,0xAC000001,0xAC000001,0xAC000001,0x87FC0000,0xAC000001,0xAC000001,0xAC000001,0xAC000001,0x1B40000,0x1740000,0x1740000,0x39FC0000,0x77FC0000,0x99FC0000,0xAC000001,0xAC000001,0x1D80000,0x53FC0000,0xA9E40000,0xAC000001, -0x67FC0000,0x1080F1A,0xFCF0065A,0xC8EC05EA,0xACEC05EB,0xFED40376,0xD0D401C3,0xB0D8028A,0xBAD0034A,0xAAD001BE,0x9ED0034A,0xFCB805F1,0xD8B40153,0xB2C4020D,0xC0B001B2,0xACB40006,0xA0B801BD,0xACB405EA,0xA4A8020F,0x9AAC0286,0x90B405ED,0x1880F1A,0xE08405EB,0xAEB405EB,0xD268034A,0xAE8C01B6,0x9E9C034A,0xC64805EB,0xAC600154,0x9C6C01C5,0x927C05ED,0x49F80F1A, -0xAC0805EB,0x9C000356,0x9000061E,0x82000F1E,0xFEE4068A,0xF9000BEA,0xFB040CAA,0xFEC400EA,0xE4B40003,0xC2B40002,0xAEBC0023,0xA8B00025,0xFED40612,0xFEB0008D,0xB2A8015B,0x9C6C01C5,0x19FC0F1A,0x12405EA,0xFD080156,0xC3080152,0xAD080153,0xEEF001A6,0xC8EC0001,0xAEF8002A,0xB2EC01A6,0xA8EC004B,0x9EEC01A6,0x3B005EA,0xD2BC0153,0xACE00153,0xC6A001A5,0xACB80002, -0x9EC801A5,0x5DFC05EA,0xAC600153,0x9E4801A5,0x900005ED,0x3B005EA,0xD2BC0153,0xACE00153,0xC6A001A5,0xACB80002,0x9EC801A5,0x5DFC05EA,0xAC600153,0x9E4801A5,0x900005ED,0x5DFC05EA,0xAC600153,0x9E4801A5,0x900005ED,0x900005ED,0xFF0002B2,0xF71C0492,0xF9200483,0xFED40072,0xE4B40003,0xC2B40002,0xAEC80002,0xACA0000B,0xFCEC02D4,0xFEB80048,0xB4980152,0x9E4801A5, -0x33FC05EA,0xEC05EA,0xEC05EA,0xEC05EA,0xEC05EA,0xE4D001A5,0xE4D001A5,0xE4D001A5,0xA4D001A5,0xA4D001A5,0x90D001A5,0xD8B40152,0xD8B40152,0xD8B40152,0xAAB40005,0xAAB40005,0x92C0004C,0x98B40152,0x98B40152,0x8CB40029,0x82B40154,0x35C05EA,0x35C05EA,0x35C05EA,0xB68401A5,0xB68401A5,0x90A801A5,0xAA680153,0xAA680153,0x907C0002,0x828C0154,0x33FC05EA, -0x33FC05EA,0x902801A5,0x820C0154,0x740005ED,0xFED80248,0xFAE4043D,0xEC05EA,0xFEBC0054,0xE2B40002,0xC2B40002,0xB8B8000C,0xA4B40001,0xFEBC020C,0xFEA40031,0xAEA80152,0x907C0002,0x1F405EA,0x1080152,0x1080152,0x1080152,0x1080152,0xC2F00001,0xC2F00001,0xC2F00001,0x9CF00001,0x9CF00001,0x90EC0001,0x1880152,0x1880152,0x1880152,0xA6C00001,0xA6C00001, -0x90D40000,0x49F80152,0x49F80152,0x90840000,0x82000154,0x1880152,0x1880152,0x1880152,0xA6C00001,0xA6C00001,0x90D40000,0x49F80152,0x49F80152,0x90840000,0x82000154,0x49F80152,0x49F80152,0x90840000,0x82000154,0x82000154,0xFAEC0071,0xF90000A2,0x1080152,0xF6CC0019,0xDABC0000,0xBCBC0001,0xB0C40000,0xA4B00000,0xFED00088,0xFEB0000D,0x19FC0152,0x90840000, -0x19FC0152,0x14001A5,0xE7240001,0xBB240001,0xAD200002,0x1D801A5,0xC8EC0000,0xAD080001,0x71F801A5,0xACB00001,0x9E0001A5,0x1D801A5,0xC8EC0000,0xAD080001,0x71F801A5,0xACB00001,0x9E0001A5,0x71F801A5,0xACB00001,0x9E0001A5,0x9E0001A5,0x1D801A5,0xC8EC0000,0xAD080001,0x71F801A5,0xACB00001,0x9E0001A5,0x71F801A5,0xACB00001,0x9E0001A5,0x9E0001A5,0x71F801A5, -0xACB00001,0x9E0001A5,0x9E0001A5,0x9E0001A5,0xFF1400E1,0x15401A5,0xF5380109,0xFED80028,0xEAA80000,0xC4AC0000,0xACD00001,0xAC840001,0xF70800DD,0xFEC00012,0xB2D40000,0x9E0001A5,0x4BFC01A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xD001A5,0xB0B40000,0xB0B40000,0xB0B40000,0xB0B40000,0xB0B40000, -0xB0B40000,0x84B40000,0x84B40000,0x84B40000,0x76B40000,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x927C0000,0x927C0000,0x927C0000,0x76980000,0x1FF801A5,0x1FF801A5,0x1FF801A5,0x763C0000,0x680001A5,0xFCC800B5,0xD001A5,0xD001A5,0xFCB80014,0xE6B40000,0xC6B40000,0xC6B40000,0xA0B40000,0xF8B00080,0xFEA0000A,0x94AC0000,0x927C0000, -0x1B801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table113[] = { -0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x17F80000, -0x17F80000,0x17F80000,0x17F80000,0x60000001,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xD00000,0xD00000,0xD00000,0x1240000,0x1A00000,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0xFC0001,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000, -0x1780000,0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0x41FC0000,0x41FC0000,0x41FC0000,0x7E000000,0x7E000000,0xF0C0000,0xFC0001,0xFC0001,0x1280000,0x33C0000,0x1580000,0x1580000,0x1AC0000,0x1280000,0x33C0000,0xFFC0000,0x41FC0000, -0xFFC0000,0x1300001,0x1300001,0x1300001,0x1300001,0x3C40000,0x3C40000,0x3C40000,0x67FC0000,0x67FC0000,0x98000000,0x3C40000,0x3C40000,0x3C40000,0x67FC0000,0x67FC0000,0x98000000,0x67FC0000,0x67FC0000,0x98000000,0x98000000,0x3C40000,0x3C40000,0x3C40000,0x67FC0000,0x67FC0000,0x98000000,0x67FC0000,0x67FC0000,0x98000000,0x98000000,0x67FC0000, -0x67FC0000,0x98000000,0x98000000,0x98000000,0x1640000,0xB440000,0x1300001,0x1A00000,0x5FC0000,0x3FFC0000,0x55F80000,0x75F80000,0x1800000,0x3C40000,0x3FFC0000,0x98000000,0x3FFC0000,0x16C0000,0x23FC0000,0x93FC0000,0xB4000001,0x23FC0000,0x93FC0000,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0x23FC0000,0x93FC0000,0xB4000001,0x93FC0000,0xB4000001, -0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0x23FC0000,0x93FC0000,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0x93FC0000,0xB4000001,0xB4000001,0xB4000001,0xB4000001,0x1C80000,0x1840000,0x1840000,0x4DFC0000,0x85FC0000,0xA5F00000,0xB4000001,0xB4000001,0x1F00000,0x65FC0000,0xB1F40000,0xB4000001, -0x77FC0000,0x1180F1A,0xFF000686,0xD0FC05EA,0xB4FC05EB,0xFEE8039E,0xD8E401C3,0xB8E8028A,0xC2E0034A,0xB2E001BE,0xA6E0034A,0xFCCC0606,0xE0C40153,0xBAD4020D,0xC8C001B2,0xB4C40006,0xA8C801BD,0xB4C405EA,0xACB8020F,0xA2BC0286,0x98C405ED,0x1A00F1A,0xE89405EB,0xB6C405EB,0xDA78034A,0xB69C01B6,0xA6AC034A,0xCE5805EB,0xB4700154,0xA47C01C5,0x9A8C05ED,0x55F80F1A, -0xB41805EB,0xA600034A,0x98000606,0x8A000F1E,0xFEF806F7,0xFF0C0BFA,0xFF0C0CEA,0xFED80150,0xECC40003,0xCAC40002,0xB6CC0023,0xB0C00025,0xFEE006BA,0xFEC000D3,0xBAB8015B,0xA47C01C5,0x27FC0F1A,0x13405EA,0xFF180162,0xCB180152,0xB5180153,0xF70001A6,0xD0FC0001,0xB708002A,0xBAFC01A6,0xB0FC004B,0xA6FC01A6,0x1C805EA,0xDACC0153,0xB4F00153,0xCEB001A5,0xB4C80002, -0xA6D801A5,0x69FC05EA,0xB4700153,0xA65801A5,0x980005ED,0x1C805EA,0xDACC0153,0xB4F00153,0xCEB001A5,0xB4C80002,0xA6D801A5,0x69FC05EA,0xB4700153,0xA65801A5,0x980005ED,0x69FC05EA,0xB4700153,0xA65801A5,0x980005ED,0x980005ED,0xFF1402D5,0xFF2C0492,0xFF2C048B,0xFCE800A5,0xECC40003,0xCAC40002,0xB6D80002,0xB4B0000B,0xFEF802F6,0xFEC80065,0xBCA80152,0xA65801A5, -0x41FC05EA,0xFC05EA,0xFC05EA,0xFC05EA,0xFC05EA,0xECE001A5,0xECE001A5,0xECE001A5,0xACE001A5,0xACE001A5,0x98E001A5,0xE0C40152,0xE0C40152,0xE0C40152,0xB2C40005,0xB2C40005,0x9AD0004C,0xA0C40152,0xA0C40152,0x94C40029,0x8AC40154,0x37405EA,0x37405EA,0x37405EA,0xBE9401A5,0xBE9401A5,0x98B801A5,0xB2780153,0xB2780153,0x988C0002,0x8A9C0154,0x3FFC05EA, -0x3FFC05EA,0x983801A5,0x8A1C0154,0x7C0005ED,0xFEE80269,0xF4F80466,0xFC05EA,0xFED40071,0xEAC40002,0xCAC40002,0xC0C8000C,0xACC40001,0xFED00229,0xFEBC0048,0xB6B80152,0x988C0002,0xDFC05EA,0x1180152,0x1180152,0x1180152,0x1180152,0xCB000001,0xCB000001,0xCB000001,0xA5000001,0xA5000001,0x98FC0001,0x1A00152,0x1A00152,0x1A00152,0xAED00001,0xAED00001, -0x98E40000,0x55F80152,0x55F80152,0x98940000,0x8A000154,0x1A00152,0x1A00152,0x1A00152,0xAED00001,0xAED00001,0x98E40000,0x55F80152,0x55F80152,0x98940000,0x8A000154,0x55F80152,0x55F80152,0x98940000,0x8A000154,0x8A000154,0xF7000080,0xFF0C00AA,0x1180152,0xFEDC0019,0xE2CC0000,0xC4CC0001,0xB8D40000,0xACC00000,0xF8EC0091,0xFEC40012,0x27FC0152,0x98940000, -0x27FC0152,0x15001A5,0xEF340001,0xC3340001,0xB5300002,0x1F001A5,0xD0FC0000,0xB5180001,0x7DF801A5,0xB4C00001,0xA60001A5,0x1F001A5,0xD0FC0000,0xB5180001,0x7DF801A5,0xB4C00001,0xA60001A5,0x7DF801A5,0xB4C00001,0xA60001A5,0xA60001A5,0x1F001A5,0xD0FC0000,0xB5180001,0x7DF801A5,0xB4C00001,0xA60001A5,0x7DF801A5,0xB4C00001,0xA60001A5,0xA60001A5,0x7DF801A5, -0xB4C00001,0xA60001A5,0xA60001A5,0xA60001A5,0xFB2C00F2,0x16401A5,0xFD480109,0xFEF40034,0xF2B80000,0xCCBC0000,0xB4E00001,0xB4940001,0xFF1800DD,0xFED80022,0xBAE40000,0xA60001A5,0x5BFC01A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xE001A5,0xB8C40000,0xB8C40000,0xB8C40000,0xB8C40000,0xB8C40000, -0xB8C40000,0x8CC40000,0x8CC40000,0x8CC40000,0x7EC40000,0x14C01A5,0x14C01A5,0x14C01A5,0x14C01A5,0x14C01A5,0x14C01A5,0x9A8C0000,0x9A8C0000,0x9A8C0000,0x7EA80000,0x2BF801A5,0x2BF801A5,0x2BF801A5,0x7E4C0000,0x700001A5,0xF4D800C8,0xE001A5,0xE001A5,0xFECC0019,0xEEC40000,0xCEC40000,0xCEC40000,0xA8C40000,0xFEBC0088,0xFEB4000D,0x9CBC0000,0x9A8C0000, -0x1DC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table114[] = { -0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x21FC0000, -0x21FC0000,0x21FC0000,0x21FC0000,0x68000001,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x8E00000,0x8E00000,0x8E00000,0x13C0000,0x1C00000,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x10C0001,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000, -0x1900000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x86000000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x86000000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x86000000,0x86000000,0x1200000,0x10C0001,0x10C0001,0x5380000,0x5500000,0x1700000,0x1700000,0x1C40000,0x5380000,0x5500000,0x1FF80000,0x4DFC0000, -0x1FF80000,0x1400001,0x1400001,0x1400001,0x1400001,0x3DC0000,0x3DC0000,0x3DC0000,0x73FC0000,0x73FC0000,0xA0000000,0x3DC0000,0x3DC0000,0x3DC0000,0x73FC0000,0x73FC0000,0xA0000000,0x73FC0000,0x73FC0000,0xA0000000,0xA0000000,0x3DC0000,0x3DC0000,0x3DC0000,0x73FC0000,0x73FC0000,0xA0000000,0x73FC0000,0x73FC0000,0xA0000000,0xA0000000,0x73FC0000, -0x73FC0000,0xA0000000,0xA0000000,0xA0000000,0x5740000,0x1580000,0x1400001,0x3B40000,0x19FC0000,0x4FFC0000,0x61FC0000,0x7FFC0000,0x1940000,0x3DC0000,0x4FFC0000,0xA0000000,0x4FFC0000,0x17C0000,0x3BFC0000,0x9FF80000,0xBC000001,0x3BFC0000,0x9FF80000,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0x3BFC0000,0x9FF80000,0xBC000001,0x9FF80000,0xBC000001, -0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0x3BFC0000,0x9FF80000,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0x9FF80000,0xBC000001,0xBC000001,0xBC000001,0xBC000001,0x1DC0000,0x3940000,0x3940000,0x61FC0000,0x93F80000,0xAFF00000,0xBC000001,0xBC000001,0xDFC0000,0x75FC0000,0xBBC80000,0xBC000001, -0x85FC0000,0x1280F1A,0xFF1006D7,0xD90C05EA,0xBD0C05EB,0xFEF803F2,0xE0F401C3,0xC0F8028A,0xCAF0034A,0xBAF001BE,0xAEF0034A,0xFEE00629,0xE8D40153,0xC2E4020D,0xD0D001B2,0xBCD40006,0xB0D801BD,0xBCD405EA,0xB4C8020F,0xAACC0286,0xA0D405ED,0x1B80F1A,0xF0A405EB,0xBED405EB,0xE288034A,0xBEAC01B6,0xAEBC034A,0xD66805EB,0xBC800154,0xAC8C01C5,0xA29C05ED,0x61F80F1A, -0xBC2805EB,0xAE0C034A,0xA00005F1,0x92000F1E,0xFF0C0766,0xF9200C4A,0xFB240CF3,0xFEEC01C5,0xF4D40003,0xD2D40002,0xBEDC0023,0xB8D00025,0xFEF806FA,0xFED4013A,0xC2C8015B,0xAC8C01C5,0x37FC0F1A,0x14405EA,0xFD2C017E,0xD3280152,0xBD280153,0xFF1001A6,0xD90C0001,0xBF18002A,0xC30C01A6,0xB90C004B,0xAF0C01A6,0x1E005EA,0xE2DC0153,0xBD000153,0xD6C001A5,0xBCD80002, -0xAEE801A5,0x75FC05EA,0xBC800153,0xAE6801A5,0xA00005ED,0x1E005EA,0xE2DC0153,0xBD000153,0xD6C001A5,0xBCD80002,0xAEE801A5,0x75FC05EA,0xBC800153,0xAE6801A5,0xA00005ED,0x75FC05EA,0xBC800153,0xAE6801A5,0xA00005ED,0xA00005ED,0xFF200312,0xF73C04BE,0xF94004B2,0xFEF800DE,0xF4D40003,0xD2D40002,0xBEE80002,0xBCC0000B,0xFD140322,0xFEE000A1,0xC4B80152,0xAE6801A5, -0x51FC05EA,0x10C05EA,0x10C05EA,0x10C05EA,0x10C05EA,0xF4F001A5,0xF4F001A5,0xF4F001A5,0xB4F001A5,0xB4F001A5,0xA0F001A5,0xE8D40152,0xE8D40152,0xE8D40152,0xBAD40005,0xBAD40005,0xA2E0004C,0xA8D40152,0xA8D40152,0x9CD40029,0x92D40154,0x38C05EA,0x38C05EA,0x38C05EA,0xC6A401A5,0xC6A401A5,0xA0C801A5,0xBA880153,0xBA880153,0xA09C0002,0x92AC0154,0x4BFC05EA, -0x4BFC05EA,0xA04801A5,0x922C0154,0x840005ED,0xFEF402A9,0xFD080466,0x10C05EA,0xFCE400A5,0xF2D40002,0xD2D40002,0xC8D8000C,0xB4D40001,0xFEE40266,0xFED00062,0xBEC80152,0xA09C0002,0x1DF805EA,0x1280152,0x1280152,0x1280152,0x1280152,0xD3100001,0xD3100001,0xD3100001,0xAD100001,0xAD100001,0xA10C0001,0x1B80152,0x1B80152,0x1B80152,0xB6E00001,0xB6E00001, -0xA0F40000,0x61F80152,0x61F80152,0xA0A40000,0x92000154,0x1B80152,0x1B80152,0x1B80152,0xB6E00001,0xB6E00001,0xA0F40000,0x61F80152,0x61F80152,0xA0A40000,0x92000154,0x61F80152,0x61F80152,0xA0A40000,0x92000154,0x92000154,0xFF100080,0xF92000B5,0x1280152,0xFCF40029,0xEADC0000,0xCCDC0001,0xC0E40000,0xB4D00000,0xFEF80095,0xFEDC0019,0x37FC0152,0xA0A40000, -0x37FC0152,0x16001A5,0xF7440001,0xCB440001,0xBD400002,0xDFC01A5,0xD90C0000,0xBD280001,0x89F801A5,0xBCD00001,0xAE0001A5,0xDFC01A5,0xD90C0000,0xBD280001,0x89F801A5,0xBCD00001,0xAE0001A5,0x89F801A5,0xBCD00001,0xAE0001A5,0xAE0001A5,0xDFC01A5,0xD90C0000,0xBD280001,0x89F801A5,0xBCD00001,0xAE0001A5,0x89F801A5,0xBCD00001,0xAE0001A5,0xAE0001A5,0x89F801A5, -0xBCD00001,0xAE0001A5,0xAE0001A5,0xAE0001A5,0xF7400109,0x17801A5,0xF5580122,0xFD100048,0xFAC80000,0xD4CC0000,0xBCF00001,0xBCA40001,0xFF2C00F4,0xFEF0003A,0xC2F40000,0xAE0001A5,0x69FC01A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xF001A5,0xC0D40000,0xC0D40000,0xC0D40000,0xC0D40000,0xC0D40000, -0xC0D40000,0x94D40000,0x94D40000,0x94D40000,0x86D40000,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0xA29C0000,0xA29C0000,0xA29C0000,0x86B80000,0x37F801A5,0x37F801A5,0x37F801A5,0x865C0000,0x780001A5,0xFCE800C8,0xF001A5,0xF001A5,0xFED80028,0xF6D40000,0xD6D40000,0xD6D40000,0xB0D40000,0xFCD40091,0xFAC80019,0xA4CC0000,0xA29C0000, -0x1FC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table115[] = { -0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x2DFC0000, -0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xF40000,0xF40000,0xF40000,0x3500000,0x1E40000,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x11C0001,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000, -0x1A80000,0x59FC0000,0x59FC0000,0x59FC0000,0x8E000000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x59FC0000,0x59FC0000,0x59FC0000,0x8E000000,0x59FC0000,0x59FC0000,0x59FC0000,0x8E000000,0x8E000000,0x1300000,0x11C0001,0x11C0001,0x14C0000,0x5640000,0x1840000,0x1840000,0x1E00000,0x14C0000,0x5640000,0x2DFC0000,0x59FC0000, -0x2DFC0000,0x1500001,0x1500001,0x1500001,0x1500001,0x3F40000,0x3F40000,0x3F40000,0x7FFC0000,0x7FFC0000,0xA8000000,0x3F40000,0x3F40000,0x3F40000,0x7FFC0000,0x7FFC0000,0xA8000000,0x7FFC0000,0x7FFC0000,0xA8000000,0xA8000000,0x3F40000,0x3F40000,0x3F40000,0x7FFC0000,0x7FFC0000,0xA8000000,0x7FFC0000,0x7FFC0000,0xA8000000,0xA8000000,0x7FFC0000, -0x7FFC0000,0xA8000000,0xA8000000,0xA8000000,0x1880000,0x1680000,0x1500001,0x1CC0000,0x2DFC0000,0x5FF80000,0x6FFC0000,0x8BF80000,0x1A80000,0x3F40000,0x5FF80000,0xA8000000,0x5FF80000,0x18C0000,0x53FC0000,0xABF80000,0xC4000001,0x53FC0000,0xABF80000,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0x53FC0000,0xABF80000,0xC4000001,0xABF80000,0xC4000001, -0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xC4000001,0x53FC0000,0xABF80000,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xC4000001,0xABF80000,0xC4000001,0xC4000001,0xC4000001,0xC4000001,0x1F00000,0xBA40000,0xBA40000,0x73FC0000,0x9FFC0000,0xB9F00000,0xC4000001,0xC4000001,0x2BFC0000,0x87FC0000,0xC3D80000,0xC4000001, -0x95FC0000,0x1380F1A,0xFF24071A,0xE11C05EA,0xC51C05EB,0xFF0C043A,0xE90401C3,0xC908028A,0xD300034A,0xC30001BE,0xB700034A,0xFEF4065A,0xF0E40153,0xCAF4020D,0xD8E001B2,0xC4E40006,0xB8E801BD,0xC4E405EA,0xBCD8020F,0xB2DC0286,0xA8E405ED,0x1D00F1A,0xF8B405EB,0xC6E405EB,0xEA98034A,0xC6BC01B6,0xB6CC034A,0xDE7805EB,0xC4900154,0xB49C01C5,0xAAAC05ED,0x6DF80F1A, -0xC43805EB,0xB61C034A,0xA80005ED,0x9A000F1E,0xFF2007D6,0xFF2C0C62,0xFF2C0D3B,0xFF000242,0xFCE40003,0xDAE40002,0xC6EC0023,0xC0E00025,0xFF100782,0xFEE801CC,0xCAD8015B,0xB49C01C5,0x45FC0F1A,0x15405EA,0xFF3C019A,0xDB380152,0xC5380153,0xFF2401B2,0xE11C0001,0xC728002A,0xCB1C01A6,0xC11C004B,0xB71C01A6,0x1F805EA,0xEAEC0153,0xC5100153,0xDED001A5,0xC4E80002, -0xB6F801A5,0x81FC05EA,0xC4900153,0xB67801A5,0xA80005ED,0x1F805EA,0xEAEC0153,0xC5100153,0xDED001A5,0xC4E80002,0xB6F801A5,0x81FC05EA,0xC4900153,0xB67801A5,0xA80005ED,0x81FC05EA,0xC4900153,0xB67801A5,0xA80005ED,0xA80005ED,0xFF340333,0xFF4C04BE,0xFF4C04BE,0xFF140109,0xFCE40003,0xDAE40002,0xC6F80002,0xC4D0000B,0xFF240356,0xFD0000DD,0xCCC80152,0xB67801A5, -0x5FFC05EA,0x11C05EA,0x11C05EA,0x11C05EA,0x11C05EA,0xFD0001A5,0xFD0001A5,0xFD0001A5,0xBD0001A5,0xBD0001A5,0xA90001A5,0xF0E40152,0xF0E40152,0xF0E40152,0xC2E40005,0xC2E40005,0xAAF0004C,0xB0E40152,0xB0E40152,0xA4E40029,0x9AE40154,0x3A405EA,0x3A405EA,0x3A405EA,0xCEB401A5,0xCEB401A5,0xA8D801A5,0xC2980153,0xC2980153,0xA8AC0002,0x9ABC0154,0x57FC05EA, -0x57FC05EA,0xA85801A5,0x9A3C0154,0x8C0005ED,0xFF0402D2,0xF5180491,0x11C05EA,0xFEF800C9,0xFAE40002,0xDAE40002,0xD0E8000C,0xBCE40001,0xFEF80289,0xFEE00099,0xC6D80152,0xA8AC0002,0x2BFC05EA,0x1380152,0x1380152,0x1380152,0x1380152,0xDB200001,0xDB200001,0xDB200001,0xB5200001,0xB5200001,0xA91C0001,0x1D00152,0x1D00152,0x1D00152,0xBEF00001,0xBEF00001, -0xA9040000,0x6DF80152,0x6DF80152,0xA8B40000,0x9A000154,0x1D00152,0x1D00152,0x1D00152,0xBEF00001,0xBEF00001,0xA9040000,0x6DF80152,0x6DF80152,0xA8B40000,0x9A000154,0x6DF80152,0x6DF80152,0xA8B40000,0x9A000154,0x9A000154,0xFF200091,0xFF2C00C1,0x1380152,0xFD040034,0xF2EC0000,0xD4EC0001,0xC8F40000,0xBCE00000,0xFD1000A2,0xFCF00029,0x45FC0152,0xA8B40000, -0x45FC0152,0x17001A5,0xFF540001,0xD3540001,0xC5500002,0x25FC01A5,0xE11C0000,0xC5380001,0x95F801A5,0xC4E00001,0xB60001A5,0x25FC01A5,0xE11C0000,0xC5380001,0x95F801A5,0xC4E00001,0xB60001A5,0x95F801A5,0xC4E00001,0xB60001A5,0xB60001A5,0x25FC01A5,0xE11C0000,0xC5380001,0x95F801A5,0xC4E00001,0xB60001A5,0x95F801A5,0xC4E00001,0xB60001A5,0xB60001A5,0x95F801A5, -0xC4E00001,0xB60001A5,0xB60001A5,0xB60001A5,0xFF500109,0x18801A5,0xFD680122,0xFF200061,0xFCE40002,0xDCDC0000,0xC5000001,0xC4B40001,0xF5480109,0xFF100048,0xCB040000,0xB60001A5,0x79FC01A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0x10001A5,0xC8E40000,0xC8E40000,0xC8E40000,0xC8E40000,0xC8E40000, -0xC8E40000,0x9CE40000,0x9CE40000,0x9CE40000,0x8EE40000,0x17C01A5,0x17C01A5,0x17C01A5,0x17C01A5,0x17C01A5,0x17C01A5,0xAAAC0000,0xAAAC0000,0xAAAC0000,0x8EC80000,0x43F801A5,0x43F801A5,0x43F801A5,0x8E6C0000,0x800001A5,0xF4F800DD,0x10001A5,0x10001A5,0xFAEC0034,0xFEE40000,0xDEE40000,0xDEE40000,0xB8E40000,0xFCE400A2,0xFED80022,0xACDC0000,0xAAAC0000, -0x11FC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table116[] = { -0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000, -0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xB040000,0xB040000,0xB040000,0x16C0000,0x7FC0000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1300000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000, -0x1C40000,0x67F80000,0x67F80000,0x67F80000,0x96000001,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x67F80000,0x67F80000,0x67F80000,0x96000001,0x67F80000,0x67F80000,0x67F80000,0x96000001,0x96000001,0x1440000,0x1300000,0x1300000,0x3600000,0x17C0000,0x19C0000,0x19C0000,0x3FC0000,0x3600000,0x17C0000,0x3FF80000,0x67F80000, -0x3FF80000,0x1640000,0x1640000,0x1640000,0x1640000,0x15FC0000,0x15FC0000,0x15FC0000,0x8DFC0000,0x8DFC0000,0xB0000001,0x15FC0000,0x15FC0000,0x15FC0000,0x8DFC0000,0x8DFC0000,0xB0000001,0x8DFC0000,0x8DFC0000,0xB0000001,0xB0000001,0x15FC0000,0x15FC0000,0x15FC0000,0x8DFC0000,0x8DFC0000,0xB0000001,0x8DFC0000,0x8DFC0000,0xB0000001,0xB0000001,0x8DFC0000, -0x8DFC0000,0xB0000001,0xB0000001,0xB0000001,0x59C0000,0x17C0000,0x1640000,0x1E40000,0x43FC0000,0x6FFC0000,0x7FF80000,0x97F80000,0x3BC0000,0x15FC0000,0x6FFC0000,0xB0000001,0x6FFC0000,0x19C0001,0x6FFC0000,0xB9F80000,0xCE000000,0x6FFC0000,0xB9F80000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0x6FFC0000,0xB9F80000,0xCE000000,0xB9F80000,0xCE000000, -0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0x6FFC0000,0xB9F80000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0xCE000000,0x15FC0000,0x5B80000,0x5B80000,0x8BFC0000,0xAFFC0000,0xC3F80000,0xCE000000,0xCE000000,0x4DFC0000,0x99FC0000,0xCDCC0000,0xCE000000, -0xA5FC0000,0x1480F1E,0xFF340795,0xEB2C05ED,0xCF2C05ED,0xFF2404B6,0xF31801C5,0xD31C0286,0xDB14034A,0xCD1001BD,0xC114034A,0xFF0C06AE,0xF8F80154,0xD508020F,0xE0F001B6,0xCCF80006,0xC0FC01BE,0xCEF405EB,0xC6EC020D,0xBAEC028A,0xB2F405EB,0x3E80F1A,0xFECC05F1,0xCEF805EA,0xF4A8034A,0xD0D001B2,0xC0DC034A,0xE69005EB,0xCEA00153,0xBEB001C3,0xB2C005EA,0x79FC0F1A, -0xCE4805EA,0xC02C034A,0xB21005EA,0xA4000F1A,0xFF340865,0xFB440CAA,0xFD480D3E,0xFF1402EF,0xFEFC0019,0xE2F80004,0xD1000025,0xCAF40023,0xFF240839,0xFF000256,0xD2E80159,0xBEB001C3,0x57FC0F1A,0x16405ED,0xFF5001C8,0xE34C0154,0xCF480154,0xFF3C01D5,0xE9300002,0xCF380029,0xD33001A5,0xC92C004C,0xC13001A5,0x19FC05EA,0xF4FC0153,0xCF200152,0xE6E401A5,0xCCF80005, -0xC10801A5,0x8FF805EA,0xCE9C0152,0xC08801A5,0xB20005EA,0x19FC05EA,0xF4FC0153,0xCF200152,0xE6E401A5,0xCCF80005,0xC10801A5,0x8FF805EA,0xCE9C0152,0xC08801A5,0xB20005EA,0x8FF805EA,0xCE9C0152,0xC08801A5,0xB20005EA,0xB20005EA,0xFF500376,0xF96004ED,0xFB6404E4,0xFF2C016D,0xFEFC0010,0xE2F80003,0xCF080001,0xCCE0000C,0xFD40039E,0xFF180122,0xD4DC0152,0xC08801A5, -0x71FC05EA,0x12C05ED,0x12C05ED,0x12C05ED,0x12C05ED,0xFD1401A9,0xFD1401A9,0xFD1401A9,0xC51401A5,0xC51401A5,0xB11401A6,0xF8F80153,0xF8F80153,0xF8F80153,0xCCF80002,0xCCF80002,0xB300004B,0xB8F80153,0xB8F80153,0xACF4002A,0xA4F40153,0x1C005EA,0x1C005EA,0x1C005EA,0xD8C401A5,0xD8C401A5,0xB0EC01A6,0xCAAC0153,0xCAAC0153,0xB2C00001,0xA4CC0152,0x65F805EA, -0x65F805EA,0xB06C01A6,0xA4480152,0x960005EA,0xFF2002FE,0xFD280492,0x12C05ED,0xFF080103,0xFEF80003,0xE0F80002,0xD8F8000B,0xC4F40002,0xFF0C02D3,0xFEF400CA,0xCEEC0153,0xB2C00001,0x3DF805EA,0x1480154,0x1480154,0x1480154,0x1480154,0xE7300000,0xE7300000,0xE7300000,0xBF300000,0xBF300000,0xB1300001,0x3E80152,0x3E80152,0x3E80152,0xC9000001,0xC9000001, -0xB1180001,0x79FC0152,0x79FC0152,0xB0C80001,0xA4000152,0x3E80152,0x3E80152,0x3E80152,0xC9000001,0xC9000001,0xB1180001,0x79FC0152,0x79FC0152,0xB0C80001,0xA4000152,0x79FC0152,0x79FC0152,0xB0C80001,0xA4000152,0xA4000152,0xFB3400A4,0xFB4400C8,0x1480154,0xFF180041,0xFCFC0000,0xDEFC0000,0xD1080000,0xC6F00000,0xF92800B5,0xFF04003A,0x57FC0152,0xB0C80001, -0x57FC0152,0x18001A5,0xFF680008,0xDD640000,0xCF640000,0x41FC01A5,0xEB2C0000,0xCF480000,0xA1FC01A5,0xCEEC0000,0xC00001A5,0x41FC01A5,0xEB2C0000,0xCF480000,0xA1FC01A5,0xCEEC0000,0xC00001A5,0xA1FC01A5,0xCEEC0000,0xC00001A5,0xC00001A5,0x41FC01A5,0xEB2C0000,0xCF480000,0xA1FC01A5,0xCEEC0000,0xC00001A5,0xA1FC01A5,0xCEEC0000,0xC00001A5,0xC00001A5,0xA1FC01A5, -0xCEEC0000,0xC00001A5,0xC00001A5,0xC00001A5,0xFD680120,0x19C01A5,0xF77C0139,0xFF400071,0xFEFC0010,0xE4F00000,0xCF100000,0xCEC00000,0xFF5C0109,0xFF2C0064,0xD3180000,0xC00001A5,0x89FC01A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0x11401A5,0xD0F80001,0xD0F80001,0xD0F80001,0xD0F80001,0xD0F80001, -0xD0F80001,0xA4F80001,0xA4F80001,0xA4F80001,0x96F40002,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0xB2C00000,0xB2C00000,0xB2C00000,0x96DC0001,0x51F801A5,0x51F801A5,0x51F801A5,0x96840001,0x880001A5,0xFF0C00DD,0x11401A5,0x11401A5,0xFD00003D,0xFEF80002,0xE4F80001,0xE4F80001,0xC0F80001,0xFEF400AA,0xFAF00032,0xB4F00001,0xB2C00000, -0x21FC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table117[] = { -0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x1840000,0x47FC0000, -0x47FC0000,0x47FC0000,0x47FC0000,0x82000000,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1040001,0x1180000,0x1180000,0x1180000,0x1840000,0x17FC0000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000, -0x1DC0000,0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x73F80000,0x73F80000,0x73F80000,0x9E000001,0x9E000001,0x3540000,0x1400000,0x1400000,0x1740000,0x1900000,0x1B40000,0x1B40000,0x17FC0000,0x1740000,0x1900000,0x4DFC0000,0x73F80000, -0x4DFC0000,0x1740000,0x1740000,0x1740000,0x1740000,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x99FC0000,0x99FC0000,0xB8000001,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x99FC0000,0x99FC0000,0xB8000001,0x99FC0000,0x99FC0000,0xB8000001,0xB8000001,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x99FC0000,0x99FC0000,0xB8000001,0x99FC0000,0x99FC0000,0xB8000001,0xB8000001,0x99FC0000, -0x99FC0000,0xB8000001,0xB8000001,0xB8000001,0x1B00000,0x18C0000,0x1740000,0x3F80000,0x57FC0000,0x7FF80000,0x8BFC0000,0xA1FC0000,0x5D00000,0x2FFC0000,0x7FF80000,0xB8000001,0x7FF80000,0x1AC0001,0x87FC0000,0xC5F80000,0xD6000000,0x87FC0000,0xC5F80000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0x87FC0000,0xC5F80000,0xD6000000,0xC5F80000,0xD6000000, -0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0x87FC0000,0xC5F80000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0xC5F80000,0xD6000000,0xD6000000,0xD6000000,0xD6000000,0x3DFC0000,0xDC80000,0xDC80000,0x9DFC0000,0xBDF80000,0xCDF80000,0xD6000000,0xD6000000,0x6BFC0000,0xABFC0000,0xD5DC0000,0xD6000000, -0xB5FC0000,0x1580F1E,0xFF4407E9,0xF33C05ED,0xD73C05ED,0xFF300542,0xFB2801C5,0xDB2C0286,0xE324034A,0xD52001BD,0xC924034A,0xFF240716,0xFF080155,0xDD18020F,0xE90001B6,0xD5080006,0xC90C01BE,0xD70405EB,0xCEFC020D,0xC2FC028A,0xBB0405EB,0x7FC0F1A,0xFEE40611,0xD70805EA,0xFCB8034A,0xD8E001B2,0xC8EC034A,0xEEA005EB,0xD6B00153,0xC6C001C3,0xBAD005EA,0x85FC0F1A, -0xD65805EA,0xC83C034A,0xBA2005EA,0xAC000F1A,0xFF4408FE,0xFF4C0CEA,0xF5580D89,0xFF2C03A6,0xFF10005D,0xEB080004,0xD9100025,0xD3040023,0xFF340886,0xFF180302,0xDAF80159,0xC6C001C3,0x65FC0F1A,0x17405ED,0xFF60020D,0xEB5C0154,0xD7580154,0xFF5001FD,0xF1400002,0xD7480029,0xDB4001A5,0xD13C004C,0xC94001A5,0x31FC05EA,0xFD0C0153,0xD7300152,0xEEF401A5,0xD5080005, -0xC91801A5,0x9BF805EA,0xD6AC0152,0xC89801A5,0xBA0005EA,0x31FC05EA,0xFD0C0153,0xD7300152,0xEEF401A5,0xD5080005,0xC91801A5,0x9BF805EA,0xD6AC0152,0xC89801A5,0xBA0005EA,0x9BF805EA,0xD6AC0152,0xC89801A5,0xBA0005EA,0xBA0005EA,0xFF5803C9,0xFF6C04F5,0xFF6C0504,0xFF4001AA,0xFF18003B,0xEB080003,0xD7180001,0xD4F0000C,0xFF5403C9,0xFF2C017D,0xDCEC0152,0xC89801A5, -0x7FFC05EA,0x13C05ED,0x13C05ED,0x13C05ED,0x13C05ED,0xFF2401B5,0xFF2401B5,0xFF2401B5,0xCD2401A5,0xCD2401A5,0xB92401A6,0xFD080155,0xFD080155,0xFD080155,0xD5080002,0xD5080002,0xBB10004B,0xC1080153,0xC1080153,0xB504002A,0xAD040153,0x1D805EA,0x1D805EA,0x1D805EA,0xE0D401A5,0xE0D401A5,0xB8FC01A6,0xD2BC0153,0xD2BC0153,0xBAD00001,0xACDC0152,0x71F805EA, -0x71F805EA,0xB87C01A6,0xAC580152,0x9E0005EA,0xFF2C032B,0xF53804C1,0x13C05ED,0xFF1C0141,0xFF0C0013,0xE9080002,0xE108000B,0xCD040002,0xFF2002F9,0xFF100109,0xD6FC0153,0xBAD00001,0x4BFC05EA,0x1580154,0x1580154,0x1580154,0x1580154,0xEF400000,0xEF400000,0xEF400000,0xC7400000,0xC7400000,0xB9400001,0x7FC0152,0x7FC0152,0x7FC0152,0xD1100001,0xD1100001, -0xB9280001,0x85FC0152,0x85FC0152,0xB8D80001,0xAC000152,0x7FC0152,0x7FC0152,0x7FC0152,0xD1100001,0xD1100001,0xB9280001,0x85FC0152,0x85FC0152,0xB8D80001,0xAC000152,0x85FC0152,0x85FC0152,0xB8D80001,0xAC000152,0xAC000152,0xF74800B5,0xF35400DD,0x1580154,0xFD300055,0xFD140002,0xE70C0000,0xD9180000,0xCF000000,0xFF3400B9,0xFD200048,0x65FC0152,0xB8D80001, -0x65FC0152,0x19001A5,0xFF78001D,0xE5740000,0xD7740000,0x59FC01A5,0xF33C0000,0xD7580000,0xADFC01A5,0xD6FC0000,0xC80001A5,0x59FC01A5,0xF33C0000,0xD7580000,0xADFC01A5,0xD6FC0000,0xC80001A5,0xADFC01A5,0xD6FC0000,0xC80001A5,0xC80001A5,0x59FC01A5,0xF33C0000,0xD7580000,0xADFC01A5,0xD6FC0000,0xC80001A5,0xADFC01A5,0xD6FC0000,0xC80001A5,0xC80001A5,0xADFC01A5, -0xD6FC0000,0xC80001A5,0xC80001A5,0xC80001A5,0xFF780122,0x1AC01A5,0xFF8C0139,0xFF580091,0xFF240020,0xED000000,0xD7200000,0xD6D00000,0xFF700120,0xFF40007D,0xDB280000,0xC80001A5,0x99FC01A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0x12401A5,0xD9080001,0xD9080001,0xD9080001,0xD9080001,0xD9080001, -0xD9080001,0xAD080001,0xAD080001,0xAD080001,0x9F040002,0x1B001A5,0x1B001A5,0x1B001A5,0x1B001A5,0x1B001A5,0x1B001A5,0xBAD00000,0xBAD00000,0xBAD00000,0x9EEC0001,0x5DF401A5,0x5DF401A5,0x5DF401A5,0x9E940001,0x900001A5,0xF71C00F2,0x12401A5,0x12401A5,0xFF10004A,0xFD08000A,0xED080001,0xED080001,0xC9080001,0xFD0C00B5,0xFF00003D,0xBD000001,0xBAD00000, -0x31FC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table118[] = { -0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x53FC0000, -0x53FC0000,0x53FC0000,0x53FC0000,0x8A000000,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1140001,0x1280000,0x1280000,0x1280000,0x19C0000,0x25FC0000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000, -0x1F40000,0x7FF80000,0x7FF80000,0x7FF80000,0xA6000001,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x1F40000,0x7FF80000,0x7FF80000,0x7FF80000,0xA6000001,0x7FF80000,0x7FF80000,0x7FF80000,0xA6000001,0xA6000001,0xB640000,0x1500000,0x1500000,0x7840000,0x1A40000,0x1C80000,0x1C80000,0x2BFC0000,0x7840000,0x1A40000,0x5DF80000,0x7FF80000, -0x5DF80000,0x1840000,0x1840000,0x1840000,0x1840000,0x47FC0000,0x47FC0000,0x47FC0000,0xA5F80000,0xA5F80000,0xC0000001,0x47FC0000,0x47FC0000,0x47FC0000,0xA5F80000,0xA5F80000,0xC0000001,0xA5F80000,0xA5F80000,0xC0000001,0xC0000001,0x47FC0000,0x47FC0000,0x47FC0000,0xA5F80000,0xA5F80000,0xC0000001,0xA5F80000,0xA5F80000,0xC0000001,0xC0000001,0xA5F80000, -0xA5F80000,0xC0000001,0xC0000001,0xC0000001,0x1C40000,0x79C0000,0x1840000,0x1BFC0000,0x6BFC0000,0x8DFC0000,0x99FC0000,0xADF80000,0x5E40000,0x47FC0000,0x8DFC0000,0xC0000001,0x8DFC0000,0x1BC0001,0x9FFC0000,0xD1F80000,0xDE000000,0x9FFC0000,0xD1F80000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0x9FFC0000,0xD1F80000,0xDE000000,0xD1F80000,0xDE000000, -0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0x9FFC0000,0xD1F80000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0xD1F80000,0xDE000000,0xDE000000,0xDE000000,0xDE000000,0x63FC0000,0x1DC0000,0x1DC0000,0xB1FC0000,0xC9FC0000,0xD7F80000,0xDE000000,0xDE000000,0x89FC0000,0xBBFC0000,0xDDEC0000,0xDE000000, -0xC3FC0000,0x1680F1E,0xFF5C0861,0xFB4C05ED,0xDF4C05ED,0xFF4405BA,0xFF3801D5,0xE33C0286,0xEB34034A,0xDD3001BD,0xD134034A,0xFF300786,0xFF1C017C,0xE528020F,0xF11001B6,0xDD180006,0xD11C01BE,0xDF1405EB,0xD70C020D,0xCB0C028A,0xC31405EB,0x1FFC0F1A,0xFEFC0651,0xDF1805EA,0xFED4035A,0xE0F001B2,0xD0FC034A,0xF6B005EB,0xDEC00153,0xCED001C3,0xC2E005EA,0x91FC0F1A, -0xDE6805EA,0xD04C034A,0xC23005EA,0xB4000F1A,0xFF58097A,0xFB640D0E,0xFD680D89,0xFF400463,0xFF2400D1,0xF3180004,0xE1200025,0xDB140023,0xFF440933,0xFF3003D3,0xE3080159,0xCED001C3,0x75FC0F1A,0x18405ED,0xFF740248,0xF36C0154,0xDF680154,0xFF5C0239,0xF9500002,0xDF580029,0xE35001A5,0xD94C004C,0xD15001A5,0x49FC05EA,0xFF280163,0xDF400152,0xF70401A5,0xDD180005, -0xD12801A5,0xA7F805EA,0xDEBC0152,0xD0A801A5,0xC20005EA,0x49FC05EA,0xFF280163,0xDF400152,0xF70401A5,0xDD180005,0xD12801A5,0xA7F805EA,0xDEBC0152,0xD0A801A5,0xC20005EA,0xA7F805EA,0xDEBC0152,0xD0A801A5,0xC20005EA,0xC20005EA,0xFD7403F6,0xF980051D,0xFB840515,0xFF540209,0xFF30007D,0xF3180003,0xDF280001,0xDD00000C,0xFF5C040A,0xFF4801C4,0xE4FC0152,0xD0A801A5, -0x8FFC05EA,0x14C05ED,0x14C05ED,0x14C05ED,0x14C05ED,0xFD3801D5,0xFD3801D5,0xFD3801D5,0xD53401A5,0xD53401A5,0xC13401A6,0xFF1C0163,0xFF1C0163,0xFF1C0163,0xDD180002,0xDD180002,0xC320004B,0xC9180153,0xC9180153,0xBD14002A,0xB5140153,0x1F005EA,0x1F005EA,0x1F005EA,0xE8E401A5,0xE8E401A5,0xC10C01A6,0xDACC0153,0xDACC0153,0xC2E00001,0xB4EC0152,0x7DF805EA, -0x7DF805EA,0xC08C01A6,0xB4680152,0xA60005EA,0xFF3C035D,0xFD4804C1,0x14C05ED,0xFF2C0182,0xFF200033,0xF1180002,0xE918000B,0xD5140002,0xFF340322,0xFF1C014E,0xDF0C0153,0xC2E00001,0x5BFC05EA,0x1680154,0x1680154,0x1680154,0x1680154,0xF7500000,0xF7500000,0xF7500000,0xCF500000,0xCF500000,0xC1500001,0x1FFC0152,0x1FFC0152,0x1FFC0152,0xD9200001,0xD9200001, -0xC1380001,0x91FC0152,0x91FC0152,0xC0E80001,0xB4000152,0x1FFC0152,0x1FFC0152,0x1FFC0152,0xD9200001,0xD9200001,0xC1380001,0x91FC0152,0x91FC0152,0xC0E80001,0xB4000152,0x91FC0152,0x91FC0152,0xC0E80001,0xB4000152,0xB4000152,0xFF5800B5,0xFB6400DD,0x1680154,0xFF440062,0xFD28000A,0xEF1C0000,0xE1280000,0xD7100000,0xFD4C00C8,0xFF300059,0x75FC0152,0xC0E80001, -0x75FC0152,0x1A001A5,0xFF8C0034,0xED840000,0xDF840000,0x71FC01A5,0xFB4C0000,0xDF680000,0xB9FC01A5,0xDF0C0000,0xD00001A5,0x71FC01A5,0xFB4C0000,0xDF680000,0xB9FC01A5,0xDF0C0000,0xD00001A5,0xB9FC01A5,0xDF0C0000,0xD00001A5,0xD00001A5,0x71FC01A5,0xFB4C0000,0xDF680000,0xB9FC01A5,0xDF0C0000,0xD00001A5,0xB9FC01A5,0xDF0C0000,0xD00001A5,0xD00001A5,0xB9FC01A5, -0xDF0C0000,0xD00001A5,0xD00001A5,0xD00001A5,0xFD900139,0x1BC01A5,0xF79C0154,0xFF6C00AA,0xFF3C003A,0xF5100000,0xDF300000,0xDEE00000,0xF7880139,0xFF6400A2,0xE3380000,0xD00001A5,0xA7FC01A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0x13401A5,0xE1180001,0xE1180001,0xE1180001,0xE1180001,0xE1180001, -0xE1180001,0xB5180001,0xB5180001,0xB5180001,0xA7140002,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0xC2E00000,0xC2E00000,0xC2E00000,0xA6FC0001,0x67FC01A5,0x67FC01A5,0x67FC01A5,0xA6A40001,0x980001A5,0xFF2C00F2,0x13401A5,0x13401A5,0xFF200059,0xFD1C0012,0xF5180001,0xF5180001,0xD1180001,0xFD1C00C8,0xFF140048,0xC5100001,0xC2E00000, -0x3FFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table119[] = { -0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x5FF80000, -0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x5380000,0x5380000,0x5380000,0x1B40000,0x35FC0000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0x1600000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000, -0xFFC0000,0x8BF80000,0x8BF80000,0x8BF80000,0xAE000001,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0xFFC0000,0x8BF80000,0x8BF80000,0x8BF80000,0xAE000001,0x8BF80000,0x8BF80000,0x8BF80000,0xAE000001,0xAE000001,0x1780000,0x1600000,0x1600000,0x3980000,0x1B80000,0x3DC0000,0x3DC0000,0x3DFC0000,0x3980000,0x1B80000,0x6BFC0000,0x8BF80000, -0x6BFC0000,0x1940000,0x1940000,0x1940000,0x1940000,0x5FFC0000,0x5FFC0000,0x5FFC0000,0xB1F80000,0xB1F80000,0xC8000001,0x5FFC0000,0x5FFC0000,0x5FFC0000,0xB1F80000,0xB1F80000,0xC8000001,0xB1F80000,0xB1F80000,0xC8000001,0xC8000001,0x5FFC0000,0x5FFC0000,0x5FFC0000,0xB1F80000,0xB1F80000,0xC8000001,0xB1F80000,0xB1F80000,0xC8000001,0xC8000001,0xB1F80000, -0xB1F80000,0xC8000001,0xC8000001,0xC8000001,0x3D40000,0xFAC0000,0x1940000,0x39FC0000,0x7DFC0000,0x9DF80000,0xA7F80000,0xB7FC0000,0x5F80000,0x5FFC0000,0x9DF80000,0xC8000001,0x9DF80000,0x1CC0001,0xB7FC0000,0xDDF40000,0xE6000000,0xB7FC0000,0xDDF40000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xB7FC0000,0xDDF40000,0xE6000000,0xDDF40000,0xE6000000, -0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0xB7FC0000,0xDDF40000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0xE6000000,0x8BFC0000,0x1EC0000,0x1EC0000,0xC5FC0000,0xD7FC0000,0xE1FC0000,0xE6000000,0xE6000000,0xA7FC0000,0xCDFC0000,0xE5FC0000,0xE6000000, -0xD3FC0000,0x1780F1E,0xFF6808D9,0xFF6005F1,0xE75C05ED,0xFF5C0662,0xFF480215,0xEB4C0286,0xF344034A,0xE54001BD,0xD944034A,0xFF4407F7,0xFF3401DC,0xED38020F,0xF92001B6,0xE5280006,0xD92C01BE,0xE72405EB,0xDF1C020D,0xD31C028A,0xCB2405EB,0x37FC0F1A,0xFF1406B1,0xE72805EA,0xFEF00392,0xE90001B2,0xD90C034A,0xFEC005EB,0xE6D00153,0xD6E001C3,0xCAF005EA,0x9DFC0F1A, -0xE67805EA,0xD85C034A,0xCA4005EA,0xBC000F1A,0xFF6409F4,0xFF6C0D5E,0xF5780DD6,0xFF54052A,0xFF380175,0xFB280004,0xE9300025,0xE3240023,0xFF5C09AA,0xFF40048F,0xEB180159,0xD6E001C3,0x83FC0F1A,0x19405ED,0xFF8402A5,0xFB7C0154,0xE7780154,0xFF740279,0xFF600004,0xE7680029,0xEB6001A5,0xE15C004C,0xD96001A5,0x63FC05EA,0xFF40018B,0xE7500152,0xFF1401A5,0xE5280005, -0xD93801A5,0xB3F805EA,0xE6CC0152,0xD8B801A5,0xCA0005EA,0x63FC05EA,0xFF40018B,0xE7500152,0xFF1401A5,0xE5280005,0xD93801A5,0xB3F805EA,0xE6CC0152,0xD8B801A5,0xCA0005EA,0xB3F805EA,0xE6CC0152,0xD8B801A5,0xCA0005EA,0xCA0005EA,0xFF800435,0xFF8C052D,0xFF8C053D,0xFF6C026A,0xFF4800CE,0xFB280003,0xE7380001,0xE510000C,0xFF78042A,0xFF5C022E,0xED0C0152,0xD8B801A5, -0x9FF805EA,0x15C05ED,0x15C05ED,0x15C05ED,0x15C05ED,0xFF4801F1,0xFF4801F1,0xFF4801F1,0xDD4401A5,0xDD4401A5,0xC94401A6,0xFF30017D,0xFF30017D,0xFF30017D,0xE5280002,0xE5280002,0xCB30004B,0xD1280153,0xD1280153,0xC524002A,0xBD240153,0xDFC05EA,0xDFC05EA,0xDFC05EA,0xF0F401A5,0xF0F401A5,0xC91C01A6,0xE2DC0153,0xE2DC0153,0xCAF00001,0xBCFC0152,0x89F805EA, -0x89F805EA,0xC89C01A6,0xBC780152,0xAE0005EA,0xFF4C038A,0xF75C04EE,0x15C05ED,0xFF4401C3,0xFF300062,0xF9280002,0xF128000B,0xDD240002,0xFF3C0371,0xFF300182,0xE71C0153,0xCAF00001,0x69FC05EA,0x1780154,0x1780154,0x1780154,0x1780154,0xFF600000,0xFF600000,0xFF600000,0xD7600000,0xD7600000,0xC9600001,0x37FC0152,0x37FC0152,0x37FC0152,0xE1300001,0xE1300001, -0xC9480001,0x9DFC0152,0x9DFC0152,0xC8F80001,0xBC000152,0x37FC0152,0x37FC0152,0x37FC0152,0xE1300001,0xE1300001,0xC9480001,0x9DFC0152,0x9DFC0152,0xC8F80001,0xBC000152,0x9DFC0152,0x9DFC0152,0xC8F80001,0xBC000152,0xBC000152,0xFB6C00C8,0xF37400F4,0x1780154,0xFD580071,0xFF400012,0xF72C0000,0xE9380000,0xDF200000,0xF56400DD,0xFF480064,0x83FC0152,0xC8F80001, -0x83FC0152,0x1B001A5,0xFF9C0061,0xF5940000,0xE7940000,0x89FC01A5,0xFF640002,0xE7780000,0xC5FC01A5,0xE71C0000,0xD80001A5,0x89FC01A5,0xFF640002,0xE7780000,0xC5FC01A5,0xE71C0000,0xD80001A5,0xC5FC01A5,0xE71C0000,0xD80001A5,0xD80001A5,0x89FC01A5,0xFF640002,0xE7780000,0xC5FC01A5,0xE71C0000,0xD80001A5,0xC5FC01A5,0xE71C0000,0xD80001A5,0xD80001A5,0xC5FC01A5, -0xE71C0000,0xD80001A5,0xD80001A5,0xD80001A5,0xF7A40152,0x1CC01A5,0xFFAC0154,0xFF8400D0,0xFF640062,0xFD200000,0xE7400000,0xE6F00000,0xFF980139,0xFD8000C8,0xEB480000,0xD80001A5,0xB7FC01A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0x14401A5,0xE9280001,0xE9280001,0xE9280001,0xE9280001,0xE9280001, -0xE9280001,0xBD280001,0xBD280001,0xBD280001,0xAF240002,0x1E001A5,0x1E001A5,0x1E001A5,0x1E001A5,0x1E001A5,0x1E001A5,0xCAF00000,0xCAF00000,0xCAF00000,0xAF0C0001,0x73FC01A5,0x73FC01A5,0x73FC01A5,0xAEB40001,0xA00001A5,0xF73C0109,0x14401A5,0x14401A5,0xFB340071,0xFB2C0022,0xFD280001,0xFD280001,0xD9280001,0xF93000DD,0xFF200061,0xCD200001,0xCAF00000, -0x4FFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table120[] = { -0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x6DF80000, -0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x14C0000,0x14C0000,0x14C0000,0x1D00000,0x45FC0000,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x1700001,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000, -0x2BFC0000,0x97FC0000,0x97FC0000,0x97FC0000,0xB8000000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x2BFC0000,0x97FC0000,0x97FC0000,0x97FC0000,0xB8000000,0x97FC0000,0x97FC0000,0x97FC0000,0xB8000000,0xB8000000,0xD880000,0x1700001,0x1700001,0x5AC0000,0x1D00000,0x1F80000,0x1F80000,0x53FC0000,0x5AC0000,0x1D00000,0x7DF80000,0x97FC0000, -0x7DF80000,0x1A40001,0x1A40001,0x1A40001,0x1A40001,0x7BFC0000,0x7BFC0000,0x7BFC0000,0xBFF80000,0xBFF80000,0xD2000000,0x7BFC0000,0x7BFC0000,0x7BFC0000,0xBFF80000,0xBFF80000,0xD2000000,0xBFF80000,0xBFF80000,0xD2000000,0xD2000000,0x7BFC0000,0x7BFC0000,0x7BFC0000,0xBFF80000,0xBFF80000,0xD2000000,0xBFF80000,0xBFF80000,0xD2000000,0xD2000000,0xBFF80000, -0xBFF80000,0xD2000000,0xD2000000,0xD2000000,0x7E80000,0x9C00000,0x1A40001,0x5BFC0000,0x93FC0000,0xADFC0000,0xB5FC0000,0xC3FC0000,0x29FC0000,0x7BFC0000,0xADFC0000,0xD2000000,0xADFC0000,0x1E00000,0xD3FC0000,0xE9FC0000,0xEE000001,0xD3FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xD3FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xEE000001, -0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0xD3FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0xEE000001,0xB7FC0000,0x17FC0000,0x17FC0000,0xDBFC0000,0xE7F80000,0xEDF40000,0xEE000001,0xEE000001,0xC9FC0000,0xE1FC0000,0xEFF00000,0xEE000001, -0xE3FC0000,0x18C0F1A,0xFF800983,0xFF70062A,0xEF7005EB,0xFF680746,0xFF6002AB,0xF35C028A,0xFD54034A,0xED5401BE,0xE154034A,0xFF5C0899,0xFF4C028C,0xF548020D,0xFF3801BA,0xEF380006,0xE33C01BD,0xEF3805EA,0xE72C020F,0xDD300286,0xD33805ED,0x53FC0F1A,0xFF38073B,0xF13805EB,0xFF140416,0xF11001B6,0xE120034A,0xFEE40615,0xEEE40154,0xDEF001C5,0xD50005ED,0xABF80F1A, -0xEE8C05EB,0xE070034A,0xD25405ED,0xC4000F1E,0xFF780A99,0xFD880D72,0xFD880DDA,0xFF6C0649,0xFF500261,0xFF3C001F,0xF1400023,0xEB340025,0xFF700A53,0xFF54059A,0xF52C015B,0xDEF001C5,0x95FC0F1A,0x1A805EA,0xFF980303,0xFF8C0162,0xEF8C0153,0xFF8C02DE,0xFF78003B,0xF17C002A,0xF57001A6,0xEB70004B,0xE17001A6,0x7DFC05EA,0xFF5801E4,0xEF640153,0xFF3801BA,0xEF3C0002, -0xE14C01A5,0xBFFC05EA,0xEEE40153,0xE0CC01A5,0xD20005ED,0x7DFC05EA,0xFF5801E4,0xEF640153,0xFF3801BA,0xEF3C0002,0xE14C01A5,0xBFFC05EA,0xEEE40153,0xE0CC01A5,0xD20005ED,0xBFFC05EA,0xEEE40153,0xE0CC01A5,0xD20005ED,0xD20005ED,0xFF94046D,0xFBA4054E,0xFBA4054B,0xFF8002E8,0xFF680146,0xFF400011,0xF14C0002,0xEF24000B,0xFD940481,0xFF7402C9,0xF71C0152,0xE0CC01A5, -0xAFFC05EA,0x17005EA,0x17005EA,0x17005EA,0x17005EA,0xFF5C0221,0xFF5C0221,0xFF5C0221,0xE75401A5,0xE75401A5,0xD35401A5,0xFF4401A8,0xFF4401A8,0xFF4401A8,0xED380005,0xED380005,0xD544004C,0xDB380152,0xDB380152,0xCF380029,0xC5380154,0x29FC05EA,0x29FC05EA,0x29FC05EA,0xF90801A5,0xF90801A5,0xD32C01A5,0xECEC0153,0xECEC0153,0xD3000002,0xC5100154,0x97F805EA, -0x97F805EA,0xD2AC01A5,0xC4900154,0xB60005ED,0xFD6403CC,0xFF6C04ED,0x17005EA,0xFF540211,0xFF4400AD,0xFF3C0006,0xFB3C000C,0xE7380001,0xFF58039E,0xFD4C01E2,0xF12C0152,0xD3000002,0x7BFC05EA,0x18C0152,0x18C0152,0x18C0152,0x18C0152,0xFF740005,0xFF740005,0xFF740005,0xDF740001,0xDF740001,0xD3700001,0x53FC0152,0x53FC0152,0x53FC0152,0xE9440001,0xE9440001, -0xD3580000,0xABF80152,0xABF80152,0xD3080000,0xC4000154,0x53FC0152,0x53FC0152,0x53FC0152,0xE9440001,0xE9440001,0xD3580000,0xABF80152,0xABF80152,0xD3080000,0xC4000154,0xABF80152,0xABF80152,0xD3080000,0xC4000154,0xC4000154,0xF78000DD,0xFD8800F2,0x18C0152,0xFB700091,0xFF540028,0xFF400001,0xF3480000,0xE7340000,0xFD7400DD,0xFF5C007D,0x95FC0152,0xD3080000, -0x95FC0152,0x1C401A5,0xFFB00092,0xFDA80001,0xEFA40002,0xA5FC01A5,0xFF880020,0xEF8C0001,0xD3FC01A5,0xEF340001,0xE00001A5,0xA5FC01A5,0xFF880020,0xEF8C0001,0xD3FC01A5,0xEF340001,0xE00001A5,0xD3FC01A5,0xEF340001,0xE00001A5,0xE00001A5,0xA5FC01A5,0xFF880020,0xEF8C0001,0xD3FC01A5,0xEF340001,0xE00001A5,0xD3FC01A5,0xEF340001,0xE00001A5,0xE00001A5,0xD3FC01A5, -0xEF340001,0xE00001A5,0xE00001A5,0xE00001A5,0xFFB40154,0x1E001A5,0xF9C0016D,0xFFA000FA,0xFF7C0092,0xFF48000A,0xEF540001,0xEF080001,0xFFAC015A,0xFF9400E9,0xF5580000,0xE00001A5,0xC7FC01A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0x15401A5,0xF3380000,0xF3380000,0xF3380000,0xF3380000,0xF3380000, -0xF3380000,0xC7380000,0xC7380000,0xC7380000,0xB9380000,0x1F801A5,0x1F801A5,0x1F801A5,0x1F801A5,0x1F801A5,0x1F801A5,0xD5000000,0xD5000000,0xD5000000,0xB91C0000,0x81FC01A5,0x81FC01A5,0x81FC01A5,0xB8C00000,0xAA0001A5,0xFF4C010D,0x15401A5,0x15401A5,0xFD480080,0xFD400034,0xFF3C0005,0xFF3C0005,0xE3380000,0xFF3C00E9,0xFF3C0071,0xD7300000,0xD5000000, -0x5FFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table121[] = { -0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0x79F80000, -0x79F80000,0x79F80000,0x79F80000,0xA2000001,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x1480000,0x75C0000,0x75C0000,0x75C0000,0x1E80000,0x55FC0000,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x1800001,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000, -0x43FC0000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0x43FC0000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xC0000000,0xC0000000,0x19C0000,0x1800001,0x1800001,0x1C00000,0x1E40000,0x17FC0000,0x17FC0000,0x67FC0000,0x1C00000,0x1E40000,0x8BFC0000,0xA3FC0000, -0x8BFC0000,0x1B40001,0x1B40001,0x1B40001,0x1B40001,0x93FC0000,0x93FC0000,0x93FC0000,0xCBF80000,0xCBF80000,0xDA000000,0x93FC0000,0x93FC0000,0x93FC0000,0xCBF80000,0xCBF80000,0xDA000000,0xCBF80000,0xCBF80000,0xDA000000,0xDA000000,0x93FC0000,0x93FC0000,0x93FC0000,0xCBF80000,0xCBF80000,0xDA000000,0xCBF80000,0xCBF80000,0xDA000000,0xDA000000,0xCBF80000, -0xCBF80000,0xDA000000,0xDA000000,0xDA000000,0x3FC0000,0x1D40000,0x1B40001,0x79FC0000,0xA7FC0000,0xBDF80000,0xC3FC0000,0xCFF80000,0x51FC0000,0x93FC0000,0xBDF80000,0xDA000000,0xBDF80000,0x1F00000,0xEBFC0000,0xF5FC0000,0xF6000001,0xEBFC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xEBFC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF6000001, -0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xEBFC0000,0xF5FC0000,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xF5FC0000,0xF6000001,0xF6000001,0xF6000001,0xF6000001,0xDFFC0000,0x97FC0000,0x97FC0000,0xEFFC0000,0xF5F80000,0xF7F40000,0xF6000001,0xF6000001,0xE7FC0000,0xF1FC0000,0xF9C40000,0xF6000001, -0xF3FC0000,0x19C0F1A,0xFF8C0A17,0xFF84069F,0xF78005EB,0xFF8007FE,0xFF700371,0xFB6C028A,0xFF640362,0xF56401BE,0xE964034A,0xFF740939,0xFF60036B,0xFD58020D,0xFF4C021D,0xF7480006,0xEB4C01BD,0xF74805EA,0xEF3C020F,0xE5400286,0xDB4805ED,0x6BFC0F1A,0xFF4C07E9,0xF94805EB,0xFF2C04BE,0xF92001B6,0xE930034A,0xFF080675,0xF6F40154,0xE70001C5,0xDD1005ED,0xB7F80F1A, -0xF69C05EB,0xE880034A,0xDA6405ED,0xCC000F1E,0xFF8C0B22,0xF5980DDA,0xF79C0E27,0xFF800738,0xFF680366,0xFF540098,0xF9500023,0xF3440025,0xFF800AF5,0xFF7006AA,0xFD3C015B,0xE70001C5,0xA3FC0F1A,0x1B805EA,0xFFA8037E,0xFFA0019A,0xF79C0153,0xFF980356,0xFF8800A9,0xF98C002A,0xFD8001A6,0xF380004B,0xE98001A6,0x95FC05EA,0xFF7C0248,0xF7740153,0xFF580205,0xF74C0002, -0xE95C01A5,0xCBFC05EA,0xF6F40153,0xE8DC01A5,0xDA0005ED,0x95FC05EA,0xFF7C0248,0xF7740153,0xFF580205,0xF74C0002,0xE95C01A5,0xCBFC05EA,0xF6F40153,0xE8DC01A5,0xDA0005ED,0xCBFC05EA,0xF6F40153,0xE8DC01A5,0xDA0005ED,0xDA0005ED,0xFBAC04B5,0xFFAC057E,0xF5B8057E,0xFF940349,0xFF7C01D6,0xFF5C005E,0xF95C0002,0xF734000B,0xFFA404B5,0xFF900329,0xFF2C0152,0xE8DC01A5, -0xBFF805EA,0x18005EA,0x18005EA,0x18005EA,0x18005EA,0xFF6C0266,0xFF6C0266,0xFF6C0266,0xEF6401A5,0xEF6401A5,0xDB6401A5,0xFF5C01E8,0xFF5C01E8,0xFF5C01E8,0xF5480005,0xF5480005,0xDD54004C,0xE3480152,0xE3480152,0xD7480029,0xCD480154,0x41FC05EA,0x41FC05EA,0x41FC05EA,0xFF1C01A6,0xFF1C01A6,0xDB3C01A5,0xF4FC0153,0xF4FC0153,0xDB100002,0xCD200154,0xA1FC05EA, -0xA1FC05EA,0xDABC01A5,0xCCA00154,0xBE0005ED,0xFF7403FE,0xF77C051E,0x18005EA,0xFF68026D,0xFF5800F9,0xFF50002D,0xFF4C000D,0xEF480001,0xFF6403EA,0xFF5C022E,0xF93C0152,0xDB100002,0x89FC05EA,0x19C0152,0x19C0152,0x19C0152,0x19C0152,0xFD880019,0xFD880019,0xFD880019,0xE7840001,0xE7840001,0xDB800001,0x6BFC0152,0x6BFC0152,0x6BFC0152,0xF1540001,0xF1540001, -0xDB680000,0xB7F80152,0xB7F80152,0xDB180000,0xCC000154,0x6BFC0152,0x6BFC0152,0x6BFC0152,0xF1540001,0xF1540001,0xDB680000,0xB7F80152,0xB7F80152,0xDB180000,0xCC000154,0xB7F80152,0xB7F80152,0xDB180000,0xCC000154,0xCC000154,0xFF9000DD,0xF5980109,0x19C0152,0xFD8400A2,0xFF70003D,0xFF58000A,0xFB580000,0xEF440000,0xFD8800F2,0xFF740095,0xA3FC0152,0xDB180000, -0xA3FC0152,0x1D401A5,0xFFC400C1,0xFFB80011,0xF7B40002,0xBDFC01A5,0xFFA00050,0xF79C0001,0xDFF801A5,0xF7440001,0xE80001A5,0xBDFC01A5,0xFFA00050,0xF79C0001,0xDFF801A5,0xF7440001,0xE80001A5,0xDFF801A5,0xF7440001,0xE80001A5,0xE80001A5,0xBDFC01A5,0xFFA00050,0xF79C0001,0xDFF801A5,0xF7440001,0xE80001A5,0xDFF801A5,0xF7440001,0xE80001A5,0xE80001A5,0xDFF801A5, -0xF7440001,0xE80001A5,0xE80001A5,0xE80001A5,0xFDCC016D,0x1F001A5,0xFFCC0179,0xFDBC0122,0xFFA800C8,0xFF70003A,0xF7640001,0xF7180001,0xF7CC016D,0xFFB80120,0xFD680000,0xE80001A5,0xD7FC01A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0x16401A5,0xFB480000,0xFB480000,0xFB480000,0xFB480000,0xFB480000, -0xFB480000,0xCF480000,0xCF480000,0xCF480000,0xC1480000,0x15FC01A5,0x15FC01A5,0x15FC01A5,0x15FC01A5,0x15FC01A5,0x15FC01A5,0xDD100000,0xDD100000,0xDD100000,0xC12C0000,0x8DFC01A5,0x8DFC01A5,0x8DFC01A5,0xC0D00000,0xB20001A5,0xF9600120,0x16401A5,0x16401A5,0xFF580091,0xFF500041,0xFF4C000D,0xFF4C000D,0xEB480000,0xFD5400F2,0xFD4C0082,0xDF400000,0xDD100000, -0x6FFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table122[] = { -0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x3FC0000,0x85F80000, -0x85F80000,0x85F80000,0x85F80000,0xAA000001,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0xF6C0000,0xF6C0000,0xF6C0000,0x3FC0000,0x63FC0000,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x1900001,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000, -0x5BFC0000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xC8000000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0x5BFC0000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xC8000000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xC8000000,0xC8000000,0x1AC0000,0x1900001,0x1900001,0x1D40000,0x1F80000,0x35FC0000,0x35FC0000,0x7BFC0000,0x1D40000,0x1F80000,0x9BFC0000,0xAFFC0000, -0x9BFC0000,0x1C40001,0x1C40001,0x1C40001,0x1C40001,0xABFC0000,0xABFC0000,0xABFC0000,0xD7F80000,0xD7F80000,0xE2000000,0xABFC0000,0xABFC0000,0xABFC0000,0xD7F80000,0xD7F80000,0xE2000000,0xD7F80000,0xD7F80000,0xE2000000,0xE2000000,0xABFC0000,0xABFC0000,0xABFC0000,0xD7F80000,0xD7F80000,0xE2000000,0xD7F80000,0xD7F80000,0xE2000000,0xE2000000,0xD7F80000, -0xD7F80000,0xE2000000,0xE2000000,0xE2000000,0x3BFC0000,0x1E40000,0x1C40001,0x97FC0000,0xBBFC0000,0xCBFC0000,0xD1FC0000,0xD9FC0000,0x77FC0000,0xABFC0000,0xCBFC0000,0xE2000000,0xCBFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1AC0EC7,0xFF9C0A97,0xFF940717,0xFF9005EA,0xFF9808B1,0xFF84044E,0xFF8002A5,0xFF7C03A7,0xFD7401B9,0xF174032D,0xFF8C09AC,0xFF700455,0xFF680234,0xFF6402A2,0xFF580005,0xF35C01A4,0xFF5805B3,0xF74C01FE,0xED500261,0xE35805B4,0x83FC0EC7,0xFF640876,0xFF5805ED,0xFF4C057F,0xFF3801B9,0xF140032D,0xFF2C06C8,0xFF040153,0xEF1001A4,0xE32005B5,0xC3F80EC7, -0xFEAC05EA,0xF090032D,0xE27405B4,0xD4000EC9,0xFFA00B5D,0xFDA80D89,0xFDA80DDA,0xFF8807F3,0xFF7C0465,0xFF680153,0xFF600030,0xFB54001C,0xFF980B2F,0xFF800755,0xFF50016C,0xEF1001A4,0xB3FC0EC7,0x1C805B3,0xFFBC03B6,0xFFAC01FB,0xFFAC0152,0xFFB00389,0xFFA00122,0xFF98002D,0xFF94019B,0xFB900042,0xF1900189,0xAFFC05B3,0xFF9402A5,0xFF840152,0xFF70024E,0xFF5C0001, -0xF16C0188,0xD7FC05B3,0xFF040152,0xF0EC0188,0xE20005B4,0xAFFC05B3,0xFF9402A5,0xFF840152,0xFF70024E,0xFF5C0001,0xF16C0188,0xD7FC05B3,0xFF040152,0xF0EC0188,0xE20005B4,0xD7FC05B3,0xFF040152,0xF0EC0188,0xE20005B4,0xE20005B4,0xFFBC04B5,0xFBC4054B,0xFBC4054B,0xFFB003A2,0xFF900261,0xFF7C00D1,0xFF6C0004,0xFD480009,0xFFB404BE,0xFFA40388,0xFF50016B,0xF0EC0188, -0xCDFC05B3,0x19005EA,0x19005EA,0x19005EA,0x19005EA,0xFF8002A5,0xFF8002A5,0xFF8002A5,0xF77401A5,0xF77401A5,0xE37401A5,0xFF680234,0xFF680234,0xFF680234,0xFD580005,0xFD580005,0xE564004C,0xEB580152,0xEB580152,0xDF580029,0xD5580154,0x59FC05EA,0x59FC05EA,0x59FC05EA,0xFF3801B9,0xFF3801B9,0xE34C01A5,0xFD0C0153,0xFD0C0153,0xE3200002,0xD5300154,0xADFC05EA, -0xADFC05EA,0xE2CC01A5,0xD4B00154,0xC60005ED,0xFF84042D,0xFF8C051E,0x19005EA,0xFF7802C9,0xFF6C0155,0xFF64006D,0xFF600030,0xF7580001,0xFF780411,0xFF740289,0xFF500153,0xE3200002,0x99FC05EA,0x1AC0152,0x1AC0152,0x1AC0152,0x1AC0152,0xFF98002D,0xFF98002D,0xFF98002D,0xEF940001,0xEF940001,0xE3900001,0x83FC0152,0x83FC0152,0x83FC0152,0xF9640001,0xF9640001, -0xE3780000,0xC3F80152,0xC3F80152,0xE3280000,0xD4000154,0x83FC0152,0x83FC0152,0x83FC0152,0xF9640001,0xF9640001,0xE3780000,0xC3F80152,0xC3F80152,0xE3280000,0xD4000154,0xC3F80152,0xC3F80152,0xE3280000,0xD4000154,0xD4000154,0xFFA000F4,0xFDA80109,0x1AC0152,0xFF9800B5,0xFF840059,0xFF740019,0xFF6C0004,0xF7540000,0xFF940104,0xFB9000B5,0xB3FC0152,0xE3280000, -0xB3FC0152,0x1E0018A,0xFFDC00F2,0xFFCC0049,0xFFC40001,0xD5FC0188,0xFFB80089,0xFFAC0000,0xEBF80188,0xFF540000,0xF0000188,0xD5FC0188,0xFFB80089,0xFFAC0000,0xEBF80188,0xFF540000,0xF0000188,0xEBF80188,0xFF540000,0xF0000188,0xF0000188,0xD5FC0188,0xFFB80089,0xFFAC0000,0xEBF80188,0xFF540000,0xF0000188,0xEBF80188,0xFF540000,0xF0000188,0xF0000188,0xEBF80188, -0xFF540000,0xF0000188,0xF0000188,0xF0000188,0xF3E0016D,0x27FC0188,0xF9E0016D,0xFDD40139,0xFFBC00E9,0xFF980074,0xFF740000,0xFF280000,0xFDD80154,0xFFCC0122,0xFF90000D,0xF0000188,0xE5FC0188,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0x17401A5,0xFD580004,0xFD580004,0xFD580004,0xFD580004,0xFD580004, -0xFD580004,0xD7580000,0xD7580000,0xD7580000,0xC9580000,0x2FFC01A5,0x2FFC01A5,0x2FFC01A5,0x2FFC01A5,0x2FFC01A5,0x2FFC01A5,0xE5200000,0xE5200000,0xE5200000,0xC93C0000,0x99FC01A5,0x99FC01A5,0x99FC01A5,0xC8E00000,0xBA0001A5,0xFF6C0128,0x17401A5,0x17401A5,0xFF6800A4,0xFF640055,0xFF5C001D,0xFF5C001D,0xF3580000,0xF9680109,0xFD6000A2,0xE7500000,0xE5200000, -0x7FF801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table123[] = { -0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x91F80000, -0x91F80000,0x91F80000,0x91F80000,0xB2000001,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1800000,0x1800000,0x1800000,0x1BFC0000,0x73FC0000,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x1A00001,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000, -0x75FC0000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xD0000000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0x75FC0000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xD0000000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xD0000000,0xD0000000,0x7BC0000,0x1A00001,0x1A00001,0x5E40000,0x1FFC0000,0x53FC0000,0x53FC0000,0x8FFC0000,0x5E40000,0x1FFC0000,0xA9FC0000,0xBBFC0000, -0xA9FC0000,0x1D40001,0x1D40001,0x1D40001,0x1D40001,0xC3FC0000,0xC3FC0000,0xC3FC0000,0xE1FC0000,0xE1FC0000,0xEA000000,0xC3FC0000,0xC3FC0000,0xC3FC0000,0xE1FC0000,0xE1FC0000,0xEA000000,0xE1FC0000,0xE1FC0000,0xEA000000,0xEA000000,0xC3FC0000,0xC3FC0000,0xC3FC0000,0xE1FC0000,0xE1FC0000,0xEA000000,0xE1FC0000,0xE1FC0000,0xEA000000,0xEA000000,0xE1FC0000, -0xE1FC0000,0xEA000000,0xEA000000,0xEA000000,0x75FC0000,0x3F40000,0x1D40001,0xB5FC0000,0xCFFC0000,0xDBFC0000,0xDFF80000,0xE5F40000,0x9FFC0000,0xC3FC0000,0xDBFC0000,0xEA000000,0xDBFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1B80C63,0xFFB0094E,0xFFA006CB,0xFFA005EA,0xFFA4076D,0xFF940436,0xFF8C0301,0xFF880313,0xFF8401A5,0xF584026D,0xFF980818,0xFF88041D,0xFF800284,0xFF7C0222,0xFF6C001D,0xF56C00F0,0xFF6C0438,0xFB600192,0xF1640165,0xE9680428,0x95FC0C63,0xFF7C07BE,0xFF7005ED,0xFF6404BF,0xFF4C01F6,0xF554026D,0xFF380594,0xFF280163,0xF32400D8,0xE9340428,0xCBFC0C63, -0xFEE005EA,0xF4B4026D,0xE88C0428,0xDA000C65,0xFFA809C9,0xFFAC0B85,0xF5B80BDB,0xFF9806E9,0xFF8C041A,0xFF7C0175,0xFF78007A,0xFF680001,0xFFA409B3,0xFF90067F,0xFF640186,0xF32400D8,0xBFF80C63,0x1D0042B,0xFFC402DB,0xFFC001BE,0xFFBC0152,0xFFC4028B,0xFFB400FA,0xFFB00055,0xFFA800F1,0xFDA0000E,0xF5A000C9,0xBDFC0428,0xFFAC022D,0xFF9C0152,0xFF88018E,0xFF780005, -0xF58000C8,0xDFF80428,0xFF340152,0xF50C00C8,0xE8000428,0xBDFC0428,0xFFAC022D,0xFF9C0152,0xFF88018E,0xFF780005,0xF58000C8,0xDFF80428,0xFF340152,0xF50C00C8,0xE8000428,0xDFF80428,0xFF340152,0xF50C00C8,0xE8000428,0xE8000428,0xFDCC0378,0xFFCC03D3,0xFFCC03E3,0xFFC002B6,0xFFA801D5,0xFF9000C1,0xFF880019,0xFF640000,0xFFC4037B,0xFDBC02B6,0xFF700162,0xF50C00C8, -0xD7FC0428,0x1A005EA,0x1A005EA,0x1A005EA,0x1A005EA,0xFF8C0301,0xFF8C0301,0xFF8C0301,0xFF8401A5,0xFF8401A5,0xEB8401A5,0xFF800284,0xFF800284,0xFF800284,0xFF6C001D,0xFF6C001D,0xED74004C,0xF3680152,0xF3680152,0xE7680029,0xDD680154,0x71FC05EA,0x71FC05EA,0x71FC05EA,0xFF4C01F6,0xFF4C01F6,0xEB5C01A5,0xFF280163,0xFF280163,0xEB300002,0xDD400154,0xB9FC05EA, -0xB9FC05EA,0xEADC01A5,0xDCC00154,0xCE0005ED,0xFB980484,0xF79C0551,0x1A005EA,0xFF900321,0xFF8001C1,0xFF7800C2,0xFF78007A,0xFF680001,0xFF900452,0xFF8002F4,0xFF64016D,0xEB300002,0xA7FC05EA,0x1BC0152,0x1BC0152,0x1BC0152,0x1BC0152,0xFFB00055,0xFFB00055,0xFFB00055,0xF7A40001,0xF7A40001,0xEBA00001,0x9BFC0152,0x9BFC0152,0x9BFC0152,0xFF780005,0xFF780005, -0xEB880000,0xCFF80152,0xCFF80152,0xEB380000,0xDC000154,0x9BFC0152,0x9BFC0152,0x9BFC0152,0xFF780005,0xFF780005,0xEB880000,0xCFF80152,0xCFF80152,0xEB380000,0xDC000154,0xCFF80152,0xCFF80152,0xEB380000,0xDC000154,0xDC000154,0xFBB40109,0xF5B80122,0x1BC0152,0xFFA400DA,0xFF98007D,0xFF8C0041,0xFF880019,0xFF640000,0xFDB00109,0xFFA400C8,0xC1FC0152,0xEB380000, -0xC1FC0152,0x1E800CA,0xFFE0007D,0xFFD80025,0xFFD40001,0xE3FC00C8,0xFFCC0049,0xFFC00001,0xF1F800C8,0xFF840000,0xF40000C8,0xE3FC00C8,0xFFCC0049,0xFFC00001,0xF1F800C8,0xFF840000,0xF40000C8,0xF1F800C8,0xFF840000,0xF40000C8,0xF40000C8,0xE3FC00C8,0xFFCC0049,0xFFC00001,0xF1F800C8,0xFF840000,0xF40000C8,0xF1F800C8,0xFF840000,0xF40000C8,0xF40000C8,0xF1F800C8, -0xFF840000,0xF40000C8,0xF40000C8,0xF40000C8,0xF7E800B5,0x67FC00C8,0xFDE800B5,0xFFD8009D,0xFFD00075,0xFFC0003D,0xFF9C0000,0xFF640000,0xFFDC00B4,0xFFD80095,0xFFB00008,0xF40000C8,0xEDFC00C8,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0x18401A5,0xFF6C000D,0xFF6C000D,0xFF6C000D,0xFF6C000D,0xFF6C000D, -0xFF6C000D,0xDF680000,0xDF680000,0xDF680000,0xD1680000,0x47FC01A5,0x47FC01A5,0x47FC01A5,0x47FC01A5,0x47FC01A5,0x47FC01A5,0xED300000,0xED300000,0xED300000,0xD14C0000,0xA5F801A5,0xA5F801A5,0xA5F801A5,0xD0F00000,0xC20001A5,0xF9800139,0x18401A5,0x18401A5,0xFB7C00C8,0xFF780071,0xFF700034,0xFF700034,0xFB680000,0xFF74010D,0xFD7400B5,0xEF600000,0xED300000, -0x8DFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table124[] = { -0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000, -0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1940000,0x1940000,0x1940000,0x37FC0000,0x83FC0000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000, -0x8FFC0000,0xC9F80000,0xC9F80000,0xC9F80000,0xD8000001,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0x8FFC0000,0xC9F80000,0xC9F80000,0xC9F80000,0xD8000001,0xC9F80000,0xC9F80000,0xC9F80000,0xD8000001,0xD8000001,0x1D00000,0x1B40000,0x1B40000,0x1FC0000,0x4BFC0000,0x75FC0000,0x75FC0000,0xA5FC0000,0x1FC0000,0x4BFC0000,0xBBFC0000,0xC9F80000, -0xBBFC0000,0x1E80000,0x1E80000,0x1E80000,0x1E80000,0xDFFC0000,0xDFFC0000,0xDFFC0000,0xEFFC0000,0xEFFC0000,0xF2000001,0xDFFC0000,0xDFFC0000,0xDFFC0000,0xEFFC0000,0xEFFC0000,0xF2000001,0xEFFC0000,0xEFFC0000,0xF2000001,0xF2000001,0xDFFC0000,0xDFFC0000,0xDFFC0000,0xEFFC0000,0xEFFC0000,0xF2000001,0xEFFC0000,0xEFFC0000,0xF2000001,0xF2000001,0xEFFC0000, -0xEFFC0000,0xF2000001,0xF2000001,0xF2000001,0xB5FC0000,0x57FC0000,0x1E80000,0xD7FC0000,0xE5FC0000,0xEBFC0000,0xEDFC0000,0xF1F80000,0xCBFC0000,0xDFFC0000,0xEBFC0000,0xF2000001,0xEBFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1C40A26,0xFFBC0819,0xFFB4067D,0xFFB005ED,0xFFB00662,0xFFA8043D,0xFFA40362,0xFFA002BE,0xFF9801C9,0xF99801E2,0xFFA406D7,0xFF9C0415,0xFF9802FB,0xFF8801E3,0xFF84007A,0xFB840073,0xFF84031B,0xFD780159,0xF77000A2,0xEF7802D3,0xA9FC0A26,0xFF940717,0xFF8C05EA,0xFF7C0432,0xFF70024D,0xF96801E2,0xFF640489,0xFF4C01A8,0xF93C003F,0xEF4802D2,0xD5F80A26, -0xFF1405EA,0xF8D801E2,0xEEAC02D2,0xE2000A26,0xFFBC082A,0xFBC40972,0xFBC409B6,0xFFAC061E,0xFFA003F3,0xFF9001DC,0xFF8C00FA,0xFF7C0029,0xFFB407F7,0xFFA405EA,0xFF7C01C3,0xF93C003F,0xC9FC0A26,0x1DC02D5,0xFFD40228,0xFFCC0194,0xFFCC0154,0xFFD001B5,0xFFC400E4,0xFFC40080,0xFFB8007D,0xFFB40001,0xF9B4003D,0xCFFC02D2,0xFFC001C8,0xFFB80152,0xFFAC00FE,0xFF940025, -0xF994003E,0xE7FC02D2,0xFF6C0152,0xF934003D,0xEE0002D2,0xCFFC02D2,0xFFC001C8,0xFFB80152,0xFFAC00FE,0xFF940025,0xF994003E,0xE7FC02D2,0xFF6C0152,0xF934003D,0xEE0002D2,0xE7FC02D2,0xFF6C0152,0xF934003D,0xEE0002D2,0xEE0002D2,0xFFD80263,0xF7DC02A9,0xF7DC02B4,0xFDD00209,0xFFC0016A,0xFFAC00B1,0xFFA8003D,0xFF8C0019,0xFDD8026D,0xFFC801D6,0xFF98015B,0xF934003D, -0xE1FC02D2,0x1B005ED,0x1B005ED,0x1B005ED,0x1B005ED,0xFFA40362,0xFFA40362,0xFFA40362,0xFF9801C9,0xFF9801C9,0xF39801A6,0xFF9802FB,0xFF9802FB,0xFF9802FB,0xFF84007A,0xFF84007A,0xF584004B,0xFB7C0153,0xFB7C0153,0xEF78002A,0xE7780153,0x8DFC05EA,0x8DFC05EA,0x8DFC05EA,0xFF70024D,0xFF70024D,0xF37001A6,0xFF4C01A8,0xFF4C01A8,0xF5440001,0xE7500152,0xC7FC05EA, -0xC7FC05EA,0xF2F001A6,0xE6CC0152,0xD80005EA,0xFFAC04B2,0xFFAC055A,0x1B005ED,0xFFA403A1,0xFF940252,0xFF900163,0xFF8C00FA,0xFF7C0029,0xFFA00491,0xFF980365,0xFF7C01B3,0xF5440001,0xB9FC05EA,0x1CC0154,0x1CC0154,0x1CC0154,0x1CC0154,0xFFC40080,0xFFC40080,0xFFC40080,0xFFB40001,0xFFB40001,0xF3B40001,0xB7FC0152,0xB7FC0152,0xB7FC0152,0xFF940025,0xFF940025, -0xF39C0001,0xDDF40152,0xDDF40152,0xF34C0001,0xE6000152,0xB7FC0152,0xB7FC0152,0xB7FC0152,0xFF940025,0xFF940025,0xF39C0001,0xDDF40152,0xDDF40152,0xF34C0001,0xE6000152,0xDDF40152,0xDDF40152,0xF34C0001,0xE6000152,0xE6000152,0xFDC80120,0xFFCC0120,0x1CC0154,0xFDC000F4,0xFFB000B4,0xFFA8006A,0xFFA8003D,0xFF8C0019,0xFFC40120,0xFBC000F2,0xD3FC0152,0xF34C0001, -0xD3FC0152,0x1F4003D,0xFFEC0028,0xFFEC000D,0xFFE80000,0xEFFC003D,0xFFE40014,0xFFDC0000,0xF7F8003D,0xFFB80000,0xF800003D,0xEFFC003D,0xFFE40014,0xFFDC0000,0xF7F8003D,0xFFB80000,0xF800003D,0xF7F8003D,0xFFB80000,0xF800003D,0xF800003D,0xEFFC003D,0xFFE40014,0xFFDC0000,0xF7F8003D,0xFFB80000,0xF800003D,0xF7F8003D,0xFFB80000,0xF800003D,0xF800003D,0xF7F8003D, -0xFFB80000,0xF800003D,0xF800003D,0xF800003D,0xFBF00034,0xA7FC003D,0xF3F4003D,0xFFEC0029,0xFFE80020,0xFFD40011,0xFFC80000,0xFFA80000,0xFFF00032,0xFFEC0032,0xFFD00001,0xF800003D,0xF5FC003D,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0x19801A5,0xFF800022,0xFF800022,0xFF800022,0xFF800022,0xFF800022, -0xFF800022,0xE77C0001,0xE77C0001,0xE77C0001,0xD9780002,0x63FC01A5,0x63FC01A5,0x63FC01A5,0x63FC01A5,0x63FC01A5,0x63FC01A5,0xF5440000,0xF5440000,0xF5440000,0xD9600001,0xB3F801A5,0xB3F801A5,0xB3F801A5,0xD9080001,0xCA0001A5,0xFF8C0151,0x19801A5,0x19801A5,0xFF9000DD,0xFF8C0091,0xFF880055,0xFF880055,0xFD7C0005,0xFD8C0120,0xFF8000DA,0xF7740001,0xF5440000, -0x9FF801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table125[] = { -0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0xA9FC0000, -0xA9FC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1880001,0x1A40000,0x1A40000,0x1A40000,0x4FFC0000,0x93FC0000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0x1C40000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000, -0xA9FC0000,0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xA9FC0000,0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0xD5F80000,0xD5F80000,0xD5F80000,0xE0000001,0xE0000001,0x9E00000,0x1C40000,0x1C40000,0x35FC0000,0x73FC0000,0x93FC0000,0x93FC0000,0xB9FC0000,0x35FC0000,0x73FC0000,0xC9FC0000,0xD5F80000, -0xC9FC0000,0x1F80000,0x1F80000,0x1F80000,0x1F80000,0xF7FC0000,0xF7FC0000,0xF7FC0000,0xFBFC0000,0xFBFC0000,0xFA000001,0xF7FC0000,0xF7FC0000,0xF7FC0000,0xFBFC0000,0xFBFC0000,0xFA000001,0xFBFC0000,0xFBFC0000,0xFA000001,0xFA000001,0xF7FC0000,0xF7FC0000,0xF7FC0000,0xFBFC0000,0xFBFC0000,0xFA000001,0xFBFC0000,0xFBFC0000,0xFA000001,0xFA000001,0xFBFC0000, -0xFBFC0000,0xFA000001,0xFA000001,0xFA000001,0xEDFC0000,0xD7FC0000,0x1F80000,0xF5FC0000,0xF9FC0000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xF3FC0000,0xF7FC0000,0xFBFC0000,0xFA000001,0xFBFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1D0088E,0xFFC80749,0xFFC00651,0xFFC005ED,0xFFC405B2,0xFFBC0463,0xFFB403DD,0xFFAC02BE,0xFFAC0215,0xFDA801AA,0xFFBC05EF,0xFFB0042C,0xFFA40383,0xFFA001F3,0xFF9C010A,0xFD94004F,0xFF94028E,0xFF900163,0xFB84003E,0xF58801FF,0xBBFC088E,0xFFAC069F,0xFFA405EA,0xFF9403FA,0xFF8802BD,0xFD7C01AA,0xFF7C0401,0xFF640218,0xFD540005,0xF55C01FE,0xDDFC088E, -0xFF4805EA,0xFCF801AA,0xF4C401FE,0xE800088E,0xFFCC0739,0xFFCC07F2,0xFFCC0846,0xFFC005B1,0xFFB003FD,0xFFA4024E,0xFFA4019A,0xFF940096,0xFFC4071A,0xFFB40585,0xFF94023D,0xFD540005,0xD5FC088E,0x1E801FD,0xFDE401B5,0xFFE0016D,0xFFDC0154,0xFFDC0149,0xFFD400EA,0xFFD000B4,0xFFCC0069,0xFFC80028,0xFDC40005,0xDFFC01FD,0xFFD80188,0xFFCC0154,0xFFB800D2,0xFFB80059, -0xFDA80006,0xEFFC01FD,0xFF9C0152,0xFD540005,0xF40001FE,0xDFFC01FD,0xFFD80188,0xFFCC0154,0xFFB800D2,0xFFB80059,0xFDA80006,0xEFFC01FD,0xFF9C0152,0xFD540005,0xF40001FE,0xEFFC01FD,0xFF9C0152,0xFD540005,0xF40001FE,0xF40001FE,0xFFE401C5,0xFDE801D9,0xFDE801E8,0xFFDC0179,0xFFD40132,0xFFC800CE,0xFFBC007D,0xFFA80049,0xFFE001CA,0xFFDC0172,0xFFB80156,0xFD540005, -0xEBFC01FD,0x1C005ED,0x1C005ED,0x1C005ED,0x1C005ED,0xFFB403DD,0xFFB403DD,0xFFB403DD,0xFFAC0215,0xFFAC0215,0xFBA801A6,0xFFA40383,0xFFA40383,0xFFA40383,0xFF9C010A,0xFF9C010A,0xFD94004B,0xFF900163,0xFF900163,0xF788002A,0xEF880153,0xA5FC05EA,0xA5FC05EA,0xA5FC05EA,0xFF8802BD,0xFF8802BD,0xFB8001A6,0xFF640218,0xFF640218,0xFD540001,0xEF600152,0xD3FC05EA, -0xD3FC05EA,0xFB0001A6,0xEEDC0152,0xE00005EA,0xFFBC04E6,0xF9C00581,0x1C005ED,0xFFB40402,0xFFAC02EA,0xFFA401FD,0xFFA4019A,0xFF940096,0xFFB404BE,0xFFB003CE,0xFF940234,0xFD540001,0xC7FC05EA,0x1DC0154,0x1DC0154,0x1DC0154,0x1DC0154,0xFFD000B4,0xFFD000B4,0xFFD000B4,0xFFC80028,0xFFC80028,0xFBC40001,0xCFFC0152,0xCFFC0152,0xCFFC0152,0xFFB80059,0xFFB80059, -0xFBAC0001,0xE7FC0152,0xE7FC0152,0xFB5C0001,0xEE000152,0xCFFC0152,0xCFFC0152,0xCFFC0152,0xFFB80059,0xFFB80059,0xFBAC0001,0xE7FC0152,0xE7FC0152,0xFB5C0001,0xEE000152,0xE7FC0152,0xE7FC0152,0xFB5C0001,0xEE000152,0xEE000152,0xFFD80122,0xF7DC0139,0x1DC0154,0xFDD80109,0xFFC800DA,0xFFBC00A9,0xFFBC007D,0xFFA80049,0xFFD00132,0xFBD40109,0xE1FC0152,0xFB5C0001, -0xE1FC0152,0x1FC0005,0xFFF80004,0xFFF80001,0xFFF80000,0xFBFC0005,0xFFF80002,0xFFF40000,0xFDF80005,0xFFEC0000,0xFC000005,0xFBFC0005,0xFFF80002,0xFFF40000,0xFDF80005,0xFFEC0000,0xFC000005,0xFDF80005,0xFFEC0000,0xFC000005,0xFC000005,0xFBFC0005,0xFFF80002,0xFFF40000,0xFDF80005,0xFFEC0000,0xFC000005,0xFDF80005,0xFFEC0000,0xFC000005,0xFC000005,0xFDF80005, -0xFFEC0000,0xFC000005,0xFC000005,0xFC000005,0xFFF80004,0xE7FC0005,0xF7FC0005,0xFBFC0005,0xFFF80002,0xFFF00001,0xFFF00000,0xFFE40000,0xF9FC0005,0xFBFC0005,0xFFF00000,0xFC000005,0xFDF80005,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0x1A801A5,0xFF900049,0xFF900049,0xFF900049,0xFF900049,0xFF900049, -0xFF900049,0xEF8C0001,0xEF8C0001,0xEF8C0001,0xE1880002,0x7BFC01A5,0x7BFC01A5,0x7BFC01A5,0x7BFC01A5,0x7BFC01A5,0x7BFC01A5,0xFD540000,0xFD540000,0xFD540000,0xE1700001,0xBFF801A5,0xBFF801A5,0xBFF801A5,0xE1180001,0xD20001A5,0xFBA40152,0x1A801A5,0x1A801A5,0xFFA000F2,0xFD9C00B5,0xFF980071,0xFF980071,0xFD900019,0xFD9C0139,0xFF9400E9,0xFF840001,0xFD540000, -0xADFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table126[] = { -0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0x69FC0000,0xB5FC0000, -0xB5FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x1980001,0x3B40000,0x3B40000,0x3B40000,0x69FC0000,0xA1FC0000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0x1D40000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000, -0xC1FC0000,0xE1F80000,0xE1F80000,0xE1F80000,0xE8000001,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xE1F80000,0xE1F80000,0xE1F80000,0xE8000001,0xE1F80000,0xE1F80000,0xE1F80000,0xE8000001,0xE8000001,0x1F40000,0x1D40000,0x1D40000,0x6DFC0000,0x9BFC0000,0xB1FC0000,0xB1FC0000,0xCDFC0000,0x6DFC0000,0x9BFC0000,0xD9FC0000,0xE1F80000, -0xD9FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1DC0693,0xFFD405C6,0xFFD0052E,0xFFD004EE,0xFFD0049F,0xFFC403C6,0xFFC40362,0xFFC00295,0xFFB8021E,0xFFB801A5,0xFFC4048F,0xFFBC037F,0xFFBC0306,0xFFAC01D4,0xFFAC012B,0xFFA4006A,0xFFAC01E3,0xFFA0010E,0xFF980011,0xF798012A,0xC9FC0691,0xFFB80566,0xFFB804ED,0xFFAC0367,0xFFA0029E,0xFF9401A5,0xFF940316,0xFF8801D1,0xFF700008,0xF7700129,0xE5F80691, -0xFF6C04ED,0xFF2001A5,0xF6EC0129,0xEC000691,0xFFD805AB,0xF5D8064D,0xF5D80672,0xFFCC0496,0xFFC00366,0xFFB8022B,0xFFB401AE,0xFFA800C3,0xFFD00576,0xFFC4045F,0xFFB001FA,0xFF700008,0xDFF80691,0x1F00126,0xFFEC0105,0xFFEC00EA,0xFFE800DD,0xFFE800C6,0xFFE000A1,0xFFE00088,0xFFD8004C,0xFFD80028,0xFFD40000,0xEBFC0126,0xFFE400F1,0xFFDC00DD,0xFFD80088,0xFFCC0050, -0xFFC00000,0xF5FC0126,0xFFB800DD,0xFF7C0000,0xF6000129,0xEBFC0126,0xFFE400F1,0xFFDC00DD,0xFFD80088,0xFFCC0050,0xFFC00000,0xF5FC0126,0xFFB800DD,0xFF7C0000,0xF6000129,0xF5FC0126,0xFFB800DD,0xFF7C0000,0xF6000129,0xF6000129,0xFDF0010C,0xFFEC0110,0xFFEC0121,0xFFEC00F3,0xFFDC00C6,0xFFD80092,0xFFD00061,0xFFC00049,0xFFEC010B,0xFFE800E5,0xFFD000DE,0xFF7C0000, -0xF3FC0126,0x1D004EE,0x1D004EE,0x1D004EE,0x1D004EE,0xFFC40362,0xFFC40362,0xFFC40362,0xFFB8021E,0xFFB8021E,0xFFB801A5,0xFFBC0306,0xFFBC0306,0xFFBC0306,0xFFAC012B,0xFFAC012B,0xFFA4006A,0xFFA0010E,0xFFA0010E,0xFD98000E,0xF59800DE,0xB7FC04ED,0xB7FC04ED,0xB7FC04ED,0xFFA0029E,0xFFA0029E,0xFF9401A5,0xFF8801D1,0xFF8801D1,0xFF700008,0xF57400DD,0xDDF404ED, -0xDDF404ED,0xFF2001A5,0xF4F400DD,0xE60004ED,0xFFCC042E,0xFFCC0492,0x1D004EE,0xFFC40382,0xFFC002BD,0xFFB401EE,0xFFB401AE,0xFFA800C3,0xFBC8042D,0xFFBC0366,0xFFA801F5,0xFF700008,0xD3FC04ED,0x1E800DD,0x1E800DD,0x1E800DD,0x1E800DD,0xFFE00088,0xFFE00088,0xFFE00088,0xFFD80028,0xFFD80028,0xFFD40000,0xDFFC00DD,0xDFFC00DD,0xDFFC00DD,0xFFCC0050,0xFFCC0050, -0xFFC00000,0xEFFC00DD,0xEFFC00DD,0xFF7C0000,0xF40000DD,0xDFFC00DD,0xDFFC00DD,0xDFFC00DD,0xFFCC0050,0xFFCC0050,0xFFC00000,0xEFFC00DD,0xEFFC00DD,0xFF7C0000,0xF40000DD,0xEFFC00DD,0xEFFC00DD,0xFF7C0000,0xF40000DD,0xF40000DD,0xF9E800C8,0xFDE800C8,0x1E800DD,0xFFDC00B4,0xFFDC0095,0xFFD80082,0xFFD00061,0xFFC00049,0xF7E800C8,0xFFDC00AA,0xEBFC00DD,0xFF7C0000, -0xEBFC00DD,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0x1B801A5,0xFFA4006A,0xFFA4006A,0xFFA4006A,0xFFA4006A,0xFFA4006A, -0xFFA4006A,0xF79C0001,0xF79C0001,0xF79C0001,0xE9980002,0x93FC01A5,0x93FC01A5,0x93FC01A5,0x93FC01A5,0x93FC01A5,0x93FC01A5,0xFF700008,0xFF700008,0xFF700008,0xE9800001,0xCBF801A5,0xCBF801A5,0xCBF801A5,0xE9280001,0xDA0001A5,0xF3B4016D,0x1B801A5,0x1B801A5,0xFFAC0115,0xFFA800DA,0xFFAC00A2,0xFFAC00A2,0xFFA0003A,0xF9B00152,0xFBAC0109,0xFF98000D,0xFF700008, -0xBDF801A5,}; -static const uint32_t g_etc1_to_bc7_m6_table127[] = { -0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0xC1FC0000, -0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0xBC40000,0xBC40000,0xBC40000,0x81FC0000,0xB1FC0000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000, -0xD9FC0000,0xEDF80000,0xEDF80000,0xEDF80000,0xF0000001,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xEDF80000,0xEDF80000,0xEDF80000,0xF0000001,0xEDF80000,0xEDF80000,0xEDF80000,0xF0000001,0xF0000001,0x37FC0000,0x1E40000,0x1E40000,0xA7FC0000,0xC1FC0000,0xCFFC0000,0xCFFC0000,0xE1FC0000,0xA7FC0000,0xC1FC0000,0xE7FC0000,0xEDF80000, -0xE7FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1E4049B,0xFFDC041B,0xFFD803C2,0xFFD8039E,0xFFDC0373,0xFFD002EE,0xFFD002AE,0xFFCC0231,0xFFCC01F1,0xFFC801A5,0xFFD0032F,0xFFD0028E,0xFFC40236,0xFFC00181,0xFFBC011B,0xFFBC00A2,0xFFB80127,0xFFAC00AA,0xFFAC0001,0xFBA80072,0xD5FC0499,0xFFCC03E2,0xFFC8039D,0xFFB802AF,0xFFB80236,0xFFAC01A5,0xFFAC0216,0xFFA00149,0xFF880028,0xFB840071,0xEBF80499, -0xFF90039D,0xFF5401A5,0xFB0C0071,0xF0000499,0xFFD8040B,0xF9E00465,0xF9E00482,0xFFD40343,0xFFCC0297,0xFFC401D1,0xFFBC0173,0xFFB800C2,0xFFD803EE,0xFFD0031A,0xFFB8015E,0xFF880028,0xE5FC0499,0x1F40072,0xFFF40062,0xFFF00059,0xFFF00055,0xFFF40052,0xFFEC003D,0xFFEC0034,0xFFE40020,0xFFE40010,0xFFE40000,0xF5FC0071,0xFFF0005D,0xFFE80055,0xFFE40030,0xFFE40020, -0xFFD80000,0xF9FC0071,0xFFD40055,0xFFAC0000,0xFA000071,0xF5FC0071,0xFFF0005D,0xFFE80055,0xFFE40030,0xFFE40020,0xFFD80000,0xF9FC0071,0xFFD40055,0xFFAC0000,0xFA000071,0xF9FC0071,0xFFD40055,0xFFAC0000,0xFA000071,0xFA000071,0xFFF40060,0xF3F40072,0xF3F40072,0xFFF0005A,0xFFF0004A,0xFFE40036,0xFFE40022,0xFFD8001D,0xFDF40060,0xFFF0005A,0xFFE00056,0xFFAC0000, -0xF9FC0071,0x1D8039E,0x1D8039E,0x1D8039E,0x1D8039E,0xFFD002AE,0xFFD002AE,0xFFD002AE,0xFFCC01F1,0xFFCC01F1,0xFFC801A5,0xFFC40236,0xFFC40236,0xFFC40236,0xFFBC011B,0xFFBC011B,0xFFBC00A2,0xFFAC00AA,0xFFAC00AA,0xFFAC0001,0xF9A80056,0xC9FC039D,0xC9FC039D,0xC9FC039D,0xFFB80236,0xFFB80236,0xFFAC01A5,0xFFA00149,0xFFA00149,0xFF880028,0xF9880055,0xE5F8039D, -0xE5F8039D,0xFF5401A5,0xF9140055,0xEC00039D,0xFFD8032A,0xF5D80379,0x1D8039E,0xFFCC02A5,0xFFC4022E,0xFFBC01AB,0xFFBC0173,0xFFB800C2,0xFFD00305,0xFFD0028A,0xFFB8015A,0xFF880028,0xDFF8039D,0x1F00055,0x1F00055,0x1F00055,0x1F00055,0xFFEC0034,0xFFEC0034,0xFFEC0034,0xFFE40010,0xFFE40010,0xFFE40000,0xEBFC0055,0xEBFC0055,0xEBFC0055,0xFFE40020,0xFFE40020, -0xFFD80000,0xF5FC0055,0xF5FC0055,0xFFAC0000,0xF8000055,0xEBFC0055,0xEBFC0055,0xEBFC0055,0xFFE40020,0xFFE40020,0xFFD80000,0xF5FC0055,0xF5FC0055,0xFFAC0000,0xF8000055,0xF5FC0055,0xF5FC0055,0xFFAC0000,0xF8000055,0xF8000055,0xFDF00048,0xFFEC0050,0x1F00055,0xFBF00048,0xFDEC003D,0xFFE4002D,0xFFE40022,0xFFD8001D,0xFBF00048,0xFFE80041,0xF3FC0055,0xFFAC0000, -0xF3FC0055,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0x1C801A5,0xFFBC00A2,0xFFBC00A2,0xFFBC00A2,0xFFBC00A2,0xFFBC00A2, -0xFFBC00A2,0xFFAC0001,0xFFAC0001,0xFFAC0001,0xF1A80002,0xABFC01A5,0xABFC01A5,0xABFC01A5,0xABFC01A5,0xABFC01A5,0xABFC01A5,0xFF880028,0xFF880028,0xFF880028,0xF1900001,0xD7F801A5,0xD7F801A5,0xD7F801A5,0xF1380001,0xE20001A5,0xFBC4016D,0x1C801A5,0x1C801A5,0xFFBC0132,0xFFBC00FA,0xFFBC00CA,0xFFBC00CA,0xFFB4006A,0xFFBC015A,0xFFBC0122,0xFFB00032,0xFF880028, -0xCBFC01A5,}; -static const uint32_t g_etc1_to_bc7_m6_table128[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x240000,0x240000,0x240000,0x240000,0x340000,0x340000,0x340000,0x680000,0x680000,0x10000001,0x340000,0x340000,0x340000,0x680000,0x680000,0x10000001,0x680000,0x680000,0x10000001,0x10000001,0x340000,0x340000,0x340000,0x680000,0x680000,0x10000001,0x680000,0x680000,0x10000001,0x10000001,0x680000, -0x680000,0x10000001,0x10000001,0x10000001,0x2280000,0xA240000,0x240000,0x300000,0x3C0000,0x4C0000,0x540000,0x800000,0x2C0000,0x340000,0x4C0000,0x10000001,0x4C0000,0x780000,0x2B00000,0x1680000,0x3A000001,0x2B00000,0x1680000,0x3A000001,0x1680000,0x3A000001,0x3A000001,0x2B00000,0x1680000,0x3A000001,0x1680000,0x3A000001, -0x3A000001,0x1680000,0x3A000001,0x3A000001,0x3A000001,0x2B00000,0x1680000,0x3A000001,0x1680000,0x3A000001,0x3A000001,0x1680000,0x3A000001,0x3A000001,0x3A000001,0x1680000,0x3A000001,0x3A000001,0x3A000001,0x3A000001,0x2940000,0x800000,0x800000,0xC80000,0x1240000,0xBF40000,0x3A000001,0x3A000001,0xA40000,0xE00000,0x2FF00000,0x3A000001, -0xFC0000,0x280964,0xAA0C00D8,0x560C00D8,0x3A0C00D9,0x76000372,0x52000061,0x3A000002,0x38000374,0x32000151,0x26000372,0x4E000768,0x460002BA,0x34000153,0x340004A5,0x2E00024E,0x2400040A,0x26000768,0x2600049D,0x2000059E,0x1800076B,0x380964,0x3A000463,0x2E000274,0x2E000596,0x2800031F,0x22000484,0x220007ED,0x24000543,0x1C000607,0x180007AB,0x700964, -0x1C000694,0x1C00070C,0x16000864,0x12000964,0xE4000231,0xF41805B2,0xF820054D,0x74000239,0x4A000252,0x3C00023D,0x3000019B,0x2A000306,0x90000413,0x5E000317,0x2E0003AB,0x1C000607,0x500964,0x340768,0xA01400A4,0x541000A4,0x3A1000A5,0x76000372,0x52000061,0x3A000002,0x38000374,0x32000151,0x26000372,0x4C0768,0x460002BA,0x34000153,0x340004A5,0x2E00024E, -0x2400040A,0x980768,0x2600049D,0x2000059E,0x1800076B,0x4C0768,0x460002BA,0x34000153,0x340004A5,0x2E00024E,0x2400040A,0x980768,0x2600049D,0x2000059E,0x1800076B,0x980768,0x2600049D,0x2000059E,0x1800076B,0x1800076B,0xE4000231,0xF82004F2,0xFC280405,0x74000239,0x4A000252,0x3C00023D,0x3000019B,0x2A000306,0x900003C2,0x5E0002F3,0x2E0003A2,0x2000059E, -0x6C0768,0xC00D8,0xC00D8,0xC00D8,0xC00D8,0x36000000,0x36000000,0x36000000,0x1A000000,0x1A000000,0x10000001,0x1A0000A2,0x1A0000A2,0x1A0000A2,0x1200003D,0x1200003D,0xE000022,0xC0000A2,0xC0000A2,0xA000062,0x80000A2,0x1000D8,0x1000D8,0x1000D8,0x12000061,0x12000061,0xC000039,0xC0000B2,0xC0000B2,0xA000072,0x80000AB,0x2000D8, -0x2000D8,0xA000093,0x60000C3,0x40000DB,0x76000032,0xF8000004,0xC00D8,0x32000041,0x1E00003D,0x1A000041,0x16000034,0x12000050,0x3400006B,0x2600005D,0x100000A3,0xA000072,0x1800D8,0x1000A4,0x1000A4,0x1000A4,0x1000A4,0x36000000,0x36000000,0x36000000,0x1A000000,0x1A000000,0x10000001,0x21800A2,0x21800A2,0x21800A2,0x1200003D,0x1200003D, -0xE000022,0x3000A2,0x3000A2,0xA000062,0x80000A2,0x21800A2,0x21800A2,0x21800A2,0x1200003D,0x1200003D,0xE000022,0x3000A2,0x3000A2,0xA000062,0x80000A2,0x3000A2,0x3000A2,0xA000062,0x80000A2,0x80000A2,0x76000032,0xF8000004,0x1000A4,0x32000041,0x1E00003D,0x1A000041,0x16000034,0x12000050,0x42000061,0x26000059,0x2400A2,0xA000062, -0x2400A2,0x4C0374,0x90240000,0x50240000,0x3A240001,0x740372,0x52000061,0x3A000002,0xE80372,0x32000151,0x26000372,0x740372,0x52000061,0x3A000002,0xE80372,0x32000151,0x26000372,0xE80372,0x32000151,0x26000372,0x26000372,0x740372,0x52000061,0x3A000002,0xE80372,0x32000151,0x26000372,0xE80372,0x32000151,0x26000372,0x26000372,0xE80372, -0x32000151,0x26000372,0x26000372,0x26000372,0xF4000164,0x540372,0xF8400188,0x7C000132,0x56000161,0x3C00013D,0x340000DA,0x320001BA,0xB20001D4,0x68000179,0x360000B9,0x26000372,0xA40372,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table129[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x340000,0x340000,0x340000,0x340000,0x4C0000,0x4C0000,0x4C0000,0x980000,0x980000,0x18000001,0x4C0000,0x4C0000,0x4C0000,0x980000,0x980000,0x18000001,0x980000,0x980000,0x18000001,0x18000001,0x4C0000,0x4C0000,0x4C0000,0x980000,0x980000,0x18000001,0x980000,0x980000,0x18000001,0x18000001,0x980000, -0x980000,0x18000001,0x18000001,0x18000001,0x3C0000,0x380000,0x340000,0x2440000,0x2540000,0x6C0000,0x7C0000,0xBC0000,0x400000,0x4C0000,0x6C0000,0x18000001,0x6C0000,0x880000,0xC80000,0x1980000,0x42000001,0xC80000,0x1980000,0x42000001,0x1980000,0x42000001,0x42000001,0xC80000,0x1980000,0x42000001,0x1980000,0x42000001, -0x42000001,0x1980000,0x42000001,0x42000001,0x42000001,0xC80000,0x1980000,0x42000001,0x1980000,0x42000001,0x42000001,0x1980000,0x42000001,0x42000001,0x42000001,0x1980000,0x42000001,0x42000001,0x42000001,0x42000001,0x2A80000,0x900000,0x900000,0xE40000,0x14C0000,0x15F40000,0x42000001,0x42000001,0xB80000,0x1000000,0x39C40000,0x42000001, -0x1200000,0x300C14,0xBE1001C4,0x601001C4,0x421001C5,0x8E000372,0x62000025,0x4400000A,0x44000374,0x38000109,0x2E000372,0x5C000933,0x5200036A,0x400001DB,0x3A00053D,0x34000266,0x2E000453,0x2E000934,0x2C0005A5,0x26000696,0x1E000933,0x440C14,0x460005BB,0x3A000354,0x340006A6,0x34000387,0x2800050C,0x280009FD,0x2C000686,0x2400073B,0x1E000997,0x880C14, -0x26000891,0x200008C2,0x1C000AAC,0x16000C14,0xFE000264,0xF8200772,0xFC280785,0x8800025D,0x5A000281,0x44000266,0x3C000195,0x36000351,0xB20004DE,0x68000393,0x3600045B,0x2400073B,0x600C14,0x400934,0xB21C0154,0x5E180154,0x42180155,0x8E000372,0x62000025,0x44040009,0x44000374,0x38000109,0x2E000372,0x5C0933,0x5200036A,0x400001DB,0x3A00053D,0x34000266, -0x2E000453,0xB80933,0x2C0005A5,0x26000696,0x1E000933,0x5C0933,0x5200036A,0x400001DB,0x3A00053D,0x34000266,0x2E000453,0xB80933,0x2C0005A5,0x26000696,0x1E000933,0xB80933,0x2C0005A5,0x26000696,0x1E000933,0x1E000933,0xFE000264,0xFE2C061E,0xF23405B4,0x8800025D,0x5A000281,0x44000266,0x3C000195,0x36000351,0xB2000465,0x68000362,0x36000452,0x26000696, -0x800933,0x1001C4,0x1001C4,0x1001C4,0x1001C4,0x4E000000,0x4E000000,0x4E000000,0x26000000,0x26000000,0x18000001,0x26000152,0x26000152,0x26000152,0x1E00007D,0x1E00007D,0x18000041,0x12000152,0x12000152,0x100000CA,0xC000152,0x21801C3,0x21801C3,0x21801C3,0x180000D1,0x180000D1,0x12000079,0x12000176,0x12000176,0x100000EE,0xC000162,0x3001C3, -0x3001C3,0xE000141,0xA00018B,0x80001C3,0x9200006A,0xFC080044,0x1001C4,0x50000089,0x3200007D,0x2600007D,0x2200006A,0x1A00009D,0x560000E9,0x320000BE,0x16000155,0x100000EE,0x2401C3,0x180154,0x180154,0x180154,0x180154,0x4E000000,0x4E000000,0x4E000000,0x26000000,0x26000000,0x18000001,0x2240152,0x2240152,0x2240152,0x1E00007D,0x1E00007D, -0x18000041,0x4C0152,0x4C0152,0x100000CA,0xC000152,0x2240152,0x2240152,0x2240152,0x1E00007D,0x1E00007D,0x18000041,0x4C0152,0x4C0152,0x100000CA,0xC000152,0x4C0152,0x4C0152,0x100000CA,0xC000152,0xC000152,0x9200006A,0xFC080034,0x180154,0x50000089,0x3200007D,0x2600007D,0x2200006A,0x1A00009D,0x560000D0,0x3C0000B4,0x340152,0x100000CA, -0x340152,0x5C0374,0x98340000,0x58340000,0x42340001,0x8C0372,0x62000025,0x420C0001,0x1180372,0x38000109,0x2E000372,0x8C0372,0x62000025,0x420C0001,0x1180372,0x38000109,0x2E000372,0x1180372,0x38000109,0x2E000372,0x2E000372,0x8C0372,0x62000025,0x420C0001,0x1180372,0x38000109,0x2E000372,0x1180372,0x38000109,0x2E000372,0x2E000372,0x1180372, -0x38000109,0x2E000372,0x2E000372,0x2E000372,0xFC080152,0x640372,0xFE4C0190,0x920000E9,0x6000010D,0x4A000104,0x3E000092,0x3600016D,0xD0000190,0x7A000128,0x4200007D,0x2E000372,0xC80372,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table130[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x440000,0x440000,0x440000,0x440000,0x640000,0x640000,0x640000,0xCC0000,0xCC0000,0x20000001,0x640000,0x640000,0x640000,0xCC0000,0xCC0000,0x20000001,0xCC0000,0xCC0000,0x20000001,0x20000001,0x640000,0x640000,0x640000,0xCC0000,0xCC0000,0x20000001,0xCC0000,0xCC0000,0x20000001,0x20000001,0xCC0000, -0xCC0000,0x20000001,0x20000001,0x20000001,0x64C0000,0x480000,0x440000,0x5C0000,0x700000,0x900000,0xA40000,0xF80000,0x540000,0x640000,0x900000,0x20000001,0x900000,0x980000,0xE00000,0x1CC0000,0x4A000001,0xE00000,0x1CC0000,0x4A000001,0x1CC0000,0x4A000001,0x4A000001,0xE00000,0x1CC0000,0x4A000001,0x1CC0000,0x4A000001, -0x4A000001,0x1CC0000,0x4A000001,0x4A000001,0x4A000001,0xE00000,0x1CC0000,0x4A000001,0x1CC0000,0x4A000001,0x4A000001,0x1CC0000,0x4A000001,0x4A000001,0x4A000001,0x1CC0000,0x4A000001,0x4A000001,0x4A000001,0x4A000001,0x2BC0000,0x8A00000,0x8A00000,0x1000000,0x1740000,0x1FF80000,0x4A000001,0x4A000001,0x2CC0000,0x11C0000,0x41D40000,0x4A000001, -0x1400000,0x380F44,0xCE180304,0x6A180304,0x4A180305,0xA6000372,0x6E000005,0x4C04003A,0x50000374,0x440000C1,0x36000372,0x70000B53,0x62000455,0x460002A3,0x460005E5,0x40000296,0x3400049B,0x36000B53,0x320006F5,0x2C0007BE,0x24000B53,0x500F44,0x4C000773,0x40000494,0x400007D6,0x3A000417,0x2E0005B4,0x2E000C75,0x32000816,0x2A00089F,0x22000BD4,0xA00F44, -0x2C000AD9,0x26000ABA,0x20000D5F,0x1A000F44,0xFE000344,0xFC2809B2,0xFE2C0A49,0x9E00029D,0x6C0002C1,0x4C0002A2,0x440001A6,0x3A0003B2,0xD00005C2,0x7C000403,0x3E000573,0x2A00089F,0x700F44,0x480B54,0xC2240244,0x68200244,0x4A200245,0xA6000372,0x6E000005,0x4E080032,0x50000374,0x440000C1,0x36000372,0x6C0B53,0x62000455,0x460002A3,0x460005E5,0x40000296, -0x3400049B,0xDC0B53,0x320006F5,0x2C0007BE,0x24000B53,0x6C0B53,0x62000455,0x460002A3,0x460005E5,0x40000296,0x3400049B,0xDC0B53,0x320006F5,0x2C0007BE,0x24000B53,0xDC0B53,0x320006F5,0x2C0007BE,0x24000B53,0x24000B53,0xFE000344,0xF43807D4,0xF8400788,0x9E00029D,0x6C0002C1,0x4C0002A2,0x440001A6,0x3A0003B2,0xD0000519,0x7C0003C3,0x3E000563,0x2C0007BE, -0x9C0B53,0x180304,0x180304,0x180304,0x180304,0x66000000,0x66000000,0x66000000,0x32000000,0x32000000,0x20000001,0x32000242,0x32000242,0x32000242,0x280000CD,0x280000CD,0x1E00006D,0x18000242,0x18000242,0x1600015A,0x10000242,0x200303,0x200303,0x200303,0x22000156,0x22000156,0x180000D1,0x18000282,0x18000282,0x1600019A,0xE000263,0x3C0303, -0x3C0303,0x10000213,0xE0002AE,0xA000303,0xC40000B4,0xFE0C00D8,0x180304,0x640000F5,0x460000DD,0x2E0000E1,0x2E0000B4,0x22000104,0x64000191,0x5000014A,0x1E000248,0x1600019A,0x2C0303,0x200244,0x200244,0x200244,0x200244,0x66000000,0x66000000,0x66000000,0x32000000,0x32000000,0x20000001,0x2300242,0x2300242,0x2300242,0x280000CD,0x280000CD, -0x1E00006D,0x640242,0x640242,0x1600015A,0x10000242,0x2300242,0x2300242,0x2300242,0x280000CD,0x280000CD,0x1E00006D,0x640242,0x640242,0x1600015A,0x10000242,0x640242,0x640242,0x1600015A,0x10000242,0x10000242,0xC40000B4,0xFE0C00B4,0x200244,0x640000F5,0x460000DD,0x2E0000E1,0x2E0000B4,0x22000104,0x74000164,0x50000131,0x480242,0x1600015A, -0x480242,0x6C0374,0xA0440000,0x60440000,0x4A440001,0xA40372,0x6E000005,0x4A1C0001,0x14C0372,0x440000C1,0x36000372,0xA40372,0x6E000005,0x4A1C0001,0x14C0372,0x440000C1,0x36000372,0x14C0372,0x440000C1,0x36000372,0x36000372,0xA40372,0x6E000005,0x4A1C0001,0x14C0372,0x440000C1,0x36000372,0x14C0372,0x440000C1,0x36000372,0x36000372,0x14C0372, -0x440000C1,0x36000372,0x36000372,0x36000372,0xFE140164,0x2740372,0xF86001A5,0xA60000A4,0x6C0000DD,0x540000B9,0x46000059,0x42000132,0xF200015A,0x8C0000F4,0x4C000041,0x36000372,0xE80372,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table131[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x100000,0x100000,0x100000,0x100000,0x100000, -0x100000,0x200000,0x200000,0x200000,0x4000001,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x200000,0x200000,0x200000,0x4000001,0x200000,0x200000,0x200000,0x4000001,0x4000001,0xC0000,0xC0000,0xC0000,0x20C0000,0x40C0000,0x100000,0x100000,0x140000,0x20C0000,0x40C0000,0x180000,0x200000, -0x180000,0x540000,0x540000,0x540000,0x540000,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0x28000001,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0x28000001,0xFC0000,0xFC0000,0x28000001,0x28000001,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0x28000001,0xFC0000,0xFC0000,0x28000001,0x28000001,0xFC0000, -0xFC0000,0x28000001,0x28000001,0x28000001,0x2600000,0x4580000,0x540000,0x2700000,0x8C0000,0xB00000,0xCC0000,0x1340000,0x680000,0x7C0000,0xB00000,0x28000001,0xB00000,0xA80000,0xF80000,0x1FC0000,0x52000001,0xF80000,0x1FC0000,0x52000001,0x1FC0000,0x52000001,0x52000001,0xF80000,0x1FC0000,0x52000001,0x1FC0000,0x52000001, -0x52000001,0x1FC0000,0x52000001,0x52000001,0x52000001,0xF80000,0x1FC0000,0x52000001,0x1FC0000,0x52000001,0x52000001,0x1FC0000,0x52000001,0x52000001,0x52000001,0x1FC0000,0x52000001,0x52000001,0x52000001,0x52000001,0x4D00000,0xB40000,0xB40000,0x1180000,0x19C0000,0x29F80000,0x52000001,0x52000001,0xE40000,0x13C0000,0x49E40000,0x52000001, -0x1640000,0x401198,0xDE200408,0x74200408,0x52200409,0xB6080386,0x78080015,0x560C007E,0x5C040386,0x4C0400A9,0x3E040386,0x84000BE8,0x680003F9,0x5200029B,0x5200058D,0x460001EE,0x3A00043B,0x40000BE8,0x3E0006C9,0x320007A2,0x2A000BEB,0x601194,0x62000829,0x4C00052C,0x4C00083E,0x460003FF,0x3A0005A4,0x3A000D81,0x38000852,0x320008C3,0x28000CAC,0xC41194, -0x32000C15,0x2C000BBE,0x26000ED7,0x20001194,0xFE0C03FE,0xFE2C0B9E,0xF63C0C94,0xB40001F1,0x76000211,0x5A0001E1,0x4C000105,0x4200030B,0xF200058B,0x90000386,0x46000541,0x320008C3,0x8C1194,0x580BE8,0xCE300288,0x70300288,0x52300289,0xB20C0372,0x760C0005,0x54140042,0x5A0C0372,0x4C0400A5,0x3E0C0372,0x2800BE8,0x680003F9,0x5200029B,0x5200058D,0x460001EE, -0x3A00043B,0x1080BE8,0x3E0006C9,0x320007A2,0x2A000BEB,0x2800BE8,0x680003F9,0x5200029B,0x5200058D,0x460001EE,0x3A00043B,0x1080BE8,0x3E0006C9,0x320007A2,0x2A000BEB,0x1080BE8,0x3E0006C9,0x320007A2,0x2A000BEB,0x2A000BEB,0xFE1403AD,0xFA440844,0xFE4C0810,0xB40001F1,0x76000211,0x5A0001E1,0x4C000105,0x4200030B,0xF20004AA,0x90000335,0x46000531,0x320007A2, -0xB80BE8,0x200408,0x200408,0x200408,0x200408,0x76080014,0x76080014,0x76080014,0x3C040014,0x3C040014,0x28040015,0x48000288,0x48000288,0x48000288,0x3400009D,0x3400009D,0x28000032,0x22000288,0x22000288,0x20000151,0x1600028A,0x300408,0x300408,0x300408,0x2E000196,0x2E000196,0x220000C3,0x1E0002FE,0x1E0002FE,0x1C0001B6,0x160002CA,0x5C0408, -0x5C0408,0x1600029B,0x1400035E,0xE00040B,0xF6000082,0xF2140195,0x200408,0x820000C1,0x5A0000A9,0x440000A9,0x40000082,0x2E0000DA,0x960001AB,0x5A000144,0x2C000291,0x1C0001B6,0x400408,0x300288,0x300288,0x300288,0x300288,0x720C0000,0x720C0000,0x720C0000,0x3A0C0000,0x3A0C0000,0x280C0001,0x2440288,0x2440288,0x2440288,0x3400009D,0x3400009D, -0x28000032,0x8C0288,0x8C0288,0x20000151,0x1600028A,0x2440288,0x2440288,0x2440288,0x3400009D,0x3400009D,0x28000032,0x8C0288,0x8C0288,0x20000151,0x1600028A,0x8C0288,0x8C0288,0x20000151,0x1600028A,0x1600028A,0xF6000082,0xF82000DD,0x300288,0x820000C1,0x5A0000A9,0x440000A9,0x40000082,0x2E0000DA,0x9600015A,0x5A000120,0x640288,0x20000151, -0x640288,0x7C0374,0xA8540000,0x68540000,0x52540001,0xBC0372,0x78080001,0x522C0001,0x17C0372,0x4A000091,0x3E000372,0xBC0372,0x78080001,0x522C0001,0x17C0372,0x4A000091,0x3E000372,0x17C0372,0x4A000091,0x3E000372,0x3E000372,0xBC0372,0x78080001,0x522C0001,0x17C0372,0x4A000091,0x3E000372,0x17C0372,0x4A000091,0x3E000372,0x3E000372,0x17C0372, -0x4A000091,0x3E000372,0x3E000372,0x3E000372,0xFC30016D,0xA840372,0xFE6C01B1,0xBC000071,0x80000095,0x5E000080,0x5000002D,0x4A0000FA,0xF80C0152,0x9E0000B5,0x56000014,0x3E000372,0x10C0372,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x40014,0x10000000,0x10000000,0x10000000,0x10000000,0x10000000, -0x10000000,0x8000000,0x8000000,0x8000000,0x4000001,0x80012,0x80012,0x80012,0x80012,0x80012,0x80012,0x6000005,0x6000005,0x6000005,0x4000005,0xC0012,0xC0012,0xC0012,0x400000A,0x2000012,0x58000000,0x40014,0x40014,0x28000000,0x1C000000,0x14000000,0x14000000,0xE000000,0x20000005,0x16000002,0xA000001,0x6000005, -0xC0012,}; -static const uint32_t g_etc1_to_bc7_m6_table132[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000, -0x2C0000,0x580000,0x580000,0x580000,0xE000000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x580000,0x580000,0x580000,0xE000000,0x580000,0x580000,0x580000,0xE000000,0xE000000,0x200000,0x1C0001,0x1C0001,0x6200000,0x240000,0x280000,0x280000,0x300000,0x6200000,0x240000,0x3C0000,0x580000, -0x3C0000,0x640001,0x640001,0x640001,0x640001,0x980000,0x980000,0x980000,0x1300000,0x1300000,0x32000000,0x980000,0x980000,0x980000,0x1300000,0x1300000,0x32000000,0x1300000,0x1300000,0x32000000,0x32000000,0x980000,0x980000,0x980000,0x1300000,0x1300000,0x32000000,0x1300000,0x1300000,0x32000000,0x32000000,0x1300000, -0x1300000,0x32000000,0x32000000,0x32000000,0x4740000,0x6C0000,0x640001,0x2880000,0xAC0000,0xD80000,0xF80000,0x1780000,0x800000,0x980000,0xD80000,0x32000000,0xD80000,0xB80001,0x1140000,0xFF80000,0x5C000000,0x1140000,0xFF80000,0x5C000000,0xFF80000,0x5C000000,0x5C000000,0x1140000,0xFF80000,0x5C000000,0xFF80000,0x5C000000, -0x5C000000,0xFF80000,0x5C000000,0x5C000000,0x5C000000,0x1140000,0xFF80000,0x5C000000,0xFF80000,0x5C000000,0x5C000000,0xFF80000,0x5C000000,0x5C000000,0x5C000000,0xFF80000,0x5C000000,0x5C000000,0x5C000000,0x5C000000,0xE80000,0xAC40000,0xAC40000,0x1380000,0x1C80000,0x35F00000,0x5C000000,0x5C000000,0xFC0000,0x15C0000,0x53D80000,0x5C000000, -0x18C0000,0x501423,0xEC2C055E,0x7E2C055E,0x5C2C055E,0xCA1003E3,0x86100072,0x6014011D,0x661003E3,0x560C00EA,0x461003E5,0xA0000BE8,0x7A00034E,0x5C04028E,0x620004C5,0x5200010D,0x460003B4,0x4E000BE8,0x4A00060E,0x3E0006ED,0x34000BE8,0x2741423,0x6E0008EE,0x58000601,0x5800089F,0x4C0003D6,0x400005B1,0x46000E44,0x4400082B,0x3C000898,0x34000D09,0xF01423, -0x38000D6E,0x32000CD1,0x2C00102C,0x26001425,0xFE200511,0xF8400DDB,0xFC480EE3,0xD000011D,0x8A000126,0x6A00010D,0x5A00005E,0x50000214,0xFE00052B,0xA80002B6,0x5400046A,0x3C000898,0xA81423,0x680BEB,0xD444028A,0x7A40028A,0x5C40028A,0xBA200373,0x821C0002,0x5E280041,0x62200373,0x561800A6,0x461C0375,0x9C0BE8,0x7A00034E,0x5C080288,0x620004C5,0x5200010D, -0x460003B4,0x13C0BE8,0x4A00060E,0x3E0006ED,0x34000BE8,0x9C0BE8,0x7A00034E,0x5C080288,0x620004C5,0x5200010D,0x460003B4,0x13C0BE8,0x4A00060E,0x3E0006ED,0x34000BE8,0x13C0BE8,0x4A00060E,0x3E0006ED,0x34000BE8,0x34000BE8,0xFA2C0402,0xF458087D,0xF860084A,0xD000011D,0x8A000126,0x6A00010D,0x5A00005E,0x50000214,0xFC040428,0xA800023D,0x54000451,0x3E0006ED, -0xE00BE8,0x2C055E,0x2C055E,0x2C055E,0x2C055E,0x8A100071,0x8A100071,0x8A100071,0x46100072,0x46100072,0x32100071,0x64000288,0x64000288,0x64000288,0x46000049,0x46000049,0x32000004,0x30000288,0x30000288,0x2A000104,0x20000288,0x40055E,0x40055E,0x40055E,0x3A0001F2,0x3A0001F2,0x2E0000F1,0x28000363,0x28000363,0x260001B2,0x1E0002F4,0x80055E, -0x80055E,0x20000359,0x1C000411,0x14000561,0xFC0C00AC,0xF8200291,0x2C055E,0xAC00006A,0x72000050,0x56000059,0x4C000032,0x40000082,0xC2000199,0x84000101,0x3E000298,0x260001B2,0x5C055E,0x40028A,0x40028A,0x40028A,0x40028A,0x7A200001,0x7A200001,0x7A200001,0x441C0001,0x441C0001,0x321C0001,0x600288,0x600288,0x600288,0x46000049,0x46000049, -0x32000004,0xC40288,0xC40288,0x2A000104,0x20000288,0x600288,0x600288,0x600288,0x46000049,0x46000049,0x32000004,0xC40288,0xC40288,0x2A000104,0x20000288,0xC40288,0xC40288,0x2A000104,0x20000288,0x20000288,0xFE100080,0xF23400F2,0x40028A,0xAC00006A,0x72000050,0x56000059,0x4C000032,0x40000082,0xC2000109,0x840000C1,0x8C0288,0x2A000104, -0x8C0288,0x900372,0xB0680001,0x70680001,0x5C640001,0xD40372,0x82180001,0x5C3C0000,0x1B00372,0x56000055,0x46000374,0xD40372,0x82180001,0x5C3C0000,0x1B00372,0x56000055,0x46000374,0x1B00372,0x56000055,0x46000374,0x46000374,0xD40372,0x82180001,0x5C3C0000,0x1B00372,0x56000055,0x46000374,0x1B00372,0x56000055,0x46000374,0x46000374,0x1B00372, -0x56000055,0x46000374,0x46000374,0x46000374,0xFE440188,0x4980372,0xFA8401C2,0xDA000041,0x9600006D,0x6C000055,0x5A00000D,0x540000B9,0xFE180164,0xBA00007D,0x62000004,0x46000374,0x1300372,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x100071,0x2C000000,0x2C000000,0x2C000000,0x2C000000,0x2C000000, -0x2C000000,0x16000000,0x16000000,0x16000000,0xE000000,0x140071,0x140071,0x140071,0x140071,0x140071,0x140071,0x12000028,0x12000028,0x12000028,0xC000014,0x240071,0x240071,0x240071,0xA000041,0x6000071,0xE8000000,0x100071,0x100071,0x68000000,0x48000000,0x36000000,0x36000000,0x24000000,0x52000022,0x42000011,0x1C000004,0x12000028, -0x1C0071,}; -static const uint32_t g_etc1_to_bc7_m6_table133[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x440000,0x440000,0x440000,0x440000,0x440000, -0x440000,0x880000,0x880000,0x880000,0x16000000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x880000,0x880000,0x880000,0x16000000,0x880000,0x880000,0x880000,0x16000000,0x16000000,0x300000,0x2C0001,0x2C0001,0x2340000,0x380000,0x23C0000,0x23C0000,0x4C0000,0x2340000,0x380000,0x600000,0x880000, -0x600000,0x740001,0x740001,0x740001,0x740001,0xB00000,0xB00000,0xB00000,0x1640000,0x1640000,0x3A000000,0xB00000,0xB00000,0xB00000,0x1640000,0x1640000,0x3A000000,0x1640000,0x1640000,0x3A000000,0x3A000000,0xB00000,0xB00000,0xB00000,0x1640000,0x1640000,0x3A000000,0x1640000,0x1640000,0x3A000000,0x3A000000,0x1640000, -0x1640000,0x3A000000,0x3A000000,0x3A000000,0x880000,0x67C0000,0x740001,0xA00000,0xC40000,0xF80000,0x1200000,0x1B40000,0x940000,0xB00000,0xF80000,0x3A000000,0xF80000,0xC80001,0x12C0000,0x1BF80000,0x64000000,0x12C0000,0x1BF80000,0x64000000,0x1BF80000,0x64000000,0x64000000,0x12C0000,0x1BF80000,0x64000000,0x1BF80000,0x64000000, -0x64000000,0x1BF80000,0x64000000,0x64000000,0x64000000,0x12C0000,0x1BF80000,0x64000000,0x1BF80000,0x64000000,0x64000000,0x1BF80000,0x64000000,0x64000000,0x64000000,0x1BF80000,0x64000000,0x64000000,0x64000000,0x64000000,0xFC0000,0xD80000,0xD80000,0x1540000,0x1EC0000,0x3FF00000,0x64000000,0x64000000,0x3100000,0x17C0000,0x5BE80000,0x64000000, -0x1AC0000,0x5C16CF,0xF83806EA,0x883806EA,0x643806EA,0xDA18047B,0x90180112,0x662001F9,0x7018047B,0x6014016E,0x4E18047D,0xB8000BE8,0x8C0002DE,0x660C02C2,0x6E00044D,0x5E00007D,0x4E00037D,0x5A000BE8,0x5000056A,0x44000675,0x3C000BE8,0x8816CF,0x7A000A0E,0x6200072E,0x68000911,0x580003FE,0x4C0005F9,0x52000F0C,0x4C00082B,0x44000886,0x3A000D5D,0x11416CF, -0x44000EFE,0x3E000E01,0x32001198,0x2C0016D1,0xFE280685,0xFE4C1017,0xFE4C119F,0xE6000086,0x9A0000A1,0x78000083,0x6200000D,0x5800015D,0xFE00061B,0xBC00020A,0x5E0003DE,0x44000886,0xC016CF,0x780BEB,0xDC54028A,0x8250028A,0x6450028A,0xC2300373,0x8A2C0002,0x66380041,0x6A300373,0x5E2800A6,0x4E2C0375,0xB40BE8,0x8C0002DE,0x64180288,0x6E00044D,0x5E00007D, -0x4E00037D,0x1700BE8,0x5000056A,0x44000675,0x3C000BE8,0xB40BE8,0x8C0002DE,0x64180288,0x6E00044D,0x5E00007D,0x4E00037D,0x1700BE8,0x5000056A,0x44000675,0x3C000BE8,0x1700BE8,0x5000056A,0x44000675,0x3C000BE8,0x3C000BE8,0xFE340432,0xFC68087D,0xFE6C085E,0xE6000086,0x9A0000A1,0x78000083,0x6200000D,0x5800015D,0xFE180455,0xBC00017A,0x5E0003BA,0x44000675, -0x1000BE8,0x3806EA,0x3806EA,0x3806EA,0x3806EA,0x9A180109,0x9A180109,0x9A180109,0x5018010A,0x5018010A,0x3A180109,0x7C000288,0x7C000288,0x7C000288,0x52000019,0x52000019,0x3A040008,0x3C000288,0x3C000288,0x320000B9,0x28000288,0x5006E9,0x5006E9,0x5006E9,0x4600028A,0x4600028A,0x34000169,0x340003DB,0x340003DB,0x2E0001C2,0x28000331,0xA006E9, -0xA006E9,0x2600043D,0x200004EC,0x1A0006E9,0xFE100140,0xFE2C03C9,0x3806EA,0xD000002D,0x86000020,0x6A00001D,0x62000009,0x4A000041,0xE40001A5,0x960000E2,0x4C0002A1,0x2E0001C2,0x7006E9,0x50028A,0x50028A,0x50028A,0x50028A,0x82300001,0x82300001,0x82300001,0x4C2C0001,0x4C2C0001,0x3A2C0001,0x780288,0x780288,0x780288,0x52000019,0x52000019, -0x3A0C0000,0xF40288,0xF40288,0x320000B9,0x28000288,0x780288,0x780288,0x780288,0x52000019,0x52000019,0x3A0C0000,0xF40288,0xF40288,0x320000B9,0x28000288,0xF40288,0xF40288,0x320000B9,0x28000288,0x28000288,0xFE200091,0xFA4400F2,0x50028A,0xD000002D,0x86000020,0x6A00001D,0x62000009,0x4A000041,0xF40000CA,0x9A000080,0xAC0288,0x320000B9, -0xAC0288,0xA00372,0xB8780001,0x78780001,0x64740001,0xEC0372,0x8A280001,0x644C0000,0x1E40372,0x60000034,0x4E000374,0xEC0372,0x8A280001,0x644C0000,0x1E40372,0x60000034,0x4E000374,0x1E40372,0x60000034,0x4E000374,0x4E000374,0xEC0372,0x8A280001,0x644C0000,0x1E40372,0x60000034,0x4E000374,0x1E40372,0x60000034,0x4E000374,0x4E000374,0x1E40372, -0x60000034,0x4E000374,0x4E000374,0x4E000374,0xFE50019A,0xCA80372,0xF29401E1,0xEE000020,0xA000003D,0x7A00002D,0x64000001,0x5C000091,0xFE2C0185,0xCC000059,0x6A080000,0x4E000374,0x1540372,0x180109,0x180109,0x180109,0x180109,0x180109,0x180109,0x180109,0x180109,0x180109,0x180109,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000, -0x44000000,0x20000001,0x20000001,0x20000001,0x16000000,0x200109,0x200109,0x200109,0x200109,0x200109,0x200109,0x18000064,0x18000064,0x18000064,0x12000034,0x3C0109,0x3C0109,0x3C0109,0x1000009D,0xA000109,0xFC080019,0x180109,0x180109,0xA0000000,0x6E000000,0x54000000,0x54000000,0x38000000,0x84000050,0x64000028,0x26000008,0x18000064, -0x2C0109,}; -static const uint32_t g_etc1_to_bc7_m6_table134[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000, -0x5C0000,0xB80000,0xB80000,0xB80000,0x1E000000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0xB80000,0xB80000,0xB80000,0x1E000000,0xB80000,0xB80000,0xB80000,0x1E000000,0x1E000000,0x8400000,0x3C0001,0x3C0001,0x480000,0x24C0000,0x540000,0x540000,0x680000,0x480000,0x24C0000,0x800000,0xB80000, -0x800000,0x840001,0x840001,0x840001,0x840001,0x2C40000,0x2C40000,0x2C40000,0x1940000,0x1940000,0x42000000,0x2C40000,0x2C40000,0x2C40000,0x1940000,0x1940000,0x42000000,0x1940000,0x1940000,0x42000000,0x42000000,0x2C40000,0x2C40000,0x2C40000,0x1940000,0x1940000,0x42000000,0x1940000,0x1940000,0x42000000,0x42000000,0x1940000, -0x1940000,0x42000000,0x42000000,0x42000000,0x9C0000,0xE8C0000,0x840001,0x2B40000,0xE00000,0x11C0000,0x1480000,0x1F00000,0xA80000,0x2C40000,0x11C0000,0x42000000,0x11C0000,0xD80001,0x1440000,0x27F80000,0x6C000000,0x1440000,0x27F80000,0x6C000000,0x27F80000,0x6C000000,0x6C000000,0x1440000,0x27F80000,0x6C000000,0x27F80000,0x6C000000, -0x6C000000,0x27F80000,0x6C000000,0x6C000000,0x6C000000,0x1440000,0x27F80000,0x6C000000,0x27F80000,0x6C000000,0x6C000000,0x27F80000,0x6C000000,0x6C000000,0x6C000000,0x27F80000,0x6C000000,0x6C000000,0x6C000000,0x6C000000,0x1100000,0xE80000,0xE80000,0x36C0000,0x9FC0000,0x49F00000,0x6C000000,0x6C000000,0x1280000,0x1980000,0x63F80000,0x6C000000, -0x1D00000,0x6819DB,0xFE4408D2,0x924008CA,0x6C4008CA,0xEA200553,0x9A2001FA,0x70280319,0x7A200553,0x681C0235,0x56200555,0xD0000BE8,0x9E00029E,0x6E10032E,0x800003ED,0x68000029,0x56000378,0x66000BE8,0x5C0004DA,0x500005E5,0x44000BE8,0x29819DB,0x86000B8E,0x6A0008DD,0x740009E9,0x62000465,0x5200068D,0x5E000FF4,0x58000853,0x4C00088E,0x40000DD1,0x13819DB, -0x4A0010D2,0x44000F69,0x3E001338,0x320019DD,0xFE340856,0xF65C1329,0xF860148A,0xFE000033,0xAC00003D,0x84000029,0x6C040006,0x640000D5,0xFE1007BB,0xD4000193,0x66000384,0x4C00088E,0xDC19DB,0x880BEB,0xE464028A,0x8A60028A,0x6C60028A,0xCA400373,0x923C0002,0x6E480041,0x72400373,0x663800A6,0x563C0375,0xCC0BE8,0x9E00029E,0x6C280288,0x800003ED,0x68000029, -0x56080374,0x1A00BE8,0x5C0004DA,0x500005E5,0x44000BE8,0xCC0BE8,0x9E00029E,0x6C280288,0x800003ED,0x68000029,0x56080374,0x1A00BE8,0x5C0004DA,0x500005E5,0x44000BE8,0x1A00BE8,0x5C0004DA,0x500005E5,0x44000BE8,0x44000BE8,0xFE50045E,0xF47808BB,0xF880088B,0xFE000033,0xAC00003D,0x84000029,0x6C040002,0x640000D5,0xFE2404A1,0xDA0000E6,0x6A000359,0x500005E5, -0x1240BE8,0x4008CA,0x4008CA,0x4008CA,0x4008CA,0xAA2001E1,0xAA2001E1,0xAA2001E1,0x5A2001E2,0x5A2001E2,0x422001E1,0x94000288,0x94000288,0x94000288,0x62000001,0x62000001,0x42080034,0x48000288,0x48000288,0x3C000088,0x30000288,0x6008C9,0x6008C9,0x6008C9,0x52000362,0x52000362,0x40000221,0x40000473,0x40000473,0x360001F8,0x2E000371,0xC408C9, -0xC408C9,0x2C000569,0x260005F4,0x200008C9,0xFE200221,0xF438058A,0x4008CA,0xF200000D,0x9E000005,0x7C000005,0x70000001,0x56000019,0xFE0001FA,0xB60000CE,0x5C0002AC,0x360001F8,0x8C08C9,0x60028A,0x60028A,0x60028A,0x60028A,0x8A400001,0x8A400001,0x8A400001,0x543C0001,0x543C0001,0x423C0001,0x900288,0x900288,0x900288,0x62000001,0x62000001, -0x421C0000,0x1240288,0x1240288,0x3C000088,0x30000288,0x900288,0x900288,0x900288,0x62000001,0x62000001,0x421C0000,0x1240288,0x1240288,0x3C000088,0x30000288,0x1240288,0x1240288,0x3C000088,0x30000288,0x30000288,0xFA3400A2,0xF2540109,0x60028A,0xF200000D,0x9E000005,0x7C000005,0x6E040000,0x56000019,0xFE0C00C8,0xBC00004A,0xD00288,0x3C000088, -0xD00288,0xB00372,0xC0880001,0x80880001,0x6C840001,0x1040372,0x92380001,0x6C5C0000,0x7FC0372,0x6A00001D,0x56000374,0x1040372,0x92380001,0x6C5C0000,0x7FC0372,0x6A00001D,0x56000374,0x7FC0372,0x6A00001D,0x56000374,0x56000374,0x1040372,0x92380001,0x6C5C0000,0x7FC0372,0x6A00001D,0x56000374,0x7FC0372,0x6A00001D,0x56000374,0x56000374,0x7FC0372, -0x6A00001D,0x56000374,0x56000374,0x56000374,0xF86C01A5,0xBC0372,0xFAA401E1,0xFE040014,0xAC040029,0x84000019,0x6C0C0000,0x64000071,0xFA4C0188,0xDE000034,0x72180000,0x56000374,0x1740372,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x2001E1,0x5C000000,0x5C000000,0x5C000000,0x5C000000,0x5C000000, -0x5C000000,0x2C000001,0x2C000001,0x2C000001,0x1E000000,0x2C01E1,0x2C01E1,0x2C01E1,0x2C01E1,0x2C01E1,0x2C01E1,0x220000AA,0x220000AA,0x220000AA,0x1A000061,0x5801E1,0x5801E1,0x5801E1,0x16000121,0xE0001E1,0xFE0C0075,0x2001E1,0x2001E1,0xD8000000,0x96000000,0x72000000,0x72000000,0x4C000000,0xB6000092,0x82000050,0x3600000D,0x220000AA, -0x3C01E1,}; -static const uint32_t g_etc1_to_bc7_m6_table135[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x740000,0x740000,0x740000,0x740000,0x740000, -0x740000,0xE80000,0xE80000,0xE80000,0x26000000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0xE80000,0xE80000,0xE80000,0x26000000,0xE80000,0xE80000,0xE80000,0x26000000,0x26000000,0x540000,0x4C0001,0x4C0001,0x4580000,0x2600000,0x2680000,0x2680000,0x2800000,0x4580000,0x2600000,0xA40000,0xE80000, -0xA40000,0x940001,0x940001,0x940001,0x940001,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x4A000000,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x4A000000,0x1C40000,0x1C40000,0x4A000000,0x4A000000,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x4A000000,0x1C40000,0x1C40000,0x4A000000,0x4A000000,0x1C40000, -0x1C40000,0x4A000000,0x4A000000,0x4A000000,0x4AC0000,0xA00000,0x940001,0xCC0000,0xFC0000,0x13C0000,0x16C0000,0xBF80000,0xBC0000,0x2DC0000,0x13C0000,0x4A000000,0x13C0000,0xE80001,0x15C0000,0x33F80000,0x74000000,0x15C0000,0x33F80000,0x74000000,0x33F80000,0x74000000,0x74000000,0x15C0000,0x33F80000,0x74000000,0x33F80000,0x74000000, -0x74000000,0x33F80000,0x74000000,0x74000000,0x74000000,0x15C0000,0x33F80000,0x74000000,0x33F80000,0x74000000,0x74000000,0x33F80000,0x74000000,0x74000000,0x74000000,0x33F80000,0x74000000,0x74000000,0x74000000,0x74000000,0x1240000,0x4F80000,0x4F80000,0x1880000,0x17FC0000,0x53F00000,0x74000000,0x74000000,0x33C0000,0x1B80000,0x6DCC0000,0x74000000, -0x1F00000,0x741D47,0xFE500B2E,0x9A4C0AFE,0x744C0AFE,0xFA28066B,0xA62C0322,0x7A340492,0x8428066B,0x6E24033A,0x5E28066D,0xEA000BE8,0xAC000289,0x781803CA,0x8C0003A5,0x72000009,0x60080394,0x72000BE8,0x6600046C,0x5600057D,0x4C000BE8,0xAC1D47,0x92000D6E,0x74000AFE,0x80000B01,0x6800053D,0x5E000775,0x680010D8,0x5E00088F,0x540008B8,0x48000E58,0x15C1D47, -0x5000130E,0x4A001121,0x440014EC,0x38001D49,0xFE3C0AD7,0xFC68162D,0xFE6C17C2,0xFE0C0095,0xC000000D,0x90000005,0x7608002D,0x6C000072,0xFE180A0E,0xE6000156,0x7600031A,0x540008B8,0xF41D47,0x980BEB,0xEC74028A,0x9270028A,0x7470028A,0xD2500373,0x9A4C0002,0x76580041,0x7A500373,0x6E4800A6,0x5E4C0375,0xE40BE8,0xAA040289,0x74380288,0x8C0003A5,0x72000009, -0x5E180374,0x1D00BE8,0x6600046C,0x5600057D,0x4C000BE8,0xE40BE8,0xAA040289,0x74380288,0x8C0003A5,0x72000009,0x5E180374,0x1D00BE8,0x6600046C,0x5600057D,0x4C000BE8,0x1D00BE8,0x6600046C,0x5600057D,0x4C000BE8,0x4C000BE8,0xFC6004C1,0xFC8808BB,0xFE8C08A3,0xFE14004A,0xC000000D,0x90000005,0x74140002,0x6C000072,0xFC4004E8,0xEC00007E,0x760002E9,0x5600057D, -0x1480BE8,0x4C0AFE,0x4C0AFE,0x4C0AFE,0x4C0AFE,0xBA2802F9,0xBA2802F9,0xBA2802F9,0x642802FA,0x642802FA,0x4A2802F9,0xAC000288,0xAC000288,0xAC000288,0x6E040005,0x6E040005,0x4C100084,0x54000288,0x54000288,0x44000055,0x38000288,0x700AFE,0x700AFE,0x700AFE,0x62000471,0x62000471,0x46000321,0x4C00052B,0x4C00052B,0x40000236,0x340003C9,0xE40AFE, -0xE40AFE,0x320006DD,0x2C00072C,0x24000B01,0xFE2C0378,0xFA440776,0x4C0AFE,0xFE080020,0xB8000001,0x8E000002,0x80040011,0x62000005,0xFE00031A,0xD40000D2,0x660002B4,0x40000236,0xA00AFE,0x70028A,0x70028A,0x70028A,0x70028A,0x92500001,0x92500001,0x92500001,0x5C4C0001,0x5C4C0001,0x4A4C0001,0xA80288,0xA80288,0xA80288,0x6A0C0001,0x6A0C0001, -0x4A2C0000,0x1580288,0x1580288,0x44000055,0x38000288,0xA80288,0xA80288,0xA80288,0x6A0C0001,0x6A0C0001,0x4A2C0000,0x1580288,0x1580288,0x44000055,0x38000288,0x1580288,0x1580288,0x44000055,0x38000288,0x38000288,0xF64800B5,0xFA640109,0x70028A,0xFA10000D,0xAE0C0001,0x88080000,0x76140000,0x62000005,0xF62400DD,0xDA000022,0xF00288,0x44000055, -0xF00288,0xC00372,0xC8980001,0x88980001,0x74940001,0x11C0372,0x9A480001,0x746C0000,0x13FC0372,0x72000008,0x5E000374,0x11C0372,0x9A480001,0x746C0000,0x13FC0372,0x72000008,0x5E000374,0x13FC0372,0x72000008,0x5E000374,0x5E000374,0x11C0372,0x9A480001,0x746C0000,0x13FC0372,0x72000008,0x5E000374,0x13FC0372,0x72000008,0x5E000374,0x5E000374,0x13FC0372, -0x72000008,0x5E000374,0x5E000374,0x5E000374,0xFE7801B1,0xCC0372,0xF2B40202,0xFE200020,0xC000000D,0x90000005,0x741C0000,0x70000050,0xFE5C018A,0xF400001D,0x7A280000,0x5E000374,0x1980372,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x2802F9,0x76000000,0x76000000,0x76000000,0x76000000,0x76000000, -0x76000000,0x38000001,0x38000001,0x38000001,0x26000000,0x3802F9,0x3802F9,0x3802F9,0x3802F9,0x3802F9,0x3802F9,0x2E000112,0x2E000112,0x2E000112,0x22000089,0x7002F9,0x7002F9,0x7002F9,0x1C0001CD,0x120002F9,0xF4180120,0x2802F9,0x2802F9,0xFE040005,0xBE000000,0x90000000,0x90000000,0x5E000000,0xF60000F1,0xA400007D,0x46000011,0x2E000112, -0x5002F9,}; -static const uint32_t g_etc1_to_bc7_m6_table136[] = { -0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x200000, -0x200000,0x200000,0x200000,0x4000001,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x100000,0x180000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000, -0x28C0000,0x1200000,0x1200000,0x1200000,0x2E000001,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x1200000,0x1200000,0x1200000,0x2E000001,0x1200000,0x1200000,0x1200000,0x2E000001,0x2E000001,0xA640000,0x600000,0x600000,0x700000,0x780000,0x2800000,0x2800000,0xA00000,0x700000,0x780000,0xCC0000,0x1200000, -0xCC0000,0xA80000,0xA80000,0xA80000,0xA80000,0xF80000,0xF80000,0xF80000,0x1FC0000,0x1FC0000,0x52000001,0xF80000,0xF80000,0xF80000,0x1FC0000,0x1FC0000,0x52000001,0x1FC0000,0x1FC0000,0x52000001,0x52000001,0xF80000,0xF80000,0xF80000,0x1FC0000,0x1FC0000,0x52000001,0x1FC0000,0x1FC0000,0x52000001,0x52000001,0x1FC0000, -0x1FC0000,0x52000001,0x52000001,0x52000001,0xC40000,0xB40000,0xA80000,0xE40000,0x1180000,0x1640000,0x19C0000,0x17F80000,0x4D00000,0xF80000,0x1640000,0x52000001,0x1640000,0xFC0000,0x3740000,0x3FFC0000,0x7C000001,0x3740000,0x3FFC0000,0x7C000001,0x3FFC0000,0x7C000001,0x7C000001,0x3740000,0x3FFC0000,0x7C000001,0x3FFC0000,0x7C000001, -0x7C000001,0x3FFC0000,0x7C000001,0x7C000001,0x7C000001,0x3740000,0x3FFC0000,0x7C000001,0x3FFC0000,0x7C000001,0x7C000001,0x3FFC0000,0x7C000001,0x7C000001,0x7C000001,0x3FFC0000,0x7C000001,0x7C000001,0x7C000001,0x7C000001,0x13C0000,0x10C0000,0x10C0000,0x1A80000,0x27F80000,0x5DFC0000,0x7C000001,0x7C000001,0x3540000,0x1D80000,0x75FC0000,0x7C000001, -0xDFC0000,0x841EA8,0xFE600C58,0xA45C0BE8,0x7C5C0BE9,0xFC3806F8,0xB23803A1,0x82440531,0x8E3406E6,0x7A3403AE,0x683406E6,0xF80C0BE8,0xB80C028A,0x84240411,0x9608038E,0x7C0C000E,0x6A1403AE,0x7C0C0BE8,0x72000417,0x62040533,0x540C0BEB,0xC41EA8,0xA8000D6B,0x7C100BE9,0x8C000A7E,0x740004CE,0x68000746,0x7400107B,0x6A000782,0x5E0007AB,0x52000DBC,0x18C1EA8, -0x5C001329,0x560010EE,0x4A0014E3,0x40001EAC,0xFE500C45,0xFE6C17DE,0xF67C1978,0xFE1C0128,0xCA0C0011,0x9A0C0006,0x80140046,0x78040046,0xFE340B52,0xFE000098,0x820002B5,0x5E0007AB,0x1181EA8,0xAC0BE8,0xF8840288,0x9A840288,0x7C840289,0xDC600372,0xA0600005,0x7E680042,0x84600372,0x765800A5,0x68600372,0x1000BE8,0xB4140289,0x7E480289,0x9A00037D,0x7C14000A, -0x68280372,0x5F80BE8,0x720003F3,0x60000513,0x54000BEB,0x1000BE8,0xB4140289,0x7E480289,0x9A00037D,0x7C14000A,0x68280372,0x5F80BE8,0x720003F3,0x60000513,0x54000BEB,0x5F80BE8,0x720003F3,0x60000513,0x54000BEB,0x54000BEB,0xFE7804ED,0xF69C08F6,0xFAA408C9,0xFE300081,0xCA10000D,0x98100006,0x7E280001,0x7A000031,0xFC580519,0xFE040033,0x820002B1,0x60000513, -0x16C0BE8,0x5C0BE8,0x5C0BE8,0x5C0BE8,0x5C0BE8,0xC6380374,0xC6380374,0xC6380374,0x6E380374,0x6E380374,0x52340375,0xBC0C0288,0xBC0C0288,0xBC0C0288,0x7A100009,0x7A100009,0x561800A6,0x5E0C0288,0x5E0C0288,0x4E080041,0x400C028A,0x880BE8,0x880BE8,0x880BE8,0x6E000465,0x6E000465,0x52000373,0x580004E1,0x580004E1,0x4C0001AA,0x4000036B,0x1140BE8, -0x1140BE8,0x3E0006ED,0x3800072A,0x2C000BEB,0xFE3C0434,0xFE4C0864,0x5C0BE8,0xFE180059,0xC80C0005,0x9A0C0005,0x88140021,0x6E0C0002,0xFE1403B9,0xF600005E,0x7C00028C,0x4C0001AA,0xC00BE8,0x840288,0x840288,0x840288,0x840288,0x9C600000,0x9C600000,0x9C600000,0x64600000,0x64600000,0x52600001,0xC40288,0xC40288,0xC40288,0x72200001,0x72200001, -0x543C0001,0x18C0288,0x18C0288,0x5000002D,0x4000028A,0xC40288,0xC40288,0xC40288,0x72200001,0x72200001,0x543C0001,0x18C0288,0x18C0288,0x5000002D,0x4000028A,0x18C0288,0x18C0288,0x5000002D,0x4000028A,0x4000028A,0xFE5800B5,0xF4780120,0x840288,0xFE240012,0xBC180000,0x92180000,0x7E280000,0x70080000,0xFE3400DD,0xFC00000A,0x1180288,0x5000002D, -0x1180288,0xD00374,0xD2A80000,0x92A80000,0x7CA80001,0x1380372,0xA25C0001,0x7C800001,0x21F80372,0x7C000001,0x68000372,0x1380372,0xA25C0001,0x7C800001,0x21F80372,0x7C000001,0x68000372,0x21F80372,0x7C000001,0x68000372,0x68000372,0x1380372,0xA25C0001,0x7C800001,0x21F80372,0x7C000001,0x68000372,0x21F80372,0x7C000001,0x68000372,0x68000372,0x21F80372, -0x7C000001,0x68000372,0x68000372,0x68000372,0xFE9401C2,0xE00372,0xFCC80200,0xFC3C0032,0xCE040005,0x9C040000,0x7C300001,0x7A00002D,0xFE7001B1,0xFE080014,0x84380000,0x68000372,0x1BC0372,0x340374,0x340374,0x340374,0x340374,0x340374,0x340374,0x340374,0x340374,0x340374,0x340374,0x840C0000,0x840C0000,0x840C0000,0x840C0000,0x840C0000, -0x840C0000,0x440C0000,0x440C0000,0x440C0000,0x2E0C0001,0x500372,0x500372,0x500372,0x500372,0x500372,0x500372,0x3A0000E9,0x3A0000E9,0x3A0000E9,0x2E000052,0xA00372,0xA00372,0xA00372,0x200001E1,0x1A000372,0xFC28016D,0x340374,0x340374,0xFE10001D,0xD20C0000,0xA20C0000,0xA20C0000,0x6C0C0000,0xF80400F2,0xD6000041,0x5A000000,0x3A0000E9, -0x700372,}; -static const uint32_t g_etc1_to_bc7_m6_table137[] = { -0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x280000,0x500000, -0x500000,0x500000,0x500000,0xC000001,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x61C0000,0x61C0000,0x61C0000,0x280000,0x380000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000, -0x2A40000,0x1500000,0x1500000,0x1500000,0x36000001,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x1500000,0x1500000,0x1500000,0x36000001,0x1500000,0x1500000,0x1500000,0x36000001,0x36000001,0x780000,0x700000,0x700000,0x4800000,0x8C0000,0x980000,0x980000,0xBC0000,0x4800000,0x8C0000,0xEC0000,0x1500000, -0xEC0000,0xB80000,0xB80000,0xB80000,0xB80000,0x1100000,0x1100000,0x1100000,0xDFC0000,0xDFC0000,0x5A000001,0x1100000,0x1100000,0x1100000,0xDFC0000,0xDFC0000,0x5A000001,0xDFC0000,0xDFC0000,0x5A000001,0x5A000001,0x1100000,0x1100000,0x1100000,0xDFC0000,0xDFC0000,0x5A000001,0xDFC0000,0xDFC0000,0x5A000001,0x5A000001,0xDFC0000, -0xDFC0000,0x5A000001,0x5A000001,0x5A000001,0x2D40000,0xC40000,0xB80000,0x2F80000,0x1340000,0x1880000,0x1C00000,0x21FC0000,0x4E40000,0x1100000,0x1880000,0x5A000001,0x1880000,0x10C0000,0x38C0000,0x4BFC0000,0x84000001,0x38C0000,0x4BFC0000,0x84000001,0x4BFC0000,0x84000001,0x84000001,0x38C0000,0x4BFC0000,0x84000001,0x4BFC0000,0x84000001, -0x84000001,0x4BFC0000,0x84000001,0x84000001,0x84000001,0x38C0000,0x4BFC0000,0x84000001,0x4BFC0000,0x84000001,0x84000001,0x4BFC0000,0x84000001,0x84000001,0x84000001,0x4BFC0000,0x84000001,0x84000001,0x84000001,0x84000001,0x1500000,0x71C0000,0x71C0000,0x3C00000,0x35F80000,0x67FC0000,0x84000001,0x84000001,0x16C0000,0x1F80000,0x7FD00000,0x84000001, -0x1DF80000,0x941EA8,0xFE740C91,0xAC6C0BE8,0x846C0BE9,0xFC4C0716,0xBA4803A1,0x8A540531,0x964406E6,0x824403AE,0x704406E6,0xFE1C0BEB,0xC01C028A,0x8C340411,0x9E18038E,0x841C000E,0x722403AE,0x841C0BE8,0x780C0413,0x6A140533,0x5C1C0BEB,0xDC1EA8,0xBA000CBB,0x84200BE9,0x9800096E,0x80000406,0x700006EC,0x86000F87,0x7400061B,0x68000663,0x5A000D03,0x1BC1EA8, -0x6600124C,0x5C000FB6,0x5600140B,0x48001EAC,0xFE640CCE,0xFC8817E8,0xFE8C1978,0xFE34018E,0xD21C0011,0xA21C0006,0x88240046,0x80140046,0xFE440C0F,0xFE1000C2,0x8A08029D,0x68000663,0x1381EA8,0xBC0BE8,0xFC940289,0xA2940288,0x84940289,0xE4700372,0xA8700005,0x86780042,0x8C700372,0x7E6800A5,0x70700372,0x1180BE8,0xBC240289,0x86580289,0xA6040372,0x8424000A, -0x70380372,0x11F80BE8,0x78000393,0x6C0004B3,0x5C000BEB,0x1180BE8,0xBC240289,0x86580289,0xA6040372,0x8424000A,0x70380372,0x11F80BE8,0x78000393,0x6C0004B3,0x5C000BEB,0x11F80BE8,0x78000393,0x6C0004B3,0x5C000BEB,0x5C000BEB,0xFE800552,0xFEAC08F6,0xFEAC0901,0xFE4000AB,0xD220000D,0xA0200006,0x86380001,0x82000022,0xFE5C0579,0xFE180059,0x8C00028E,0x6C0004B3, -0x1900BE8,0x6C0BE8,0x6C0BE8,0x6C0BE8,0x6C0BE8,0xCE480374,0xCE480374,0xCE480374,0x76480374,0x76480374,0x5A440375,0xC41C0288,0xC41C0288,0xC41C0288,0x82200009,0x82200009,0x5E2800A6,0x661C0288,0x661C0288,0x56180041,0x481C028A,0xA00BE8,0xA00BE8,0xA00BE8,0x800003ED,0x800003ED,0x5A100373,0x6800042A,0x6800042A,0x540000F6,0x460002EB,0x1440BE8, -0x1440BE8,0x4A000655,0x3E00068A,0x34000BEB,0xFE4C0461,0xFA64087D,0x6C0BE8,0xFE2C0081,0xD01C0005,0xA21C0005,0x90240021,0x761C0002,0xFA2C03F9,0xFC080049,0x840C028A,0x540000F6,0xE40BE8,0x940288,0x940288,0x940288,0x940288,0xA4700000,0xA4700000,0xA4700000,0x6C700000,0x6C700000,0x5A700001,0xDC0288,0xDC0288,0xDC0288,0x7A300001,0x7A300001, -0x5C4C0001,0x1BC0288,0x1BC0288,0x58000019,0x4800028A,0xDC0288,0xDC0288,0xDC0288,0x7A300001,0x7A300001,0x5C4C0001,0x1BC0288,0x1BC0288,0x58000019,0x4800028A,0x1BC0288,0x1BC0288,0x58000019,0x4800028A,0x4800028A,0xFA6C00C8,0xFC880120,0x940288,0xFE34001D,0xC4280000,0x9A280000,0x86380000,0x78180000,0xFA4800F4,0xFC14000D,0x1380288,0x58000019, -0x1380288,0xE00374,0xDAB80000,0x9AB80000,0x84B80001,0x1500372,0xAA6C0001,0x84900001,0x2DF80372,0x84100001,0x70000372,0x1500372,0xAA6C0001,0x84900001,0x2DF80372,0x84100001,0x70000372,0x2DF80372,0x84100001,0x70000372,0x70000372,0x1500372,0xAA6C0001,0x84900001,0x2DF80372,0x84100001,0x70000372,0x2DF80372,0x84100001,0x70000372,0x70000372,0x2DF80372, -0x84100001,0x70000372,0x70000372,0x70000372,0xF8A801E1,0xF00372,0xF4D80221,0xFC540048,0xDC080001,0xA4140000,0x84400001,0x82000019,0xFC8C01C2,0xFE200028,0x8C480000,0x70000372,0x1E00372,0x440374,0x440374,0x440374,0x440374,0x440374,0x440374,0x440374,0x440374,0x440374,0x440374,0x8C1C0000,0x8C1C0000,0x8C1C0000,0x8C1C0000,0x8C1C0000, -0x8C1C0000,0x4C1C0000,0x4C1C0000,0x4C1C0000,0x361C0001,0x680372,0x680372,0x680372,0x680372,0x680372,0x680372,0x4C000089,0x4C000089,0x4C000089,0x36000011,0xD00372,0xD00372,0xD00372,0x2C000179,0x22000372,0xF4380188,0x440374,0x440374,0xFE200028,0xDA1C0000,0xAA1C0000,0xAA1C0000,0x741C0000,0xFE1000FA,0xFE000014,0x62100000,0x4C000089, -0x940372,}; -static const uint32_t g_etc1_to_bc7_m6_table138[] = { -0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x400000,0x800000, -0x800000,0x800000,0x800000,0x14000001,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0xE2C0000,0xE2C0000,0xE2C0000,0x400000,0x5C0000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000, -0x2BC0000,0x1800000,0x1800000,0x1800000,0x3E000001,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x1800000,0x1800000,0x1800000,0x3E000001,0x1800000,0x1800000,0x1800000,0x3E000001,0x3E000001,0x880000,0x800000,0x800000,0x940000,0xA00000,0x2AC0000,0x2AC0000,0x2D40000,0x940000,0xA00000,0x1100000,0x1800000, -0x1100000,0xC80000,0xC80000,0xC80000,0xC80000,0x1280000,0x1280000,0x1280000,0x19FC0000,0x19FC0000,0x62000001,0x1280000,0x1280000,0x1280000,0x19FC0000,0x19FC0000,0x62000001,0x19FC0000,0x19FC0000,0x62000001,0x62000001,0x1280000,0x1280000,0x1280000,0x19FC0000,0x19FC0000,0x62000001,0x19FC0000,0x19FC0000,0x62000001,0x62000001,0x19FC0000, -0x19FC0000,0x62000001,0x62000001,0x62000001,0xE80000,0x2D40000,0xC80000,0x1100000,0x1500000,0x1A80000,0x1E80000,0x2DF80000,0x4F80000,0x1280000,0x1A80000,0x62000001,0x1A80000,0x11C0000,0x3A40000,0x57FC0000,0x8C000001,0x3A40000,0x57FC0000,0x8C000001,0x57FC0000,0x8C000001,0x8C000001,0x3A40000,0x57FC0000,0x8C000001,0x57FC0000,0x8C000001, -0x8C000001,0x57FC0000,0x8C000001,0x8C000001,0x8C000001,0x3A40000,0x57FC0000,0x8C000001,0x57FC0000,0x8C000001,0x8C000001,0x57FC0000,0x8C000001,0x8C000001,0x8C000001,0x57FC0000,0x8C000001,0x8C000001,0x8C000001,0x8C000001,0x1640000,0xF2C0000,0xF2C0000,0x1DC0000,0x41FC0000,0x71FC0000,0x8C000001,0x8C000001,0x3800000,0xFFC0000,0x87E00000,0x8C000001, -0x2BFC0000,0xA41EA8,0xFE800CD5,0xB47C0BE8,0x8C7C0BE9,0xFE5C073E,0xC25803A1,0x92640531,0x9E5406E6,0x8A5403AE,0x785406E6,0xFE300BF8,0xC82C028A,0x94440411,0xA628038E,0x8C2C000E,0x7A3403AE,0x8C2C0BE8,0x801C0413,0x72240533,0x642C0BEB,0xF41EA8,0xC6000C43,0x8C300BE9,0xA8000866,0x8C00039E,0x780806E6,0x92000EA7,0x800004F3,0x70000563,0x64000C64,0x1F01EA8, -0x72001164,0x66000EB4,0x5C00131B,0x50001EAC,0xFE780D71,0xF498186E,0xF8A019DD,0xFE440206,0xDA2C0011,0xAA2C0006,0x90340046,0x88240046,0xFE540C9B,0xFE240136,0x9218029D,0x70000563,0x15C1EA8,0xCC0BE8,0xFEA40291,0xAAA40288,0x8CA40289,0xEC800372,0xB0800005,0x8E880042,0x94800372,0x867800A5,0x78800372,0x1300BE8,0xC4340289,0x8E680289,0xAE140372,0x8C34000A, -0x78480372,0x1DF40BE8,0x8400033B,0x72000463,0x64000BEB,0x1300BE8,0xC4340289,0x8E680289,0xAE140372,0x8C34000A,0x78480372,0x1DF40BE8,0x8400033B,0x72000463,0x64000BEB,0x1DF40BE8,0x8400033B,0x72000463,0x64000BEB,0x64000BEB,0xFE94057B,0xF8C00934,0xFAC4090C,0xFE5400EA,0xDA30000D,0xA8300006,0x8E480001,0x8A100022,0xFE780595,0xFE300095,0x96080288,0x72000463, -0x1B00BE8,0x7C0BE8,0x7C0BE8,0x7C0BE8,0x7C0BE8,0xD6580374,0xD6580374,0xD6580374,0x7E580374,0x7E580374,0x62540375,0xCC2C0288,0xCC2C0288,0xCC2C0288,0x8A300009,0x8A300009,0x663800A6,0x6E2C0288,0x6E2C0288,0x5E280041,0x502C028A,0xB80BE8,0xB80BE8,0xB80BE8,0x8C00039D,0x8C00039D,0x62200373,0x7400039A,0x7400039A,0x5E00006A,0x500002A3,0x1740BE8, -0x1740BE8,0x500005CD,0x4A0005FA,0x3C000BEB,0xFE5804B9,0xFE6C08A5,0x7C0BE8,0xFE3C00A8,0xD82C0005,0xAA2C0005,0x98340021,0x7E2C0002,0xFE3C0428,0xFE180062,0x8C1C028A,0x5E00006A,0x1080BE8,0xA40288,0xA40288,0xA40288,0xA40288,0xAC800000,0xAC800000,0xAC800000,0x74800000,0x74800000,0x62800001,0xF40288,0xF40288,0xF40288,0x82400001,0x82400001, -0x645C0001,0x1F00288,0x1F00288,0x6000000A,0x5000028A,0xF40288,0xF40288,0xF40288,0x82400001,0x82400001,0x645C0001,0x1F00288,0x1F00288,0x6000000A,0x5000028A,0x1F00288,0x1F00288,0x6000000A,0x5000028A,0x5000028A,0xF68000DD,0xF4980139,0xA40288,0xF8500029,0xCC380000,0xA2380000,0x8E480000,0x80280000,0xF2600109,0xFE240014,0x15C0288,0x6000000A, -0x15C0288,0xF00374,0xE2C80000,0xA2C80000,0x8CC80001,0x1680372,0xB27C0001,0x8CA00001,0x39F80372,0x8C200001,0x78000372,0x1680372,0xB27C0001,0x8CA00001,0x39F80372,0x8C200001,0x78000372,0x39F80372,0x8C200001,0x78000372,0x78000372,0x1680372,0xB27C0001,0x8CA00001,0x39F80372,0x8C200001,0x78000372,0x39F80372,0x8C200001,0x78000372,0x78000372,0x39F80372, -0x8C200001,0x78000372,0x78000372,0x78000372,0xFEB401ED,0x9000372,0xFCE80221,0xFE6C0055,0xE4180001,0xAC240000,0x8C500001,0x8A00000D,0xFE9801D4,0xFE400032,0x94580000,0x78000372,0x3FC0372,0x540374,0x540374,0x540374,0x540374,0x540374,0x540374,0x540374,0x540374,0x540374,0x540374,0x942C0000,0x942C0000,0x942C0000,0x942C0000,0x942C0000, -0x942C0000,0x542C0000,0x542C0000,0x542C0000,0x3E2C0001,0x800372,0x800372,0x800372,0x800372,0x800372,0x800372,0x58000041,0x58000041,0x58000041,0x3E040001,0x1000372,0x1000372,0x1000372,0x38000131,0x2A000372,0xFC480188,0x540374,0x540374,0xFA340034,0xE22C0000,0xB22C0000,0xB22C0000,0x7C2C0000,0xFE200115,0xFE140019,0x6A200000,0x58000041, -0xB40372,}; -static const uint32_t g_etc1_to_bc7_m6_table139[] = { -0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0x580000,0xB00000, -0xB00000,0xB00000,0xB00000,0x1C000001,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x3C0000,0x400000,0x400000,0x400000,0x580000,0x7C0000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000, -0xD40000,0x1B00000,0x1B00000,0x1B00000,0x46000001,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x1B00000,0x1B00000,0x1B00000,0x46000001,0x1B00000,0x1B00000,0x1B00000,0x46000001,0x46000001,0x4980000,0x900000,0x900000,0xA80000,0xB40000,0xC40000,0xC40000,0xF00000,0xA80000,0xB40000,0x1300000,0x1B00000, -0x1300000,0xD80000,0xD80000,0xD80000,0xD80000,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x6A000001,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x6A000001,0x25F80000,0x25F80000,0x6A000001,0x6A000001,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x6A000001,0x25F80000,0x25F80000,0x6A000001,0x6A000001,0x25F80000, -0x25F80000,0x6A000001,0x6A000001,0x6A000001,0xFC0000,0xAE40000,0xD80000,0x3240000,0x16C0000,0x1CC0000,0x9F80000,0x37FC0000,0x50C0000,0x1400000,0x1CC0000,0x6A000001,0x1CC0000,0x12C0000,0x3BC0000,0x63FC0000,0x94000001,0x3BC0000,0x63FC0000,0x94000001,0x63FC0000,0x94000001,0x94000001,0x3BC0000,0x63FC0000,0x94000001,0x63FC0000,0x94000001, -0x94000001,0x63FC0000,0x94000001,0x94000001,0x94000001,0x3BC0000,0x63FC0000,0x94000001,0x63FC0000,0x94000001,0x94000001,0x63FC0000,0x94000001,0x94000001,0x94000001,0x63FC0000,0x94000001,0x94000001,0x94000001,0x94000001,0x1780000,0x1400000,0x1400000,0x1F80000,0x4FFC0000,0x7BFC0000,0x94000001,0x94000001,0x1980000,0x21FC0000,0x8FF00000,0x94000001, -0x3BFC0000,0xB41EA8,0xFE980D35,0xBC8C0BE8,0x948C0BE9,0xFE74078E,0xCA6803A1,0x9A740531,0xA66406E6,0x926403AE,0x806406E6,0xFE440C13,0xD03C028A,0x9C540411,0xAE38038E,0x943C000E,0x824403AE,0x943C0BE8,0x882C0413,0x7A340533,0x6C3C0BEB,0x10C1EA8,0xD8000BFB,0x94400BE9,0xBA0007BE,0x9608038E,0x801806E6,0x9E000DE7,0x8C00040B,0x7A000497,0x6C000C0F,0xBF81EA8, -0x7800109C,0x72000DB4,0x6600126C,0x58001EAC,0xFE8C0E18,0xFCA8186E,0xFEAC19E1,0xFE5C0296,0xE23C0011,0xB23C0006,0x98440046,0x90340046,0xFE700D55,0xFE3401B7,0x9A28029D,0x7A000497,0x17C1EA8,0xDC0BE8,0xFCB802A9,0xB2B40288,0x94B40289,0xF4900372,0xB8900005,0x96980042,0x9C900372,0x8E8800A5,0x80900372,0x3440BE8,0xCC440289,0x96780289,0xB6240372,0x9444000A, -0x80580372,0x27FC0BE8,0x8E000301,0x7C000422,0x6C000BEB,0x3440BE8,0xCC440289,0x96780289,0xB6240372,0x9444000A,0x80580372,0x27FC0BE8,0x8E000301,0x7C000422,0x6C000BEB,0x27FC0BE8,0x8E000301,0x7C000422,0x6C000BEB,0x6C000BEB,0xFCB005BD,0xFECC0938,0xFECC094C,0xFE6C0129,0xE240000D,0xB0400006,0x96580001,0x92200022,0xFE8805E8,0xFE4800B9,0x9E180288,0x7C000422, -0x1D40BE8,0x8C0BE8,0x8C0BE8,0x8C0BE8,0x8C0BE8,0xDE680374,0xDE680374,0xDE680374,0x86680374,0x86680374,0x6A640375,0xD43C0288,0xD43C0288,0xD43C0288,0x92400009,0x92400009,0x6E4800A6,0x763C0288,0x763C0288,0x66380041,0x583C028A,0xD00BE8,0xD00BE8,0xD00BE8,0x9E000375,0x9E000375,0x6A300373,0x8000032A,0x8000032A,0x6800001A,0x5A00028A,0x1A40BE8, -0x1A40BE8,0x5C000545,0x5000056A,0x44000BEB,0xFE6804EE,0xFA8408B8,0x8C0BE8,0xFE4C00D9,0xE03C0005,0xB23C0005,0xA0440021,0x863C0002,0xFE500455,0xFE300081,0x942C028A,0x6800001A,0x1280BE8,0xB40288,0xB40288,0xB40288,0xB40288,0xB4900000,0xB4900000,0xB4900000,0x7C900000,0x7C900000,0x6A900001,0x10C0288,0x10C0288,0x10C0288,0x8A500001,0x8A500001, -0x6C6C0001,0xBF80288,0xBF80288,0x6A000001,0x5800028A,0x10C0288,0x10C0288,0x10C0288,0x8A500001,0x8A500001,0x6C6C0001,0xBF80288,0xBF80288,0x6A000001,0x5800028A,0xBF80288,0xBF80288,0x6A000001,0x5800028A,0x5800028A,0xFE9000DD,0xFCA80139,0xB40288,0xFE5C002D,0xD4480000,0xAA480000,0x96580000,0x88380000,0xFA700109,0xFA400020,0x17C0288,0x6A000001, -0x17C0288,0x1000374,0xEAD80000,0xAAD80000,0x94D80001,0x1800372,0xBA8C0001,0x94B00001,0x45F80372,0x94300001,0x80000372,0x1800372,0xBA8C0001,0x94B00001,0x45F80372,0x94300001,0x80000372,0x45F80372,0x94300001,0x80000372,0x80000372,0x1800372,0xBA8C0001,0x94B00001,0x45F80372,0x94300001,0x80000372,0x45F80372,0x94300001,0x80000372,0x80000372,0x45F80372, -0x94300001,0x80000372,0x80000372,0x80000372,0xFCCC0202,0x1140372,0xF4F80244,0xFE800071,0xEC280001,0xB4340000,0x94600001,0x94000002,0xFEAC01F9,0xFE58004A,0x9C680000,0x80000372,0x13FC0372,0x640374,0x640374,0x640374,0x640374,0x640374,0x640374,0x640374,0x640374,0x640374,0x640374,0x9C3C0000,0x9C3C0000,0x9C3C0000,0x9C3C0000,0x9C3C0000, -0x9C3C0000,0x5C3C0000,0x5C3C0000,0x5C3C0000,0x463C0001,0x980372,0x980372,0x980372,0x980372,0x980372,0x980372,0x68000011,0x68000011,0x68000011,0x46140001,0x1300372,0x1300372,0x1300372,0x3E0000E1,0x32000372,0xF45801A5,0x640374,0x640374,0xFC48003D,0xEA3C0000,0xBA3C0000,0xBA3C0000,0x843C0000,0xFC380120,0xF8280029,0x72300000,0x68000011, -0xD80372,}; -static const uint32_t g_etc1_to_bc7_m6_table140[] = { -0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0xE80000, -0xE80000,0xE80000,0xE80000,0x26000000,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x540000,0x540000,0x540000,0x740000,0xA40000,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xA00001,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000, -0xF00000,0x1E80000,0x1E80000,0x1E80000,0x50000000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0xF00000,0x1E80000,0x1E80000,0x1E80000,0x50000000,0x1E80000,0x1E80000,0x1E80000,0x50000000,0x50000000,0xAC0000,0xA00001,0xA00001,0xBC0000,0xCC0000,0xDC0000,0xDC0000,0x1100000,0xBC0000,0xCC0000,0x1580000,0x1E80000, -0x1580000,0xE80001,0xE80001,0xE80001,0xE80001,0x15C0000,0x15C0000,0x15C0000,0x33F80000,0x33F80000,0x74000000,0x15C0000,0x15C0000,0x15C0000,0x33F80000,0x33F80000,0x74000000,0x33F80000,0x33F80000,0x74000000,0x74000000,0x15C0000,0x15C0000,0x15C0000,0x33F80000,0x33F80000,0x74000000,0x33F80000,0x33F80000,0x74000000,0x74000000,0x33F80000, -0x33F80000,0x74000000,0x74000000,0x74000000,0x1100000,0x4F80000,0xE80001,0x33C0000,0x1880000,0x1F00000,0x17FC0000,0x43FC0000,0x1240000,0x15C0000,0x1F00000,0x74000000,0x1F00000,0x13C0001,0x1D80000,0x71F80000,0x9E000000,0x1D80000,0x71F80000,0x9E000000,0x71F80000,0x9E000000,0x9E000000,0x1D80000,0x71F80000,0x9E000000,0x71F80000,0x9E000000, -0x9E000000,0x71F80000,0x9E000000,0x9E000000,0x9E000000,0x1D80000,0x71F80000,0x9E000000,0x71F80000,0x9E000000,0x9E000000,0x71F80000,0x9E000000,0x9E000000,0x9E000000,0x71F80000,0x9E000000,0x9E000000,0x9E000000,0x9E000000,0x58C0000,0x1540000,0x1540000,0x13FC0000,0x5FF80000,0x87F80000,0x9E000000,0x9E000000,0x1B00000,0x33FC0000,0x99E40000,0x9E000000, -0x4BFC0000,0xC41EAC,0xFEA40D93,0xC4A00BEB,0x9E9C0BEB,0xFE8407F4,0xD47C03A3,0xA2840533,0xAE7806E6,0x9A7403AE,0x887806E6,0xFE5C0C49,0xDA50028A,0xA6680413,0xB84C038E,0x9E4C000E,0x8A5403AE,0x9C500BE9,0x92400411,0x82440531,0x764C0BE9,0x3241EA8,0xE8080BE9,0x9E500BE8,0xC6000736,0xA01C038E,0x882C06E6,0xAE000D2F,0x98000345,0x840003FD,0x76000BE8,0x17FC1EA8, -0x84000FB8,0x78000C98,0x6C001198,0x62001EA8,0xFEA00EBE,0xF6BC18F4,0xF8C01A44,0xFE70034E,0xF04C000E,0xBC500006,0xA2580046,0x9A480046,0xFE800E11,0xFE500235,0xA438029D,0x840003FD,0x1A41EA8,0xEC0BEB,0xFEC802CA,0xBCC4028A,0x9EC4028A,0xFCA40373,0xC4A00002,0xA0AC0041,0xA4A40373,0x989C00A6,0x88A00375,0x1600BE8,0xD4580289,0x9E8C0288,0xBE380372,0x9C540009, -0x886C0374,0x35FC0BE8,0x9A0002CA,0x840003E4,0x76000BE8,0x1600BE8,0xD4580289,0x9E8C0288,0xBE380372,0x9C540009,0x886C0374,0x35FC0BE8,0x9A0002CA,0x840003E4,0x76000BE8,0x35FC0BE8,0x9A0002CA,0x840003E4,0x76000BE8,0x76000BE8,0xFEBC0611,0xF8E00975,0xFCE8094E,0xFE800189,0xEA54000D,0xBA540005,0x9E680002,0x9A380021,0xFEA40632,0xFE5C0116,0xA62C0289,0x840003E4, -0x1F80BE8,0x9C0BEB,0x9C0BEB,0x9C0BEB,0x9C0BEB,0xE8780372,0xE8780372,0xE8780372,0x90780372,0x90780372,0x74780372,0xDA500289,0xDA500289,0xDA500289,0x9A50000A,0x9A50000A,0x785C00A5,0x804C0289,0x804C0289,0x704C0042,0x624C0289,0x2E80BE8,0x2E80BE8,0x2E80BE8,0xAA0C0372,0xAA0C0372,0x74400372,0x8C0002D9,0x8C0002D9,0x74000005,0x62140288,0x1DC0BE8, -0x1DC0BE8,0x660004D8,0x5C0004E1,0x4E000BE8,0xFE840522,0xF49808F6,0x9C0BEB,0xFE680122,0xE6500006,0xB8500005,0xA8540022,0x904C0001,0xFE6404B5,0xFE4400B9,0x9E3C0289,0x74000005,0x1500BE8,0xC4028A,0xC4028A,0xC4028A,0xC4028A,0xBCA40001,0xBCA40001,0xBCA40001,0x86A00001,0x86A00001,0x74A00001,0x3240288,0x3240288,0x3240288,0x94600001,0x94600001, -0x74800000,0x17FC0288,0x17FC0288,0x740C0000,0x62000288,0x3240288,0x3240288,0x3240288,0x94600001,0x94600001,0x74800000,0x17FC0288,0x17FC0288,0x740C0000,0x62000288,0x17FC0288,0x17FC0288,0x740C0000,0x62000288,0x62000288,0xFEA000F4,0xF6BC0152,0xC4028A,0xFE78003D,0xD8600001,0xB25C0000,0xA0680000,0x904C0000,0xF8880120,0xFC580029,0x1A40288,0x740C0000, -0x1A40288,0x1140372,0xF2EC0001,0xB2EC0001,0x9EE80001,0x3980372,0xC49C0001,0x9EC00000,0x51FC0372,0x9E3C0000,0x88000374,0x3980372,0xC49C0001,0x9EC00000,0x51FC0372,0x9E3C0000,0x88000374,0x51FC0372,0x9E3C0000,0x88000374,0x88000374,0x3980372,0xC49C0001,0x9EC00000,0x51FC0372,0x9E3C0000,0x88000374,0x51FC0372,0x9E3C0000,0x88000374,0x88000374,0x51FC0372, -0x9E3C0000,0x88000374,0x88000374,0x88000374,0xF6E80221,0xB240372,0xFF0C0242,0xFE9C0091,0xF43C0001,0xBE440000,0x9E700000,0x9E000000,0xF8D00200,0xFA7C0071,0xA47C0000,0x88000374,0x23FC0372,0x780372,0x780372,0x780372,0x780372,0x780372,0x780372,0x780372,0x780372,0x780372,0x780372,0xA4500001,0xA4500001,0xA4500001,0xA4500001,0xA4500001, -0xA4500001,0x64500001,0x64500001,0x64500001,0x504C0001,0x2B00372,0x2B00372,0x2B00372,0x2B00372,0x2B00372,0x2B00372,0x76000001,0x76000001,0x76000001,0x50240000,0x1680372,0x1680372,0x1680372,0x4A00009D,0x3A000374,0xFE6C01A5,0x780372,0x780372,0xFE58004A,0xF0500001,0xC0500001,0xC0500001,0x8C500001,0xF84C0139,0xFE3C0032,0x78440001,0x76000001, -0xFC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table141[] = { -0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x8C0000,0x1180000, -0x1180000,0x1180000,0x1180000,0x2E000000,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x640000,0x640000,0x640000,0x8C0000,0xC80000,0xB00001,0xB00001,0xB00001,0xB00001,0xB00001,0xB00001,0xB00001,0xB00001,0xB00001,0xB00001,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000, -0x1080000,0x9F80000,0x9F80000,0x9F80000,0x58000000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x9F80000,0x9F80000,0x9F80000,0x58000000,0x9F80000,0x9F80000,0x9F80000,0x58000000,0x58000000,0x6BC0000,0xB00001,0xB00001,0x6CC0000,0xE00000,0x2F00000,0x2F00000,0x12C0000,0x6CC0000,0xE00000,0x1780000,0x9F80000, -0x1780000,0xF80001,0xF80001,0xF80001,0xF80001,0x1740000,0x1740000,0x1740000,0x3FF80000,0x3FF80000,0x7C000000,0x1740000,0x1740000,0x1740000,0x3FF80000,0x3FF80000,0x7C000000,0x3FF80000,0x3FF80000,0x7C000000,0x7C000000,0x1740000,0x1740000,0x1740000,0x3FF80000,0x3FF80000,0x7C000000,0x3FF80000,0x3FF80000,0x7C000000,0x7C000000,0x3FF80000, -0x3FF80000,0x7C000000,0x7C000000,0x7C000000,0x7200000,0xD080000,0xF80001,0x1540000,0x1A40000,0xBFC0000,0x25FC0000,0x4FF80000,0x1380000,0x1740000,0xBFC0000,0x7C000000,0xBFC0000,0x14C0001,0x1F00000,0x7DF80000,0xA6000000,0x1F00000,0x7DF80000,0xA6000000,0x7DF80000,0xA6000000,0xA6000000,0x1F00000,0x7DF80000,0xA6000000,0x7DF80000,0xA6000000, -0xA6000000,0x7DF80000,0xA6000000,0xA6000000,0xA6000000,0x1F00000,0x7DF80000,0xA6000000,0x7DF80000,0xA6000000,0xA6000000,0x7DF80000,0xA6000000,0xA6000000,0xA6000000,0x7DF80000,0xA6000000,0xA6000000,0xA6000000,0xA6000000,0x5A00000,0x1640000,0x1640000,0x27FC0000,0x6BFC0000,0x91F80000,0xA6000000,0xA6000000,0x3C40000,0x45FC0000,0xA1F40000,0xA6000000, -0x5BFC0000,0xD41EAC,0xFEBC0E0B,0xCCB00BEB,0xA6AC0BEB,0xFE980856,0xDC8C03A3,0xAA940533,0xB68806E6,0xA28403AE,0x908806E6,0xFE740C91,0xE260028A,0xAE780413,0xC05C038E,0xA65C000E,0x926403AE,0xA4600BE9,0x9A500411,0x8A540531,0x7E5C0BE9,0x33C1EA8,0xF0180BE9,0xA6600BE8,0xD80006F6,0xA82C038E,0x903C06E6,0xBA000CAF,0xA20002CE,0x8E0003B5,0x7E100BE8,0x23FC1EA8, -0x90000EF8,0x84000BA8,0x780010D8,0x6A001EA8,0xFEB40F7B,0xFECC18F4,0xFECC1A5C,0xFE8003FA,0xF85C000E,0xC4600006,0xAA680046,0xA2580046,0xFE900EA5,0xFE6002FA,0xAC48029D,0x8E0003B5,0x1C81EA8,0xFC0BEB,0xFEDC02EB,0xC4D4028A,0xA6D4028A,0xFEB4037B,0xCCB00002,0xA8BC0041,0xACB40373,0xA0AC00A6,0x90B00375,0x1780BE8,0xDC680289,0xA69C0288,0xC6480372,0xA4640009, -0x907C0374,0x41FC0BE8,0xA20002AA,0x900003B4,0x7E000BE8,0x1780BE8,0xDC680289,0xA69C0288,0xC6480372,0xA4640009,0x907C0374,0x41FC0BE8,0xA20002AA,0x900003B4,0x7E000BE8,0x41FC0BE8,0xA20002AA,0x900003B4,0x7E000BE8,0x7E000BE8,0xFED00640,0xFEEC098D,0xF4F80993,0xFE9801D5,0xF264000D,0xC2640005,0xA6780002,0xA2480021,0xFEB40682,0xFC80016E,0xAE3C0289,0x900003B4, -0xFFC0BE8,0xAC0BEB,0xAC0BEB,0xAC0BEB,0xAC0BEB,0xF0880372,0xF0880372,0xF0880372,0x98880372,0x98880372,0x7C880372,0xE2600289,0xE2600289,0xE2600289,0xA260000A,0xA260000A,0x806C00A5,0x885C0289,0x885C0289,0x785C0042,0x6A5C0289,0x3000BE8,0x3000BE8,0x3000BE8,0xB21C0372,0xB21C0372,0x7C500372,0x9E0002A1,0x9E0002A1,0x7C100005,0x6A240288,0x5FC0BE8, -0x5FC0BE8,0x72000478,0x64000489,0x56000BE8,0xFE90056E,0xFCA808F6,0xAC0BEB,0xFE780156,0xEE600006,0xC0600005,0xB0640022,0x985C0001,0xFE7804E6,0xFE5C00F5,0xA64C0289,0x7C100005,0x1700BE8,0xD4028A,0xD4028A,0xD4028A,0xD4028A,0xC4B40001,0xC4B40001,0xC4B40001,0x8EB00001,0x8EB00001,0x7CB00001,0x33C0288,0x33C0288,0x33C0288,0x9C700001,0x9C700001, -0x7C900000,0x23FC0288,0x23FC0288,0x7C1C0000,0x6A000288,0x33C0288,0x33C0288,0x33C0288,0x9C700001,0x9C700001,0x7C900000,0x23FC0288,0x23FC0288,0x7C1C0000,0x6A000288,0x23FC0288,0x23FC0288,0x7C1C0000,0x6A000288,0x6A000288,0xFAB40109,0xFECC0152,0xD4028A,0xFE88004A,0xE0700001,0xBA6C0000,0xA8780000,0x985C0000,0xFE940128,0xFE680034,0x1C80288,0x7C1C0000, -0x1C80288,0x1240372,0xFAFC0001,0xBAFC0001,0xA6F80001,0x3B00372,0xCCAC0001,0xA6D00000,0x5DFC0372,0xA64C0000,0x90000374,0x3B00372,0xCCAC0001,0xA6D00000,0x5DFC0372,0xA64C0000,0x90000374,0x5DFC0372,0xA64C0000,0x90000374,0x90000374,0x3B00372,0xCCAC0001,0xA6D00000,0x5DFC0372,0xA64C0000,0x90000374,0x5DFC0372,0xA64C0000,0x90000374,0x90000374,0x5DFC0372, -0xA64C0000,0x90000374,0x90000374,0x90000374,0xFEF80221,0x1380372,0xF71C0265,0xFEB000AA,0xFC4C0001,0xC6540000,0xA6800000,0xA6100000,0xFEDC0208,0xFE940080,0xAC8C0000,0x90000374,0x33FC0372,0x880372,0x880372,0x880372,0x880372,0x880372,0x880372,0x880372,0x880372,0x880372,0x880372,0xAC600001,0xAC600001,0xAC600001,0xAC600001,0xAC600001, -0xAC600001,0x6C600001,0x6C600001,0x6C600001,0x585C0001,0xC80372,0xC80372,0xC80372,0xC80372,0xC80372,0xC80372,0x7E100001,0x7E100001,0x7E100001,0x58340000,0x1980372,0x1980372,0x1980372,0x50000071,0x42000374,0xF67C01C2,0x880372,0x880372,0xFE680059,0xF8600001,0xC8600001,0xC8600001,0x94600001,0xFE580145,0xFE50003D,0x80540001,0x7E100001, -0x1200372,}; -static const uint32_t g_etc1_to_bc7_m6_table142[] = { -0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0x14C0000, -0x14C0000,0x14C0000,0x14C0000,0x36000000,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0x2740000,0x2740000,0x2740000,0xA40000,0xE80000,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0xC00001,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000, -0x1200000,0x15F80000,0x15F80000,0x15F80000,0x60000000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x1200000,0x15F80000,0x15F80000,0x15F80000,0x60000000,0x15F80000,0x15F80000,0x15F80000,0x60000000,0x60000000,0xECC0000,0xC00001,0xC00001,0x2E00000,0xF40000,0x1080000,0x1080000,0x1440000,0x2E00000,0xF40000,0x19C0000,0x15F80000, -0x19C0000,0x1080001,0x1080001,0x1080001,0x1080001,0x18C0000,0x18C0000,0x18C0000,0x4BF80000,0x4BF80000,0x84000000,0x18C0000,0x18C0000,0x18C0000,0x4BF80000,0x4BF80000,0x84000000,0x4BF80000,0x4BF80000,0x84000000,0x84000000,0x18C0000,0x18C0000,0x18C0000,0x4BF80000,0x4BF80000,0x84000000,0x4BF80000,0x4BF80000,0x84000000,0x84000000,0x4BF80000, -0x4BF80000,0x84000000,0x84000000,0x84000000,0x3340000,0x11C0000,0x1080001,0x3680000,0x1C00000,0x1BFC0000,0x33F80000,0x59FC0000,0x34C0000,0x18C0000,0x1BFC0000,0x84000000,0x1BFC0000,0x15C0001,0xDFC0000,0x89F80000,0xAE000000,0xDFC0000,0x89F80000,0xAE000000,0x89F80000,0xAE000000,0xAE000000,0xDFC0000,0x89F80000,0xAE000000,0x89F80000,0xAE000000, -0xAE000000,0x89F80000,0xAE000000,0xAE000000,0xAE000000,0xDFC0000,0x89F80000,0xAE000000,0x89F80000,0xAE000000,0xAE000000,0x89F80000,0xAE000000,0xAE000000,0xAE000000,0x89F80000,0xAE000000,0xAE000000,0xAE000000,0xAE000000,0x5B40000,0x3740000,0x3740000,0x3BFC0000,0x79FC0000,0x9BF80000,0xAE000000,0xAE000000,0x1DC0000,0x55FC0000,0xABC80000,0xAE000000, -0x69FC0000,0xE41EAC,0xFEC80E73,0xD4C00BEB,0xAEBC0BEB,0xFEA808EC,0xE49C03A3,0xB2A40533,0xBE9806E6,0xAA9403AE,0x989806E6,0xFE840CF4,0xEA70028A,0xB6880413,0xC86C038E,0xAE6C000E,0x9A7403AE,0xAC700BE9,0xA2600411,0x92640531,0x866C0BE9,0x1541EA8,0xF8280BE9,0xAE700BE8,0xE20406E6,0xB03C038E,0x984C06E6,0xC6000C4F,0xAC000292,0x980403A1,0x86200BE8,0x2FFC1EA8, -0x9C000E58,0x8A000AE8,0x7E00102C,0x72001EA8,0xFEBC1022,0xF6DC197E,0xF8E01AAF,0xFE9804BE,0xFA70000F,0xCC700006,0xB2780046,0xAA680046,0xFEA40F96,0xFE7403B7,0xB458029D,0x980403A1,0x1E81EA8,0x10C0BEB,0xFEEC032A,0xCCE4028A,0xAEE4028A,0xFEC8038D,0xD4C00002,0xB0CC0041,0xB4C40373,0xA8BC00A6,0x98C00375,0x1900BE8,0xE4780289,0xAEAC0288,0xCE580372,0xAC740009, -0x988C0374,0x4DFC0BE8,0xAC00028E,0x96000394,0x86000BE8,0x1900BE8,0xE4780289,0xAEAC0288,0xCE580372,0xAC740009,0x988C0374,0x4DFC0BE8,0xAC00028E,0x96000394,0x86000BE8,0x4DFC0BE8,0xAC00028E,0x96000394,0x86000BE8,0x86000BE8,0xFEE406A5,0xFB0409B3,0xFD080993,0xFEB0022E,0xFA74000D,0xCA740005,0xAE880002,0xAA580021,0xFAD406D1,0xFE9001B2,0xB64C0289,0x96000394, -0x1FF80BE8,0xBC0BEB,0xBC0BEB,0xBC0BEB,0xBC0BEB,0xF8980372,0xF8980372,0xF8980372,0xA0980372,0xA0980372,0x84980372,0xEA700289,0xEA700289,0xEA700289,0xAA70000A,0xAA70000A,0x887C00A5,0x906C0289,0x906C0289,0x806C0042,0x726C0289,0x3180BE8,0x3180BE8,0x3180BE8,0xBA2C0372,0xBA2C0372,0x84600372,0xAA000289,0xAA000289,0x84200005,0x72340288,0x11FC0BE8, -0x11FC0BE8,0x7C000432,0x6C000414,0x5E000BE8,0xFEA005A5,0xF4B80933,0xBC0BEB,0xFE880193,0xF6700006,0xC8700005,0xB8740022,0xA06C0001,0xFC8C0549,0xFE680138,0xAE5C0289,0x84200005,0x1940BE8,0xE4028A,0xE4028A,0xE4028A,0xE4028A,0xCCC40001,0xCCC40001,0xCCC40001,0x96C00001,0x96C00001,0x84C00001,0x1540288,0x1540288,0x1540288,0xA4800001,0xA4800001, -0x84A00000,0x2FFC0288,0x2FFC0288,0x842C0000,0x72000288,0x1540288,0x1540288,0x1540288,0xA4800001,0xA4800001,0x84A00000,0x2FFC0288,0x2FFC0288,0x842C0000,0x72000288,0x2FFC0288,0x2FFC0288,0x842C0000,0x72000288,0x72000288,0xF6C80120,0xF6DC016D,0xE4028A,0xFE980061,0xE8800001,0xC27C0000,0xB0880000,0xA06C0000,0xFAAC0139,0xFE800048,0x1E80288,0x842C0000, -0x1E80288,0x1340372,0xFF0C0002,0xC30C0001,0xAF080001,0x1C80372,0xD4BC0001,0xAEE00000,0x69FC0372,0xAE5C0000,0x98000374,0x1C80372,0xD4BC0001,0xAEE00000,0x69FC0372,0xAE5C0000,0x98000374,0x69FC0372,0xAE5C0000,0x98000374,0x98000374,0x1C80372,0xD4BC0001,0xAEE00000,0x69FC0372,0xAE5C0000,0x98000374,0x69FC0372,0xAE5C0000,0x98000374,0x98000374,0x69FC0372, -0xAE5C0000,0x98000374,0x98000374,0x98000374,0xFB0C0242,0x1480372,0xFF2C0265,0xFEC800D0,0xFE680005,0xCE640000,0xAE900000,0xAE200000,0xFEF0022D,0xFEAC00A4,0xB49C0000,0x98000374,0x41FC0372,0x980372,0x980372,0x980372,0x980372,0x980372,0x980372,0x980372,0x980372,0x980372,0x980372,0xB4700001,0xB4700001,0xB4700001,0xB4700001,0xB4700001, -0xB4700001,0x74700001,0x74700001,0x74700001,0x606C0001,0xE00372,0xE00372,0xE00372,0xE00372,0xE00372,0xE00372,0x86200001,0x86200001,0x86200001,0x60440000,0x1CC0372,0x1CC0372,0x1CC0372,0x5C000041,0x4A000374,0xFE8C01C2,0x980372,0x980372,0xFA7C0071,0xFA700002,0xD0700001,0xD0700001,0x9C700001,0xFC700152,0xFC600055,0x88640001,0x86200001, -0x1400372,}; -static const uint32_t g_etc1_to_bc7_m6_table143[] = { -0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0xBC0000,0x17C0000, -0x17C0000,0x17C0000,0x17C0000,0x3E000000,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0xA840000,0xA840000,0xA840000,0xBC0000,0x10C0000,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000, -0x1380000,0x21F80000,0x21F80000,0x21F80000,0x68000000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x21F80000,0x21F80000,0x21F80000,0x68000000,0x21F80000,0x21F80000,0x21F80000,0x68000000,0x68000000,0xE00000,0xD00001,0xD00001,0xF40000,0x1080000,0x11C0000,0x11C0000,0x1600000,0xF40000,0x1080000,0x1BC0000,0x21F80000, -0x1BC0000,0x1180001,0x1180001,0x1180001,0x1180001,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x8C000000,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x8C000000,0x57F80000,0x57F80000,0x8C000000,0x8C000000,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x8C000000,0x57F80000,0x57F80000,0x8C000000,0x8C000000,0x57F80000, -0x57F80000,0x8C000000,0x8C000000,0x8C000000,0x1480000,0x12C0000,0x1180001,0x1800000,0x1D80000,0x29FC0000,0x3FFC0000,0x65F40000,0x3600000,0x1A40000,0x29FC0000,0x8C000000,0x29FC0000,0x16C0001,0x25FC0000,0x95F80000,0xB6000000,0x25FC0000,0x95F80000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0x25FC0000,0x95F80000,0xB6000000,0x95F80000,0xB6000000, -0xB6000000,0x95F80000,0xB6000000,0xB6000000,0xB6000000,0x25FC0000,0x95F80000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0xB6000000,0xB6000000,0x1CC0000,0xB840000,0xB840000,0x4FFC0000,0x87F80000,0xA5F80000,0xB6000000,0xB6000000,0x3F00000,0x67FC0000,0xB3D80000,0xB6000000, -0x79FC0000,0xF41EAC,0xFEDC0EEC,0xDCD00BEB,0xB6CC0BEB,0xFEBC096E,0xECAC03A3,0xBAB40533,0xC6A806E6,0xB2A403AE,0xA0A806E6,0xFE980D51,0xF280028A,0xBE980413,0xD07C038E,0xB67C000E,0xA28403AE,0xB4800BE9,0xAA700411,0x9A740531,0x8E7C0BE9,0x16C1EA8,0xFE380BEF,0xB6800BE8,0xEA1406E6,0xB84C038E,0xA05C06E6,0xD2000C0F,0xB608028A,0xA01403A1,0x8E300BE8,0x3BFC1EA8, -0xA6000DDB,0x96000A18,0x8A000F9C,0x7A001EA8,0xFED010D1,0xFEEC197E,0xFEEC1ACB,0xFEAC059E,0xFE840027,0xD4800006,0xBA880046,0xB2780046,0xFEB4101B,0xFE900462,0xBC68029D,0xA01403A1,0x7FC1EA8,0x11C0BEB,0xFF000363,0xD4F4028A,0xB6F4028A,0xFEDC03AB,0xDCD00002,0xB8DC0041,0xBCD40373,0xB0CC00A6,0xA0D00375,0x1A80BE8,0xEC880289,0xB6BC0288,0xD6680372,0xB4840009, -0xA09C0374,0x59FC0BE8,0xB6000288,0xA000037D,0x8E000BE8,0x1A80BE8,0xEC880289,0xB6BC0288,0xD6680372,0xB4840009,0xA09C0374,0x59FC0BE8,0xB6000288,0xA000037D,0x8E000BE8,0x59FC0BE8,0xB6000288,0xA000037D,0x8E000BE8,0x8E000BE8,0xFEF806DA,0xFF0C09DB,0xF51809DA,0xFEC00296,0xFE88001A,0xD2840005,0xB6980002,0xB2680021,0xFEDC06F9,0xFEA40224,0xBE5C0289,0xA000037D, -0x2DFC0BE8,0xCC0BEB,0xCC0BEB,0xCC0BEB,0xCC0BEB,0xFEA80373,0xFEA80373,0xFEA80373,0xA8A80372,0xA8A80372,0x8CA80372,0xF2800289,0xF2800289,0xF2800289,0xB280000A,0xB280000A,0x908C00A5,0x987C0289,0x987C0289,0x887C0042,0x7A7C0289,0x3300BE8,0x3300BE8,0x3300BE8,0xC23C0372,0xC23C0372,0x8C700372,0xB2100289,0xB2100289,0x8C300005,0x7A440288,0x1DFC0BE8, -0x1DFC0BE8,0x840003E4,0x760003C9,0x66000BE8,0xFCB805F6,0xFCC80933,0xCC0BEB,0xFE9801DA,0xFE800006,0xD0800005,0xC0840022,0xA87C0001,0xFC9C0581,0xFE800171,0xB66C0289,0x8C300005,0x1B40BE8,0xF4028A,0xF4028A,0xF4028A,0xF4028A,0xD4D40001,0xD4D40001,0xD4D40001,0x9ED00001,0x9ED00001,0x8CD00001,0x16C0288,0x16C0288,0x16C0288,0xAC900001,0xAC900001, -0x8CB00000,0x3BFC0288,0x3BFC0288,0x8C3C0000,0x7A000288,0x16C0288,0x16C0288,0x16C0288,0xAC900001,0xAC900001,0x8CB00000,0x3BFC0288,0x3BFC0288,0x8C3C0000,0x7A000288,0x3BFC0288,0x3BFC0288,0x8C3C0000,0x7A000288,0x7A000288,0xFED80120,0xFEEC016D,0xF4028A,0xFEB40071,0xF0900001,0xCA8C0000,0xB8980000,0xA87C0000,0xFCC00152,0xFE980055,0x7FC0288,0x8C3C0000, -0x7FC0288,0x1440372,0xFF1C0011,0xCB1C0001,0xB7180001,0x1E00372,0xDCCC0001,0xB6F00000,0x75FC0372,0xB66C0000,0xA0000374,0x1E00372,0xDCCC0001,0xB6F00000,0x75FC0372,0xB66C0000,0xA0000374,0x75FC0372,0xB66C0000,0xA0000374,0xA0000374,0x1E00372,0xDCCC0001,0xB6F00000,0x75FC0372,0xB66C0000,0xA0000374,0x75FC0372,0xB66C0000,0xA0000374,0xA0000374,0x75FC0372, -0xB66C0000,0xA0000374,0xA0000374,0xA0000374,0xFF140262,0x5580372,0xF73C028A,0xFCE800F2,0xFC8C0019,0xD6740000,0xB6A00000,0xB6300000,0xFD0C0242,0xFEC000C1,0xBCAC0000,0xA0000374,0x51FC0372,0xA80372,0xA80372,0xA80372,0xA80372,0xA80372,0xA80372,0xA80372,0xA80372,0xA80372,0xA80372,0xBC800001,0xBC800001,0xBC800001,0xBC800001,0xBC800001, -0xBC800001,0x7C800001,0x7C800001,0x7C800001,0x687C0001,0xF80372,0xF80372,0xF80372,0xF80372,0xF80372,0xF80372,0x8E300001,0x8E300001,0x8E300001,0x68540000,0x1FC0372,0x1FC0372,0x1FC0372,0x66000028,0x52000374,0xF69C01E1,0xA80372,0xA80372,0xFC8C0082,0xFE800005,0xD8800001,0xD8800001,0xA4800001,0xF884016D,0xFC740062,0x90740001,0x8E300001, -0x1640372,}; -static const uint32_t g_etc1_to_bc7_m6_table144[] = { -0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x1B00000, -0x1B00000,0x1B00000,0x1B00000,0x46000001,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x4980000,0x4980000,0x4980000,0xD40000,0x1300000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0xE40000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000, -0x3500000,0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x3500000,0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0x2DFC0000,0x2DFC0000,0x2DFC0000,0x70000001,0x70000001,0xF40000,0xE40000,0xE40000,0x1080000,0x31C0000,0x3340000,0x3340000,0x1800000,0x1080000,0x31C0000,0x1E40000,0x2DFC0000, -0x1E40000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x3BC0000,0x3BC0000,0x3BC0000,0x63FC0000,0x63FC0000,0x94000001,0x3BC0000,0x3BC0000,0x3BC0000,0x63FC0000,0x63FC0000,0x94000001,0x63FC0000,0x63FC0000,0x94000001,0x94000001,0x3BC0000,0x3BC0000,0x3BC0000,0x63FC0000,0x63FC0000,0x94000001,0x63FC0000,0x63FC0000,0x94000001,0x94000001,0x63FC0000, -0x63FC0000,0x94000001,0x94000001,0x94000001,0x15C0000,0x1400000,0x12C0000,0x1980000,0x1F80000,0x3BFC0000,0x4FFC0000,0x71F80000,0x1780000,0x3BC0000,0x3BFC0000,0x94000001,0x3BFC0000,0x1800000,0x41FC0000,0xA1FC0000,0xBE000001,0x41FC0000,0xA1FC0000,0xBE000001,0xA1FC0000,0xBE000001,0xBE000001,0x41FC0000,0xA1FC0000,0xBE000001,0xA1FC0000,0xBE000001, -0xBE000001,0xA1FC0000,0xBE000001,0xBE000001,0xBE000001,0x41FC0000,0xA1FC0000,0xBE000001,0xA1FC0000,0xBE000001,0xBE000001,0xA1FC0000,0xBE000001,0xBE000001,0xBE000001,0xA1FC0000,0xBE000001,0xBE000001,0xBE000001,0xBE000001,0x3E00000,0x5980000,0x5980000,0x65FC0000,0x95FC0000,0xB1F40000,0xBE000001,0xBE000001,0x13FC0000,0x79FC0000,0xBDCC0000,0xBE000001, -0x89FC0000,0x1081EA8,0xFEE80F9C,0xE6E00BE8,0xBEE00BE9,0xFED00A18,0xF4BC03A1,0xC4C80531,0xD0B806E6,0xBCB803AE,0xAAB806E6,0xFEB00DDB,0xFA90028A,0xC6A80411,0xD88C038E,0xBE90000E,0xAC9803AE,0xBE900BE8,0xB2800413,0xA4880533,0x96900BEB,0x1881EA8,0xFE580C0F,0xBE940BE9,0xF22806E6,0xC05C038E,0xAA6C06E6,0xE0000BEF,0xBE18028A,0xA82403A3,0x96440BEB,0x49F81EA8, -0xB2000D51,0xA000096E,0x90000EEC,0x82001EAC,0xFEE41196,0xF9001A08,0xFB041B18,0xFEC006A1,0xFE9C0075,0xDC900006,0xC2980046,0xBA880046,0xFED410EA,0xFEA40584,0xC47C029D,0xA82403A3,0x19FC1EA8,0x1300BE8,0xFF1003C9,0xDD080288,0xBF080289,0xFEF403E4,0xE2E40005,0xC0EC0042,0xC6E40372,0xB8DC00A5,0xAAE40372,0x1C40BE8,0xF6980289,0xC0CC0289,0xE0780372,0xBE98000A, -0xAAAC0372,0x67F80BE8,0xBE140289,0xAA000373,0x96000BEB,0x1C40BE8,0xF6980289,0xC0CC0289,0xE0780372,0xBE98000A,0xAAAC0372,0x67F80BE8,0xBE140289,0xAA000373,0x96000BEB,0x67F80BE8,0xBE140289,0xAA000373,0x96000BEB,0x96000BEB,0xFD10074D,0xFD2809F6,0xFF2C09D9,0xFEDC0312,0xFEA4003E,0xDA940006,0xC0AC0001,0xBC740022,0xFEF80752,0xFEC00281,0xC86C0288,0xAA000373, -0x3FF80BE8,0xE00BE8,0xE00BE8,0xE00BE8,0xE00BE8,0xFEBC037D,0xFEBC037D,0xFEBC037D,0xB0BC0374,0xB0BC0374,0x94B80375,0xFE900288,0xFE900288,0xFE900288,0xBC940009,0xBC940009,0x989C00A6,0xA0900288,0xA0900288,0x908C0041,0x8290028A,0x14C0BE8,0x14C0BE8,0x14C0BE8,0xCA500372,0xCA500372,0x94840373,0xBA240289,0xBA240289,0x96440002,0x8454028A,0x2BF80BE8, -0x2BF80BE8,0x900003AB,0x7E000363,0x6E000BEB,0xFECC062C,0xF4D80975,0xE00BE8,0xFEAC023D,0xFE940011,0xDC900005,0xCA980021,0xB0900002,0xFEB405B5,0xFE9801C6,0xBE80028A,0x96440002,0x1DC0BE8,0x1080288,0x1080288,0x1080288,0x1080288,0xDEE40000,0xDEE40000,0xDEE40000,0xA6E40000,0xA6E40000,0x94E40001,0x1880288,0x1880288,0x1880288,0xB4A40001,0xB4A40001, -0x96C00001,0x49F80288,0x49F80288,0x94540001,0x8200028A,0x1880288,0x1880288,0x1880288,0xB4A40001,0xB4A40001,0x96C00001,0x49F80288,0x49F80288,0x94540001,0x8200028A,0x49F80288,0x49F80288,0x94540001,0x8200028A,0x8200028A,0xFAEC0139,0xF9000188,0x1080288,0xFEC40088,0xFE9C0000,0xD49C0000,0xC0AC0000,0xB28C0000,0xFED0015A,0xFEB00071,0x19FC0288,0x94540001, -0x19FC0288,0x1540374,0xFF300028,0xD52C0000,0xBF2C0001,0x1FC0372,0xE4E00001,0xBF040001,0x83F80372,0xBE840001,0xAA000372,0x1FC0372,0xE4E00001,0xBF040001,0x83F80372,0xBE840001,0xAA000372,0x83F80372,0xBE840001,0xAA000372,0xAA000372,0x1FC0372,0xE4E00001,0xBF040001,0x83F80372,0xBE840001,0xAA000372,0x83F80372,0xBE840001,0xAA000372,0xAA000372,0x83F80372, -0xBE840001,0xAA000372,0xAA000372,0xAA000372,0xFF340265,0x16C0372,0xFF4C0290,0xFF000120,0xFEA8002D,0xDE880000,0xBEB40001,0xBE480001,0xFF180262,0xFEE400F4,0xC6BC0000,0xAA000372,0x61FC0372,0xB80374,0xB80374,0xB80374,0xB80374,0xB80374,0xB80374,0xB80374,0xB80374,0xB80374,0xB80374,0xC6900000,0xC6900000,0xC6900000,0xC6900000,0xC6900000, -0xC6900000,0x86900000,0x86900000,0x86900000,0x70900001,0x1140372,0x1140372,0x1140372,0x1140372,0x1140372,0x1140372,0x96440001,0x96440001,0x96440001,0x70680001,0xFF80372,0xFF80372,0xFF80372,0x70000011,0x5C000372,0xFEAC01E5,0xB80374,0xB80374,0xFEA00091,0xFE94000D,0xE4900000,0xE4900000,0xAE900000,0xFE900179,0xFC880080,0x9C840000,0x96440001, -0x18C0372,}; -static const uint32_t g_etc1_to_bc7_m6_table145[] = { -0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0x1E40000, -0x1E40000,0x1E40000,0x1E40000,0x4E000001,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0xCA80000,0xCA80000,0xCA80000,0xEC0000,0x1540000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0x3680000,0x3680000,0x3680000,0x3680000,0x3680000, -0x3680000,0x39FC0000,0x39FC0000,0x39FC0000,0x78000001,0x3680000,0x3680000,0x3680000,0x3680000,0x3680000,0x3680000,0x39FC0000,0x39FC0000,0x39FC0000,0x78000001,0x39FC0000,0x39FC0000,0x39FC0000,0x78000001,0x78000001,0x1040000,0xF40000,0xF40000,0x11C0000,0x3300000,0x14C0000,0x14C0000,0x1980000,0x11C0000,0x3300000,0x5FC0000,0x39FC0000, -0x5FC0000,0x13C0000,0x13C0000,0x13C0000,0x13C0000,0x1D40000,0x1D40000,0x1D40000,0x6FFC0000,0x6FFC0000,0x9C000001,0x1D40000,0x1D40000,0x1D40000,0x6FFC0000,0x6FFC0000,0x9C000001,0x6FFC0000,0x6FFC0000,0x9C000001,0x9C000001,0x1D40000,0x1D40000,0x1D40000,0x6FFC0000,0x6FFC0000,0x9C000001,0x6FFC0000,0x6FFC0000,0x9C000001,0x9C000001,0x6FFC0000, -0x6FFC0000,0x9C000001,0x9C000001,0x9C000001,0x1700000,0x1500000,0x13C0000,0x3AC0000,0x11FC0000,0x49FC0000,0x5DF80000,0x7BFC0000,0x18C0000,0x1D40000,0x49FC0000,0x9C000001,0x49FC0000,0x1900000,0x59FC0000,0xADFC0000,0xC6000001,0x59FC0000,0xADFC0000,0xC6000001,0xADFC0000,0xC6000001,0xC6000001,0x59FC0000,0xADFC0000,0xC6000001,0xADFC0000,0xC6000001, -0xC6000001,0xADFC0000,0xC6000001,0xC6000001,0xC6000001,0x59FC0000,0xADFC0000,0xC6000001,0xADFC0000,0xC6000001,0xC6000001,0xADFC0000,0xC6000001,0xC6000001,0xC6000001,0xADFC0000,0xC6000001,0xC6000001,0xC6000001,0xC6000001,0x3F40000,0xDA80000,0xDA80000,0x79FC0000,0xA3FC0000,0xBBF40000,0xC6000001,0xC6000001,0x31FC0000,0x8BFC0000,0xC5DC0000,0xC6000001, -0x99FC0000,0x1181EA8,0xFF00102C,0xEEF00BE8,0xC6F00BE9,0xFEE80AE8,0xFCCC03A1,0xCCD80531,0xD8C806E6,0xC4C803AE,0xB2C806E6,0xFEC40E58,0xFEA40292,0xCEB80411,0xE09C038E,0xC6A0000E,0xB4A803AE,0xC6A00BE8,0xBA900413,0xAC980533,0x9EA00BEB,0x1A01EA8,0xFE700C4F,0xC6A40BE9,0xFA3806E6,0xC86C038E,0xB27C06E6,0xEA0C0BE9,0xC628028A,0xB03403A3,0x9E540BEB,0x55F81EA8, -0xBC000CF4,0xAA0008EC,0x9A000E73,0x8A001EAC,0xFEF81255,0xFF0C1A18,0xFF0C1B58,0xFED4078E,0xFEB000ED,0xE4A00006,0xCAA80046,0xC2980046,0xFEDC11C3,0xFEC00675,0xCC8C029D,0xB03403A3,0x27FC1EA8,0x1400BE8,0xFF240414,0xE5180288,0xC7180289,0xFF040432,0xEAF40005,0xC8FC0042,0xCEF40372,0xC0EC00A5,0xB2F40372,0x1DC0BE8,0xFEA80289,0xC8DC0289,0xE8880372,0xC6A8000A, -0xB2BC0372,0x73F80BE8,0xC6240289,0xB2080372,0x9E000BEB,0x1DC0BE8,0xFEA80289,0xC8DC0289,0xE8880372,0xC6A8000A,0xB2BC0372,0x73F80BE8,0xC6240289,0xB2080372,0x9E000BEB,0x73F80BE8,0xC6240289,0xB2080372,0x9E000BEB,0x9E000BEB,0xFF20078E,0xF5380A38,0xF73C0A20,0xFEEC0395,0xFEBC007E,0xE2A40006,0xC8BC0001,0xC4840022,0xFF0807A3,0xFEDC0305,0xD07C0288,0xB2080372, -0x4DFC0BE8,0xF00BE8,0xF00BE8,0xF00BE8,0xF00BE8,0xFED00394,0xFED00394,0xFED00394,0xB8CC0374,0xB8CC0374,0x9CC80375,0xFEA4028E,0xFEA4028E,0xFEA4028E,0xC4A40009,0xC4A40009,0xA0AC00A6,0xA8A00288,0xA8A00288,0x989C0041,0x8AA0028A,0x1640BE8,0x1640BE8,0x1640BE8,0xD2600372,0xD2600372,0x9C940373,0xC2340289,0xC2340289,0x9E540002,0x8C64028A,0x37F80BE8, -0x37F80BE8,0x9A00038D,0x8800032A,0x76000BEB,0xFED80672,0xFCE80975,0xF00BE8,0xFEC4028C,0xFEAC0031,0xE4A00005,0xD2A80021,0xB8A00002,0xFEBC061A,0xFCAC0225,0xC690028A,0x9E540002,0x1FC0BE8,0x1180288,0x1180288,0x1180288,0x1180288,0xE6F40000,0xE6F40000,0xE6F40000,0xAEF40000,0xAEF40000,0x9CF40001,0x1A00288,0x1A00288,0x1A00288,0xBCB40001,0xBCB40001, -0x9ED00001,0x55F80288,0x55F80288,0x9C640001,0x8A00028A,0x1A00288,0x1A00288,0x1A00288,0xBCB40001,0xBCB40001,0x9ED00001,0x55F80288,0x55F80288,0x9C640001,0x8A00028A,0x55F80288,0x55F80288,0x9C640001,0x8A00028A,0x8A00028A,0xF7000152,0xFF0C0190,0x1180288,0xFEDC0091,0xFEB00004,0xDCAC0000,0xC8BC0000,0xBA9C0000,0xF8EC016D,0xFEC40080,0x27FC0288,0x9C640001, -0x27FC0288,0x1640374,0xFF440041,0xDD3C0000,0xC73C0001,0x19FC0372,0xECF00001,0xC7140001,0x8FF80372,0xC6940001,0xB2000372,0x19FC0372,0xECF00001,0xC7140001,0x8FF80372,0xC6940001,0xB2000372,0x8FF80372,0xC6940001,0xB2000372,0xB2000372,0x19FC0372,0xECF00001,0xC7140001,0x8FF80372,0xC6940001,0xB2000372,0x8FF80372,0xC6940001,0xB2000372,0xB2000372,0x8FF80372, -0xC6940001,0xB2000372,0xB2000372,0xB2000372,0xFB480288,0x77C0372,0xF96002AD,0xFF14013D,0xFECC0055,0xE6980000,0xC6C40001,0xC6580001,0xF1400288,0xFD040120,0xCECC0000,0xB2000372,0x71FC0372,0xC80374,0xC80374,0xC80374,0xC80374,0xC80374,0xC80374,0xC80374,0xC80374,0xC80374,0xC80374,0xCEA00000,0xCEA00000,0xCEA00000,0xCEA00000,0xCEA00000, -0xCEA00000,0x8EA00000,0x8EA00000,0x8EA00000,0x78A00001,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x9E540001,0x9E540001,0x9E540001,0x78780001,0x1BF80372,0x1BF80372,0x1BF80372,0x78000002,0x64000372,0xF8C00200,0xC80374,0xC80374,0xFEAC00B4,0xFEA80019,0xECA00000,0xECA00000,0xB6A00000,0xFEA0019A,0xFC9C0091,0xA4940000,0x9E540001, -0x1AC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table146[] = { -0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x7FC0000, -0x7FC0000,0x7FC0000,0x7FC0000,0x56000001,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xBC0000,0xBC0000,0xBC0000,0x1040000,0x1740000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x1040000,0x3800000,0x3800000,0x3800000,0x3800000,0x3800000, -0x3800000,0x45FC0000,0x45FC0000,0x45FC0000,0x80000001,0x3800000,0x3800000,0x3800000,0x3800000,0x3800000,0x3800000,0x45FC0000,0x45FC0000,0x45FC0000,0x80000001,0x45FC0000,0x45FC0000,0x45FC0000,0x80000001,0x80000001,0x3140000,0x1040000,0x1040000,0x52C0000,0x3440000,0x1600000,0x1600000,0x1B40000,0x52C0000,0x3440000,0x15FC0000,0x45FC0000, -0x15FC0000,0x14C0000,0x14C0000,0x14C0000,0x14C0000,0x1EC0000,0x1EC0000,0x1EC0000,0x7BFC0000,0x7BFC0000,0xA4000001,0x1EC0000,0x1EC0000,0x1EC0000,0x7BFC0000,0x7BFC0000,0xA4000001,0x7BFC0000,0x7BFC0000,0xA4000001,0xA4000001,0x1EC0000,0x1EC0000,0x1EC0000,0x7BFC0000,0x7BFC0000,0xA4000001,0x7BFC0000,0x7BFC0000,0xA4000001,0xA4000001,0x7BFC0000, -0x7BFC0000,0xA4000001,0xA4000001,0xA4000001,0x5800000,0x9600000,0x14C0000,0x1C40000,0x25FC0000,0x59FC0000,0x69FC0000,0x87F40000,0x1A00000,0x1EC0000,0x59FC0000,0xA4000001,0x59FC0000,0x1A00000,0x71FC0000,0xB9FC0000,0xCE000001,0x71FC0000,0xB9FC0000,0xCE000001,0xB9FC0000,0xCE000001,0xCE000001,0x71FC0000,0xB9FC0000,0xCE000001,0xB9FC0000,0xCE000001, -0xCE000001,0xB9FC0000,0xCE000001,0xCE000001,0xCE000001,0x71FC0000,0xB9FC0000,0xCE000001,0xB9FC0000,0xCE000001,0xCE000001,0xB9FC0000,0xCE000001,0xCE000001,0xCE000001,0xB9FC0000,0xCE000001,0xCE000001,0xCE000001,0xCE000001,0x1BFC0000,0x1BC0000,0x1BC0000,0x8DFC0000,0xB1FC0000,0xC5F40000,0xCE000001,0xCE000001,0x4FFC0000,0x9BFC0000,0xCDEC0000,0xCE000001, -0xA7FC0000,0x1281EA8,0xFF0C10D8,0xF7000BE8,0xCF000BE9,0xFEF40BA8,0xFEDC03B5,0xD4E80531,0xE0D806E6,0xCCD803AE,0xBAD806E6,0xFEDC0EF8,0xFEB802CE,0xD6C80411,0xE8AC038E,0xCEB0000E,0xBCB803AE,0xCEB00BE8,0xC2A00413,0xB4A80533,0xA6B00BEB,0x1B81EA8,0xFE880CAF,0xCEB40BE9,0xFE4C06F6,0xD07C038E,0xBA8C06E6,0xF21C0BE9,0xCE38028A,0xB84403A3,0xA6640BEB,0x61F81EA8, -0xC4000C91,0xB2000856,0xA0000E0B,0x92001EAC,0xFF0C1316,0xF9201A96,0xFB241B85,0xFEEC08C9,0xFEC40195,0xECB00006,0xD2B80046,0xCAA80046,0xFEF81262,0xFED0075B,0xD49C029D,0xB84403A3,0x37FC1EA8,0x1500BE8,0xFF340489,0xED280288,0xCF280289,0xFF180478,0xF3040005,0xD10C0042,0xD7040372,0xC8FC00A5,0xBB040372,0x1F40BE8,0xFEC002A1,0xD0EC0289,0xF0980372,0xCEB8000A, -0xBACC0372,0x7FF80BE8,0xCE340289,0xBA180372,0xA6000BEB,0x1F40BE8,0xFEC002A1,0xD0EC0289,0xF0980372,0xCEB8000A,0xBACC0372,0x7FF80BE8,0xCE340289,0xBA180372,0xA6000BEB,0x7FF80BE8,0xCE340289,0xBA180372,0xA6000BEB,0xA6000BEB,0xFF3407C9,0xFD480A38,0xFF4C0A20,0xFF08040E,0xFED000DE,0xEAB40006,0xD0CC0001,0xCC940022,0xFF180806,0xFEF00396,0xD88C0288,0xBA180372, -0x5DF80BE8,0x1000BE8,0x1000BE8,0x1000BE8,0x1000BE8,0xFEDC03B4,0xFEDC03B4,0xFEDC03B4,0xC0DC0374,0xC0DC0374,0xA4D80375,0xFCB802AA,0xFCB802AA,0xFCB802AA,0xCCB40009,0xCCB40009,0xA8BC00A6,0xB0B00288,0xB0B00288,0xA0AC0041,0x92B0028A,0x17C0BE8,0x17C0BE8,0x17C0BE8,0xDA700372,0xDA700372,0xA4A40373,0xCA440289,0xCA440289,0xA6640002,0x9474028A,0x43F80BE8, -0x43F80BE8,0xA400037B,0x900002EB,0x7E000BEB,0xFEE806AD,0xF6FC09B4,0x1000BE8,0xFED402DD,0xFEC0005D,0xECB00005,0xDAB80021,0xC0B00002,0xFED0064B,0xFEBC0272,0xCEA0028A,0xA6640002,0x11FC0BE8,0x1280288,0x1280288,0x1280288,0x1280288,0xEF040000,0xEF040000,0xEF040000,0xB7040000,0xB7040000,0xA5040001,0x1B80288,0x1B80288,0x1B80288,0xC4C40001,0xC4C40001, -0xA6E00001,0x61F80288,0x61F80288,0xA4740001,0x9200028A,0x1B80288,0x1B80288,0x1B80288,0xC4C40001,0xC4C40001,0xA6E00001,0x61F80288,0x61F80288,0xA4740001,0x9200028A,0x61F80288,0x61F80288,0xA4740001,0x9200028A,0x9200028A,0xFF100152,0xF92001A5,0x1280288,0xFCF400B5,0xFEC8000A,0xE4BC0000,0xD0CC0000,0xC2AC0000,0xFEF80171,0xFEDC0091,0x37FC0288,0xA4740001, -0x37FC0288,0x1740374,0xFF5C0071,0xE54C0000,0xCF4C0001,0x31FC0372,0xF5000001,0xCF240001,0x9BF80372,0xCEA40001,0xBA000372,0x31FC0372,0xF5000001,0xCF240001,0x9BF80372,0xCEA40001,0xBA000372,0x9BF80372,0xCEA40001,0xBA000372,0xBA000372,0x31FC0372,0xF5000001,0xCF240001,0x9BF80372,0xCEA40001,0xBA000372,0x9BF80372,0xCEA40001,0xBA000372,0xBA000372,0x9BF80372, -0xCEA40001,0xBA000372,0xBA000372,0xBA000372,0xFF5002A8,0xF8C0372,0xFF6C02B9,0xFF30016D,0xFEE80075,0xEEA80000,0xCED40001,0xCE680001,0xF9500288,0xFF140145,0xD6DC0000,0xBA000372,0x7FFC0372,0xD80374,0xD80374,0xD80374,0xD80374,0xD80374,0xD80374,0xD80374,0xD80374,0xD80374,0xD80374,0xD6B00000,0xD6B00000,0xD6B00000,0xD6B00000,0xD6B00000, -0xD6B00000,0x96B00000,0x96B00000,0x96B00000,0x80B00001,0x1440372,0x1440372,0x1440372,0x1440372,0x1440372,0x1440372,0xA6640001,0xA6640001,0xA6640001,0x80880001,0x27F80372,0x27F80372,0x27F80372,0x80080001,0x6C000372,0xFECC0208,0xD80374,0xD80374,0xFAC400C8,0xFEB40028,0xF4B00000,0xF4B00000,0xBEB00000,0xFCB801A5,0xFAAC00A4,0xACA40000,0xA6640001, -0x1D00372,}; -static const uint32_t g_etc1_to_bc7_m6_table147[] = { -0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x13FC0000, -0x13FC0000,0x13FC0000,0x13FC0000,0x5E000001,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xC00000,0xCC0000,0xCC0000,0xCC0000,0x11C0000,0x1980000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000, -0x3980000,0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x88000001,0xB240000,0x1140000,0x1140000,0x1400000,0x3580000,0x1780000,0x1780000,0x1D00000,0x1400000,0x3580000,0x23FC0000,0x51FC0000, -0x23FC0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x87FC0000,0x87FC0000,0xAC000001,0xAC000001,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x87FC0000,0x87FC0000,0xAC000001,0xAC000001,0x87FC0000, -0x87FC0000,0xAC000001,0xAC000001,0xAC000001,0x1940000,0x1740000,0x15C0000,0x1D80000,0x39FC0000,0x67FC0000,0x77FC0000,0x91FC0000,0x1B40000,0x9FC0000,0x67FC0000,0xAC000001,0x67FC0000,0x1B00000,0x89FC0000,0xC5FC0000,0xD6000001,0x89FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0x89FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xD6000001, -0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0x89FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0xD6000001,0x41FC0000,0x1CC0000,0x1CC0000,0xA1FC0000,0xBFF80000,0xCFF40000,0xD6000001,0xD6000001,0x6FFC0000,0xADFC0000,0xD5FC0000,0xD6000001, -0xB7FC0000,0x1381EA8,0xFF241198,0xFF100BE8,0xD7100BE9,0xFF0C0C98,0xFEF403FD,0xDCF80531,0xE8E806E6,0xD4E803AE,0xC2E806E6,0xFEF40FB8,0xFECC0345,0xDED80411,0xF0BC038E,0xD6C0000E,0xC4C803AE,0xD6C00BE8,0xCAB00413,0xBCB80533,0xAEC00BEB,0x1D01EA8,0xFEA00D2F,0xD6C40BE9,0xFE700736,0xD88C038E,0xC29C06E6,0xFA2C0BE9,0xD648028A,0xC05403A3,0xAE740BEB,0x6DF81EA8, -0xD0000C49,0xBC0007F4,0xAC000D93,0x9A001EAC,0xFF2013CE,0xFF2C1AAE,0xFF2C1BCD,0xFF0009E0,0xFED8026D,0xF4C00006,0xDAC80046,0xD2B80046,0xFF101346,0xFEE008B4,0xDCAC029D,0xC05403A3,0x45FC1EA8,0x1600BE8,0xFF4404E1,0xF5380288,0xD7380289,0xFF3004D8,0xFB140005,0xD91C0042,0xDF140372,0xD10C00A5,0xC3140372,0xFFC0BE8,0xFED802D9,0xD8FC0289,0xF8A80372,0xD6C8000A, -0xC2DC0372,0x8BF80BE8,0xD6440289,0xC2280372,0xAE000BEB,0xFFC0BE8,0xFED802D9,0xD8FC0289,0xF8A80372,0xD6C8000A,0xC2DC0372,0x8BF80BE8,0xD6440289,0xC2280372,0xAE000BEB,0x8BF80BE8,0xD6440289,0xC2280372,0xAE000BEB,0xAE000BEB,0xFB480849,0xF5580A7E,0xF75C0A69,0xFF180496,0xFEE80149,0xF2C40006,0xD8DC0001,0xD4A40022,0xFF34084E,0xFF040403,0xE09C0288,0xC2280372, -0x6BFC0BE8,0x1100BE8,0x1100BE8,0x1100BE8,0x1100BE8,0xFEF403E4,0xFEF403E4,0xFEF403E4,0xC8EC0374,0xC8EC0374,0xACE80375,0xFEC802CA,0xFEC802CA,0xFEC802CA,0xD4C40009,0xD4C40009,0xB0CC00A6,0xB8C00288,0xB8C00288,0xA8BC0041,0x9AC0028A,0x1940BE8,0x1940BE8,0x1940BE8,0xE2800372,0xE2800372,0xACB40373,0xD2540289,0xD2540289,0xAE740002,0x9C84028A,0x4FF80BE8, -0x4FF80BE8,0xAC040373,0x9A0002CA,0x86000BEB,0xFD000714,0xFF0C09B4,0x1100BE8,0xFEE8034D,0xFED40099,0xF4C00005,0xE2C80021,0xC8C00002,0xFEE406AA,0xFED002BA,0xD6B0028A,0xAE740002,0x1FFC0BE8,0x1380288,0x1380288,0x1380288,0x1380288,0xF7140000,0xF7140000,0xF7140000,0xBF140000,0xBF140000,0xAD140001,0x1D00288,0x1D00288,0x1D00288,0xCCD40001,0xCCD40001, -0xAEF00001,0x6DF80288,0x6DF80288,0xAC840001,0x9A00028A,0x1D00288,0x1D00288,0x1D00288,0xCCD40001,0xCCD40001,0xAEF00001,0x6DF80288,0x6DF80288,0xAC840001,0x9A00028A,0x6DF80288,0x6DF80288,0xAC840001,0x9A00028A,0x9A00028A,0xFF20016D,0xFF2C01B1,0x1380288,0xFD0400CA,0xFEE00019,0xECCC0000,0xD8DC0000,0xCABC0000,0xFD100188,0xFEE800B4,0x45FC0288,0xAC840001, -0x45FC0288,0x1840374,0xFF68009D,0xED5C0000,0xD75C0001,0x49FC0372,0xFD100001,0xD7340001,0xA7F80372,0xD6B40001,0xC2000372,0x49FC0372,0xFD100001,0xD7340001,0xA7F80372,0xD6B40001,0xC2000372,0xA7F80372,0xD6B40001,0xC2000372,0xC2000372,0x49FC0372,0xFD100001,0xD7340001,0xA7F80372,0xD6B40001,0xC2000372,0xA7F80372,0xD6B40001,0xC2000372,0xC2000372,0xA7F80372, -0xD6B40001,0xC2000372,0xC2000372,0xC2000372,0xFB7002AD,0x1A00372,0xF98002D4,0xFF40019A,0xFF0C00B5,0xF6B80000,0xD6E40001,0xD6780001,0xFF5C0290,0xFF2C0185,0xDEEC0000,0xC2000372,0x8FFC0372,0xE80374,0xE80374,0xE80374,0xE80374,0xE80374,0xE80374,0xE80374,0xE80374,0xE80374,0xE80374,0xDEC00000,0xDEC00000,0xDEC00000,0xDEC00000,0xDEC00000, -0xDEC00000,0x9EC00000,0x9EC00000,0x9EC00000,0x88C00001,0x15C0372,0x15C0372,0x15C0372,0x15C0372,0x15C0372,0x15C0372,0xAE740001,0xAE740001,0xAE740001,0x88980001,0x33F80372,0x33F80372,0x33F80372,0x88180001,0x74000372,0xF8E00221,0xE80374,0xE80374,0xFCD400DD,0xFCCC003D,0xFCC00000,0xFCC00000,0xC6C00000,0xF8CC01C2,0xFEBC00B9,0xB4B40000,0xAE740001, -0x1F00372,}; -static const uint32_t g_etc1_to_bc7_m6_table148[] = { -0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x21F80000, -0x21F80000,0x21F80000,0x21F80000,0x68000000,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xD00001,0xE00000,0xE00000,0xE00000,0x1380000,0x1BC0000,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1240001,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000, -0x1B40000,0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x1B40000,0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x5FF80000,0x5FF80000,0x5FF80000,0x92000000,0x92000000,0x5380000,0x1240001,0x1240001,0x3540000,0x1700000,0x1900000,0x1900000,0x3EC0000,0x3540000,0x1700000,0x35FC0000,0x5FF80000, -0x35FC0000,0x16C0001,0x16C0001,0x16C0001,0x16C0001,0x25FC0000,0x25FC0000,0x25FC0000,0x95F80000,0x95F80000,0xB6000000,0x25FC0000,0x25FC0000,0x25FC0000,0x95F80000,0x95F80000,0xB6000000,0x95F80000,0x95F80000,0xB6000000,0xB6000000,0x25FC0000,0x25FC0000,0x25FC0000,0x95F80000,0x95F80000,0xB6000000,0x95F80000,0x95F80000,0xB6000000,0xB6000000,0x95F80000, -0x95F80000,0xB6000000,0xB6000000,0xB6000000,0x3A80000,0xB840000,0x16C0001,0x3F00000,0x4FFC0000,0x79FC0000,0x87F80000,0x9DFC0000,0x1CC0000,0x25FC0000,0x79FC0000,0xB6000000,0x79FC0000,0x1C00001,0xA5FC0000,0xD3FC0000,0xE0000000,0xA5FC0000,0xD3FC0000,0xE0000000,0xD3FC0000,0xE0000000,0xE0000000,0xA5FC0000,0xD3FC0000,0xE0000000,0xD3FC0000,0xE0000000, -0xE0000000,0xD3FC0000,0xE0000000,0xE0000000,0xE0000000,0xA5FC0000,0xD3FC0000,0xE0000000,0xD3FC0000,0xE0000000,0xE0000000,0xD3FC0000,0xE0000000,0xE0000000,0xE0000000,0xD3FC0000,0xE0000000,0xE0000000,0xE0000000,0xE0000000,0x6DFC0000,0x1E00000,0x1E00000,0xB7FC0000,0xCDFC0000,0xD9FC0000,0xE0000000,0xE0000000,0x8FFC0000,0xC1FC0000,0xDFF00000,0xE0000000, -0xC7FC0000,0x1481EAC,0xFF30126C,0xFF200C0F,0xE1200BEB,0xFF180DB4,0xFF080497,0xE5080533,0xF0FC06E6,0xDCF803AE,0xCAFC06E6,0xFF00109C,0xFEE4040B,0xE8EC0413,0xFAD0038E,0xE0D0000E,0xCCD803AE,0xDED40BE9,0xD4C40411,0xC4C80531,0xB8D00BE9,0x3E81EA8,0xFEC00DE7,0xE0D40BE8,0xFE8807BE,0xE2A0038E,0xCAB006E6,0xFE4C0BFB,0xE05C028A,0xCA6803A1,0xB8840BE8,0x79FC1EA8, -0xDC000C13,0xC400078E,0xB2000D35,0xA4001EA8,0xFF3414AF,0xFB441B24,0xFD481BF4,0xFF140B27,0xFEF00392,0xFED40006,0xE4DC0046,0xDCCC0046,0xFF181429,0xFF0009F4,0xE6BC029D,0xCA6803A1,0x57FC1EA8,0x1700BEB,0xFF5C056A,0xFF48028A,0xE148028A,0xFF440545,0xFF28001A,0xE3300041,0xE7280373,0xDB2000A6,0xCB240375,0x2BFC0BE8,0xFEFC032A,0xE1100288,0xFEC00375,0xDED80009, -0xCAF00374,0x97FC0BE8,0xE0540288,0xCA400374,0xB8000BE8,0x2BFC0BE8,0xFEFC032A,0xE1100288,0xFEC00375,0xDED80009,0xCAF00374,0x97FC0BE8,0xE0540288,0xCA400374,0xB8000BE8,0x97FC0BE8,0xE0540288,0xCA400374,0xB8000BE8,0xB8000BE8,0xFF580895,0xFF6C0A7D,0xFF6C0A6E,0xFF30053A,0xFF1001EE,0xFCD80005,0xE0EC0002,0xDCBC0021,0xFF4408B8,0xFF2404CA,0xE8B00289,0xCA400374, -0x7DF80BE8,0x1200BEB,0x1200BEB,0x1200BEB,0x1200BEB,0xFF040422,0xFF040422,0xFF040422,0xD2FC0372,0xD2FC0372,0xB6FC0372,0xFEE00301,0xFEE00301,0xFEE00301,0xDCD4000A,0xDCD4000A,0xBAE000A5,0xC2D00289,0xC2D00289,0xB2D00042,0xA4D00289,0x1B00BE8,0x1B00BE8,0x1B00BE8,0xEC900372,0xEC900372,0xB6C40372,0xDC640289,0xDC640289,0xB6840005,0xA4980288,0x5DF40BE8, -0x5DF40BE8,0xB6100372,0xA20002A9,0x90000BE8,0xFF100755,0xF71C09F6,0x1200BEB,0xFEF803C2,0xFEE400F1,0xFAD40005,0xEAD80022,0xD2D00001,0xFEF806F2,0xFEE80352,0xE0C00289,0xB6840005,0x31FC0BE8,0x148028A,0x148028A,0x148028A,0x148028A,0xFF280001,0xFF280001,0xFF280001,0xC9240001,0xC9240001,0xB7240001,0x3E80288,0x3E80288,0x3E80288,0xD6E40001,0xD6E40001, -0xB7040000,0x79FC0288,0x79FC0288,0xB6900000,0xA4000288,0x3E80288,0x3E80288,0x3E80288,0xD6E40001,0xD6E40001,0xB7040000,0x79FC0288,0x79FC0288,0xB6900000,0xA4000288,0x79FC0288,0x79FC0288,0xB6900000,0xA4000288,0xA4000288,0xFB34018A,0xFB4401C2,0x148028A,0xFF1800E1,0xFCFC0032,0xF4E00000,0xE2EC0000,0xD2D00000,0xF92801A5,0xFF0400D0,0x57FC0288,0xB6900000, -0x57FC0288,0x1980372,0xFF8000E1,0xF5700001,0xE16C0001,0x65FC0372,0xFF2C0011,0xE1440000,0xB3FC0372,0xE0C00000,0xCA000374,0x65FC0372,0xFF2C0011,0xE1440000,0xB3FC0372,0xE0C00000,0xCA000374,0xB3FC0372,0xE0C00000,0xCA000374,0xCA000374,0x65FC0372,0xFF2C0011,0xE1440000,0xB3FC0372,0xE0C00000,0xCA000374,0xB3FC0372,0xE0C00000,0xCA000374,0xCA000374,0xB3FC0372, -0xE0C00000,0xCA000374,0xCA000374,0xCA000374,0xFB8402D2,0x1B40372,0xFF8C02F2,0xFD6801E1,0xFF2800E9,0xFECC0001,0xE0F40000,0xE0840000,0xFF7002C5,0xFF4C01B1,0xE7000000,0xCA000374,0x9FFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xFC0372,0xE6D40001,0xE6D40001,0xE6D40001,0xE6D40001,0xE6D40001, -0xE6D40001,0xA6D40001,0xA6D40001,0xA6D40001,0x92D00001,0x3740372,0x3740372,0x3740372,0x3740372,0x3740372,0x3740372,0xB8840001,0xB8840001,0xB8840001,0x92A80000,0x3FFC0372,0x3FFC0372,0x3FFC0372,0x92240000,0x7C000374,0xFEEC0239,0xFC0372,0xFC0372,0xFEE800F2,0xFCE00055,0xFED40002,0xFED40002,0xCED40001,0xFED801D4,0xFED000D0,0xBAC80001,0xB8840001, -0xDFC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table149[] = { -0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x1500000,0x2DF80000, -0x2DF80000,0x2DF80000,0x2DF80000,0x70000000,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xE00001,0xF00000,0xF00000,0xF00000,0x1500000,0x1E00000,0x1340001,0x1340001,0x1340001,0x1340001,0x1340001,0x1340001,0x1340001,0x1340001,0x1340001,0x1340001,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000, -0x1CC0000,0x6BF80000,0x6BF80000,0x6BF80000,0x9A000000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x6BF80000,0x6BF80000,0x6BF80000,0x9A000000,0x6BF80000,0x6BF80000,0x6BF80000,0x9A000000,0x9A000000,0xD480000,0x1340001,0x1340001,0x1680000,0x1840000,0x3A40000,0x3A40000,0xBFC0000,0x1680000,0x1840000,0x43FC0000,0x6BF80000, -0x43FC0000,0x17C0001,0x17C0001,0x17C0001,0x17C0001,0x3DFC0000,0x3DFC0000,0x3DFC0000,0xA1F80000,0xA1F80000,0xBE000000,0x3DFC0000,0x3DFC0000,0x3DFC0000,0xA1F80000,0xA1F80000,0xBE000000,0xA1F80000,0xA1F80000,0xBE000000,0xBE000000,0x3DFC0000,0x3DFC0000,0x3DFC0000,0xA1F80000,0xA1F80000,0xBE000000,0xA1F80000,0xA1F80000,0xBE000000,0xBE000000,0xA1F80000, -0xA1F80000,0xBE000000,0xBE000000,0xBE000000,0x1BC0000,0x1980000,0x17C0001,0xFFC0000,0x63FC0000,0x87FC0000,0x95F80000,0xA9F40000,0x1E00000,0x3DFC0000,0x87FC0000,0xBE000000,0x87FC0000,0x1D00001,0xBDFC0000,0xDFF80000,0xE8000000,0xBDFC0000,0xDFF80000,0xE8000000,0xDFF80000,0xE8000000,0xE8000000,0xBDFC0000,0xDFF80000,0xE8000000,0xDFF80000,0xE8000000, -0xE8000000,0xDFF80000,0xE8000000,0xE8000000,0xE8000000,0xBDFC0000,0xDFF80000,0xE8000000,0xDFF80000,0xE8000000,0xE8000000,0xDFF80000,0xE8000000,0xE8000000,0xE8000000,0xDFF80000,0xE8000000,0xE8000000,0xE8000000,0xE8000000,0x95FC0000,0x1F00000,0x1F00000,0xCBFC0000,0xDBFC0000,0xE5F00000,0xE8000000,0xE8000000,0xAFFC0000,0xD1FC0000,0xE9C40000,0xE8000000, -0xD7FC0000,0x1581EAC,0xFF44131B,0xFF340C64,0xE9300BEB,0xFF300EB4,0xFF180563,0xED180533,0xF90C06E6,0xE50803AE,0xD30C06E6,0xFF181164,0xFEFC04F3,0xF0FC0413,0xFEE4039E,0xE8E0000E,0xD4E803AE,0xE6E40BE9,0xDCD40411,0xCCD80531,0xC0E00BE9,0x7FC1EA8,0xFED80EA7,0xE8E40BE8,0xFEAC0866,0xEAB0038E,0xD2C006E6,0xFE640C43,0xE86C028A,0xD27803A1,0xC0940BE8,0x85FC1EA8, -0xE6000BF8,0xD000073E,0xBE000CD5,0xAC001EA8,0xFF3C1574,0xFF4C1B64,0xF5581C63,0xFF240C9E,0xFF0404CE,0xFEE80032,0xECEC0046,0xE4DC0046,0xFF3414DA,0xFF100B2E,0xEECC029D,0xD27803A1,0x65FC1EA8,0x1800BEB,0xFF6805FA,0xFF5802A3,0xE958028A,0xFF5C05CD,0xFF40006A,0xEB400041,0xEF380373,0xE33000A6,0xD3340375,0x43FC0BE8,0xFF14039A,0xE9200288,0xFEE4039D,0xE6E80009, -0xD3000374,0xA3FC0BE8,0xE8640288,0xD2500374,0xC0000BE8,0x43FC0BE8,0xFF14039A,0xE9200288,0xFEE4039D,0xE6E80009,0xD3000374,0xA3FC0BE8,0xE8640288,0xD2500374,0xC0000BE8,0xA3FC0BE8,0xE8640288,0xD2500374,0xC0000BE8,0xC0000BE8,0xFF640905,0xF77C0AC3,0xF9800AB3,0xFF4405E1,0xFF24028E,0xFEF0001B,0xE8FC0002,0xE4CC0021,0xFF5C08DE,0xFF400550,0xF0C00289,0xD2500374, -0x8BFC0BE8,0x1300BEB,0x1300BEB,0x1300BEB,0x1300BEB,0xFF180463,0xFF180463,0xFF180463,0xDB0C0372,0xDB0C0372,0xBF0C0372,0xFEF4033B,0xFEF4033B,0xFEF4033B,0xE4E4000A,0xE4E4000A,0xC2F000A5,0xCAE00289,0xCAE00289,0xBAE00042,0xACE00289,0x3C40BE8,0x3C40BE8,0x3C40BE8,0xF4A00372,0xF4A00372,0xBED40372,0xE4740289,0xE4740289,0xBE940005,0xACA80288,0x67FC0BE8, -0x67FC0BE8,0xBE200372,0xAC000291,0x98000BE8,0xFF200792,0xFF2C09F6,0x1300BEB,0xFF100426,0xFEF8014D,0xFEE8000E,0xF2E80022,0xDAE00001,0xFF100749,0xFEF403B6,0xE8D00289,0xBE940005,0x3FFC0BE8,0x158028A,0x158028A,0x158028A,0x158028A,0xFD38000A,0xFD38000A,0xFD38000A,0xD1340001,0xD1340001,0xBF340001,0x7FC0288,0x7FC0288,0x7FC0288,0xDEF40001,0xDEF40001, -0xBF140000,0x85FC0288,0x85FC0288,0xBEA00000,0xAC000288,0x7FC0288,0x7FC0288,0x7FC0288,0xDEF40001,0xDEF40001,0xBF140000,0x85FC0288,0x85FC0288,0xBEA00000,0xAC000288,0x85FC0288,0x85FC0288,0xBEA00000,0xAC000288,0xAC000288,0xF74801A5,0xF35401E1,0x158028A,0xFD300109,0xFD140048,0xFCF00000,0xEAFC0000,0xDAE00000,0xFF3401A9,0xFF1800E9,0x65FC0288,0xBEA00000, -0x65FC0288,0x1A80372,0xFF8C0131,0xFD800001,0xE97C0001,0x7DFC0372,0xFF4C0041,0xE9540000,0xBFFC0372,0xE8D00000,0xD2000374,0x7DFC0372,0xFF4C0041,0xE9540000,0xBFFC0372,0xE8D00000,0xD2000374,0xBFFC0372,0xE8D00000,0xD2000374,0xD2000374,0x7DFC0372,0xFF4C0041,0xE9540000,0xBFFC0372,0xE8D00000,0xD2000374,0xBFFC0372,0xE8D00000,0xD2000374,0xD2000374,0xBFFC0372, -0xE8D00000,0xD2000374,0xD2000374,0xD2000374,0xFF9402D4,0x1C40372,0xFBA402F9,0xFF740212,0xFF500139,0xFEF0001A,0xE9040000,0xE8940000,0xFB9002D2,0xFF6401F9,0xEF100000,0xD2000374,0xAFFC0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0x10C0372,0xEEE40001,0xEEE40001,0xEEE40001,0xEEE40001,0xEEE40001, -0xEEE40001,0xAEE40001,0xAEE40001,0xAEE40001,0x9AE00001,0x38C0372,0x38C0372,0x38C0372,0x38C0372,0x38C0372,0x38C0372,0xC0940001,0xC0940001,0xC0940001,0x9AB80000,0x4BFC0372,0x4BFC0372,0x4BFC0372,0x9A340000,0x84000374,0xFB040242,0x10C0372,0x10C0372,0xFEF40115,0xFEEC006A,0xFEE8000D,0xFEE8000D,0xD6E40001,0xFCF001E1,0xFEE400F4,0xC2D80001,0xC0940001, -0x1DF80372,}; -static const uint32_t g_etc1_to_bc7_m6_table150[] = { -0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x39F80000, -0x39F80000,0x39F80000,0x39F80000,0x78000000,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0xF00001,0x9000000,0x9000000,0x9000000,0x1680000,0x3FC0000,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1440001,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000, -0x1E40000,0x77F80000,0x77F80000,0x77F80000,0xA2000000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x1E40000,0x77F80000,0x77F80000,0x77F80000,0xA2000000,0x77F80000,0x77F80000,0x77F80000,0xA2000000,0xA2000000,0x15C0000,0x1440001,0x1440001,0x17C0000,0x1980000,0x1BC0000,0x1BC0000,0x1DFC0000,0x17C0000,0x1980000,0x53FC0000,0x77F80000, -0x53FC0000,0x18C0001,0x18C0001,0x18C0001,0x18C0001,0x55FC0000,0x55FC0000,0x55FC0000,0xADF80000,0xADF80000,0xC6000000,0x55FC0000,0x55FC0000,0x55FC0000,0xADF80000,0xADF80000,0xC6000000,0xADF80000,0xADF80000,0xC6000000,0xC6000000,0x55FC0000,0x55FC0000,0x55FC0000,0xADF80000,0xADF80000,0xC6000000,0xADF80000,0xADF80000,0xC6000000,0xC6000000,0xADF80000, -0xADF80000,0xC6000000,0xC6000000,0xC6000000,0x7CC0000,0x1A80000,0x18C0001,0x2FFC0000,0x77FC0000,0x97FC0000,0xA1FC0000,0xB3FC0000,0x1F40000,0x55FC0000,0x97FC0000,0xC6000000,0x97FC0000,0x1E00001,0xD5FC0000,0xEBF80000,0xF0000000,0xD5FC0000,0xEBF80000,0xF0000000,0xEBF80000,0xF0000000,0xF0000000,0xD5FC0000,0xEBF80000,0xF0000000,0xEBF80000,0xF0000000, -0xF0000000,0xEBF80000,0xF0000000,0xF0000000,0xF0000000,0xD5FC0000,0xEBF80000,0xF0000000,0xEBF80000,0xF0000000,0xF0000000,0xEBF80000,0xF0000000,0xF0000000,0xF0000000,0xEBF80000,0xF0000000,0xF0000000,0xF0000000,0xF0000000,0xBDFC0000,0x27FC0000,0x27FC0000,0xDDFC0000,0xE9F80000,0xEFF00000,0xF0000000,0xF0000000,0xCDFC0000,0xE3FC0000,0xF1D40000,0xF0000000, -0xE5FC0000,0x1681EAC,0xFF50140B,0xFF480D03,0xF1400BEB,0xFF440FB6,0xFF2C0663,0xF5280533,0xFF1C06EC,0xED1803AE,0xDB1C06E6,0xFF30124C,0xFF14061B,0xF90C0413,0xFEFC0406,0xF0F0000E,0xDCF803AE,0xEEF40BE9,0xE4E40411,0xD4E80531,0xC8F00BE9,0x1FFC1EA8,0xFEF00F87,0xF0F40BE8,0xFEC0096E,0xF2C0038E,0xDAD006E6,0xFE880CBB,0xF07C028A,0xDA8803A1,0xC8A40BE8,0x91FC1EA8, -0xF0000BEB,0xD8000716,0xC4000C91,0xB4001EA8,0xFF50163F,0xFB641BB6,0xFD681C63,0xFF340DE2,0xFF1C0636,0xFEFC00C2,0xF4FC0046,0xECEC0046,0xFF4415D9,0xFF240CCA,0xF6DC029D,0xDA8803A1,0x75FC1EA8,0x1900BEB,0xFF80068A,0xFF7002EB,0xF168028A,0xFF680655,0xFF5400F6,0xF3500041,0xF7480373,0xEB4000A6,0xDB440375,0x5BFC0BE8,0xFF2C042A,0xF1300288,0xFEFC03ED,0xEEF80009, -0xDB100374,0xAFFC0BE8,0xF0740288,0xDA600374,0xC8000BE8,0x5BFC0BE8,0xFF2C042A,0xF1300288,0xFEFC03ED,0xEEF80009,0xDB100374,0xAFFC0BE8,0xF0740288,0xDA600374,0xC8000BE8,0xAFFC0BE8,0xF0740288,0xDA600374,0xC8000BE8,0xC8000BE8,0xFF78093E,0xFF8C0AC3,0xFF8C0ABB,0xFF5C0671,0xFF380356,0xFF10007D,0xF10C0002,0xECDC0021,0xFF780956,0xFF540602,0xF8D00289,0xDA600374, -0x9BFC0BE8,0x1400BEB,0x1400BEB,0x1400BEB,0x1400BEB,0xFF2404B3,0xFF2404B3,0xFF2404B3,0xE31C0372,0xE31C0372,0xC71C0372,0xFF0C0393,0xFF0C0393,0xFF0C0393,0xECF4000A,0xECF4000A,0xCB0000A5,0xD2F00289,0xD2F00289,0xC2F00042,0xB4F00289,0x3DC0BE8,0x3DC0BE8,0x3DC0BE8,0xFCB00372,0xFCB00372,0xC6E40372,0xEC840289,0xEC840289,0xC6A40005,0xB4B80288,0x73FC0BE8, -0x73FC0BE8,0xC6300372,0xB4000289,0xA0000BE8,0xFF2C07F1,0xF73C0A3B,0x1400BEB,0xFF1804AA,0xFF0C01B9,0xFEF80032,0xFAF80022,0xE2F00001,0xFF20078D,0xFF10042D,0xF0E00289,0xC6A40005,0x4FFC0BE8,0x168028A,0x168028A,0x168028A,0x168028A,0xFD4C0019,0xFD4C0019,0xFD4C0019,0xD9440001,0xD9440001,0xC7440001,0x1FFC0288,0x1FFC0288,0x1FFC0288,0xE7040001,0xE7040001, -0xC7240000,0x91FC0288,0x91FC0288,0xC6B00000,0xB4000288,0x1FFC0288,0x1FFC0288,0x1FFC0288,0xE7040001,0xE7040001,0xC7240000,0x91FC0288,0x91FC0288,0xC6B00000,0xB4000288,0x91FC0288,0x91FC0288,0xC6B00000,0xB4000288,0xB4000288,0xFF5801A5,0xFB6401E1,0x168028A,0xFF440120,0xFD280064,0xFF080008,0xF30C0000,0xE2F00000,0xFD4C01C2,0xFF30010D,0x75FC0288,0xC6B00000, -0x75FC0288,0x1B80372,0xFFA40179,0xFF900011,0xF18C0001,0x95FC0372,0xFF640089,0xF1640000,0xCBFC0372,0xF0E00000,0xDA000374,0x95FC0372,0xFF640089,0xF1640000,0xCBFC0372,0xF0E00000,0xDA000374,0xCBFC0372,0xF0E00000,0xDA000374,0xDA000374,0x95FC0372,0xFF640089,0xF1640000,0xCBFC0372,0xF0E00000,0xDA000374,0xCBFC0372,0xF0E00000,0xDA000374,0xDA000374,0xCBFC0372, -0xF0E00000,0xDA000374,0xDA000374,0xDA000374,0xFBAC02F9,0x3D40372,0xFFAC0321,0xFF940242,0xFF680179,0xFF180055,0xF1140000,0xF0A40000,0xFF9802F2,0xFF880221,0xF7200000,0xDA000374,0xBFF80372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0x11C0372,0xF6F40001,0xF6F40001,0xF6F40001,0xF6F40001,0xF6F40001, -0xF6F40001,0xB6F40001,0xB6F40001,0xB6F40001,0xA2F00001,0x3A40372,0x3A40372,0x3A40372,0x3A40372,0x3A40372,0x3A40372,0xC8A40001,0xC8A40001,0xC8A40001,0xA2C80000,0x57FC0372,0x57FC0372,0x57FC0372,0xA2440000,0x8C000374,0xFF0C0262,0x11C0372,0x11C0372,0xFF040132,0xFF000082,0xFEF80019,0xFEF80019,0xDEF40001,0xF9040200,0xFEF80109,0xCAE80001,0xC8A40001, -0x2BFC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table151[] = { -0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x45F80000, -0x45F80000,0x45F80000,0x45F80000,0x80000000,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1000001,0x1140000,0x1140000,0x1140000,0x1800000,0x13FC0000,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000, -0x1FC0000,0x83F80000,0x83F80000,0x83F80000,0xAA000000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x83F80000,0x83F80000,0x83F80000,0xAA000000,0x83F80000,0x83F80000,0x83F80000,0xAA000000,0xAA000000,0x16C0000,0x1540001,0x1540001,0x38C0000,0x1AC0000,0x1D00000,0x1D00000,0x31FC0000,0x38C0000,0x1AC0000,0x61FC0000,0x83F80000, -0x61FC0000,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xCE000000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xCE000000,0xB9F80000,0xB9F80000,0xCE000000,0xCE000000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xCE000000,0xB9F80000,0xB9F80000,0xCE000000,0xCE000000,0xB9F80000, -0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0x3E00000,0x5B80000,0x19C0001,0x4DFC0000,0x8BFC0000,0xA5FC0000,0xAFFC0000,0xBFF40000,0x15FC0000,0x6FFC0000,0xA5FC0000,0xCE000000,0xA5FC0000,0x1F00001,0xEFFC0000,0xF7F80000,0xF8000000,0xEFFC0000,0xF7F80000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xEFFC0000,0xF7F80000,0xF8000000,0xF7F80000,0xF8000000, -0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xEFFC0000,0xF7F80000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xF8000000,0xE3FC0000,0xA7FC0000,0xA7FC0000,0xF1FC0000,0xF5FC0000,0xF9F00000,0xF8000000,0xF8000000,0xEBFC0000,0xF3FC0000,0xF9E40000,0xF8000000, -0xF5FC0000,0x1781EAC,0xFF6814E3,0xFF580DBC,0xF9500BEB,0xFF5010EE,0xFF4007AB,0xFD380533,0xFF2C0746,0xF52803AE,0xE32C06E6,0xFF441329,0xFF280782,0xFF180417,0xFF0804CE,0xF900000E,0xE50803AE,0xF7040BE9,0xECF40411,0xDCF80531,0xD1000BE9,0x37FC1EA8,0xFF14107B,0xF9040BE8,0xFEE40A7E,0xFAD0038E,0xE2E006E6,0xFEAC0D6B,0xF88C028A,0xE29803A1,0xD0B40BE8,0x9DFC1EA8, -0xF8080BE8,0xE00006F8,0xCE000C58,0xBC001EA8,0xFF641706,0xFF6C1C06,0xF5781CD4,0xFF440F42,0xFF2807C3,0xFF1001BE,0xFD0C0046,0xF4FC0046,0xFF54168D,0xFF400E29,0xFEEC029D,0xE29803A1,0x83FC1EA8,0x1A00BEB,0xFF8C072A,0xFF7C036B,0xF978028A,0xFF8006ED,0xFF6401AA,0xFB600041,0xFF580373,0xF35000A6,0xE3540375,0x75FC0BE8,0xFF4C04E1,0xF9400288,0xFF200465,0xF7080009, -0xE3200374,0xBBFC0BE8,0xF8840288,0xE2700374,0xD0000BE8,0x75FC0BE8,0xFF4C04E1,0xF9400288,0xFF200465,0xF7080009,0xE3200374,0xBBFC0BE8,0xF8840288,0xE2700374,0xD0000BE8,0xBBFC0BE8,0xF8840288,0xE2700374,0xD0000BE8,0xD0000BE8,0xFF940998,0xF79C0B0D,0xF9A00AFE,0xFF780729,0xFF50043A,0xFF2C0113,0xF91C0002,0xF4EC0021,0xFF88099B,0xFF6806C8,0xFEE40291,0xE2700374, -0xA9FC0BE8,0x1500BEB,0x1500BEB,0x1500BEB,0x1500BEB,0xFF3C0513,0xFF3C0513,0xFF3C0513,0xEB2C0372,0xEB2C0372,0xCF2C0372,0xFF1803F3,0xFF1803F3,0xFF1803F3,0xF504000A,0xF504000A,0xD31000A5,0xDB000289,0xDB000289,0xCB000042,0xBD000289,0x3F40BE8,0x3F40BE8,0x3F40BE8,0xFEC8037D,0xFEC8037D,0xCEF40372,0xF4940289,0xF4940289,0xCEB40005,0xBCC80288,0x7FFC0BE8, -0x7FFC0BE8,0xCE400372,0xBC0C0288,0xA8000BE8,0xFF3C0843,0xFF4C0A3B,0x1500BEB,0xFF34051E,0xFF200235,0xFF10007A,0xFF080031,0xEB000001,0xFF3407CA,0xFF2404BA,0xF8F00289,0xCEB40005,0x5FF80BE8,0x178028A,0x178028A,0x178028A,0x178028A,0xFF5C002D,0xFF5C002D,0xFF5C002D,0xE1540001,0xE1540001,0xCF540001,0x37FC0288,0x37FC0288,0x37FC0288,0xEF140001,0xEF140001, -0xCF340000,0x9DFC0288,0x9DFC0288,0xCEC00000,0xBC000288,0x37FC0288,0x37FC0288,0x37FC0288,0xEF140001,0xEF140001,0xCF340000,0x9DFC0288,0x9DFC0288,0xCEC00000,0xBC000288,0x9DFC0288,0x9DFC0288,0xCEC00000,0xBC000288,0xBC000288,0xFB6C01C2,0xF3740202,0x178028A,0xFD580139,0xFF400080,0xFF200014,0xFB1C0000,0xEB000000,0xF56401E1,0xFF480122,0x83FC0288,0xCEC00000, -0x83FC0288,0x1C80372,0xFFB001E1,0xFFA00052,0xF99C0001,0xAFFC0372,0xFF8800E9,0xF9740000,0xD7FC0372,0xF8F00000,0xE2000374,0xAFFC0372,0xFF8800E9,0xF9740000,0xD7FC0372,0xF8F00000,0xE2000374,0xD7FC0372,0xF8F00000,0xE2000374,0xE2000374,0xAFFC0372,0xFF8800E9,0xF9740000,0xD7FC0372,0xF8F00000,0xE2000374,0xD7FC0372,0xF8F00000,0xE2000374,0xE2000374,0xD7FC0372, -0xF8F00000,0xE2000374,0xE2000374,0xE2000374,0xFFB40311,0xBE40372,0xFBC40322,0xFFAC0288,0xFF7C01E1,0xFF4800A9,0xF9240000,0xF8B40000,0xF1C00320,0xFFA00269,0xFF300000,0xE2000374,0xCDFC0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0x12C0372,0xFF040001,0xFF040001,0xFF040001,0xFF040001,0xFF040001, -0xFF040001,0xBF040001,0xBF040001,0xBF040001,0xAB000001,0x3BC0372,0x3BC0372,0x3BC0372,0x3BC0372,0x3BC0372,0x3BC0372,0xD0B40001,0xD0B40001,0xD0B40001,0xAAD80000,0x63FC0372,0x63FC0372,0x63FC0372,0xAA540000,0x94000374,0xFB240265,0x12C0372,0x12C0372,0xFD1C0152,0xFF1400A2,0xFF08002D,0xFF08002D,0xE7040001,0xFF100208,0xFB0C0139,0xD2F80001,0xD0B40001, -0x3BFC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table152[] = { -0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x3980000,0x51FC0000, -0x51FC0000,0x51FC0000,0x51FC0000,0x88000001,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0xB240000,0xB240000,0xB240000,0x3980000,0x23FC0000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1680000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000, -0x1BFC0000,0x91F80000,0x91F80000,0x91F80000,0xB2000001,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x91F80000,0x91F80000,0x91F80000,0xB2000001,0x91F80000,0x91F80000,0x91F80000,0xB2000001,0xB2000001,0x1800000,0x1680000,0x1680000,0x7A00000,0x1C40000,0x3E80000,0x3E80000,0x47FC0000,0x7A00000,0x1C40000,0x73FC0000,0x91F80000, -0x73FC0000,0x1B00000,0x1B00000,0x1B00000,0x1B00000,0x89FC0000,0x89FC0000,0x89FC0000,0xC5FC0000,0xC5FC0000,0xD6000001,0x89FC0000,0x89FC0000,0x89FC0000,0xC5FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xC5FC0000,0xD6000001,0xD6000001,0x89FC0000,0x89FC0000,0x89FC0000,0xC5FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xC5FC0000,0xD6000001,0xD6000001,0xC5FC0000, -0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0x5F40000,0x1CC0000,0x1B00000,0x6FFC0000,0xA1FC0000,0xB7FC0000,0xBFF80000,0xCBF80000,0x41FC0000,0x89FC0000,0xB7FC0000,0xD6000001,0xB7FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x18C1D49,0xFF7414EC,0xFF6C0E58,0xFF640BE8,0xFF681121,0xFF5408B8,0xFF50057D,0xFF400775,0xFB3C0394,0xEB3C066D,0xFF5C130E,0xFF40088F,0xFF30046C,0xFF20053D,0xFF180009,0xEB1C033A,0xFF140AFE,0xF30C03CA,0xE5080492,0xD9140AFE,0x4FFC1D47,0xFF2C10D8,0xFF180BE8,0xFEFC0B01,0xFEE403A5,0xEAF4066B,0xFED80D6E,0xFEA00289,0xE8B00322,0xD8C80AFE,0xA9FC1D47, -0xFE280BE8,0xEA04066B,0xD6000B2E,0xC4001D47,0xFF7816B6,0xFD881AF5,0xFD881B85,0xFF5C0FB9,0xFF4808E2,0xFF2C02B1,0xFF240072,0xFB10002D,0xFF70165C,0xFF500E9A,0xFF0802CE,0xE8B00322,0x93FC1D47,0x1B00B01,0xFFA4072C,0xFF9403C9,0xFF8C0288,0xFF9806DD,0xFF7C0236,0xFF740055,0xFF700321,0xF7640084,0xEB6802F9,0x8DFC0AFE,0xFF64052B,0xFF540288,0xFF380471,0xFD200005, -0xEB3002FA,0xC7FC0AFE,0xFEA00288,0xEA8402F9,0xD8000AFE,0x8DFC0AFE,0xFF64052B,0xFF540288,0xFF380471,0xFD200005,0xEB3002FA,0xC7FC0AFE,0xFEA00288,0xEA8402F9,0xD8000AFE,0xC7FC0AFE,0xFEA00288,0xEA8402F9,0xD8000AFE,0xD8000AFE,0xFFA0091B,0xFFAC0A29,0xFFAC0A2C,0xFF94070A,0xFF680489,0xFF480194,0xFF340005,0xFCFC0011,0xFF98091E,0xFF8406A8,0xFF1002BB,0xEA8402F9, -0xB9FC0AFE,0x1640BE8,0x1640BE8,0x1640BE8,0x1640BE8,0xFF50057D,0xFF50057D,0xFF50057D,0xF3400374,0xF3400374,0xD73C0375,0xFF30046C,0xFF30046C,0xFF30046C,0xFF180009,0xFF180009,0xDB2000A6,0xE3140288,0xE3140288,0xD3100041,0xC514028A,0x15FC0BE8,0x15FC0BE8,0x15FC0BE8,0xFEE403A5,0xFEE403A5,0xD7080373,0xFCA80289,0xFCA80289,0xD8C80002,0xC6D8028A,0x8DFC0BE8, -0x8DFC0BE8,0xD6580373,0xC420028A,0xB0000BEB,0xFF58088D,0xF9600A7D,0x1640BE8,0xFF4405A2,0xFF3402D2,0xFF2400E9,0xFF240072,0xF3140002,0xFD4C0845,0xFF300545,0xFF08028E,0xD8C80002,0x6FFC0BE8,0x18C0288,0x18C0288,0x18C0288,0x18C0288,0xFF740055,0xFF740055,0xFF740055,0xE9680000,0xE9680000,0xD7680001,0x53FC0288,0x53FC0288,0x53FC0288,0xF7280001,0xF7280001, -0xD9440001,0xABF80288,0xABF80288,0xD6D80001,0xC400028A,0x53FC0288,0x53FC0288,0x53FC0288,0xF7280001,0xF7280001,0xD9440001,0xABF80288,0xABF80288,0xD6D80001,0xC400028A,0xABF80288,0xABF80288,0xD6D80001,0xC400028A,0xC400028A,0xF78001E1,0xFD880200,0x18C0288,0xFB70016D,0xFF5400AA,0xFF3C0034,0xFF340005,0xF5100000,0xFD7401E1,0xFF5C0145,0x95FC0288,0xD6D80001, -0x95FC0288,0x1D802F9,0xFFC401CD,0xFFB80089,0xFFB00000,0xC3FC02F9,0xFFA00112,0xFF880001,0xE1FC02F9,0xFF100000,0xEA0002F9,0xC3FC02F9,0xFFA00112,0xFF880001,0xE1FC02F9,0xFF100000,0xEA0002F9,0xE1FC02F9,0xFF100000,0xEA0002F9,0xEA0002F9,0xC3FC02F9,0xFFA00112,0xFF880001,0xE1FC02F9,0xFF100000,0xEA0002F9,0xE1FC02F9,0xFF100000,0xEA0002F9,0xEA0002F9,0xE1FC02F9, -0xFF100000,0xEA0002F9,0xEA0002F9,0xEA0002F9,0xFFD002AD,0x1F802F9,0xF3D402D4,0xFFC00244,0xFFA801CA,0xFF7000E8,0xFF3C0000,0xFED80000,0xF9D002AD,0xFDBC0244,0xFF580019,0xEA0002F9,0xDBFC02F9,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0x13C0374,0xFF180008,0xFF180008,0xFF180008,0xFF180008,0xFF180008, -0xFF180008,0xC9140000,0xC9140000,0xC9140000,0xB3140001,0x1D80372,0x1D80372,0x1D80372,0x1D80372,0x1D80372,0x1D80372,0xD8C80001,0xD8C80001,0xD8C80001,0xB2EC0001,0x71F80372,0x71F80372,0x71F80372,0xB26C0001,0x9E000372,0xF5380288,0x13C0374,0x13C0374,0xFF2C0171,0xFF2800C8,0xFF1C0050,0xFF1C0050,0xF1140000,0xFF200239,0xFF200152,0xDF080000,0xD8C80001, -0x4BFC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table153[] = { -0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x3B00000,0x5DFC0000, -0x5DFC0000,0x5DFC0000,0x5DFC0000,0x90000001,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1240000,0x1380000,0x1380000,0x1380000,0x3B00000,0x33FC0000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x1780000,0x35FC0000,0x35FC0000,0x35FC0000,0x35FC0000,0x35FC0000, -0x35FC0000,0x9DF40000,0x9DF40000,0x9DF40000,0xBA000001,0x35FC0000,0x35FC0000,0x35FC0000,0x35FC0000,0x35FC0000,0x35FC0000,0x9DF40000,0x9DF40000,0x9DF40000,0xBA000001,0x9DF40000,0x9DF40000,0x9DF40000,0xBA000001,0xBA000001,0x1900000,0x1780000,0x1780000,0x3B40000,0x1D80000,0x5FC0000,0x5FC0000,0x5BFC0000,0x3B40000,0x1D80000,0x81FC0000,0x9DF40000, -0x81FC0000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xD1FC0000,0xD1FC0000,0xDE000001,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xD1FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xD1FC0000,0xDE000001,0xDE000001,0xA3FC0000,0xA3FC0000,0xA3FC0000,0xD1FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xD1FC0000,0xDE000001,0xDE000001,0xD1FC0000, -0xD1FC0000,0xDE000001,0xDE000001,0xDE000001,0x27FC0000,0x7DC0000,0x1C00000,0x8DFC0000,0xB3FC0000,0xC5FC0000,0xCBFC0000,0xD5FC0000,0x69FC0000,0xA3FC0000,0xC5FC0000,0xDE000001,0xC5FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x19819DD,0xFF801338,0xFF7C0DD1,0xFF740BE8,0xFF740F69,0xFF64088E,0xFF5C05E5,0xFF58068D,0xFD4C0378,0xEF4C0555,0xFF6810D2,0xFF4C0853,0xFF4404DA,0xFF380465,0xFF2C0029,0xF12C0235,0xFF2808DD,0xF51C032E,0xEB1C0319,0xDF2408CA,0x63FC19DB,0xFF380FF4,0xFF300BE8,0xFF1409E9,0xFEFC03ED,0xEF080553,0xFEF00B8E,0xFEC0029E,0xECC401FA,0xDED808CA,0xB3F819DB, -0xFE580BE8,0xEE280553,0xDC0008D2,0xCA0019DB,0xFF801459,0xFF8C17D1,0xFF8C1891,0xFF700E65,0xFF50086A,0xFF3C02F4,0xFF3400D5,0xFD240006,0xFF7813DA,0xFF5C0D8F,0xFF1C02E2,0xECC401FA,0x9FF819DB,0x1BC08C9,0xFFB005F4,0xFFA00371,0xFF9C0288,0xFFA40569,0xFF9001F8,0xFF840088,0xFF7C0221,0xFB780034,0xEF7801E1,0x9BFC08C9,0xFF7C0473,0xFF6C0288,0xFF580362,0xFF380001, -0xEF4401E2,0xCFF808C9,0xFED40288,0xEEA801E1,0xDE0008CA,0x9BFC08C9,0xFF7C0473,0xFF6C0288,0xFF580362,0xFF380001,0xEF4401E2,0xCFF808C9,0xFED40288,0xEEA801E1,0xDE0008CA,0xCFF808C9,0xFED40288,0xEEA801E1,0xDE0008CA,0xDE0008CA,0xFFB4074A,0xF5B80845,0xF7BC0849,0xFF9805B9,0xFF7C03C5,0xFF5C0171,0xFF500019,0xFF180001,0xFFA4076A,0xFF90057E,0xFF3002AE,0xEEA801E1, -0xC1FC08C9,0x1740BE8,0x1740BE8,0x1740BE8,0x1740BE8,0xFF5C05E5,0xFF5C05E5,0xFF5C05E5,0xFB500374,0xFB500374,0xDF4C0375,0xFF4404DA,0xFF4404DA,0xFF4404DA,0xFF2C0029,0xFF2C0029,0xE33000A6,0xEB240288,0xEB240288,0xDB200041,0xCD24028A,0x2FFC0BE8,0x2FFC0BE8,0x2FFC0BE8,0xFEFC03ED,0xFEFC03ED,0xDF180373,0xFEC0029E,0xFEC0029E,0xE0D80002,0xCEE8028A,0x99FC0BE8, -0x99FC0BE8,0xDE680373,0xCC30028A,0xB8000BEB,0xFF6808CE,0xFF6C0A8D,0x1740BE8,0xFF540625,0xFF440371,0xFF3C0164,0xFF3400D5,0xFB240002,0xFF58089A,0xFF5005B6,0xFF1C02B1,0xE0D80002,0x7FF80BE8,0x19C0288,0x19C0288,0x19C0288,0x19C0288,0xFF840088,0xFF840088,0xFF840088,0xF1780000,0xF1780000,0xDF780001,0x6BFC0288,0x6BFC0288,0x6BFC0288,0xFF380001,0xFF380001, -0xE1540001,0xB7F80288,0xB7F80288,0xDEE80001,0xCC00028A,0x6BFC0288,0x6BFC0288,0x6BFC0288,0xFF380001,0xFF380001,0xE1540001,0xB7F80288,0xB7F80288,0xDEE80001,0xCC00028A,0xB7F80288,0xB7F80288,0xDEE80001,0xCC00028A,0xCC00028A,0xFF9001E1,0xF5980221,0x19C0288,0xFD840188,0xFF7000DD,0xFF580064,0xFF500019,0xFD200000,0xFD880200,0xFF740171,0xA3FC0288,0xDEE80001, -0xA3FC0288,0x1E001E1,0xFFD00121,0xFFC80061,0xFFC00000,0xCFFC01E1,0xFFB800AA,0xFFA00001,0xE7FC01E1,0xFF400000,0xEE0001E1,0xCFFC01E1,0xFFB800AA,0xFFA00001,0xE7FC01E1,0xFF400000,0xEE0001E1,0xE7FC01E1,0xFF400000,0xEE0001E1,0xEE0001E1,0xCFFC01E1,0xFFB800AA,0xFFA00001,0xE7FC01E1,0xFF400000,0xEE0001E1,0xE7FC01E1,0xFF400000,0xEE0001E1,0xEE0001E1,0xE7FC01E1, -0xFF400000,0xEE0001E1,0xEE0001E1,0xEE0001E1,0xFFD001BD,0x7FC01E1,0xF7DC01C4,0xFFC80179,0xFFBC0122,0xFF900092,0xFF640000,0xFF140000,0xFDD801A5,0xFFC00164,0xFF780010,0xEE0001E1,0xE1FC01E1,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0x14C0374,0xFF28001D,0xFF28001D,0xFF28001D,0xFF28001D,0xFF28001D, -0xFF28001D,0xD1240000,0xD1240000,0xD1240000,0xBB240001,0x1F00372,0x1F00372,0x1F00372,0x1F00372,0x1F00372,0x1F00372,0xE0D80001,0xE0D80001,0xE0D80001,0xBAFC0001,0x7DF80372,0x7DF80372,0x7DF80372,0xBA7C0001,0xA6000372,0xFD480288,0x14C0374,0x14C0374,0xFF3C0190,0xFF3400E9,0xFF340071,0xFF340071,0xF9240000,0xFD380244,0xFF34016D,0xE7180000,0xE0D80001, -0x5BFC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table154[] = { -0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0x69FC0000, -0x69FC0000,0x69FC0000,0x69FC0000,0x98000001,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1340000,0x1480000,0x1480000,0x1480000,0x1C80000,0x41FC0000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000, -0x4DFC0000,0xA7FC0000,0xA7FC0000,0xA7FC0000,0xC2000001,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0x4DFC0000,0xA7FC0000,0xA7FC0000,0xA7FC0000,0xC2000001,0xA7FC0000,0xA7FC0000,0xA7FC0000,0xC2000001,0xC2000001,0x9A00000,0x1880000,0x1880000,0x1C80000,0x1EC0000,0x23FC0000,0x23FC0000,0x6FFC0000,0x1C80000,0x1EC0000,0x91FC0000,0xA7FC0000, -0x91FC0000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xDDFC0000,0xDDFC0000,0xE6000001,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xDDFC0000,0xDDFC0000,0xE6000001,0xDDFC0000,0xDDFC0000,0xE6000001,0xE6000001,0xBBFC0000,0xBBFC0000,0xBBFC0000,0xDDFC0000,0xDDFC0000,0xE6000001,0xDDFC0000,0xDDFC0000,0xE6000001,0xE6000001,0xDDFC0000, -0xDDFC0000,0xE6000001,0xE6000001,0xE6000001,0x5FFC0000,0xFEC0000,0x1D00000,0xABFC0000,0xC7FC0000,0xD5FC0000,0xD9FC0000,0xE1F40000,0x91FC0000,0xBBFC0000,0xD5FC0000,0xE6000001,0xD5FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1A416D1,0xFF981198,0xFF880D5D,0xFF840BE8,0xFF800E01,0xFF740886,0xFF740675,0xFF6405F9,0xFF60037D,0xF35C047D,0xFF740EFE,0xFF64082B,0xFF5C056A,0xFF4C03FE,0xFF40007D,0xF53C016E,0xFF38072E,0xF93002C2,0xEF3001F9,0xE33406EA,0x75FC16CF,0xFF580F0C,0xFF480BE8,0xFF2C0911,0xFF20044D,0xF31C047B,0xFF080A0E,0xFEE402DE,0xF2DC0112,0xE2EC06EA,0xBBFC16CF, -0xFE880BE8,0xF248047B,0xE20806EA,0xD00016CF,0xFF8C1241,0xF9A0153D,0xF9A015C4,0xFF800D27,0xFF68080D,0xFF54034B,0xFF4C015D,0xFF38000D,0xFF9011EA,0xFF740C8A,0xFF340318,0xF2DC0112,0xA9FC16CF,0x1C806E9,0xFFBC04EC,0xFFAC0331,0xFFAC0288,0xFFB0043D,0xFFA001C2,0xFF9800B9,0xFF940169,0xFD880008,0xF3880109,0xAFFC06E9,0xFF9403DB,0xFF840288,0xFF70028A,0xFF580019, -0xF358010A,0xD7FC06E9,0xFF040288,0xF2C80109,0xE20006EA,0xAFFC06E9,0xFF9403DB,0xFF840288,0xFF70028A,0xFF580019,0xF358010A,0xD7FC06E9,0xFF040288,0xF2C80109,0xE20006EA,0xD7FC06E9,0xFF040288,0xF2C80109,0xE20006EA,0xE20006EA,0xFFBC05CD,0xFBC4066D,0xFBC40681,0xFFB004A6,0xFF900329,0xFF7C0153,0xFF680041,0xFF380009,0xFFB405D6,0xFFA40482,0xFF5002A1,0xF2C80109, -0xCDFC06E9,0x1840BE8,0x1840BE8,0x1840BE8,0x1840BE8,0xFF740675,0xFF740675,0xFF740675,0xFF60037D,0xFF60037D,0xE75C0375,0xFF5C056A,0xFF5C056A,0xFF5C056A,0xFF40007D,0xFF40007D,0xEB4000A6,0xF3340288,0xF3340288,0xE3300041,0xD534028A,0x47FC0BE8,0x47FC0BE8,0x47FC0BE8,0xFF20044D,0xFF20044D,0xE7280373,0xFEE402DE,0xFEE402DE,0xE8E80002,0xD6F8028A,0xA5F80BE8, -0xA5F80BE8,0xE6780373,0xD440028A,0xC0000BEB,0xFF740934,0xF9800AC4,0x1840BE8,0xFF6806BD,0xFF580419,0xFF4C021D,0xFF4C015D,0xFF38000D,0xFD70090C,0xFF5C0656,0xFF3402F4,0xE8E80002,0x8DFC0BE8,0x1AC0288,0x1AC0288,0x1AC0288,0x1AC0288,0xFF9800B9,0xFF9800B9,0xFF9800B9,0xF9880000,0xF9880000,0xE7880001,0x83FC0288,0x83FC0288,0x83FC0288,0xFF580019,0xFF580019, -0xE9640001,0xC3F80288,0xC3F80288,0xE6F80001,0xD400028A,0x83FC0288,0x83FC0288,0x83FC0288,0xFF580019,0xFF580019,0xE9640001,0xC3F80288,0xC3F80288,0xE6F80001,0xD400028A,0xC3F80288,0xC3F80288,0xE6F80001,0xD400028A,0xD400028A,0xFFA00202,0xFDA80221,0x1AC0288,0xFF9801A5,0xFF84010D,0xFF740091,0xFF680041,0xFF380009,0xFF940212,0xFB9001A5,0xB3FC0288,0xE6F80001, -0xB3FC0288,0x1E80109,0xFFDC009D,0xFFD80034,0xFFD00000,0xDBFC0109,0xFFCC0064,0xFFB80001,0xEDFC0109,0xFF700000,0xF2000109,0xDBFC0109,0xFFCC0064,0xFFB80001,0xEDFC0109,0xFF700000,0xF2000109,0xEDFC0109,0xFF700000,0xF2000109,0xF2000109,0xDBFC0109,0xFFCC0064,0xFFB80001,0xEDFC0109,0xFF700000,0xF2000109,0xEDFC0109,0xFF700000,0xF2000109,0xF2000109,0xEDFC0109, -0xFF700000,0xF2000109,0xF2000109,0xF2000109,0xFBE400F2,0x47FC0109,0xFBE400F4,0xFFD800CA,0xFFD000A2,0xFFAC0050,0xFF8C0000,0xFF500000,0xFFDC00E1,0xFFD800C8,0xFF9C0009,0xF2000109,0xE9FC0109,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0x15C0374,0xFF3C0034,0xFF3C0034,0xFF3C0034,0xFF3C0034,0xFF3C0034, -0xFF3C0034,0xD9340000,0xD9340000,0xD9340000,0xC3340001,0xDFC0372,0xDFC0372,0xDFC0372,0xDFC0372,0xDFC0372,0xDFC0372,0xE8E80001,0xE8E80001,0xE8E80001,0xC30C0001,0x89F80372,0x89F80372,0x89F80372,0xC28C0001,0xAE000372,0xF55802AD,0x15C0374,0x15C0374,0xFF4C01B1,0xFD4C0120,0xFF440091,0xFF440091,0xFF340001,0xF94C0265,0xFB4801A5,0xEF280000,0xE8E80001, -0x69FC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table155[] = { -0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0x75FC0000, -0x75FC0000,0x75FC0000,0x75FC0000,0xA0000001,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x5580000,0x5580000,0x5580000,0x1E00000,0x51FC0000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x1980000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000, -0x65FC0000,0xB3FC0000,0xB3FC0000,0xB3FC0000,0xCA000001,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0x65FC0000,0xB3FC0000,0xB3FC0000,0xB3FC0000,0xCA000001,0xB3FC0000,0xB3FC0000,0xB3FC0000,0xCA000001,0xCA000001,0x1B40000,0x1980000,0x1980000,0x5D80000,0x7FC0000,0x41FC0000,0x41FC0000,0x83FC0000,0x5D80000,0x7FC0000,0x9FFC0000,0xB3FC0000, -0x9FFC0000,0x1E00000,0x1E00000,0x1E00000,0x1E00000,0xD3FC0000,0xD3FC0000,0xD3FC0000,0xE9FC0000,0xE9FC0000,0xEE000001,0xD3FC0000,0xD3FC0000,0xD3FC0000,0xE9FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xE9FC0000,0xEE000001,0xEE000001,0xD3FC0000,0xD3FC0000,0xD3FC0000,0xE9FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xE9FC0000,0xEE000001,0xEE000001,0xE9FC0000, -0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0x97FC0000,0x17FC0000,0x1E00000,0xC9FC0000,0xDBFC0000,0xE3FC0000,0xE7F80000,0xEBF80000,0xB7FC0000,0xD3FC0000,0xE3FC0000,0xEE000001,0xE3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1B01425,0xFFA4102C,0xFF940D09,0xFF940BE8,0xFF980CD1,0xFF840898,0xFF8006ED,0xFF7C05B1,0xFF7003B4,0xF76C03E5,0xFF8C0D6E,0xFF74082B,0xFF68060E,0xFF6403D6,0xFF54010D,0xF95000EA,0xFF4C0601,0xFD44028E,0xF53C011D,0xE944055E,0x87FC1423,0xFF700E44,0xFF600BE8,0xFF4C089F,0xFF3804C5,0xF73003E3,0xFF2008EE,0xFEFC034E,0xF6F00072,0xE900055E,0xC5F81423, -0xFEB80BE8,0xF66803E3,0xE820055E,0xD6001423,0xFFA0103F,0xFFAC12A9,0xFFAC133C,0xFF940C5A,0xFF7807F2,0xFF6803C5,0xFF5C0214,0xFF48005E,0xFF981017,0xFF800B9F,0xFF50039A,0xF6F00072,0xB5FC1423,0x1D00561,0xFFC40411,0xFFC002F4,0xFFBC0288,0xFFBC0359,0xFFB001B2,0xFFA80104,0xFFA000F1,0xFF980004,0xF7980071,0xBDFC055E,0xFFAC0363,0xFF9C0288,0xFF8801F2,0xFF700049, -0xF76C0072,0xDFF8055E,0xFF340288,0xF6E80071,0xE800055E,0xBDFC055E,0xFFAC0363,0xFF9C0288,0xFF8801F2,0xFF700049,0xF76C0072,0xDFF8055E,0xFF340288,0xF6E80071,0xE800055E,0xDFF8055E,0xFF340288,0xF6E80071,0xE800055E,0xE800055E,0xFDCC049A,0xFFCC04F5,0xFFCC0519,0xFFC003C4,0xFFA402B5,0xFF90016B,0xFF7C0082,0xFF640032,0xFFC4049D,0xFFB003C2,0xFF700298,0xF6E80071, -0xD7FC055E,0x1940BE8,0x1940BE8,0x1940BE8,0x1940BE8,0xFF8006ED,0xFF8006ED,0xFF8006ED,0xFF7003B4,0xFF7003B4,0xEF6C0375,0xFF68060E,0xFF68060E,0xFF68060E,0xFF54010D,0xFF54010D,0xF35000A6,0xFB440288,0xFB440288,0xEB400041,0xDD44028A,0x5FFC0BE8,0x5FFC0BE8,0x5FFC0BE8,0xFF3804C5,0xFF3804C5,0xEF380373,0xFEFC034E,0xFEFC034E,0xF0F80002,0xDF08028A,0xB1F80BE8, -0xB1F80BE8,0xEE880373,0xDC50028A,0xC8000BEB,0xFF84097D,0xFF8C0AD8,0x1940BE8,0xFF80074E,0xFF6C04D1,0xFF6002D9,0xFF5C0214,0xFF48005E,0xFF800956,0xFF7406E1,0xFF500381,0xF0F80002,0x9DF80BE8,0x1BC0288,0x1BC0288,0x1BC0288,0x1BC0288,0xFFA80104,0xFFA80104,0xFFA80104,0xFF980004,0xFF980004,0xEF980001,0x9BFC0288,0x9BFC0288,0x9BFC0288,0xFF700049,0xFF700049, -0xF1740001,0xCFF80288,0xCFF80288,0xEF080001,0xDC00028A,0x9BFC0288,0x9BFC0288,0x9BFC0288,0xFF700049,0xFF700049,0xF1740001,0xCFF80288,0xCFF80288,0xEF080001,0xDC00028A,0xCFF80288,0xCFF80288,0xEF080001,0xDC00028A,0xDC00028A,0xFBB40221,0xF5B80244,0x1BC0288,0xFFA401D4,0xFF980145,0xFF8C00E1,0xFF7C0082,0xFF640032,0xFDB00221,0xFFA401C2,0xC1FC0288,0xEF080001, -0xC1FC0288,0x1F00071,0xFFE80041,0xFFE40014,0xFFE00000,0xE9FC0071,0xFFD80028,0xFFD00000,0xF3FC0071,0xFFA00000,0xF6000071,0xE9FC0071,0xFFD80028,0xFFD00000,0xF3FC0071,0xFFA00000,0xF6000071,0xF3FC0071,0xFFA00000,0xF6000071,0xF6000071,0xE9FC0071,0xFFD80028,0xFFD00000,0xF3FC0071,0xFFA00000,0xF6000071,0xF3FC0071,0xFFA00000,0xF6000071,0xF6000071,0xF3FC0071, -0xFFA00000,0xF6000071,0xF6000071,0xF6000071,0xFFEC0062,0x87FC0071,0xFFEC0064,0xFDE80055,0xFDE40048,0xFFC8001D,0xFFB40000,0xFF8C0000,0xFDEC0062,0xFFE40055,0xFFBC0004,0xF6000071,0xF1FC0071,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0x16C0374,0xFF500055,0xFF500055,0xFF500055,0xFF500055,0xFF500055, -0xFF500055,0xE1440000,0xE1440000,0xE1440000,0xCB440001,0x25FC0372,0x25FC0372,0x25FC0372,0x25FC0372,0x25FC0372,0x25FC0372,0xF0F80001,0xF0F80001,0xF0F80001,0xCB1C0001,0x95F80372,0x95F80372,0x95F80372,0xCA9C0001,0xB6000372,0xFD6802AD,0x16C0374,0x16C0374,0xFD6401E1,0xFF580145,0xFF5400B9,0xFF5400B9,0xFF48000D,0xFF580271,0xFF5001BD,0xF7380000,0xF0F80001, -0x79FC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table156[] = { -0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x1FC0000,0x83F80000, -0x83F80000,0x83F80000,0x83F80000,0xAA000000,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x1540001,0x16C0000,0x16C0000,0x16C0000,0x1FC0000,0x61FC0000,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000, -0x81FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0x81FC0000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0xD4000000,0xBC40000,0x1A80001,0x1A80001,0x1F00000,0x33FC0000,0x63FC0000,0x63FC0000,0x99FC0000,0x1F00000,0x33FC0000,0xB1FC0000,0xC1FC0000, -0xB1FC0000,0x1F00001,0x1F00001,0x1F00001,0x1F00001,0xEFFC0000,0xEFFC0000,0xEFFC0000,0xF7F80000,0xF7F80000,0xF8000000,0xEFFC0000,0xEFFC0000,0xEFFC0000,0xF7F80000,0xF7F80000,0xF8000000,0xF7F80000,0xF7F80000,0xF8000000,0xF8000000,0xEFFC0000,0xEFFC0000,0xEFFC0000,0xF7F80000,0xF7F80000,0xF8000000,0xF7F80000,0xF7F80000,0xF8000000,0xF8000000,0xF7F80000, -0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xD7FC0000,0xA7FC0000,0x1F00001,0xEBFC0000,0xF1FC0000,0xF5FC0000,0xF5FC0000,0xF7FC0000,0xE3FC0000,0xEFFC0000,0xF5FC0000,0xF8000000,0xF5FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1BC1194,0xFFB00ED7,0xFFAC0CAC,0xFFA40BEB,0xFFA40BBE,0xFF9808C3,0xFF9807A2,0xFF8805A4,0xFF88043B,0xFB800386,0xFF980C15,0xFF8C0852,0xFF8006C9,0xFF7003FF,0xFF6C01EE,0xFD6400A9,0xFF64052C,0xFF58029B,0xF950007E,0xEF540409,0x9BFC1194,0xFF880D81,0xFF7C0BE8,0xFF64083E,0xFF58058D,0xFD440386,0xFF380829,0xFF2003F9,0xFB080015,0xEF140408,0xCFF81194, -0xFEF00BE8,0xFA8C0386,0xEE400408,0xDC001198,0xFFB40EBF,0xF5B810AC,0xF7BC1114,0xFF980B8A,0xFF8C0803,0xFF7C0476,0xFF78030B,0xFF640105,0xFDB00E9B,0xFF980AFA,0xFF640451,0xFB080015,0xC1FC1194,0x1DC040B,0xFFD4035E,0xFFCC02CA,0xFFCC028A,0xFFD0029B,0xFFC401B6,0xFFBC0151,0xFFB800C3,0xFFAC0032,0xFBA80015,0xCFFC0408,0xFFC002FE,0xFFB80288,0xFFA00196,0xFF94009D, -0xFB840014,0xE7FC0408,0xFF6C0288,0xFB0C0014,0xEE000408,0xCFFC0408,0xFFC002FE,0xFFB80288,0xFFA00196,0xFF94009D,0xFB840014,0xE7FC0408,0xFF6C0288,0xFB0C0014,0xEE000408,0xE7FC0408,0xFF6C0288,0xFB0C0014,0xEE000408,0xEE000408,0xFFD80385,0xF7DC03D5,0xF7DC03EA,0xFDD00321,0xFFC0025A,0xFFA80179,0xFFA000DA,0xFF7C0082,0xFFD00395,0xFFC802E4,0xFF980291,0xFB0C0014, -0xE1FC0408,0x1A40BEB,0x1A40BEB,0x1A40BEB,0x1A40BEB,0xFF9807A2,0xFF9807A2,0xFF9807A2,0xFF88043B,0xFF88043B,0xF9800372,0xFF8006C9,0xFF8006C9,0xFF8006C9,0xFF6C01EE,0xFF6C01EE,0xFD6400A5,0xFF58029B,0xFF58029B,0xF5540042,0xE7540289,0x7BFC0BE8,0x7BFC0BE8,0x7BFC0BE8,0xFF58058D,0xFF58058D,0xF9480372,0xFF2003F9,0xFF2003F9,0xF9080005,0xE71C0288,0xBFF80BE8, -0xBFF80BE8,0xF8940372,0xE6600288,0xD2000BE8,0xFFA009E1,0xFBA40B0A,0x1A40BEB,0xFF9007E6,0xFF8005BA,0xFF7803C3,0xFF78030B,0xFF640105,0xFF9409A4,0xFF8007C1,0xFF640438,0xF9080005,0xADFC0BE8,0x1CC028A,0x1CC028A,0x1CC028A,0x1CC028A,0xFFBC0151,0xFFBC0151,0xFFBC0151,0xFFAC0032,0xFFAC0032,0xF9A80001,0xB7FC0288,0xB7FC0288,0xB7FC0288,0xFF94009D,0xFF94009D, -0xF9880000,0xDDF40288,0xDDF40288,0xF9140000,0xE6000288,0xB7FC0288,0xB7FC0288,0xB7FC0288,0xFF94009D,0xFF94009D,0xF9880000,0xDDF40288,0xDDF40288,0xF9140000,0xE6000288,0xDDF40288,0xDDF40288,0xF9140000,0xE6000288,0xE6000288,0xFDC80242,0xFFCC0242,0x1CC028A,0xFDC00202,0xFFAC0195,0xFFA80128,0xFFA000DA,0xFF7C0082,0xFFC40242,0xFBC00200,0xD3FC0288,0xF9140000, -0xD3FC0288,0x1F80012,0xFFF4000A,0xFFF00005,0xFFF00001,0xF7FC0012,0xFFF00005,0xFFEC0000,0xFBFC0012,0xFFD80000,0xFA000014,0xF7FC0012,0xFFF00005,0xFFEC0000,0xFBFC0012,0xFFD80000,0xFA000014,0xFBFC0012,0xFFD80000,0xFA000014,0xFA000014,0xF7FC0012,0xFFF00005,0xFFEC0000,0xFBFC0012,0xFFD80000,0xFA000014,0xFBFC0012,0xFFD80000,0xFA000014,0xFA000014,0xFBFC0012, -0xFFD80000,0xFA000014,0xFA000014,0xFA000014,0xFFF8000D,0xD7FC0012,0xF5F80012,0xFFF4000D,0xFDF4000D,0xFFE80005,0xFFE00000,0xFFD00000,0xF5FC0012,0xFFF00011,0xFFE40001,0xFA000014,0xFBFC0012,0x1800372,0x1800372,0x1800372,0x1800372,0x1800372,0x1800372,0x1800372,0x1800372,0x1800372,0x1800372,0xFF680091,0xFF680091,0xFF680091,0xFF680091,0xFF680091, -0xFF680091,0xE9580001,0xE9580001,0xE9580001,0xD5540001,0x41FC0372,0x41FC0372,0x41FC0372,0x41FC0372,0x41FC0372,0x41FC0372,0xFB080001,0xFB080001,0xFB080001,0xD52C0000,0xA1FC0372,0xA1FC0372,0xA1FC0372,0xD4A80000,0xBE000374,0xF77C02D2,0x1800372,0x1800372,0xFF740202,0xFF6C0179,0xFF6800FA,0xFF6800FA,0xFF5C002D,0xFD70028A,0xFF6401F9,0xFD4C0001,0xFB080001, -0x89FC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table157[] = { -0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x19FC0000,0x8FF80000, -0x8FF80000,0x8FF80000,0x8FF80000,0xB2000000,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x1640001,0x77C0000,0x77C0000,0x77C0000,0x19FC0000,0x71FC0000,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x1B80001,0x99FC0000,0x99FC0000,0x99FC0000,0x99FC0000,0x99FC0000, -0x99FC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xDC000000,0x99FC0000,0x99FC0000,0x99FC0000,0x99FC0000,0x99FC0000,0x99FC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xDC000000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xDC000000,0xDC000000,0x1D80000,0x1B80001,0x1B80001,0x11FC0000,0x5BFC0000,0x81FC0000,0x81FC0000,0xADFC0000,0x11FC0000,0x5BFC0000,0xBFFC0000,0xCDFC0000, -0xBFFC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1C80F44,0xFFBC0D5F,0xFFB80BD4,0xFFB40B53,0xFFB00ABA,0xFFA4089F,0xFFA407BE,0xFFA005B4,0xFF94049B,0xFF900372,0xFFA40AD9,0xFF980816,0xFF9806F5,0xFF880417,0xFF7C0296,0xFF7400C1,0xFF7C0494,0xFF7002A3,0xFD64003A,0xF3640305,0xABFC0F44,0xFF940C75,0xFF900B53,0xFF7C07D6,0xFF7005E5,0xFF580374,0xFF580773,0xFF380455,0xFF200005,0xF3280304,0xD7F80F44, -0xFF1C0B53,0xFEAC0372,0xF2600304,0xE2000F44,0xFFBC0CF6,0xFBC40E6C,0xFBC40EDC,0xFFAC0A8E,0xFF9C07CB,0xFF9004FA,0xFF8803B2,0xFF7401A6,0xFFB40CB7,0xFFA40A4C,0xFF780483,0xFF200005,0xCBFC0F44,0x1E80303,0xFFE002AE,0xFFE00263,0xFFDC0242,0xFFDC0213,0xFFD0019A,0xFFD0015A,0xFFC000D1,0xFFC0006D,0xFFB80001,0xDFFC0303,0xFFCC0282,0xFFCC0242,0xFFB80156,0xFFAC00CD, -0xFF980000,0xEFFC0303,0xFF940242,0xFF2C0000,0xF2000304,0xDFFC0303,0xFFCC0282,0xFFCC0242,0xFFB80156,0xFFAC00CD,0xFF980000,0xEFFC0303,0xFF940242,0xFF2C0000,0xF2000304,0xEFFC0303,0xFF940242,0xFF2C0000,0xF2000304,0xF2000304,0xFFE402C1,0xFBE402D9,0xFDE802EE,0xFFDC025D,0xFFD40202,0xFFB80171,0xFFB80104,0xFFA000B4,0xFFDC02BD,0xFFDC025A,0xFFB40246,0xFF2C0000, -0xEBFC0303,0x1B40B53,0x1B40B53,0x1B40B53,0x1B40B53,0xFFA407BE,0xFFA407BE,0xFFA407BE,0xFF94049B,0xFF94049B,0xFF900372,0xFF9806F5,0xFF9806F5,0xFF9806F5,0xFF7C0296,0xFF7C0296,0xFF7400C1,0xFF7002A3,0xFF7002A3,0xFB600032,0xED640245,0x8FFC0B53,0x8FFC0B53,0x8FFC0B53,0xFF7005E5,0xFF7005E5,0xFF580374,0xFF380455,0xFF380455,0xFF200005,0xED2C0244,0xC9F80B53, -0xC9F80B53,0xFEAC0372,0xEC780244,0xDA000B54,0xFFAC09A2,0xFFAC0A9E,0x1B40B53,0xFFA4081B,0xFF940612,0xFF900481,0xFF8803B2,0xFF7401A6,0xFFA0097D,0xFF9807C5,0xFF780473,0xFF200005,0xBBFC0B53,0x1DC0242,0x1DC0242,0x1DC0242,0x1DC0242,0xFFD0015A,0xFFD0015A,0xFFD0015A,0xFFC0006D,0xFFC0006D,0xFFB80001,0xCDFC0242,0xCDFC0242,0xCDFC0242,0xFFAC00CD,0xFFAC00CD, -0xFF980000,0xE7F80242,0xE7F80242,0xFF2C0000,0xEC000244,0xCDFC0242,0xCDFC0242,0xCDFC0242,0xFFAC00CD,0xFFAC00CD,0xFF980000,0xE7F80242,0xE7F80242,0xFF2C0000,0xEC000244,0xE7F80242,0xE7F80242,0xFF2C0000,0xEC000244,0xEC000244,0xFFD80200,0xF7DC0221,0x1DC0242,0xFBD401E1,0xFFC80190,0xFFB80140,0xFFB80104,0xFFA000B4,0xFFD00208,0xFFC801D4,0xDFFC0242,0xFF2C0000, -0xDFFC0242,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1900372,0x1900372,0x1900372,0x1900372,0x1900372,0x1900372,0x1900372,0x1900372,0x1900372,0x1900372,0xFF7400C1,0xFF7400C1,0xFF7400C1,0xFF7400C1,0xFF7400C1, -0xFF7400C1,0xF1680001,0xF1680001,0xF1680001,0xDD640001,0x59FC0372,0x59FC0372,0x59FC0372,0x59FC0372,0x59FC0372,0x59FC0372,0xFF200005,0xFF200005,0xFF200005,0xDD3C0000,0xADFC0372,0xADFC0372,0xADFC0372,0xDCB80000,0xC6000374,0xFF8C02D2,0x1900372,0x1900372,0xFF840225,0xFF8001A9,0xFF780132,0xFF780132,0xFF700059,0xF98402AD,0xFF780212,0xFF60000D,0xFF200005, -0x99FC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table158[] = { -0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x31FC0000,0x9BF80000, -0x9BF80000,0x9BF80000,0x9BF80000,0xBA000000,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0x1740001,0xF8C0000,0xF8C0000,0xF8C0000,0x31FC0000,0x7FFC0000,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0x1C80001,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000, -0xB1FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xE4000000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xB1FC0000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xE4000000,0xD9FC0000,0xD9FC0000,0xD9FC0000,0xE4000000,0xE4000000,0x1E80000,0x1C80001,0x1C80001,0x49FC0000,0x81FC0000,0x9FFC0000,0x9FFC0000,0xC1FC0000,0x49FC0000,0x81FC0000,0xCFFC0000,0xD9FC0000, -0xCFFC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1D00C14,0xFFC40AAC,0xFFC00997,0xFFC00933,0xFFBC08C2,0xFFB4073B,0xFFB00696,0xFFAC050C,0xFFA00453,0xFFA00372,0xFFB00891,0xFFA40686,0xFFA405A5,0xFF940387,0xFF900266,0xFF8C0109,0xFF880354,0xFF7C01DB,0xFF74000A,0xF77401C5,0xB7FC0C14,0xFFAC09FD,0xFFA00934,0xFF8806A6,0xFF7C053D,0xFF700374,0xFF7005BB,0xFF58036A,0xFF380025,0xF73C01C4,0xDDF40C14, -0xFF400933,0xFEE00372,0xF68001C4,0xE6000C14,0xFFC40A74,0xFFCC0B5C,0xFFCC0BBC,0xFFBC089D,0xFFAC066B,0xFF98043E,0xFF900351,0xFF840195,0xFFBC0A41,0xFFB00837,0xFF9003AD,0xFF380025,0xD3FC0C14,0x1EC01C3,0xFFE8018B,0xFFE40162,0xFFE40152,0xFFE00141,0xFFDC00EE,0xFFDC00CA,0xFFD80079,0xFFCC0041,0xFFC80001,0xE5FC01C3,0xFFD80176,0xFFD80152,0xFFCC00D1,0xFFB8007D, -0xFFB00000,0xF3F801C3,0xFFAC0152,0xFF600000,0xF60001C4,0xE5FC01C3,0xFFD80176,0xFFD80152,0xFFCC00D1,0xFFB8007D,0xFFB00000,0xF3F801C3,0xFFAC0152,0xFF600000,0xF60001C4,0xF3F801C3,0xFFAC0152,0xFF600000,0xF60001C4,0xF60001C4,0xFBEC01A1,0xFFEC01A1,0xFFEC01B2,0xFFDC016D,0xFFDC0125,0xFFD000E3,0xFFC8009D,0xFFB8006A,0xF9EC01A1,0xFFDC015A,0xFFC80156,0xFF600000, -0xEFFC01C3,0x1C00933,0x1C00933,0x1C00933,0x1C00933,0xFFB00696,0xFFB00696,0xFFB00696,0xFFA00453,0xFFA00453,0xFFA00372,0xFFA405A5,0xFFA405A5,0xFFA405A5,0xFF900266,0xFF900266,0xFF8C0109,0xFF7C01DB,0xFF7C01DB,0xFD740009,0xF1740155,0xA3FC0933,0xA3FC0933,0xA3FC0933,0xFF7C053D,0xFF7C053D,0xFF700374,0xFF58036A,0xFF58036A,0xFF380025,0xF1400154,0xD1FC0933, -0xD1FC0933,0xFEE00372,0xF0980154,0xDE000934,0xFFBC07F2,0xF7BC08BB,0x1C00933,0xFFAC06AE,0xFFA00542,0xFF9803DA,0xFF900351,0xFF840195,0xFFB407AE,0xFFB0067E,0xFF9003A4,0xFF380025,0xC5FC0933,0x1E40152,0x1E40152,0x1E40152,0x1E40152,0xFFDC00CA,0xFFDC00CA,0xFFDC00CA,0xFFCC0041,0xFFCC0041,0xFFC80001,0xD9FC0152,0xD9FC0152,0xD9FC0152,0xFFB8007D,0xFFB8007D, -0xFFB00000,0xEDF80152,0xEDF80152,0xFF600000,0xF0000154,0xD9FC0152,0xD9FC0152,0xD9FC0152,0xFFB8007D,0xFFB8007D,0xFFB00000,0xEDF80152,0xEDF80152,0xFF600000,0xF0000154,0xEDF80152,0xEDF80152,0xFF600000,0xF0000154,0xF0000154,0xF7E40139,0xFBE40139,0x1E40152,0xFFDC0109,0xFFD400E1,0xFFD000CA,0xFFC8009D,0xFFB8006A,0xF5E40139,0xFFDC0109,0xE7FC0152,0xFF600000, -0xE7FC0152,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0x1A00372,0xFF8C0109,0xFF8C0109,0xFF8C0109,0xFF8C0109,0xFF8C0109, -0xFF8C0109,0xF9780001,0xF9780001,0xF9780001,0xE5740001,0x71FC0372,0x71FC0372,0x71FC0372,0x71FC0372,0x71FC0372,0x71FC0372,0xFF380025,0xFF380025,0xFF380025,0xE54C0000,0xB9FC0372,0xB9FC0372,0xB9FC0372,0xE4C80000,0xCE000374,0xF79C02F9,0x1A00372,0x1A00372,0xFF900262,0xFF9401E1,0xFF90016D,0xFF90016D,0xFF800092,0xFF9002B9,0xFD900244,0xFF74002D,0xFF380025, -0xA7FC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table159[] = { -0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0x49FC0000,0xA7F80000, -0xA7F80000,0xA7F80000,0xA7F80000,0xC2000000,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1840001,0x1A00000,0x1A00000,0x1A00000,0x49FC0000,0x8FFC0000,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0x1D80001,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000, -0xC9FC0000,0xE5F80000,0xE5F80000,0xE5F80000,0xEC000000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xC9FC0000,0xE5F80000,0xE5F80000,0xE5F80000,0xEC000000,0xE5F80000,0xE5F80000,0xE5F80000,0xEC000000,0xEC000000,0x5F80000,0x1D80001,0x1D80001,0x83FC0000,0xA9FC0000,0xBDFC0000,0xBDFC0000,0xD3FC0000,0x83FC0000,0xA9FC0000,0xDFF80000,0xE5F80000, -0xDFF80000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1D80964,0xFFD00864,0xFFCC07AB,0xFFC8076B,0xFFC4070C,0xFFC40607,0xFFBC059E,0xFFB80484,0xFFB4040A,0xFFB00372,0xFFC40694,0xFFB40543,0xFFB0049D,0xFFAC031F,0xFFA0024E,0xFF980151,0xFF940274,0xFF940153,0xFF880002,0xF98400D9,0xC3FC0964,0xFFB807ED,0xFFB00768,0xFFA00596,0xFF9404A5,0xFF880374,0xFF880463,0xFF7002BA,0xFF580061,0xF95000D8,0xE1FC0964, -0xFF600768,0xFF100372,0xF8A800D8,0xEA000964,0xFFCC082B,0xF3D4091A,0xF5D8093F,0xFFC406CC,0xFFB4054F,0xFFAC03A2,0xFFA40306,0xFF9C019B,0xFFD0080D,0xFFC406A4,0xFF9C02F7,0xFF580061,0xDBFC0964,0x1F000DB,0xFDF000C3,0xFFEC00AB,0xFFEC00A2,0xFFE80093,0xFFE80072,0xFFE80062,0xFFE40039,0xFFE00022,0xFFD80001,0xEFFC00D8,0xFFE400B2,0xFFE400A2,0xFFD80061,0xFFD8003D, -0xFFC80000,0xF7F800D8,0xFFC800A2,0xFF900000,0xF80000D8,0xEFFC00D8,0xFFE400B2,0xFFE400A2,0xFFD80061,0xFFD8003D,0xFFC80000,0xF7F800D8,0xFFC800A2,0xFF900000,0xF80000D8,0xF7F800D8,0xFFC800A2,0xFF900000,0xF80000D8,0xF80000D8,0xFDF000C1,0xFFEC00D1,0xF1F000DB,0xFFEC00AE,0xFFE80092,0xFFE0006B,0xFFD80050,0xFFD00034,0xFBF000C1,0xFFE800A6,0xFFD800A3,0xFF900000, -0xF5FC00D8,0x1C8076B,0x1C8076B,0x1C8076B,0x1C8076B,0xFFBC059E,0xFFBC059E,0xFFBC059E,0xFFB4040A,0xFFB4040A,0xFFB00372,0xFFB0049D,0xFFB0049D,0xFFB0049D,0xFFA0024E,0xFFA0024E,0xFF980151,0xFF940153,0xFF940153,0xFF880002,0xF58400A5,0xB1FC0768,0xB1FC0768,0xB1FC0768,0xFF9404A5,0xFF9404A5,0xFF880374,0xFF7002BA,0xFF7002BA,0xFF580061,0xF55400A4,0xD9FC0768, -0xD9FC0768,0xFF100372,0xF4B800A4,0xE4000768,0xFBC40683,0xFDC80703,0x1C8076B,0xFFBC057D,0xFFB4046E,0xFFAC0362,0xFFA40306,0xFF9C019B,0xFFBC0651,0xFFB4055B,0xFF9C02EE,0xFF580061,0xCFFC0768,0x1EC00A2,0x1EC00A2,0x1EC00A2,0x1EC00A2,0xFFE80062,0xFFE80062,0xFFE80062,0xFFE00022,0xFFE00022,0xFFD80001,0xE5FC00A2,0xE5FC00A2,0xE5FC00A2,0xFFD8003D,0xFFD8003D, -0xFFC80000,0xF3F800A2,0xF3F800A2,0xFF900000,0xF40000A4,0xE5FC00A2,0xE5FC00A2,0xE5FC00A2,0xFFD8003D,0xFFD8003D,0xFFC80000,0xF3F800A2,0xF3F800A2,0xFF900000,0xF40000A4,0xF3F800A2,0xF3F800A2,0xFF900000,0xF40000A4,0xF40000A4,0xFBEC0091,0xFFEC0091,0x1EC00A2,0xF9EC0091,0xFFDC0074,0xFFD80061,0xFFD80050,0xFFD00034,0xF9EC0091,0xFDE40082,0xEFFC00A2,0xFF900000, -0xEFFC00A2,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0x1B00372,0xFF980151,0xFF980151,0xFF980151,0xFF980151,0xFF980151, -0xFF980151,0xFF880002,0xFF880002,0xFF880002,0xED840001,0x89FC0372,0x89FC0372,0x89FC0372,0x89FC0372,0x89FC0372,0x89FC0372,0xFF580061,0xFF580061,0xFF580061,0xED5C0000,0xC5FC0372,0xC5FC0372,0xC5FC0372,0xECD80000,0xD6000374,0xFFAC02F9,0x1B00372,0x1B00372,0xFDA8028A,0xFFA00212,0xFF9801BA,0xFF9801BA,0xFF9400DA,0xFFA002E4,0xFFA00269,0xFF88007D,0xFF580061, -0xB7FC0372,}; -static const uint32_t g_etc1_to_bc7_m6_table160[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x300000,0x300000,0x300000,0x300000,0x2440000,0x2440000,0x2440000,0x8C0000,0x8C0000,0x16000001,0x2440000,0x2440000,0x2440000,0x8C0000,0x8C0000,0x16000001,0x8C0000,0x8C0000,0x16000001,0x16000001,0x2440000,0x2440000,0x2440000,0x8C0000,0x8C0000,0x16000001,0x8C0000,0x8C0000,0x16000001,0x16000001,0x8C0000, -0x8C0000,0x16000001,0x16000001,0x16000001,0x380000,0x340000,0x300000,0x400000,0x500000,0x640000,0x740000,0xAC0000,0x3C0000,0x2440000,0x640000,0x16000001,0x640000,0xA00000,0xEC0000,0x1E40000,0x4E000001,0xEC0000,0x1E40000,0x4E000001,0x1E40000,0x4E000001,0x4E000001,0xEC0000,0x1E40000,0x4E000001,0x1E40000,0x4E000001, -0x4E000001,0x1E40000,0x4E000001,0x4E000001,0x4E000001,0xEC0000,0x1E40000,0x4E000001,0x1E40000,0x4E000001,0x4E000001,0x1E40000,0x4E000001,0x4E000001,0x4E000001,0x1E40000,0x4E000001,0x4E000001,0x4E000001,0x4E000001,0xC80000,0xCA80000,0xCA80000,0x10C0000,0x1880000,0x25F00000,0x4E000001,0x4E000001,0xD80000,0x12C0000,0x45DC0000,0x4E000001, -0x1540000,0x3410B0,0xE2100180,0x72100180,0x4E100181,0x9C000620,0x6E0000A9,0x4E000005,0x4C000620,0x4400025D,0x32000622,0x6A000D2B,0x620004E9,0x46000263,0x46000851,0x3C00041A,0x30000732,0x32000D2C,0x32000831,0x2C000A06,0x22000D2B,0x4C10B0,0x4C0007F3,0x4000045C,0x3A000A12,0x3A00058B,0x2E000814,0x2E000E21,0x2C000952,0x26000ABF,0x22000DA4,0x9810B0, -0x26000BDD,0x20000CBA,0x1C000EF4,0x180010B4,0xFE0004A0,0xFA240B7A,0xFE2C0B05,0x9E000409,0x62000449,0x4C00041A,0x440002DE,0x36000555,0xD0000776,0x7C00058B,0x3E00065B,0x26000ABF,0x6C10B0,0x440D2C,0xDA180120,0x70180120,0x4E180121,0x9C000620,0x6E0000A9,0x4E000005,0x4C000620,0x4400025D,0x32000622,0x680D2B,0x620004E9,0x46000263,0x46000851,0x3C00041A, -0x30000732,0xD00D2B,0x32000831,0x2C000A06,0x22000D2B,0x680D2B,0x620004E9,0x46000263,0x46000851,0x3C00041A,0x30000732,0xD00D2B,0x32000831,0x2C000A06,0x22000D2B,0xD00D2B,0x32000831,0x2C000A06,0x22000D2B,0x22000D2B,0xFE0004A0,0xFE2C09C6,0xF63C08B8,0x9E000409,0x62000449,0x4C00041A,0x440002DE,0x36000555,0xD00006CD,0x7C00054B,0x3E00064B,0x2C000A06, -0x940D2B,0x100180,0x100180,0x100180,0x100180,0x48000000,0x48000000,0x48000000,0x22000000,0x22000000,0x16000001,0x24000120,0x24000120,0x24000120,0x1E00006D,0x1E00006D,0x1400003A,0x10000122,0x10000122,0x100000AA,0xA000122,0x180180,0x180180,0x180180,0x180000B1,0x180000B1,0x12000061,0xE000141,0xE000141,0xE0000CE,0xA000132,0x2C0180, -0x2C0180,0xA00010B,0xA000153,0x6000183,0x84000059,0xFA04002C,0x100180,0x42000075,0x3200006D,0x2200006A,0x2200005A,0x16000082,0x420000C5,0x3200009E,0x16000121,0xE0000CE,0x200180,0x180120,0x180120,0x180120,0x180120,0x48000000,0x48000000,0x48000000,0x22000000,0x22000000,0x16000001,0x240120,0x240120,0x240120,0x1E00006D,0x1E00006D, -0x1400003A,0x440120,0x440120,0x100000AA,0xA000122,0x240120,0x240120,0x240120,0x1E00006D,0x1E00006D,0x1400003A,0x440120,0x440120,0x100000AA,0xA000122,0x440120,0x440120,0x100000AA,0xA000122,0xA000122,0x84000059,0xFC080020,0x180120,0x42000075,0x3200006D,0x2200006A,0x2200005A,0x16000082,0x560000B4,0x32000095,0x300120,0x100000AA, -0x300120,0x680620,0xC2300000,0x6A300000,0x4E300001,0x2980620,0x6E0000A9,0x4E000005,0x1380620,0x4400025D,0x32000622,0x2980620,0x6E0000A9,0x4E000005,0x1380620,0x4400025D,0x32000622,0x1380620,0x4400025D,0x32000622,0x32000622,0x2980620,0x6E0000A9,0x4E000005,0x1380620,0x4400025D,0x32000622,0x1380620,0x4400025D,0x32000622,0x32000622,0x1380620, -0x4400025D,0x32000622,0x32000622,0x32000622,0xFE140320,0xE6C0620,0xF65C039D,0xA6000220,0x6A000269,0x54000249,0x46000195,0x3E000305,0xF2000352,0x8C0002A8,0x4C000161,0x32000622,0xDC0620,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table161[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x400000,0x400000,0x400000,0x400000,0x25C0000,0x25C0000,0x25C0000,0xBC0000,0xBC0000,0x1E000001,0x25C0000,0x25C0000,0x25C0000,0xBC0000,0xBC0000,0x1E000001,0xBC0000,0xBC0000,0x1E000001,0x1E000001,0x25C0000,0x25C0000,0x25C0000,0xBC0000,0xBC0000,0x1E000001,0xBC0000,0xBC0000,0x1E000001,0x1E000001,0xBC0000, -0xBC0000,0x1E000001,0x1E000001,0x1E000001,0x4480000,0x440000,0x400000,0x2540000,0x6C0000,0x880000,0x9C0000,0xE80000,0x500000,0x25C0000,0x880000,0x1E000001,0x880000,0xB00000,0x1040000,0x7FC0000,0x56000001,0x1040000,0x7FC0000,0x56000001,0x7FC0000,0x56000001,0x56000001,0x1040000,0x7FC0000,0x56000001,0x7FC0000,0x56000001, -0x56000001,0x7FC0000,0x56000001,0x56000001,0x56000001,0x1040000,0x7FC0000,0x56000001,0x7FC0000,0x56000001,0x56000001,0x7FC0000,0x56000001,0x56000001,0x56000001,0x7FC0000,0x56000001,0x56000001,0x56000001,0x56000001,0xDC0000,0xBC0000,0xBC0000,0x1280000,0x1AC0000,0x2FF00000,0x56000001,0x56000001,0xF00000,0x1480000,0x4DEC0000,0x56000001, -0x1740000,0x3C1430,0xF61402AC,0x7C1402AD,0x561402AD,0xB6000620,0x7A000059,0x5600000A,0x58000620,0x4A0001ED,0x3A000622,0x78000F80,0x680005A9,0x5200030B,0x4C000911,0x46000432,0x3A00078B,0x3A000F80,0x38000989,0x32000B46,0x26000F83,0x581430,0x580009AB,0x4C00058C,0x46000B62,0x40000613,0x340008C4,0x340010D1,0x38000AF2,0x2C000C47,0x2400102B,0xB01430, -0x2C000E45,0x26000EDA,0x200011F7,0x1C001434,0xFC080612,0xFE2C0E0A,0xFE2C0E55,0xA6000431,0x76000461,0x5A000421,0x480002C3,0x420005B3,0xD0000856,0x8600061A,0x46000791,0x2C000C47,0x7C1430,0x500F80,0xEA200200,0x7A200200,0x56200201,0xB6000620,0x7A000059,0x58040006,0x58000620,0x4A0001ED,0x3A000622,0x2740F80,0x680005A9,0x5200030B,0x4C000911,0x46000432, -0x3A00078B,0xF00F80,0x38000989,0x32000B46,0x26000F83,0x2740F80,0x680005A9,0x5200030B,0x4C000911,0x46000432,0x3A00078B,0xF00F80,0x38000989,0x32000B46,0x26000F83,0xF00F80,0x38000989,0x32000B46,0x26000F83,0x26000F83,0xFE0C05F6,0xF63C0BA4,0xFC480AC4,0xA6000431,0x76000461,0x5A000421,0x480002C3,0x420005B3,0xD00007AD,0x900005D9,0x46000781,0x32000B46, -0xA80F80,0x1402AC,0x1402AC,0x1402AC,0x1402AC,0x60000000,0x60000000,0x60000000,0x2E000000,0x2E000000,0x1E000001,0x30000200,0x30000200,0x30000200,0x220000B9,0x220000B9,0x1E000065,0x16000202,0x16000202,0x16000132,0xE000202,0x2002AB,0x2002AB,0x2002AB,0x22000132,0x22000132,0x180000B1,0x12000236,0x12000236,0x1400016E,0xE00021B,0x3C02AB, -0x3C02AB,0x100001D3,0xA000263,0xA0002AB,0xB600009D,0xFE0C00AC,0x1402AC,0x5C0000DA,0x3C0000C1,0x2E0000C1,0x2A00009D,0x220000E8,0x64000161,0x44000125,0x1E000204,0x1400016E,0x2C02AB,0x200200,0x200200,0x200200,0x200200,0x60000000,0x60000000,0x60000000,0x2E000000,0x2E000000,0x1E000001,0x300200,0x300200,0x300200,0x220000B9,0x220000B9, -0x1E000065,0x5C0200,0x5C0200,0x16000132,0xE000202,0x300200,0x300200,0x300200,0x220000B9,0x220000B9,0x1E000065,0x5C0200,0x5C0200,0x16000132,0xE000202,0x5C0200,0x5C0200,0x16000132,0xE000202,0xE000202,0xB600009D,0xFE0C0088,0x200200,0x5C0000DA,0x3C0000C1,0x2E0000C1,0x2A00009D,0x220000E8,0x6400013D,0x4A000112,0x400200,0x16000132, -0x400200,0x780620,0xCA400000,0x72400000,0x56400001,0x2B00620,0x7A000059,0x58080001,0x1680620,0x4A0001ED,0x3A000622,0x2B00620,0x7A000059,0x58080001,0x1680620,0x4A0001ED,0x3A000622,0x1680620,0x4A0001ED,0x3A000622,0x3A000622,0x2B00620,0x7A000059,0x58080001,0x1680620,0x4A0001ED,0x3A000622,0x1680620,0x4A0001ED,0x3A000622,0x3A000622,0x1680620, -0x4A0001ED,0x3A000622,0x3A000622,0x3A000622,0xF8280349,0x800620,0xFE6C039D,0xBC0001BD,0x80000209,0x5E0001D4,0x50000131,0x460002B1,0xF8040320,0x9E000239,0x560000E8,0x3A000622,0xFC0620,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table162[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x500000,0x500000,0x500000,0x500000,0x2740000,0x2740000,0x2740000,0xF00000,0xF00000,0x26000001,0x2740000,0x2740000,0x2740000,0xF00000,0xF00000,0x26000001,0xF00000,0xF00000,0x26000001,0x26000001,0x2740000,0x2740000,0x2740000,0xF00000,0xF00000,0x26000001,0xF00000,0xF00000,0x26000001,0x26000001,0xF00000, -0xF00000,0x26000001,0x26000001,0x26000001,0x5C0000,0x2540000,0x500000,0x6C0000,0x840000,0xA80000,0xC00000,0x1240000,0x640000,0x2740000,0xA80000,0x26000001,0xA80000,0xC00000,0x11C0000,0x13FC0000,0x5E000001,0x11C0000,0x13FC0000,0x5E000001,0x13FC0000,0x5E000001,0x5E000001,0x11C0000,0x13FC0000,0x5E000001,0x13FC0000,0x5E000001, -0x5E000001,0x13FC0000,0x5E000001,0x5E000001,0x5E000001,0x11C0000,0x13FC0000,0x5E000001,0x13FC0000,0x5E000001,0x5E000001,0x13FC0000,0x5E000001,0x5E000001,0x5E000001,0x13FC0000,0x5E000001,0x5E000001,0x5E000001,0x5E000001,0xF00000,0xCC0000,0xCC0000,0x3400000,0x1D40000,0x39F00000,0x5E000001,0x5E000001,0x1040000,0x1680000,0x55FC0000,0x5E000001, -0x1980000,0x441830,0xFE1C0435,0x861C042D,0x5E1C042D,0xCE000620,0x8C000025,0x62040035,0x64000620,0x56000195,0x42000622,0x8800122B,0x740006C9,0x580003F3,0x580009E9,0x4C00046A,0x400007EB,0x4200122B,0x3E000B29,0x38000CB6,0x2C00122B,0x641830,0x62000B89,0x52000704,0x52000CF2,0x460006D3,0x3A000994,0x3A0013E9,0x3E000CE2,0x32000E07,0x2A0012FF,0xCC1830, -0x32001115,0x2C00114A,0x26001547,0x20001834,0xFE1407F5,0xFE2C116A,0xF63C11FC,0xC800047D,0x8000049D,0x5E000465,0x520002DE,0x4A00061E,0xF2000977,0x9E0006AD,0x4E0008E5,0x32000E07,0x901830,0x5C122C,0xFA280320,0x84280320,0x5E280321,0xCE000620,0x8C000025,0x6008002A,0x64000620,0x56000195,0x42000622,0x84122B,0x740006C9,0x580003F3,0x580009E9,0x4C00046A, -0x400007EB,0x10C122B,0x3E000B29,0x38000CB6,0x2C00122B,0x84122B,0x740006C9,0x580003F3,0x580009E9,0x4C00046A,0x400007EB,0x10C122B,0x3E000B29,0x38000CB6,0x2C00122B,0x10C122B,0x3E000B29,0x38000CB6,0x2C00122B,0x2C00122B,0xFE140791,0xFC480DB8,0xFE4C0D38,0xC800047D,0x8000049D,0x5E000465,0x520002DE,0x4A00061E,0xFA00088B,0x9E000649,0x4E0008CC,0x38000CB6, -0xBC122B,0x1C042C,0x1C042C,0x1C042C,0x1C042C,0x78000000,0x78000000,0x78000000,0x3A000000,0x3A000000,0x26000001,0x3C000320,0x3C000320,0x3C000320,0x2E000121,0x2E000121,0x22000092,0x1C000322,0x1C000322,0x1C0001E2,0x12000322,0x224042B,0x224042B,0x224042B,0x280001E2,0x280001E2,0x2200010B,0x18000372,0x18000372,0x1A00023E,0x12000346,0x4C042B, -0x4C042B,0x160002E3,0x100003AB,0xC00042B,0xF60000FA,0xFE0C018C,0x1C042C,0x72000151,0x50000131,0x4000013A,0x38000105,0x2A000161,0x8200022D,0x500001C2,0x24000324,0x1A00023E,0x34042B,0x280320,0x280320,0x280320,0x280320,0x78000000,0x78000000,0x78000000,0x3A000000,0x3A000000,0x26000001,0x3C0320,0x3C0320,0x3C0320,0x2E000121,0x2E000121, -0x22000092,0x740320,0x740320,0x1C0001E2,0x12000322,0x3C0320,0x3C0320,0x3C0320,0x2E000121,0x2E000121,0x22000092,0x740320,0x740320,0x1C0001E2,0x12000322,0x740320,0x740320,0x1C0001E2,0x12000322,0x12000322,0xF60000FA,0xF4180139,0x280320,0x72000151,0x50000131,0x4000013A,0x38000105,0x2A000161,0x820001ED,0x5A0001A8,0x540320,0x1C0001E2, -0x540320,0x880620,0xD2500000,0x7A500000,0x5E500001,0xC80620,0x8C000025,0x60180001,0x1980620,0x56000195,0x42000622,0xC80620,0x8C000025,0x60180001,0x1980620,0x56000195,0x42000622,0x1980620,0x56000195,0x42000622,0x42000622,0xC80620,0x8C000025,0x60180001,0x1980620,0x56000195,0x42000622,0x1980620,0x56000195,0x42000622,0x42000622,0x1980620, -0x56000195,0x42000622,0x42000622,0x42000622,0xFE340355,0x900620,0xF67C03C8,0xD2000164,0x8A0001A9,0x68000190,0x580000DA,0x5000024A,0xFC140322,0xB40001E2,0x5E000095,0x42000622,0x1200620,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table163[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x600000,0x600000,0x600000,0x600000,0x28C0000,0x28C0000,0x28C0000,0x1200000,0x1200000,0x2E000001,0x28C0000,0x28C0000,0x28C0000,0x1200000,0x1200000,0x2E000001,0x1200000,0x1200000,0x2E000001,0x2E000001,0x28C0000,0x28C0000,0x28C0000,0x1200000,0x1200000,0x2E000001,0x1200000,0x1200000,0x2E000001,0x2E000001,0x1200000, -0x1200000,0x2E000001,0x2E000001,0x2E000001,0x700000,0xA640000,0x600000,0x2800000,0xA00000,0xCC0000,0xE80000,0x1640000,0x780000,0x28C0000,0xCC0000,0x2E000001,0xCC0000,0xD00000,0x1340000,0x1FF80000,0x66000001,0x1340000,0x1FF80000,0x66000001,0x1FF80000,0x66000001,0x66000001,0x1340000,0x1FF80000,0x66000001,0x1FF80000,0x66000001, -0x66000001,0x1FF80000,0x66000001,0x66000001,0x66000001,0x1340000,0x1FF80000,0x66000001,0x1FF80000,0x66000001,0x66000001,0x1FF80000,0x66000001,0x66000001,0x66000001,0x1FF80000,0x66000001,0x66000001,0x66000001,0x66000001,0x1040000,0x6DC0000,0x6DC0000,0x15C0000,0x1FC0000,0x43F00000,0x66000001,0x66000001,0x3180000,0x1840000,0x5FD00000,0x66000001, -0x1B80000,0x4C1CB0,0xFE24064C,0x92200600,0x66200601,0xE6000620,0x98000005,0x6A08008D,0x70000620,0x5C00013D,0x4A000622,0x9A00152B,0x80000829,0x62000519,0x62000AC2,0x580004BA,0x46000863,0x4A00152C,0x44000D11,0x3E000E56,0x3200152B,0x701CB0,0x6E000DF9,0x580008DC,0x58000EB2,0x520007AB,0x46000A74,0x46001751,0x44000F22,0x38000FFF,0x30001633,0xE41CB0, -0x3800144D,0x3200140A,0x2C00190F,0x24001CB4,0xFE140A75,0xF63C1528,0xFA44160C,0xDE0004E3,0x90000506,0x6E0004C2,0x5E000302,0x500006CB,0xFA000B2B,0xB2000792,0x56000A45,0x38000FFF,0xA01CB0,0x64152C,0xFE300490,0x8E300480,0x66300481,0xE6000620,0x98000005,0x6A08007D,0x70000620,0x5C00013D,0x4A000622,0x98152B,0x80000829,0x62000519,0x62000AC2,0x580004BA, -0x46000863,0x130152B,0x44000D11,0x3E000E56,0x3200152B,0x98152B,0x80000829,0x62000519,0x62000AC2,0x580004BA,0x46000863,0x130152B,0x44000D11,0x3E000E56,0x3200152B,0x130152B,0x44000D11,0x3E000E56,0x3200152B,0x3200152B,0xFE2009B6,0xFE4C1044,0xF65C1031,0xDE0004E3,0x90000506,0x6E0004C2,0x5E000302,0x500006CB,0xFA000A2B,0xB2000719,0x56000A2C,0x3E000E56, -0xD8152B,0x200600,0x200600,0x200600,0x200600,0x90000000,0x90000000,0x90000000,0x46000000,0x46000000,0x2E000001,0x48000480,0x48000480,0x48000480,0x3A0001A9,0x3A0001A9,0x280000DA,0x22000480,0x22000480,0x200002C5,0x16000482,0x300600,0x300600,0x300600,0x2E0002C2,0x2E0002C2,0x28000183,0x1E0004F6,0x1E0004F6,0x1C000336,0x160004C2,0x5C0600, -0x5C0600,0x16000433,0x14000556,0xE000603,0xF600018A,0xF21402D9,0x200600,0x900001E1,0x5E0001BA,0x480001BA,0x40000172,0x2E000212,0x9600032B,0x660002A1,0x2C000489,0x1C000336,0x400600,0x300480,0x300480,0x300480,0x300480,0x90000000,0x90000000,0x90000000,0x46000000,0x46000000,0x2E000001,0x2440480,0x2440480,0x2440480,0x3A0001A9,0x3A0001A9, -0x280000DA,0x8C0480,0x8C0480,0x200002C5,0x16000482,0x2440480,0x2440480,0x2440480,0x3A0001A9,0x3A0001A9,0x280000DA,0x8C0480,0x8C0480,0x200002C5,0x16000482,0x8C0480,0x8C0480,0x200002C5,0x16000482,0x16000482,0xF600018A,0xF8200221,0x300480,0x900001E1,0x5E0001BA,0x480001BA,0x40000172,0x2E000212,0xA40002D5,0x6C000274,0x640480,0x200002C5, -0x640480,0x980620,0xDA600000,0x82600000,0x66600001,0xE00620,0x98000005,0x68280001,0x1CC0620,0x5C00013D,0x4A000622,0xE00620,0x98000005,0x68280001,0x1CC0620,0x5C00013D,0x4A000622,0x1CC0620,0x5C00013D,0x4A000622,0x4A000622,0xE00620,0x98000005,0x68280001,0x1CC0620,0x5C00013D,0x4A000622,0x1CC0620,0x5C00013D,0x4A000622,0x4A000622,0x1CC0620, -0x5C00013D,0x4A000622,0x4A000622,0x4A000622,0xFC4C0374,0x8A00620,0xFE8C03C8,0xE600010D,0xA0000161,0x76000132,0x5E000091,0x58000202,0xFE2C0349,0xC600019A,0x6A000061,0x4A000622,0x1400620,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table164[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000, -0x2180000,0x300000,0x300000,0x300000,0x8000000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x300000,0x300000,0x300000,0x8000000,0x300000,0x300000,0x300000,0x8000000,0x8000000,0x140000,0x100001,0x100001,0x140000,0x2140000,0x180000,0x180000,0x1C0000,0x140000,0x2140000,0x240000,0x300000, -0x240000,0x700001,0x700001,0x700001,0x700001,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x38000000,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x38000000,0x1580000,0x1580000,0x38000000,0x38000000,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x38000000,0x1580000,0x1580000,0x38000000,0x38000000,0x1580000, -0x1580000,0x38000000,0x38000000,0x38000000,0x840000,0x4780000,0x700001,0x2980000,0xC00000,0xF00000,0x1140000,0x1A40000,0x48C0000,0xA80000,0xF00000,0x38000000,0xF00000,0xE00001,0x1500000,0x2DF80000,0x70000000,0x1500000,0x2DF80000,0x70000000,0x2DF80000,0x70000000,0x70000000,0x1500000,0x2DF80000,0x70000000,0x2DF80000,0x70000000, -0x70000000,0x2DF80000,0x70000000,0x70000000,0x70000000,0x1500000,0x2DF80000,0x70000000,0x2DF80000,0x70000000,0x70000000,0x2DF80000,0x70000000,0x70000000,0x70000000,0x2DF80000,0x70000000,0x70000000,0x70000000,0x70000000,0x11C0000,0xF00000,0xF00000,0x17C0000,0x11FC0000,0x4DF80000,0x70000000,0x70000000,0x1340000,0x1A80000,0x69C40000,0x70000000, -0x1E00000,0x581F9B,0xFE30080B,0x9C2C0756,0x702C0756,0xFA080649,0xA408002A,0x741000FA,0x7C080649,0x68040139,0x54080649,0xB600152B,0x92000706,0x6E000496,0x740009B1,0x62000339,0x5200076C,0x5800152B,0x50000BF2,0x44000D79,0x3A00152C,0x841F99,0x7A000EA6,0x62000946,0x68000E9D,0x5E00071A,0x4C000A11,0x5200182C,0x4E000EC8,0x44000F8A,0x3A001695,0x10C1F99, -0x440015A6,0x3E00150D,0x32001A90,0x2C001F99,0xFE200C15,0xFE4C178F,0xFE4C18DF,0xF400035A,0xA2000391,0x7C00033A,0x660001B8,0x60000548,0xFE000BDB,0xC6000621,0x5E000926,0x44000F8A,0xBC1F99,0x78152B,0xFE4404A6,0x96440482,0x70400482,0xEE140621,0xA0100006,0x741C007A,0x78140621,0x660C0131,0x54100621,0x2B0152B,0x92000706,0x6E000496,0x740009B1,0x62000339, -0x5200076C,0x168152B,0x50000BF2,0x44000D79,0x3A00152C,0x2B0152B,0x92000706,0x6E000496,0x740009B1,0x62000339,0x5200076C,0x168152B,0x50000BF2,0x44000D79,0x3A00152C,0x168152B,0x50000BF2,0x44000D79,0x3A00152C,0x3A00152C,0xFE340A02,0xFA641079,0xFE6C1036,0xF400035A,0xA2000391,0x7C00033A,0x660001B8,0x60000548,0xFE080A6C,0xC6000591,0x5E000902,0x44000D79, -0xFC152B,0x2C0756,0x2C0756,0x2C0756,0x2C0756,0xA4080029,0xA4080029,0xA4080029,0x52080029,0x52080029,0x38080029,0x64000480,0x64000480,0x64000480,0x46000115,0x46000115,0x34000050,0x30000480,0x30000480,0x2C000249,0x20000480,0x400756,0x400756,0x400756,0x3A0002EE,0x3A0002EE,0x2E000169,0x2800055B,0x2800055B,0x2600030E,0x1E0004EC,0x800756, -0x800756,0x200004CD,0x1C000609,0x14000759,0xFC0C01B4,0xF82003D5,0x2C0756,0xB2000151,0x7C000124,0x5E000131,0x560000DD,0x40000172,0xC20002F5,0x8400022D,0x3E000490,0x2600030E,0x5C0756,0x400482,0x400482,0x400482,0x400482,0x98140001,0x98140001,0x98140001,0x50100001,0x50100001,0x38100001,0x600480,0x600480,0x600480,0x46000115,0x46000115, -0x34000050,0xC40480,0xC40480,0x2C000249,0x20000480,0x600480,0x600480,0x600480,0x46000115,0x46000115,0x34000050,0xC40480,0xC40480,0x2C000249,0x20000480,0xC40480,0xC40480,0x2C000249,0x20000480,0x20000480,0xFE100188,0xFE2C0239,0x400482,0xB2000151,0x7C000124,0x5E000131,0x560000DD,0x40000172,0xD6000262,0x900001E1,0x8C0480,0x2C000249, -0x8C0480,0xA80622,0xE0740001,0x8C700001,0x70700001,0xFC0620,0xA4080001,0x703C0000,0x3F80620,0x660000F4,0x54000620,0xFC0620,0xA4080001,0x703C0000,0x3F80620,0x660000F4,0x54000620,0x3F80620,0x660000F4,0x54000620,0x54000620,0xFC0620,0xA4080001,0x703C0000,0x3F80620,0x660000F4,0x54000620,0x3F80620,0x660000F4,0x54000620,0x54000620,0x3F80620, -0x660000F4,0x54000620,0x54000620,0x54000620,0xF668039D,0x2B40620,0xF8A003F5,0xFC0000C8,0xAA000109,0x7E0400F2,0x6C000050,0x640001B1,0xF4480372,0xD800013D,0x74000022,0x54000620,0x1680620,0x80029,0x80029,0x80029,0x80029,0x80029,0x80029,0x80029,0x80029,0x80029,0x80029,0x1A000000,0x1A000000,0x1A000000,0x1A000000,0x1A000000, -0x1A000000,0xC000000,0xC000000,0xC000000,0x8000000,0xC0029,0xC0029,0xC0029,0xC0029,0xC0029,0xC0029,0xC000010,0xC000010,0xC000010,0x6000008,0x140029,0x140029,0x140029,0x4000019,0x4000029,0x88000000,0x80029,0x80029,0x3C000000,0x2A000000,0x20000000,0x20000000,0x14000000,0x3600000A,0x24000005,0x10000001,0xC000010, -0x100029,}; -static const uint32_t g_etc1_to_bc7_m6_table165[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000, -0x2300000,0x640000,0x640000,0x640000,0x10000000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x640000,0x640000,0x640000,0x10000000,0x640000,0x640000,0x640000,0x10000000,0x10000000,0x240000,0x200001,0x200001,0x280000,0x2280000,0x22C0000,0x22C0000,0x380000,0x280000,0x2280000,0x480000,0x640000, -0x480000,0x800001,0x800001,0x800001,0x800001,0xC00000,0xC00000,0xC00000,0x1880000,0x1880000,0x40000000,0xC00000,0xC00000,0xC00000,0x1880000,0x1880000,0x40000000,0x1880000,0x1880000,0x40000000,0x40000000,0xC00000,0xC00000,0xC00000,0x1880000,0x1880000,0x40000000,0x1880000,0x1880000,0x40000000,0x40000000,0x1880000, -0x1880000,0x40000000,0x40000000,0x40000000,0x980000,0xC880000,0x800001,0xB00000,0xD80000,0x1140000,0x13C0000,0x1E40000,0x4A00000,0xC00000,0x1140000,0x40000000,0x1140000,0xF00001,0x1680000,0x39F80000,0x78000000,0x1680000,0x39F80000,0x78000000,0x39F80000,0x78000000,0x78000000,0x1680000,0x39F80000,0x78000000,0x39F80000,0x78000000, -0x78000000,0x39F80000,0x78000000,0x78000000,0x78000000,0x1680000,0x39F80000,0x78000000,0x39F80000,0x78000000,0x78000000,0x39F80000,0x78000000,0x78000000,0x78000000,0x39F80000,0x78000000,0x78000000,0x78000000,0x78000000,0x1300000,0x9000000,0x9000000,0x3940000,0x1FF80000,0x57F80000,0x78000000,0x78000000,0x1480000,0x1C40000,0x71D40000,0x78000000, -0x3FC0000,0x642297,0xFE3C0A17,0xA63808E2,0x783808E2,0xFC1406C7,0xAE100096,0x7E1801AE,0x861006B1,0x6E100185,0x5C1006B1,0xCE00152B,0xA2000619,0x78000482,0x800008D9,0x6E000231,0x580006D0,0x6400152B,0x5C000B02,0x50000C99,0x4200152C,0x982295,0x8C000F9A,0x6E000A26,0x74000F05,0x620006C9,0x58000A19,0x5E001914,0x56000E8F,0x4A000F5A,0x400016F9,0x1302295, -0x4A00172A,0x4400162D,0x38001C24,0x32002295,0xFE340DE6,0xFE4C1A9F,0xF8601BF2,0xFE000293,0xB6000271,0x88000239,0x740000E4,0x64000421,0xFE100D87,0xDA000512,0x6E00085A,0x4A000F5A,0xD82295,0x88152B,0xFC5804D2,0x9E540482,0x78500482,0xF6240621,0xA8200006,0x7C2C007A,0x80240621,0x6E1C0131,0x5C200621,0xC8152B,0xA2000619,0x78040480,0x800008D9,0x6E000231, -0x580006D0,0x198152B,0x5C000B02,0x50000C99,0x4200152C,0xC8152B,0xA2000619,0x78040480,0x800008D9,0x6E000231,0x580006D0,0x198152B,0x5C000B02,0x50000C99,0x4200152C,0x198152B,0x5C000B02,0x50000C99,0x4200152C,0x4200152C,0xFC4C0A7E,0xFE6C10C1,0xF880108B,0xFE000293,0xB6000271,0x88000239,0x740000E4,0x64000421,0xFE240AC5,0xDA00044E,0x6E000829,0x50000C99, -0x120152B,0x3808E2,0x3808E2,0x3808E2,0x3808E2,0xB4100091,0xB4100091,0xB4100091,0x5C100091,0x5C100091,0x40100091,0x7C000480,0x7C000480,0x7C000480,0x580000A9,0x580000A9,0x40000010,0x3C000480,0x3C000480,0x320001E5,0x28000480,0x5008E1,0x5008E1,0x5008E1,0x46000356,0x46000356,0x3A000191,0x340005D3,0x340005D3,0x30000300,0x28000529,0xA008E1, -0xA008E1,0x26000599,0x200006E4,0x1A0008E1,0xFE100248,0xFE2C050D,0x3808E2,0xD00000E1,0x900000B4,0x6E0000B4,0x66000074,0x4C000104,0xF40002E3,0xA60001E9,0x4C000499,0x30000300,0x7008E1,0x500482,0x500482,0x500482,0x500482,0xA0240001,0xA0240001,0xA0240001,0x58200001,0x58200001,0x40200001,0x780480,0x780480,0x780480,0x580000A9,0x580000A9, -0x40000010,0xF40480,0xF40480,0x320001E5,0x28000480,0x780480,0x780480,0x780480,0x580000A9,0x580000A9,0x40000010,0xF40480,0xF40480,0x320001E5,0x28000480,0xF40480,0xF40480,0x320001E5,0x28000480,0x28000480,0xFE2001A5,0xFA440242,0x500482,0xD00000E1,0x900000B4,0x6E0000B4,0x66000074,0x4C000104,0xF4000202,0xAC000184,0xAC0480,0x320001E5, -0xAC0480,0xB80622,0xE8840001,0x94800001,0x78800001,0x1140620,0xAC180001,0x784C0000,0xFF80620,0x720000B4,0x5C000620,0x1140620,0xAC180001,0x784C0000,0xFF80620,0x720000B4,0x5C000620,0xFF80620,0x720000B4,0x5C000620,0x5C000620,0x1140620,0xAC180001,0x784C0000,0xFF80620,0x720000B4,0x5C000620,0xFF80620,0x720000B4,0x5C000620,0x5C000620,0xFF80620, -0x720000B4,0x5C000620,0x5C000620,0x5C000620,0xFE78039D,0xAC40620,0xFEAC03F9,0xFE1400DD,0xC00000CD,0x900000A9,0x74000020,0x6C000171,0xFC580372,0xEE0000FA,0x7E000008,0x5C000620,0x18C0620,0x100091,0x100091,0x100091,0x100091,0x100091,0x100091,0x100091,0x100091,0x100091,0x100091,0x32000000,0x32000000,0x32000000,0x32000000,0x32000000, -0x32000000,0x18000000,0x18000000,0x18000000,0x10000000,0x180091,0x180091,0x180091,0x180091,0x180091,0x180091,0x12000034,0x12000034,0x12000034,0xE00001D,0x2C0091,0x2C0091,0x2C0091,0xA000055,0x8000091,0xF8000001,0x100091,0x100091,0x76000000,0x52000000,0x3E000000,0x3E000000,0x28000000,0x6000002D,0x42000019,0x1E000005,0x12000034, -0x200091,}; -static const uint32_t g_etc1_to_bc7_m6_table166[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x300001,0x480000,0x480000,0x480000,0x480000,0x480000, -0x480000,0x940000,0x940000,0x940000,0x18000000,0x480000,0x480000,0x480000,0x480000,0x480000,0x480000,0x940000,0x940000,0x940000,0x18000000,0x940000,0x940000,0x940000,0x18000000,0x18000000,0x2340000,0x300001,0x300001,0x4380000,0x23C0000,0x440000,0x440000,0x540000,0x4380000,0x23C0000,0x680000,0x940000, -0x680000,0x900001,0x900001,0x900001,0x900001,0xD80000,0xD80000,0xD80000,0x1B80000,0x1B80000,0x48000000,0xD80000,0xD80000,0xD80000,0x1B80000,0x1B80000,0x48000000,0x1B80000,0x1B80000,0x48000000,0x48000000,0xD80000,0xD80000,0xD80000,0x1B80000,0x1B80000,0x48000000,0x1B80000,0x1B80000,0x48000000,0x48000000,0x1B80000, -0x1B80000,0x48000000,0x48000000,0x48000000,0x2A80000,0x9C0000,0x900001,0x2C40000,0xF40000,0x1340000,0x1640000,0x7FC0000,0x4B40000,0xD80000,0x1340000,0x48000000,0x1340000,0x1000001,0x1800000,0x45F80000,0x80000000,0x1800000,0x45F80000,0x80000000,0x45F80000,0x80000000,0x80000000,0x1800000,0x45F80000,0x80000000,0x45F80000,0x80000000, -0x80000000,0x45F80000,0x80000000,0x80000000,0x80000000,0x1800000,0x45F80000,0x80000000,0x45F80000,0x80000000,0x80000000,0x45F80000,0x80000000,0x80000000,0x80000000,0x45F80000,0x80000000,0x80000000,0x80000000,0x80000000,0x1440000,0x1140000,0x1140000,0x1B00000,0x2BFC0000,0x61FC0000,0x80000000,0x80000000,0x35C0000,0x1E40000,0x79E40000,0x80000000, -0x13FC0000,0x7025F3,0xFE480C9B,0xB0400AC2,0x80400AC2,0xFE2407C7,0xBA1C0142,0x842402A6,0x90180759,0x78180209,0x64180759,0xE600152B,0xAE000579,0x820804A6,0x8C000821,0x76000159,0x62000659,0x7000152B,0x66000A44,0x56000BE9,0x4A00152C,0xA825F1,0x980010EA,0x7A000B86,0x80000FAD,0x6E0006D1,0x5E000A4D,0x680019F0,0x60000E80,0x54000F30,0x4600177D,0x15825F1, -0x50001916,0x4A00179D,0x3E001DF0,0x380025F1,0xFE3C105F,0xFA641D9D,0xFE6C1F1A,0xFE0802E9,0xCA000191,0x96000163,0x7C000051,0x7000031D,0xFE180FB2,0xF2000433,0x7600075A,0x54000F30,0xF025F1,0x98152B,0xFE6804F6,0xA6640482,0x80600482,0xFE340621,0xB0300006,0x843C007A,0x88340621,0x762C0131,0x64300621,0xE0152B,0xAE000579,0x80140480,0x8C000821,0x76000159, -0x62000659,0x1CC152B,0x66000A44,0x56000BE9,0x4A00152C,0xE0152B,0xAE000579,0x80140480,0x8C000821,0x76000159,0x62000659,0x1CC152B,0x66000A44,0x56000BE9,0x4A00152C,0x1CC152B,0x66000A44,0x56000BE9,0x4A00152C,0x4A00152C,0xFE580AE5,0xFC8810CB,0xFE8C1093,0xFE1402D6,0xCA000191,0x96000163,0x7C000051,0x7000031D,0xFE340B25,0xF2000352,0x76000729,0x56000BE9, -0x140152B,0x400AC2,0x400AC2,0x400AC2,0x400AC2,0xC4180139,0xC4180139,0xC4180139,0x66180139,0x66180139,0x48180139,0x94000480,0x94000480,0x94000480,0x62000055,0x62000055,0x48000001,0x48000480,0x48000480,0x3E000185,0x30000480,0x600AC1,0x600AC1,0x600AC1,0x520003FE,0x520003FE,0x40000209,0x4000066B,0x4000066B,0x3A00030E,0x2E000569,0xC40AC1, -0xC40AC1,0x2C0006AD,0x260007EC,0x20000AC1,0xFE200335,0xF43806DA,0x400AC2,0xFA000088,0xA8000061,0x80000061,0x78000032,0x5A0000B4,0xFE000332,0xC40001B1,0x5C0004A4,0x3A00030E,0x8C0AC1,0x600482,0x600482,0x600482,0x600482,0xA8340001,0xA8340001,0xA8340001,0x60300001,0x60300001,0x48300001,0x900480,0x900480,0x900480,0x62000055,0x62000055, -0x48040000,0x1240480,0x1240480,0x3E000185,0x30000480,0x900480,0x900480,0x900480,0x62000055,0x62000055,0x48040000,0x1240480,0x1240480,0x3E000185,0x30000480,0x1240480,0x1240480,0x3E000185,0x30000480,0x30000480,0xFA3401C2,0xFE4C0262,0x600482,0xFA000088,0xA8000061,0x80000061,0x78000032,0x5A0000B4,0xFE0C0200,0xC4000121,0xD00480,0x3E000185, -0xD00480,0xC80622,0xF0940001,0x9C900001,0x80900001,0x12C0620,0xB4280001,0x805C0000,0x1BF80620,0x78000080,0x64000620,0x12C0620,0xB4280001,0x805C0000,0x1BF80620,0x78000080,0x64000620,0x1BF80620,0x78000080,0x64000620,0x64000620,0x12C0620,0xB4280001,0x805C0000,0x1BF80620,0x78000080,0x64000620,0x1BF80620,0x78000080,0x64000620,0x64000620,0x1BF80620, -0x78000080,0x64000620,0x64000620,0x64000620,0xFA8C03C8,0xD80620,0xF8C00422,0xFE2C0109,0xCA000091,0x9A00006A,0x7E000008,0x76000128,0xFC6C039D,0xFC0000C8,0x88000001,0x64000620,0x1AC0620,0x180139,0x180139,0x180139,0x180139,0x180139,0x180139,0x180139,0x180139,0x180139,0x180139,0x4A000000,0x4A000000,0x4A000000,0x4A000000,0x4A000000, -0x4A000000,0x24000000,0x24000000,0x24000000,0x18000000,0x240139,0x240139,0x240139,0x240139,0x240139,0x240139,0x1E000074,0x1E000074,0x1E000074,0x18000040,0x440139,0x440139,0x440139,0x100000B9,0xC000139,0xFC080029,0x180139,0x180139,0xAE000000,0x78000000,0x5C000000,0x5C000000,0x3C000000,0x92000061,0x74000032,0x2E000009,0x1E000074, -0x300139,}; -static const uint32_t g_etc1_to_bc7_m6_table167[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x600000,0x600000,0x600000,0x600000,0x600000, -0x600000,0xC40000,0xC40000,0xC40000,0x20000000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0xC40000,0xC40000,0xC40000,0x20000000,0xC40000,0xC40000,0xC40000,0x20000000,0x20000000,0xA440000,0x400001,0x400001,0x4C0000,0x4500000,0x580000,0x580000,0x26C0000,0x4C0000,0x4500000,0x8C0000,0xC40000, -0x8C0000,0xA00001,0xA00001,0xA00001,0xA00001,0xF00000,0xF00000,0xF00000,0x1E80000,0x1E80000,0x50000000,0xF00000,0xF00000,0xF00000,0x1E80000,0x1E80000,0x50000000,0x1E80000,0x1E80000,0x50000000,0x50000000,0xF00000,0xF00000,0xF00000,0x1E80000,0x1E80000,0x50000000,0x1E80000,0x1E80000,0x50000000,0x50000000,0x1E80000, -0x1E80000,0x50000000,0x50000000,0x50000000,0xBC0000,0xAC0000,0xA00001,0xDC0000,0x1100000,0x1580000,0x18C0000,0x13F80000,0xCC0000,0xF00000,0x1580000,0x50000000,0x1580000,0x1100001,0x1980000,0x51F80000,0x88000000,0x1980000,0x51F80000,0x88000000,0x51F80000,0x88000000,0x88000000,0x1980000,0x51F80000,0x88000000,0x51F80000,0x88000000, -0x88000000,0x51F80000,0x88000000,0x88000000,0x88000000,0x1980000,0x51F80000,0x88000000,0x51F80000,0x88000000,0x88000000,0x51F80000,0x88000000,0x88000000,0x88000000,0x51F80000,0x88000000,0x88000000,0x88000000,0x88000000,0x1580000,0x1240000,0x1240000,0x1CC0000,0x39FC0000,0x6BFC0000,0x88000000,0x88000000,0x1740000,0x5FC0000,0x81F40000,0x88000000, -0x21FC0000,0x7C29AF,0xFE540F97,0xB84C0CF6,0x884C0CF6,0xFE300953,0xC4240236,0x8E2C03EA,0x9A200841,0x801C02D1,0x6C200841,0xFE00152B,0xC00004F9,0x8C100502,0x98000789,0x800000B5,0x6C000629,0x7C00152B,0x72000984,0x60000B40,0x5200152C,0xBC29AD,0xA800126A,0x82000D65,0x8C001095,0x7A000739,0x68000AC5,0x74001B10,0x68000E8C,0x5C000F2A,0x52001805,0x17C29AD, -0x5C001B46,0x5000195D,0x4A001FD0,0x3E0029AD,0xFE501342,0xFE6C2105,0xFE6C231A,0xFE1403DA,0xD80000EA,0xA20000B9,0x88000009,0x7A000236,0xFE2412A6,0xFC00038C,0x7E0006CC,0x5C000F2A,0x10C29AD,0xA8152B,0xFE78053B,0xAE740482,0x88700482,0xFE440629,0xB8400006,0x8C4C007A,0x90440621,0x7E3C0131,0x6C400621,0xF8152B,0xC00004F9,0x88240480,0x98000789,0x800000B5, -0x6C000629,0x1FC152B,0x72000984,0x60000B40,0x5200152C,0xF8152B,0xC00004F9,0x88240480,0x98000789,0x800000B5,0x6C000629,0x1FC152B,0x72000984,0x60000B40,0x5200152C,0x1FC152B,0x72000984,0x60000B40,0x5200152C,0x5200152C,0xFC740B5A,0xF4981121,0xF8A010E6,0xFE240355,0xD80000EA,0xA20000B9,0x88000009,0x7A000236,0xFE440B94,0xFC00028C,0x7E00068C,0x60000B40, -0x164152B,0x4C0CF6,0x4C0CF6,0x4C0CF6,0x4C0CF6,0xD4200221,0xD4200221,0xD4200221,0x70200221,0x70200221,0x50200221,0xAC000480,0xAC000480,0xAC000480,0x7400001D,0x7400001D,0x52040018,0x54000480,0x54000480,0x44000139,0x38000480,0x700CF6,0x700CF6,0x700CF6,0x620004C5,0x620004C5,0x4C0002C1,0x4C000723,0x4C000723,0x40000332,0x340005C1,0xE40CF6, -0xE40CF6,0x380007FD,0x2C000924,0x24000CF9,0xFE2C0498,0xFA4408C6,0x4C0CF6,0xFE080098,0xBC000029,0x9200002D,0x84000008,0x6A000068,0xFE000452,0xD4000186,0x660004AC,0x40000332,0xA00CF6,0x700482,0x700482,0x700482,0x700482,0xB0440001,0xB0440001,0xB0440001,0x68400001,0x68400001,0x50400001,0xA80480,0xA80480,0xA80480,0x7400001D,0x7400001D, -0x50140000,0x1580480,0x1580480,0x44000139,0x38000480,0xA80480,0xA80480,0xA80480,0x7400001D,0x7400001D,0x50140000,0x1580480,0x1580480,0x44000139,0x38000480,0x1580480,0x1580480,0x44000139,0x38000480,0x38000480,0xF64801E1,0xFA640265,0x700482,0xFE080088,0xBC000029,0x9200002D,0x84000008,0x6A000068,0xF6240221,0xDA0000CA,0xF00480,0x44000139, -0xF00480,0xD80622,0xF8A40001,0xA4A00001,0x88A00001,0x1440620,0xBC380001,0x886C0000,0x27F80620,0x84000050,0x6C000620,0x1440620,0xBC380001,0x886C0000,0x27F80620,0x84000050,0x6C000620,0x27F80620,0x84000050,0x6C000620,0x6C000620,0x1440620,0xBC380001,0x886C0000,0x27F80620,0x84000050,0x6C000620,0x27F80620,0x84000050,0x6C000620,0x6C000620,0x27F80620, -0x84000050,0x6C000620,0x6C000620,0x6C000620,0xFE9403E8,0xE80620,0xFECC042A,0xFE400128,0xE000006D,0xA6000050,0x88000000,0x7E0000F4,0xF88403C8,0xFE1400E1,0x90100001,0x6C000620,0x1D00620,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x64000000,0x64000000,0x64000000,0x64000000,0x64000000, -0x64000000,0x30000000,0x30000000,0x30000000,0x20000000,0x300221,0x300221,0x300221,0x300221,0x300221,0x300221,0x280000C2,0x280000C2,0x280000C2,0x1E000068,0x5C0221,0x5C0221,0x5C0221,0x16000145,0x10000221,0xFE0C009D,0x200221,0x200221,0xE8000000,0xA0000000,0x7A000000,0x7A000000,0x50000000,0xC40000A9,0x96000055,0x3E000010,0x280000C2, -0x400221,}; -static const uint32_t g_etc1_to_bc7_m6_table168[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000, -0x7C0000,0xFC0000,0xFC0000,0xFC0000,0x28000001,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0xFC0000,0xFC0000,0xFC0000,0x28000001,0xFC0000,0xFC0000,0xFC0000,0x28000001,0x28000001,0x4580000,0x540000,0x540000,0x2600000,0x680000,0x2700000,0x2700000,0x8C0000,0x2600000,0x680000,0xB00000,0xFC0000, -0xB00000,0xB40000,0xB40000,0xB40000,0xB40000,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0x58000001,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0x58000001,0xBF80000,0xBF80000,0x58000001,0x58000001,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0x58000001,0xBF80000,0xBF80000,0x58000001,0x58000001,0xBF80000, -0xBF80000,0x58000001,0x58000001,0x58000001,0xD00000,0xC00000,0xB40000,0xF40000,0x32C0000,0x17C0000,0x1B80000,0x1FF80000,0x2E00000,0x10C0000,0x17C0000,0x58000001,0x17C0000,0x1240000,0x3B00000,0x5DFC0000,0x90000001,0x3B00000,0x5DFC0000,0x90000001,0x5DFC0000,0x90000001,0x90000001,0x3B00000,0x5DFC0000,0x90000001,0x5DFC0000,0x90000001, -0x90000001,0x5DFC0000,0x90000001,0x90000001,0x90000001,0x3B00000,0x5DFC0000,0x90000001,0x5DFC0000,0x90000001,0x90000001,0x5DFC0000,0x90000001,0x90000001,0x90000001,0x5DFC0000,0x90000001,0x90000001,0x90000001,0x90000001,0x36C0000,0x1380000,0x1380000,0x1EC0000,0x49F80000,0x77F40000,0x90000001,0x90000001,0x18C0000,0x17FC0000,0x8BE80000,0x90000001, -0x33FC0000,0x8C2E54,0xFE681371,0xC2580FD9,0x90580FD9,0xFE3C0BBC,0xD42C039D,0x9A3805B5,0xA42C0994,0x8A240406,0x74280996,0xFE0C1590,0xD20004A2,0x961805A9,0xA80006E9,0x8C000042,0x7404062A,0x8A00152B,0x780008B3,0x6C000A83,0x5C00152B,0xCC2E54,0xB40014BB,0x8E000FFC,0x980011E6,0x8000080E,0x6E000BB6,0x80001C6F,0x74000EBF,0x66000F3F,0x5800189C,0x1A02E54, -0x60001E64,0x5C001B96,0x50002227,0x44002E54,0xFE58170A,0xF88025CC,0xFA842794,0xFE2405E6,0xEA000061,0xB0000042,0x9204000A,0x86000173,0xFE3415FA,0xFE00042C,0x90000627,0x66000F3F,0x1242E54,0xB8152C,0xFE8C0581,0xB8840480,0x90840481,0xFE5C0642,0xC2540005,0x945C007D,0x9A540620,0x864C0132,0x74540622,0x114152B,0xD20004A2,0x90380481,0xA80006E9,0x8C000042, -0x740C0622,0xFF8152B,0x780008B3,0x6C000A83,0x5C00152B,0x114152B,0xD20004A2,0x90380481,0xA80006E9,0x8C000042,0x740C0622,0xFF8152B,0x780008B3,0x6C000A83,0x5C00152B,0xFF8152B,0x780008B3,0x6C000A83,0x5C00152B,0x5C00152B,0xFE800BBE,0xFEAC1122,0xFEAC1101,0xFE4003CB,0xEA000061,0xB0000042,0x92080002,0x86000173,0xFE5C0BD5,0xFE1002E5,0x900005D6,0x6C000A83, -0x18C152B,0x580FD8,0x580FD8,0x580FD8,0x580FD8,0xE42C0374,0xE42C0374,0xE42C0374,0x7A2C0374,0x7A2C0374,0x58280375,0xC8000480,0xC8000480,0xC8000480,0x82000005,0x82000005,0x5C0C005E,0x60000482,0x60000482,0x500000E1,0x40000482,0x2800FD8,0x2800FD8,0x2800FD8,0x6E000615,0x6E000615,0x520003EB,0x58000811,0x58000811,0x4C00037E,0x4000063B,0x1080FD8, -0x1080FD8,0x3E0009BD,0x32000AC6,0x2A000FDB,0xFC380694,0xFE4C0B58,0x580FD8,0xFE100141,0xDA000005,0xA6000005,0x98000002,0x7600002D,0xFE1405F9,0xF6000172,0x7C0004C0,0x4C00037E,0xB80FD8,0x840480,0x840480,0x840480,0x840480,0xBA540000,0xBA540000,0xBA540000,0x70540000,0x70540000,0x58540001,0xC40480,0xC40480,0xC40480,0x82000005,0x82000005, -0x5A240001,0x18C0480,0x18C0480,0x500000E1,0x40000482,0xC40480,0xC40480,0xC40480,0x82000005,0x82000005,0x5A240001,0x18C0480,0x18C0480,0x500000E1,0x40000482,0x18C0480,0x18C0480,0x500000E1,0x40000482,0x40000482,0xFE5801E1,0xF4780288,0x840480,0xFE2400A2,0xDA000005,0xA6000005,0x96040000,0x7600002D,0xFE340221,0xFC000082,0x1180480,0x500000E1, -0x1180480,0xEC0620,0xFEB40004,0xACB40000,0x90B40001,0x35C0620,0xC44C0001,0x927C0001,0x33FC0620,0x8E00002D,0x74000622,0x35C0620,0xC44C0001,0x927C0001,0x33FC0620,0x8E00002D,0x74000622,0x33FC0620,0x8E00002D,0x74000622,0x74000622,0x35C0620,0xC44C0001,0x927C0001,0x33FC0620,0x8E00002D,0x74000622,0x33FC0620,0x8E00002D,0x74000622,0x74000622,0x33FC0620, -0x8E00002D,0x74000622,0x74000622,0x74000622,0xFEB403F5,0xFC0620,0xFAE40451,0xFE580164,0xEA00003D,0xB2000022,0x90140001,0x8A0000C1,0xFE9803C8,0xFE380120,0x9A200000,0x74000622,0x1F40620,0x280374,0x280374,0x280374,0x280374,0x280374,0x280374,0x280374,0x280374,0x280374,0x280374,0x7E000000,0x7E000000,0x7E000000,0x7E000000,0x7E000000, -0x7E000000,0x3E000000,0x3E000000,0x3E000000,0x28000001,0x23C0372,0x23C0372,0x23C0372,0x23C0372,0x23C0372,0x23C0372,0x2E000145,0x2E000145,0x2E000145,0x240000A9,0x7C0372,0x7C0372,0x7C0372,0x1C000212,0x14000372,0xF61C016D,0x280374,0x280374,0xFE040014,0xCC000000,0x9C000000,0x9C000000,0x66000000,0xF6000112,0xB4000092,0x4E000019,0x2E000145, -0x580372,}; -static const uint32_t g_etc1_to_bc7_m6_table169[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x940000,0x940000,0x940000,0x940000,0x940000, -0x940000,0x12C0000,0x12C0000,0x12C0000,0x30000001,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x12C0000,0x12C0000,0x12C0000,0x30000001,0x12C0000,0x12C0000,0x12C0000,0x30000001,0x30000001,0xC680000,0x640000,0x640000,0x740000,0x7C0000,0x880000,0x880000,0xA80000,0x740000,0x7C0000,0xD40000,0x12C0000, -0xD40000,0xC40000,0xC40000,0xC40000,0xC40000,0x1240000,0x1240000,0x1240000,0x17F80000,0x17F80000,0x60000001,0x1240000,0x1240000,0x1240000,0x17F80000,0x17F80000,0x60000001,0x17F80000,0x17F80000,0x60000001,0x60000001,0x1240000,0x1240000,0x1240000,0x17F80000,0x17F80000,0x60000001,0x17F80000,0x17F80000,0x60000001,0x60000001,0x17F80000, -0x17F80000,0x60000001,0x60000001,0x60000001,0xE40000,0xD00000,0xC40000,0x3080000,0x1480000,0x1A00000,0x1E00000,0x29FC0000,0x2F40000,0x1240000,0x1A00000,0x60000001,0x1A00000,0x1340000,0x1C80000,0x69FC0000,0x98000001,0x1C80000,0x69FC0000,0x98000001,0x69FC0000,0x98000001,0x98000001,0x1C80000,0x69FC0000,0x98000001,0x69FC0000,0x98000001, -0x98000001,0x69FC0000,0x98000001,0x98000001,0x98000001,0x1C80000,0x69FC0000,0x98000001,0x69FC0000,0x98000001,0x98000001,0x69FC0000,0x98000001,0x98000001,0x98000001,0x69FC0000,0x98000001,0x98000001,0x98000001,0x98000001,0x3800000,0x1480000,0x1480000,0x7FC0000,0x55FC0000,0x81F40000,0x98000001,0x98000001,0x1A40000,0x29FC0000,0x93F80000,0x98000001, -0x41FC0000,0x9832DC,0xFE741765,0xCC6412C4,0x986412C5,0xFE440E76,0xDE340525,0xA0440799,0xAE340B04,0x942C055E,0x7C300B06,0xFE18169C,0xE2000481,0xA0200679,0xB4000691,0x96000012,0x7C080656,0x9600152B,0x840007FB,0x720009EB,0x6400152B,0xE032DC,0xC0001733,0x980012C5,0xA2001322,0x8C000906,0x7A000CD6,0x8C001DCF,0x7C000F22,0x6E000F63,0x62001933,0x1C432DC, -0x6C00213C,0x60001E14,0x5600247F,0x4A0032DC,0xFE641ADA,0xFE8C29F4,0xFE8C2C04,0xFE2C081A,0xFA00002A,0xBC00000D,0x9C08003B,0x900000E2,0xFE4419D3,0xFE100626,0x960005A9,0x6E000F63,0x13C32DC,0xC8152C,0xFEA405E1,0xC0940480,0x98940481,0xFE740672,0xCA640005,0x9C6C007D,0xA2640620,0x8E5C0132,0x7C640622,0x12C152B,0xE2000481,0x98480481,0xB4000691,0x96000012, -0x7C1C0622,0x1BF8152B,0x840007FB,0x720009EB,0x6400152B,0x12C152B,0xE2000481,0x98480481,0xB4000691,0x96000012,0x7C1C0622,0x1BF8152B,0x840007FB,0x720009EB,0x6400152B,0x1BF8152B,0x840007FB,0x720009EB,0x6400152B,0x6400152B,0xFE940C03,0xF6BC1178,0xFAC41144,0xFE540456,0xFA00002A,0xBC00000D,0x9A180002,0x900000E2,0xFE780C41,0xFE240375,0x9A000551,0x720009EB, -0x1AC152B,0x6412C4,0x6412C4,0x6412C4,0x6412C4,0xF43404E4,0xF43404E4,0xF43404E4,0x843404E4,0x843404E4,0x603004E5,0xE0000480,0xE0000480,0xE0000480,0x90000005,0x90000005,0x641000C2,0x6C000482,0x6C000482,0x5C0000A9,0x48000482,0x9012C3,0x9012C3,0x9012C3,0x7A000785,0x7A000785,0x5E000533,0x620008E2,0x620008E2,0x520003DE,0x460006A3,0x12412C3, -0x12412C3,0x44000B9D,0x3E000C56,0x300012C3,0xFE3C08B8,0xF4580E45,0x6412C4,0xFE1C0258,0xF0000001,0xB8000001,0xA6040018,0x8000000D,0xFE200802,0xFE0001C8,0x860004C8,0x520003DE,0xD012C3,0x940480,0x940480,0x940480,0x940480,0xC2640000,0xC2640000,0xC2640000,0x78640000,0x78640000,0x60640001,0xDC0480,0xDC0480,0xDC0480,0x8C0C0001,0x8C0C0001, -0x62340001,0x1BC0480,0x1BC0480,0x5C0000A9,0x48000482,0xDC0480,0xDC0480,0xDC0480,0x8C0C0001,0x8C0C0001,0x62340001,0x1BC0480,0x1BC0480,0x5C0000A9,0x48000482,0x1BC0480,0x1BC0480,0x5C0000A9,0x48000482,0x48000482,0xFA6C0200,0xFC880288,0x940480,0xFE3400B9,0xEE040000,0xB6040000,0x9E140000,0x8000000D,0xFA480244,0xFC140091,0x1380480,0x5C0000A9, -0x1380480,0xFC0620,0xFEC8000D,0xB4C40000,0x98C40001,0x3740620,0xCC5C0001,0x9A8C0001,0x3FFC0620,0x96000012,0x7C000622,0x3740620,0xCC5C0001,0x9A8C0001,0x3FFC0620,0x96000012,0x7C000622,0x3FFC0620,0x96000012,0x7C000622,0x7C000622,0x3740620,0xCC5C0001,0x9A8C0001,0x3FFC0620,0x96000012,0x7C000622,0x3FFC0620,0x96000012,0x7C000622,0x7C000622,0x3FFC0620, -0x96000012,0x7C000622,0x7C000622,0x7C000622,0xFAC80422,0x10C0620,0xFEEC0469,0xFE740190,0xF8040029,0xBC00000D,0x98240001,0x90000091,0xFEAC03F5,0xFE4C013D,0xA2300000,0x7C000622,0xDFC0620,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x3004E4,0x96000000,0x96000000,0x96000000,0x96000000,0x96000000, -0x96000000,0x4A000000,0x4A000000,0x4A000000,0x30000001,0x4804E2,0x4804E2,0x4804E2,0x4804E2,0x4804E2,0x4804E2,0x3A0001CD,0x3A0001CD,0x3A0001CD,0x2E0000EA,0x9404E2,0x9404E2,0x9404E2,0x20000305,0x180004E2,0xFA240265,0x3004E4,0x3004E4,0xFE100071,0xF4000000,0xBA000000,0xBA000000,0x7A000000,0xF60001C2,0xD60000CD,0x5E000024,0x3A0001CD, -0x6804E2,}; -static const uint32_t g_etc1_to_bc7_m6_table170[] = { -0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x80000, -0x80000,0x80000,0x80000,0x1,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x80000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000, -0xAC0000,0x15C0000,0x15C0000,0x15C0000,0x38000001,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0xAC0000,0x15C0000,0x15C0000,0x15C0000,0x38000001,0x15C0000,0x15C0000,0x15C0000,0x38000001,0x38000001,0x7C0000,0x740000,0x740000,0x6840000,0x900000,0x9C0000,0x9C0000,0x2C00000,0x6840000,0x900000,0xF40000,0x15C0000, -0xF40000,0xD40000,0xD40000,0xD40000,0xD40000,0x13C0000,0x13C0000,0x13C0000,0x21FC0000,0x21FC0000,0x68000001,0x13C0000,0x13C0000,0x13C0000,0x21FC0000,0x21FC0000,0x68000001,0x21FC0000,0x21FC0000,0x68000001,0x68000001,0x13C0000,0x13C0000,0x13C0000,0x21FC0000,0x21FC0000,0x68000001,0x21FC0000,0x21FC0000,0x68000001,0x68000001,0x21FC0000, -0x21FC0000,0x68000001,0x68000001,0x68000001,0x4F40000,0x8E00000,0xD40000,0x1200000,0x1640000,0x1C00000,0x5FC0000,0x35F80000,0x3080000,0x13C0000,0x1C00000,0x68000001,0x1C00000,0x1440000,0x1E00000,0x75FC0000,0xA0000001,0x1E00000,0x75FC0000,0xA0000001,0x75FC0000,0xA0000001,0xA0000001,0x1E00000,0x75FC0000,0xA0000001,0x75FC0000,0xA0000001, -0xA0000001,0x75FC0000,0xA0000001,0xA0000001,0xA0000001,0x1E00000,0x75FC0000,0xA0000001,0x75FC0000,0xA0000001,0xA0000001,0x75FC0000,0xA0000001,0xA0000001,0xA0000001,0x75FC0000,0xA0000001,0xA0000001,0xA0000001,0xA0000001,0x3940000,0x5580000,0x5580000,0x1BFC0000,0x63FC0000,0x8BF40000,0xA0000001,0xA0000001,0x1B80000,0x39FC0000,0x9DCC0000,0xA0000001, -0x51FC0000,0xA43680,0xFE801AD5,0xD470152D,0xA070152D,0xFE5C1112,0xE440067D,0xAA4C0931,0xB83C0C40,0x9A38068A,0x843C0C42,0xFE3017F0,0xF0080485,0xAA280735,0xC6000655,0xA0080012,0x86100686,0xA004152B,0x90000767,0x7E00095F,0x6C04152B,0xF43680,0xD20018EB,0xA204152C,0xAE0013F2,0x9800099A,0x80000D92,0x92001E87,0x86000EDF,0x76000F1F,0x68001953,0x1F03680, -0x7200234C,0x6C001F94,0x5C00261B,0x50003684,0xFE781E55,0xFE8C2DE0,0xF8A02FFD,0xFE400A6F,0xFE0C0052,0xC804000E,0xA4100086,0x98000089,0xFE541CF7,0xFE18084E,0xA4000539,0x76000F1F,0x15C3680,0xD8152C,0xFEB00631,0xC8A40480,0xA0A40481,0xFE8006A6,0xD2740005,0xA47C007D,0xAA740620,0x966C0132,0x84740622,0x144152B,0xEA100481,0xA0580481,0xC6000651,0xA008000E, -0x842C0622,0x27F8152B,0x90000763,0x7E00095B,0x6C00152B,0x144152B,0xEA100481,0xA0580481,0xC6000651,0xA008000E,0x842C0622,0x27F8152B,0x90000763,0x7E00095B,0x6C00152B,0x27F8152B,0x90000763,0x7E00095B,0x6C00152B,0x6C00152B,0xFEA00C86,0xFECC1178,0xFECC1164,0xFE6C04E5,0xFE100035,0xC410000D,0xA2280002,0x98000085,0xFE880CA0,0xFE4003DB,0xA40004F9,0x7E00095B, -0x1D0152B,0x70152C,0x70152C,0x70152C,0x70152C,0xFE3C0624,0xFE3C0624,0xFE3C0624,0x8E3C0620,0x8E3C0620,0x683C0621,0xF4040480,0xF4040480,0xF4040480,0x9E040011,0x9E040011,0x6C180131,0x78040480,0x78040480,0x64000081,0x50040482,0xA4152B,0xA4152B,0xA4152B,0x86000889,0x86000889,0x68000641,0x6E000966,0x6E000966,0x5E0003E6,0x4C0006C3,0x14C152B, -0x14C152B,0x4A000D01,0x44000D62,0x3600152B,0xFE4C0A8D,0xFA641079,0x70152C,0xFE2C037D,0xFE08000D,0xC608000C,0xB6080038,0x8E040001,0xFC3009DD,0xFE0002CC,0x960004B9,0x5E0003E6,0xE8152B,0xA40480,0xA40480,0xA40480,0xA40480,0xCA740000,0xCA740000,0xCA740000,0x80740000,0x80740000,0x68740001,0xF40480,0xF40480,0xF40480,0x941C0001,0x941C0001, -0x6A440001,0x1F00480,0x1F00480,0x6400007D,0x50000482,0xF40480,0xF40480,0xF40480,0x941C0001,0x941C0001,0x6A440001,0x1F00480,0x1F00480,0x6400007D,0x50000482,0x1F00480,0x1F00480,0x6400007D,0x50000482,0x50000482,0xFE740220,0xF49802AD,0xA40480,0xFE4400DA,0xF6140000,0xBE140000,0xA6240000,0x8E000001,0xF2600265,0xFE2400A4,0x15C0480,0x6400007D, -0x15C0480,0x10C0620,0xFEDC0020,0xBCD40000,0xA0D40001,0x38C0620,0xD46C0001,0xA29C0001,0x4BFC0620,0xA0000005,0x84000622,0x38C0620,0xD46C0001,0xA29C0001,0x4BFC0620,0xA0000005,0x84000622,0x4BFC0620,0xA0000005,0x84000622,0x84000622,0x38C0620,0xD46C0001,0xA29C0001,0x4BFC0620,0xA0000005,0x84000622,0x4BFC0620,0xA0000005,0x84000622,0x84000622,0x4BFC0620, -0xA0000005,0x84000622,0x84000622,0x84000622,0xFED00442,0x71C0620,0xFB040480,0xFC9001C4,0xFE100035,0xCA000004,0xA0340001,0x9C00006A,0xF4C80422,0xFE640179,0xAA400000,0x84000622,0x1DF80620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0x3C0620,0xAC040000,0xAC040000,0xAC040000,0xAC040000,0xAC040000, -0xAC040000,0x54040000,0x54040000,0x54040000,0x38040001,0x580620,0x580620,0x580620,0x580620,0x580620,0x580620,0x4600021D,0x4600021D,0x4600021D,0x340000FA,0xB00620,0xB00620,0xB00620,0x260003A9,0x1C000622,0xFE2C0349,0x3C0620,0x3C0620,0xFA1800F4,0xFC08000D,0xD2040000,0xD2040000,0x8A040000,0xFA08028A,0xFE0000E8,0x66000019,0x4600021D, -0x7C0620,}; -static const uint32_t g_etc1_to_bc7_m6_table171[] = { -0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x380000, -0x380000,0x380000,0x380000,0x8000001,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x2140000,0x2140000,0x2140000,0x1C0000,0x280000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000, -0xC40000,0x18C0000,0x18C0000,0x18C0000,0x40000001,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x18C0000,0x40000001,0x18C0000,0x18C0000,0x18C0000,0x40000001,0x40000001,0x8C0000,0x840000,0x840000,0x2980000,0xA40000,0xB40000,0xB40000,0xDC0000,0x2980000,0xA40000,0x1180000,0x18C0000, -0x1180000,0xE40000,0xE40000,0xE40000,0xE40000,0x3500000,0x3500000,0x3500000,0x2DFC0000,0x2DFC0000,0x70000001,0x3500000,0x3500000,0x3500000,0x2DFC0000,0x2DFC0000,0x70000001,0x2DFC0000,0x2DFC0000,0x70000001,0x70000001,0x3500000,0x3500000,0x3500000,0x2DFC0000,0x2DFC0000,0x70000001,0x2DFC0000,0x2DFC0000,0x70000001,0x70000001,0x2DFC0000, -0x2DFC0000,0x70000001,0x70000001,0x70000001,0x1080000,0xF40000,0xE40000,0x3340000,0x1800000,0x1E40000,0x13F80000,0x3FFC0000,0x31C0000,0x3500000,0x1E40000,0x70000001,0x1E40000,0x1540000,0x1F80000,0x81FC0000,0xA8000001,0x1F80000,0x81FC0000,0xA8000001,0x81FC0000,0xA8000001,0xA8000001,0x1F80000,0x81FC0000,0xA8000001,0x81FC0000,0xA8000001, -0xA8000001,0x81FC0000,0xA8000001,0xA8000001,0xA8000001,0x1F80000,0x81FC0000,0xA8000001,0x81FC0000,0xA8000001,0xA8000001,0x81FC0000,0xA8000001,0xA8000001,0xA8000001,0x81FC0000,0xA8000001,0xA8000001,0xA8000001,0xA8000001,0x3A80000,0xD680000,0xD680000,0x2FFC0000,0x71FC0000,0x95F40000,0xA8000001,0xA8000001,0x3CC0000,0x4BFC0000,0xA5DC0000,0xA8000001, -0x5FFC0000,0xB43680,0xFE8C1BA1,0xDC80152D,0xA880152D,0xFE6811EA,0xEC50067D,0xB25C0931,0xC04C0C40,0xA248068A,0x8C4C0C42,0xFE441883,0xF8180485,0xB2380735,0xCC0C0651,0xA8180012,0x8E200686,0xA814152B,0x98040733,0x86040933,0x7414152B,0x10C3680,0xE20017A1,0xAA14152C,0xC0001242,0xA2000823,0x8C000CC2,0xA2001CE9,0x92000CD7,0x80000D2B,0x7000182C,0xBF83680, -0x7E0021E4,0x72001DD4,0x660024F4,0x58003684,0xFE8C1F58,0xFCA82E0A,0xFEAC3001,0xFE540B96,0xFE2000B6,0xD014000E,0xAC200086,0xA20C0082,0xFE701E35,0xFE300991,0xB00004B1,0x80000D2B,0x17C3680,0xE8152C,0xFEC40690,0xD0B40480,0xA8B40481,0xFE9806E6,0xDA840005,0xAC8C007D,0xB2840620,0x9E7C0132,0x8C840622,0x15C152B,0xF2200481,0xA8680481,0xD2000629,0xA818000E, -0x8C3C0622,0x33F8152B,0x960006DB,0x840008D3,0x7400152B,0x15C152B,0xF2200481,0xA8680481,0xD2000629,0xA818000E,0x8C3C0622,0x33F8152B,0x960006DB,0x840008D3,0x7400152B,0x33F8152B,0x960006DB,0x840008D3,0x7400152B,0x7400152B,0xFEB40CC9,0xF6DC11D2,0xFAE411A1,0xFE78057E,0xFE280069,0xCC20000D,0xAA380002,0xA400004B,0xFE980D11,0xFE54047D,0xB00004B0,0x840008D3, -0x1F0152B,0x80152C,0x80152C,0x80152C,0x80152C,0xFE500631,0xFE500631,0xFE500631,0x964C0620,0x964C0620,0x704C0621,0xFC140480,0xFC140480,0xFC140480,0xA6140011,0xA6140011,0x74280131,0x80140480,0x80140480,0x6C0C007A,0x58140482,0xBC152B,0xBC152B,0xBC152B,0x980007B9,0x980007B9,0x70040621,0x7A000866,0x7A000866,0x680002AA,0x580005EB,0x17C152B, -0x17C152B,0x56000C19,0x4A000C82,0x3E00152B,0xFC640B12,0xFE6C10C1,0x80152C,0xFE3C03E0,0xFE1C001D,0xCE18000C,0xBE180038,0x96140001,0xFE3C0A38,0xFE18031E,0xA8000481,0x680002AA,0x10C152B,0xB40480,0xB40480,0xB40480,0xB40480,0xD2840000,0xD2840000,0xD2840000,0x88840000,0x88840000,0x70840001,0x10C0480,0x10C0480,0x10C0480,0x9C2C0001,0x9C2C0001, -0x72540001,0xBF80480,0xBF80480,0x6C00004A,0x58000482,0x10C0480,0x10C0480,0x10C0480,0x9C2C0001,0x9C2C0001,0x72540001,0xBF80480,0xBF80480,0x6C00004A,0x58000482,0xBF80480,0xBF80480,0x6C00004A,0x58000482,0x58000482,0xFE900221,0xFCA802AD,0xB40480,0xFE5C00E1,0xFE240000,0xC6240000,0xAE340000,0x980C0000,0xFA700265,0xFA4000C8,0x17C0480,0x6C00004A, -0x17C0480,0x11C0620,0xFEEC0041,0xC4E40000,0xA8E40001,0x3A40620,0xDC7C0001,0xAAAC0001,0x57FC0620,0xA8000001,0x8C000622,0x3A40620,0xDC7C0001,0xAAAC0001,0x57FC0620,0xA8000001,0x8C000622,0x57FC0620,0xA8000001,0x8C000622,0x8C000622,0x3A40620,0xDC7C0001,0xAAAC0001,0x57FC0620,0xA8000001,0x8C000622,0x57FC0620,0xA8000001,0x8C000622,0x8C000622,0x57FC0620, -0xA8000001,0x8C000622,0x8C000622,0x8C000622,0xFAF00451,0xF2C0620,0xFF0C04A0,0xFEA001F9,0xFE380055,0xD4040000,0xA8440001,0xA400004A,0xFCD80422,0xFE8401A5,0xB2500000,0x8C000622,0x2BFC0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0x4C0620,0xB4140000,0xB4140000,0xB4140000,0xB4140000,0xB4140000, -0xB4140000,0x5C140000,0x5C140000,0x5C140000,0x40140001,0x700620,0x700620,0x700620,0x700620,0x700620,0x700620,0x52000185,0x52000185,0x52000185,0x4000007A,0xE40620,0xE40620,0xE40620,0x32000321,0x24000622,0xF63C0374,0x4C0620,0x4C0620,0xFE2C0109,0xFC1C0019,0xDA140000,0xDA140000,0x92140000,0xFC1C02AD,0xFA0C00DD,0x7A040000,0x52000185, -0xA00620,}; -static const uint32_t g_etc1_to_bc7_m6_table172[] = { -0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x700000, -0x700000,0x700000,0x700000,0x12000000,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x280000,0x280000,0x280000,0x380000,0x500000,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000, -0x2DC0000,0x1C40000,0x1C40000,0x1C40000,0x4A000000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000,0x1C40000,0x1C40000,0x4A000000,0x1C40000,0x1C40000,0x1C40000,0x4A000000,0x4A000000,0xA00000,0x940001,0x940001,0x4AC0000,0xBC0000,0xCC0000,0xCC0000,0xFC0000,0x4AC0000,0xBC0000,0x13C0000,0x1C40000, -0x13C0000,0xF40001,0xF40001,0xF40001,0xF40001,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x3BFC0000,0x7A000000,0x7A000000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x3BFC0000,0x7A000000,0x7A000000,0x3BFC0000, -0x3BFC0000,0x7A000000,0x7A000000,0x7A000000,0x51C0000,0xB040000,0xF40001,0x34C0000,0x19C0000,0x7FC0000,0x21FC0000,0x4BFC0000,0x1340000,0x16C0000,0x7FC0000,0x7A000000,0x7FC0000,0x1640001,0x19FC0000,0x8FF80000,0xB2000000,0x19FC0000,0x8FF80000,0xB2000000,0x8FF80000,0xB2000000,0xB2000000,0x19FC0000,0x8FF80000,0xB2000000,0x8FF80000,0xB2000000, -0xB2000000,0x8FF80000,0xB2000000,0xB2000000,0xB2000000,0x19FC0000,0x8FF80000,0xB2000000,0x8FF80000,0xB2000000,0xB2000000,0x8FF80000,0xB2000000,0xB2000000,0xB2000000,0x8FF80000,0xB2000000,0xB2000000,0xB2000000,0xB2000000,0x1C00000,0x77C0000,0x77C0000,0x45FC0000,0x7FFC0000,0xA1F00000,0xB2000000,0xB2000000,0x1E80000,0x5DFC0000,0xAFD00000,0xB2000000, -0x71FC0000,0xC43684,0xFEA41C83,0xE690152B,0xB290152B,0xFE801302,0xF664067B,0xBA6C0933,0xC8600C42,0xAC5C0686,0x965C0C42,0xFE5C1959,0xFE28048A,0xBA480733,0xD620064F,0xB0280012,0x9630068A,0xB224152C,0xA0140735,0x8E140931,0x7C24152D,0x3243680,0xF400169F,0xB228152B,0xD20010AA,0xAE000711,0x94000C50,0xAE001B7F,0x9E000AD1,0x8C000B51,0x7A0016F9,0x17FC3680, -0x8A00206C,0x7E001C08,0x720023A4,0x62003680,0xFEA0204E,0xF6BC2EC4,0xF8C0308C,0xFE6C0D33,0xFE38015B,0xDA28000E,0xB6340082,0xAA1C0086,0xFE781F23,0xFE440AEA,0xBA0C049F,0x8C000B51,0x1A43680,0xFC152B,0xFED40722,0xD8C80482,0xB2C40482,0xFEB00749,0xE2940006,0xB6A0007A,0xBA980621,0xA8900131,0x96940621,0x374152B,0xFC300481,0xB2780480,0xDE080621,0xB0280011, -0x964C0620,0x3FFC152B,0xA6000662,0x9000084C,0x7C00152C,0x374152B,0xFC300481,0xB2780480,0xDE080621,0xB0280011,0x964C0620,0x3FFC152B,0xA6000662,0x9000084C,0x7C00152C,0x3FFC152B,0xA6000662,0x9000084C,0x7C00152C,0x7C00152C,0xFED00D38,0xFEEC11D9,0xFEEC11E2,0xFE940602,0xFE4800C6,0xD630000D,0xB24C0001,0xAE04003D,0xFEB40D8E,0xFE700541,0xBC000486,0x9000084C, -0xDFC152B,0x90152B,0x90152B,0x90152B,0x90152B,0xFE600653,0xFE600653,0xFE600653,0x9E600622,0x9E600622,0x7A5C0622,0xFE280489,0xFE280489,0xFE280489,0xB028000E,0xB028000E,0x7E3C0132,0x88280481,0x88280481,0x741C007D,0x62240481,0xD4152B,0xD4152B,0xD4152B,0xA80006F1,0xA80006F1,0x7A140620,0x86000771,0x86000771,0x7400019D,0x62000529,0x1B0152B, -0x1B0152B,0x60000B4C,0x56000B91,0x4800152C,0xFE740B63,0xFC8810CB,0x90152B,0xFE54045A,0xFE300042,0xD628000B,0xC628003B,0x9E240002,0xFE500A8E,0xFE30038A,0xB2100480,0x7400019D,0x130152B,0xC40482,0xC40482,0xC40482,0xC40482,0xDA980001,0xDA980001,0xDA980001,0x92940001,0x92940001,0x7A940001,0x3240480,0x3240480,0x3240480,0xA63C0001,0xA63C0001, -0x7A680000,0x17FC0480,0x17FC0480,0x78000028,0x62000480,0x3240480,0x3240480,0x3240480,0xA63C0001,0xA63C0001,0x7A680000,0x17FC0480,0x17FC0480,0x78000028,0x62000480,0x17FC0480,0x17FC0480,0x78000028,0x62000480,0x62000480,0xFEA00244,0xF6BC02D2,0xC40482,0xFE780109,0xFC3C0004,0xD0340000,0xB6480000,0xA21C0000,0xF8880288,0xFC5800DD,0x1A40480,0x78000028, -0x1A40480,0x12C0622,0xFF00006A,0xCEF40001,0xB2F40001,0x1C00620,0xE68C0001,0xB2C00000,0x65F80620,0xB2100000,0x96000620,0x1C00620,0xE68C0001,0xB2C00000,0x65F80620,0xB2100000,0x96000620,0x65F80620,0xB2100000,0x96000620,0x96000620,0x1C00620,0xE68C0001,0xB2C00000,0x65F80620,0xB2100000,0x96000620,0x65F80620,0xB2100000,0x96000620,0x96000620,0x65F80620, -0xB2100000,0x96000620,0x96000620,0x96000620,0xFEF80479,0x9400620,0xFD2804B1,0xFEC00225,0xFE500089,0xDC180000,0xB2500000,0xAC000034,0xFEF00451,0xFEA001E5,0xBA640001,0x96000620,0x3DF80620,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0x5C0622,0xBA280001,0xBA280001,0xBA280001,0xBA280001,0xBA280001, -0xBA280001,0x66240001,0x66240001,0x66240001,0x4A240001,0x8C0620,0x8C0620,0x8C0620,0x8C0620,0x8C0620,0x8C0620,0x620000E9,0x620000E9,0x620000E9,0x4800001D,0x1180620,0x1180620,0x1180620,0x3E0002A1,0x2E000620,0xFE4C037A,0x5C0622,0x5C0622,0xFE3C0122,0xFC300029,0xE2280001,0xE2280001,0x9A280001,0xF83002D2,0xFC1C00F4,0x82180000,0x620000E9, -0xC80620,}; -static const uint32_t g_etc1_to_bc7_m6_table173[] = { -0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0xA00000, -0xA00000,0xA00000,0xA00000,0x1A000000,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x4380000,0x4380000,0x4380000,0x500000,0x700000,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000, -0x2F40000,0x1F40000,0x1F40000,0x1F40000,0x52000000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x1F40000,0x1F40000,0x1F40000,0x52000000,0x1F40000,0x1F40000,0x1F40000,0x52000000,0x52000000,0xB00000,0xA40001,0xA40001,0xC00000,0xD00000,0xE00000,0xE00000,0x3140000,0xC00000,0xD00000,0x1600000,0x1F40000, -0x1600000,0x1040001,0x1040001,0x1040001,0x1040001,0x1840000,0x1840000,0x1840000,0x47FC0000,0x47FC0000,0x82000000,0x1840000,0x1840000,0x1840000,0x47FC0000,0x47FC0000,0x82000000,0x47FC0000,0x47FC0000,0x82000000,0x82000000,0x1840000,0x1840000,0x1840000,0x47FC0000,0x47FC0000,0x82000000,0x47FC0000,0x47FC0000,0x82000000,0x82000000,0x47FC0000, -0x47FC0000,0x82000000,0x82000000,0x82000000,0x1300000,0x1180000,0x1040001,0x1640000,0x1B80000,0x17FC0000,0x2FFC0000,0x57F80000,0x1480000,0x1840000,0x17FC0000,0x82000000,0x17FC0000,0x1740001,0x31FC0000,0x9BF80000,0xBA000000,0x31FC0000,0x9BF80000,0xBA000000,0x9BF80000,0xBA000000,0xBA000000,0x31FC0000,0x9BF80000,0xBA000000,0x9BF80000,0xBA000000, -0xBA000000,0x9BF80000,0xBA000000,0xBA000000,0xBA000000,0x31FC0000,0x9BF80000,0xBA000000,0x9BF80000,0xBA000000,0xBA000000,0x9BF80000,0xBA000000,0xBA000000,0xBA000000,0x9BF80000,0xBA000000,0xBA000000,0xBA000000,0xBA000000,0x1D40000,0xF8C0000,0xF8C0000,0x59FC0000,0x8DFC0000,0xABF00000,0xBA000000,0xBA000000,0x1FC0000,0x6FFC0000,0xB7E00000,0xBA000000, -0x7FFC0000,0xD43684,0xFEB01D6B,0xEEA0152B,0xBAA0152B,0xFE8C1422,0xFE74067B,0xC27C0933,0xD0700C42,0xB46C0686,0x9E6C0C42,0xFE681A21,0xFE4004BA,0xC2580733,0xDE30064F,0xB8380012,0x9E40068A,0xBA34152C,0xA8240735,0x96240931,0x8434152D,0x33C3680,0xFE04164D,0xBA38152B,0xE2000F5A,0xBA000681,0x9E080C40,0xBA001A5F,0xA8000936,0x940009ED,0x82001640,0x23FC3680, -0x96001F3C,0x84001A90,0x78002270,0x6A003680,0xFEA82162,0xFECC2EC4,0xFECC30A4,0xFE800E82,0xFE4C0223,0xE238000E,0xBE440082,0xB22C0086,0xFE902009,0xFE5C0C52,0xC21C049F,0x940009ED,0x1C83680,0x10C152B,0xFEE80793,0xE0D80482,0xBAD40482,0xFEC407A3,0xEAA40006,0xBEB0007A,0xC2A80621,0xB0A00131,0x9EA40621,0x38C152B,0xFE4C0491,0xBA880480,0xE6180621,0xB8380011, -0x9E5C0620,0x4BFC152B,0xAC0005E6,0x960007E4,0x8400152C,0x38C152B,0xFE4C0491,0xBA880480,0xE6180621,0xB8380011,0x9E5C0620,0x4BFC152B,0xAC0005E6,0x960007E4,0x8400152C,0x4BFC152B,0xAC0005E6,0x960007E4,0x8400152C,0x8400152C,0xFEE40DD9,0xF900122B,0xFB041203,0xFEB006D2,0xFE680131,0xDE40000D,0xBA5C0001,0xB80C0038,0xFEC40DFB,0xFE8405C2,0xC6040480,0x960007E4, -0x1DF8152B,0xA0152B,0xA0152B,0xA0152B,0xA0152B,0xFE740672,0xFE740672,0xFE740672,0xA6700622,0xA6700622,0x826C0622,0xFE3C049B,0xFE3C049B,0xFE3C049B,0xB838000E,0xB838000E,0x864C0132,0x90380481,0x90380481,0x7C2C007D,0x6A340481,0xEC152B,0xEC152B,0xEC152B,0xBA000681,0xBA000681,0x82240620,0x980006B1,0x980006B1,0x7A0000E9,0x680004B9,0x1E4152B, -0x1E4152B,0x6C000A8C,0x5C000AD1,0x5000152C,0xFE840BAE,0xF4981122,0xA0152B,0xFE6804E6,0xFE440072,0xDE38000B,0xCE38003B,0xA6340002,0xFE640B11,0xFE440409,0xBA200480,0x7A0000E9,0x154152B,0xD40482,0xD40482,0xD40482,0xD40482,0xE2A80001,0xE2A80001,0xE2A80001,0x9AA40001,0x9AA40001,0x82A40001,0x33C0480,0x33C0480,0x33C0480,0xAE4C0001,0xAE4C0001, -0x82780000,0x23FC0480,0x23FC0480,0x7E000014,0x6A000480,0x33C0480,0x33C0480,0x33C0480,0xAE4C0001,0xAE4C0001,0x82780000,0x23FC0480,0x23FC0480,0x7E000014,0x6A000480,0x23FC0480,0x23FC0480,0x7E000014,0x6A000480,0x6A000480,0xFAB40265,0xFECC02D2,0xD40482,0xFE880122,0xFE540008,0xD8440000,0xBE580000,0xAA2C0000,0xFE940290,0xFE6800F4,0x1C80480,0x7E000014, -0x1C80480,0x13C0622,0xFF1800A2,0xD7040001,0xBB040001,0x1D80620,0xEE9C0001,0xBAD00000,0x71F80620,0xBA200000,0x9E000620,0x1D80620,0xEE9C0001,0xBAD00000,0x71F80620,0xBA200000,0x9E000620,0x71F80620,0xBA200000,0x9E000620,0x9E000620,0x1D80620,0xEE9C0001,0xBAD00000,0x71F80620,0xBA200000,0x9E000620,0x71F80620,0xBA200000,0x9E000620,0x9E000620,0x71F80620, -0xBA200000,0x9E000620,0x9E000620,0x9E000620,0xFF140482,0x1540620,0xF53804E2,0xFED80269,0xFE7C00B5,0xE4280000,0xBA600000,0xB6000019,0xF7080480,0xFEC00221,0xC2740001,0x9E000620,0x4BFC0620,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0x6C0622,0xC2380001,0xC2380001,0xC2380001,0xC2380001,0xC2380001, -0xC2380001,0x6E340001,0x6E340001,0x6E340001,0x52340001,0xA40620,0xA40620,0xA40620,0xA40620,0xA40620,0xA40620,0x74000089,0x74000089,0x74000089,0x52000000,0x14C0620,0x14C0620,0x14C0620,0x4400022D,0x36000620,0xF860039D,0x6C0622,0x6C0622,0xFE4C013D,0xFE3C003A,0xEA380001,0xEA380001,0xA2380001,0xFE3C02DA,0xFC300109,0x8A280000,0x74000089, -0xE80620,}; -static const uint32_t g_etc1_to_bc7_m6_table174[] = { -0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0xD00000, -0xD00000,0xD00000,0xD00000,0x22000000,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0xC480000,0xC480000,0xC480000,0x680000,0x940000,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0xB40001,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000, -0x30C0000,0xBFC0000,0xBFC0000,0xBFC0000,0x5A000000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0x30C0000,0xBFC0000,0xBFC0000,0xBFC0000,0x5A000000,0xBFC0000,0xBFC0000,0xBFC0000,0x5A000000,0x5A000000,0x8C00000,0xB40001,0xB40001,0xD40000,0xE40000,0xF80000,0xF80000,0x1300000,0xD40000,0xE40000,0x1800000,0xBFC0000, -0x1800000,0x1140001,0x1140001,0x1140001,0x1140001,0x19C0000,0x19C0000,0x19C0000,0x53FC0000,0x53FC0000,0x8A000000,0x19C0000,0x19C0000,0x19C0000,0x53FC0000,0x53FC0000,0x8A000000,0x53FC0000,0x53FC0000,0x8A000000,0x8A000000,0x19C0000,0x19C0000,0x19C0000,0x53FC0000,0x53FC0000,0x8A000000,0x53FC0000,0x53FC0000,0x8A000000,0x8A000000,0x53FC0000, -0x53FC0000,0x8A000000,0x8A000000,0x8A000000,0x1440000,0x1280000,0x1140001,0x3780000,0x1D40000,0x25FC0000,0x3DF80000,0x61FC0000,0x15C0000,0x19C0000,0x25FC0000,0x8A000000,0x25FC0000,0x1840001,0x49FC0000,0xA7F80000,0xC2000000,0x49FC0000,0xA7F80000,0xC2000000,0xA7F80000,0xC2000000,0xC2000000,0x49FC0000,0xA7F80000,0xC2000000,0xA7F80000,0xC2000000, -0xC2000000,0xA7F80000,0xC2000000,0xC2000000,0xC2000000,0x49FC0000,0xA7F80000,0xC2000000,0xA7F80000,0xC2000000,0xC2000000,0xA7F80000,0xC2000000,0xC2000000,0xC2000000,0xA7F80000,0xC2000000,0xC2000000,0xC2000000,0xC2000000,0x1E80000,0x1A00000,0x1A00000,0x6DFC0000,0x9BFC0000,0xB5F00000,0xC2000000,0xC2000000,0x1FFC0000,0x81FC0000,0xBFF00000,0xC2000000, -0x8FFC0000,0xE43684,0xFEC41E2C,0xF6B0152B,0xC2B0152B,0xFEA41532,0xFE8406AF,0xCA8C0933,0xD8800C42,0xBC7C0686,0xA67C0C42,0xFE801AF9,0xFE540527,0xCA680733,0xE640064F,0xC0480012,0xA650068A,0xC244152C,0xB0340735,0x9E340931,0x8C44152D,0x1543680,0xFE1416C3,0xC248152B,0xEE000E4A,0xC6000651,0xA6180C40,0xCC001953,0xB40007E6,0x9E0008C1,0x8C0015A5,0x2FFC3680, -0x9C001E10,0x90001910,0x84002170,0x72003680,0xFEBC2236,0xF6DC2F82,0xF8E0311F,0xFE940FF3,0xFE640317,0xEA48000E,0xC6540082,0xBA3C0086,0xFEA42172,0xFE700DE2,0xCA2C049F,0x9E0008C1,0x1E83680,0x11C152B,0xFEF4082B,0xE8E80482,0xC2E40482,0xFED0081B,0xF2B40006,0xC6C0007A,0xCAB80621,0xB8B00131,0xA6B40621,0x3A4152B,0xFE6404B9,0xC2980480,0xEE280621,0xC0480011, -0xA66C0620,0x57FC152B,0xB8000586,0xA0000789,0x8C00152C,0x3A4152B,0xFE6404B9,0xC2980480,0xEE280621,0xC0480011,0xA66C0620,0x57FC152B,0xB8000586,0xA0000789,0x8C00152C,0x57FC152B,0xB8000586,0xA0000789,0x8C00152C,0x8C00152C,0xFEF80E2A,0xFF0C123B,0xFF0C124B,0xFEC0075E,0xFE7C01A9,0xE650000D,0xC26C0001,0xC01C0038,0xFEDC0E35,0xFE980692,0xCE140480,0xA0000789, -0x2BFC152B,0xB0152B,0xB0152B,0xB0152B,0xB0152B,0xFE8406AB,0xFE8406AB,0xFE8406AB,0xAE800622,0xAE800622,0x8A7C0622,0xFE5004B9,0xFE5004B9,0xFE5004B9,0xC048000E,0xC048000E,0x8E5C0132,0x98480481,0x98480481,0x843C007D,0x72440481,0x104152B,0x104152B,0x104152B,0xC6000641,0xC6000641,0x8A340620,0xA20005F6,0xA20005F6,0x86000061,0x72000489,0x7FC152B, -0x7FC152B,0x720009E8,0x66000A24,0x5800152C,0xFE900C2A,0xFCA81122,0xB0152B,0xFE78055A,0xFE5800B2,0xE648000B,0xD648003B,0xAE440002,0xFE780B5A,0xFE500485,0xC2300480,0x86000061,0x174152B,0xE40482,0xE40482,0xE40482,0xE40482,0xEAB80001,0xEAB80001,0xEAB80001,0xA2B40001,0xA2B40001,0x8AB40001,0x1540480,0x1540480,0x1540480,0xB65C0001,0xB65C0001, -0x8A880000,0x2FFC0480,0x2FFC0480,0x8A000004,0x72000480,0x1540480,0x1540480,0x1540480,0xB65C0001,0xB65C0001,0x8A880000,0x2FFC0480,0x2FFC0480,0x8A000004,0x72000480,0x2FFC0480,0x2FFC0480,0x8A000004,0x72000480,0x72000480,0xF6C80288,0xF6DC02F9,0xE40482,0xFE980145,0xFC6C0019,0xE0540000,0xC6680000,0xB23C0000,0xFAAC02AD,0xFE800120,0x1E80480,0x8A000004, -0x1E80480,0x14C0622,0xFF2400DA,0xDF140001,0xC3140001,0x1F00620,0xF6AC0001,0xC2E00000,0x7DF80620,0xC2300000,0xA6000620,0x1F00620,0xF6AC0001,0xC2E00000,0x7DF80620,0xC2300000,0xA6000620,0x7DF80620,0xC2300000,0xA6000620,0xA6000620,0x1F00620,0xF6AC0001,0xC2E00000,0x7DF80620,0xC2300000,0xA6000620,0x7DF80620,0xC2300000,0xA6000620,0xA6000620,0x7DF80620, -0xC2300000,0xA6000620,0xA6000620,0xA6000620,0xFB2C04B1,0x1640620,0xFD4804E2,0xFEEC029A,0xFE9000F5,0xEC380000,0xC2700000,0xC000000D,0xFF180480,0xFECC0262,0xCA840001,0xA6000620,0x5BFC0620,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0x7C0622,0xCA480001,0xCA480001,0xCA480001,0xCA480001,0xCA480001, -0xCA480001,0x76440001,0x76440001,0x76440001,0x5A440001,0xBC0620,0xBC0620,0xBC0620,0xBC0620,0xBC0620,0xBC0620,0x80000041,0x80000041,0x80000041,0x5A100000,0x17C0620,0x17C0620,0x17C0620,0x500001CD,0x3E000620,0xFE6C03A9,0x7C0622,0x7C0622,0xFA60016D,0xFE50004A,0xF2480001,0xF2480001,0xAA480001,0xFC5402F9,0xFE3C0132,0x92380000,0x80000041, -0x10C0620,}; -static const uint32_t g_etc1_to_bc7_m6_table175[] = { -0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x1000000, -0x1000000,0x1000000,0x1000000,0x2A000000,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x5C0000,0x5C0000,0x5C0000,0x800000,0xB40000,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000, -0x3240000,0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0x62000000,0xD40000,0xC40001,0xC40001,0x4E40000,0xF80000,0x10C0000,0x10C0000,0x14C0000,0x4E40000,0xF80000,0x1A40000,0x17FC0000, -0x1A40000,0x1240001,0x1240001,0x1240001,0x1240001,0x1B40000,0x1B40000,0x1B40000,0x5FF80000,0x5FF80000,0x92000000,0x1B40000,0x1B40000,0x1B40000,0x5FF80000,0x5FF80000,0x92000000,0x5FF80000,0x5FF80000,0x92000000,0x92000000,0x1B40000,0x1B40000,0x1B40000,0x5FF80000,0x5FF80000,0x92000000,0x5FF80000,0x5FF80000,0x92000000,0x92000000,0x5FF80000, -0x5FF80000,0x92000000,0x92000000,0x92000000,0x3540000,0x5380000,0x1240001,0x1900000,0x3EC0000,0x35FC0000,0x49FC0000,0x6DF80000,0x1700000,0x1B40000,0x35FC0000,0x92000000,0x35FC0000,0x1940001,0x63FC0000,0xB3F80000,0xCA000000,0x63FC0000,0xB3F80000,0xCA000000,0xB3F80000,0xCA000000,0xCA000000,0x63FC0000,0xB3F80000,0xCA000000,0xB3F80000,0xCA000000, -0xCA000000,0xB3F80000,0xCA000000,0xCA000000,0xCA000000,0x63FC0000,0xB3F80000,0xCA000000,0xB3F80000,0xCA000000,0xCA000000,0xB3F80000,0xCA000000,0xCA000000,0xCA000000,0xB3F80000,0xCA000000,0xCA000000,0xCA000000,0xCA000000,0x1FC0000,0x1B00000,0x1B00000,0x81FC0000,0xA9F80000,0xBFF00000,0xCA000000,0xCA000000,0x3DFC0000,0x91FC0000,0xC9C40000,0xCA000000, -0x9FF80000,0xF43684,0xFED01F3C,0xFEC0152B,0xCAC0152B,0xFEB01682,0xFE980713,0xD29C0933,0xE0900C42,0xC48C0686,0xAE8C0C42,0xFE981BF1,0xFE6C05CF,0xD2780733,0xEE50064F,0xC8580012,0xAE60068A,0xCA54152C,0xB8440735,0xA6440931,0x9454152D,0x16C3680,0xFE38176F,0xCA58152B,0xFA000D7A,0xCE100651,0xAE280C40,0xD8001863,0xBC0006CD,0xA60007D9,0x94001550,0x3BFC3680, -0xA6001D1B,0x960017C8,0x8A002044,0x7A003680,0xFED02341,0xFEEC2F82,0xFEEC313B,0xFEAC11B2,0xFE78043B,0xF258000E,0xCE640082,0xC24C0086,0xFEB4221F,0xFE800F42,0xD23C049F,0xA60007D9,0x7FC3680,0x12C152B,0xFF0C08BB,0xF0F80482,0xCAF40482,0xFEE80893,0xFAC40006,0xCED0007A,0xD2C80621,0xC0C00131,0xAEC40621,0x3BC152B,0xFE7C0501,0xCAA80480,0xF6380621,0xC8580011, -0xAE7C0620,0x63FC152B,0xC2000540,0xAA000740,0x9400152C,0x3BC152B,0xFE7C0501,0xCAA80480,0xF6380621,0xC8580011,0xAE7C0620,0x63FC152B,0xC2000540,0xAA000740,0x9400152C,0x63FC152B,0xC2000540,0xAA000740,0x9400152C,0x9400152C,0xFF000EBB,0xF9201289,0xFD281262,0xFED40821,0xFE900249,0xEE60000D,0xCA7C0001,0xC82C0038,0xFCF40ED9,0xFEC0074A,0xD6240480,0xAA000740, -0x3BFC152B,0xC0152B,0xC0152B,0xC0152B,0xC0152B,0xFE9806E2,0xFE9806E2,0xFE9806E2,0xB6900622,0xB6900622,0x928C0622,0xFE6804F1,0xFE6804F1,0xFE6804F1,0xC858000E,0xC858000E,0x966C0132,0xA0580481,0xA0580481,0x8C4C007D,0x7A540481,0x11C152B,0x11C152B,0x11C152B,0xD8000621,0xD8000621,0x92440620,0xAE000576,0xAE000576,0x92000019,0x7A080480,0x13FC152B, -0x13FC152B,0x7E000938,0x72000984,0x6000152C,0xFEA00C7D,0xF4B8117B,0xC0152B,0xFE8805D3,0xFE6C0102,0xEE58000B,0xDE58003B,0xB6540002,0xFE900BE5,0xFE680518,0xCA400480,0x92000019,0x198152B,0xF40482,0xF40482,0xF40482,0xF40482,0xF2C80001,0xF2C80001,0xF2C80001,0xAAC40001,0xAAC40001,0x92C40001,0x16C0480,0x16C0480,0x16C0480,0xBE6C0001,0xBE6C0001, -0x92980000,0x3BFC0480,0x3BFC0480,0x92000000,0x7A000480,0x16C0480,0x16C0480,0x16C0480,0xBE6C0001,0xBE6C0001,0x92980000,0x3BFC0480,0x3BFC0480,0x92000000,0x7A000480,0x3BFC0480,0x3BFC0480,0x92000000,0x7A000480,0x7A000480,0xFED80288,0xFEEC02F9,0xF40482,0xFEB4016D,0xFE800029,0xE8640000,0xCE780000,0xBA4C0000,0xFCC002D2,0xFE980139,0x7FC0480,0x92000000, -0x7FC0480,0x15C0622,0xFF3C0122,0xE7240001,0xCB240001,0xDFC0620,0xFEBC0001,0xCAF00000,0x89F80620,0xCA400000,0xAE000620,0xDFC0620,0xFEBC0001,0xCAF00000,0x89F80620,0xCA400000,0xAE000620,0x89F80620,0xCA400000,0xAE000620,0xAE000620,0xDFC0620,0xFEBC0001,0xCAF00000,0x89F80620,0xCA400000,0xAE000620,0x89F80620,0xCA400000,0xAE000620,0xAE000620,0x89F80620, -0xCA400000,0xAE000620,0xAE000620,0xAE000620,0xFF3404C9,0x3740620,0xF5580515,0xFF0402E4,0xFEBC0139,0xF4480000,0xCA800000,0xCA000004,0xFF2C04B1,0xFEF002B1,0xD2940001,0xAE000620,0x69FC0620,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0x8C0622,0xD2580001,0xD2580001,0xD2580001,0xD2580001,0xD2580001, -0xD2580001,0x7E540001,0x7E540001,0x7E540001,0x62540001,0x2D00620,0x2D00620,0x2D00620,0x2D00620,0x2D00620,0x2D00620,0x8C000019,0x8C000019,0x8C000019,0x62200000,0x1AC0620,0x1AC0620,0x1AC0620,0x56000171,0x46000620,0xF88003CA,0x8C0622,0x8C0622,0xFC70018A,0xFE640062,0xFA580001,0xFA580001,0xB2580001,0xFC640320,0xFE500145,0x9A480000,0x8C000019, -0x12C0620,}; -static const uint32_t g_etc1_to_bc7_m6_table176[] = { -0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x1380000, -0x1380000,0x1380000,0x1380000,0x32000001,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0xE6C0000,0xE6C0000,0xE6C0000,0x2980000,0xDC0000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000, -0x1400000,0x25F80000,0x25F80000,0x25F80000,0x6A000001,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x25F80000,0x25F80000,0x25F80000,0x6A000001,0x25F80000,0x25F80000,0x25F80000,0x6A000001,0x6A000001,0xAE40000,0xD80000,0xD80000,0xFC0000,0x50C0000,0x3240000,0x3240000,0x16C0000,0xFC0000,0x50C0000,0x1CC0000,0x25F80000, -0x1CC0000,0x1380000,0x1380000,0x1380000,0x1380000,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x9A000001,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x9A000001,0x6DF80000,0x6DF80000,0x9A000001,0x9A000001,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x9A000001,0x6DF80000,0x6DF80000,0x9A000001,0x9A000001,0x6DF80000, -0x6DF80000,0x9A000001,0x9A000001,0x9A000001,0x7680000,0x14C0000,0x1380000,0x1A80000,0xDFC0000,0x45FC0000,0x59FC0000,0x79F80000,0x1880000,0x1D00000,0x45FC0000,0x9A000001,0x45FC0000,0x1A80000,0x7DFC0000,0xBFFC0000,0xD2000001,0x7DFC0000,0xBFFC0000,0xD2000001,0xBFFC0000,0xD2000001,0xD2000001,0x7DFC0000,0xBFFC0000,0xD2000001,0xBFFC0000,0xD2000001, -0xD2000001,0xBFFC0000,0xD2000001,0xD2000001,0xD2000001,0x7DFC0000,0xBFFC0000,0xD2000001,0xBFFC0000,0xD2000001,0xD2000001,0xBFFC0000,0xD2000001,0xD2000001,0xD2000001,0xBFFC0000,0xD2000001,0xD2000001,0xD2000001,0xD2000001,0x2DFC0000,0x1C40000,0x1C40000,0x97FC0000,0xB7FC0000,0xC9FC0000,0xD2000001,0xD2000001,0x5FFC0000,0xA5FC0000,0xD1F40000,0xD2000001, -0xAFFC0000,0x1083680,0xFEE82044,0xFED41550,0xD2D4152D,0xFED017C8,0xFEAC07D9,0xDCB00931,0xEAA00C40,0xCC9C068A,0xB6A00C42,0xFEB01D1B,0xFE8406CD,0xDC8C0735,0xF6600651,0xD26C0012,0xB8740686,0xD268152B,0xC2580733,0xB0580933,0x9E68152B,0x1883680,0xFE4C1863,0xD468152C,0xFE080D7A,0xD620064F,0xB63C0C42,0xE200176F,0xC80005CF,0xB2000713,0x9E00152B,0x49F83680, -0xB2001BF1,0xA0001682,0x96001F3C,0x82003684,0xFEE42462,0xF9003040,0xFB0431B0,0xFEC01361,0xFE9005B6,0xFA68000E,0xD6740086,0xCC600082,0xFED02373,0xFE981122,0xDC4C049F,0xB2000713,0x19FC3680,0x13C152C,0xFF180984,0xFB080480,0xD3080481,0xFF000938,0xFED80019,0xD6E0007D,0xDCD80620,0xC8D00132,0xB6D80622,0x1D8152B,0xFEA00576,0xD2BC0481,0xFE4C0621,0xD26C000E, -0xB6900622,0x71F8152B,0xCA0004F1,0xB20006E2,0x9E00152B,0x1D8152B,0xFEA00576,0xD2BC0481,0xFE4C0621,0xD26C000E,0xB6900622,0x71F8152B,0xCA0004F1,0xB20006E2,0x9E00152B,0x71F8152B,0xCA0004F1,0xB20006E2,0x9E00152B,0x9E00152B,0xFF140F21,0xFF2C12B6,0xF53812C4,0xFEEC08F1,0xFEA80326,0xF674000D,0xD48C0002,0xD03C003B,0xFF080F33,0xFEC8081B,0xDE380481,0xB20006E2, -0x4BFC152B,0xD4152C,0xD4152C,0xD4152C,0xD4152C,0xFEA80740,0xFEA80740,0xFEA80740,0xC0A00620,0xC0A00620,0x9AA00621,0xFE780540,0xFE780540,0xFE780540,0xD0680011,0xD0680011,0x9E7C0131,0xAA680480,0xAA680480,0x9660007A,0x82680482,0x138152B,0x138152B,0x138152B,0xE2100621,0xE2100621,0x9A580621,0xC0000501,0xC0000501,0x9C040006,0x821C0482,0x21F8152B, -0x21F8152B,0x8A000893,0x780008BB,0x6800152B,0xFEBC0CE5,0xFECC1178,0xD4152C,0xFE980671,0xFE80016D,0xF86C000C,0xE86C0038,0xC0680001,0xFEA00C3A,0xFE8005A2,0xD2540481,0x9C040006,0x1BC152B,0x1080480,0x1080480,0x1080480,0x1080480,0xFCD80000,0xFCD80000,0xFCD80000,0xB2D80000,0xB2D80000,0x9AD80001,0x1880480,0x1880480,0x1880480,0xC6800001,0xC6800001, -0x9CA80001,0x49F80480,0x49F80480,0x9A180001,0x82000482,0x1880480,0x1880480,0x1880480,0xC6800001,0xC6800001,0x9CA80001,0x49F80480,0x49F80480,0x9A180001,0x82000482,0x49F80480,0x49F80480,0x9A180001,0x82000482,0x82000482,0xFAEC02AD,0xF9000320,0x1080480,0xFEC40190,0xFE980041,0xF0780000,0xD8880000,0xC2600000,0xFED002DA,0xFEB0016D,0x19FC0480,0x9A180001, -0x19FC0480,0x1700620,0xFF500171,0xEF380000,0xD3380001,0x29FC0620,0xFED80019,0xD5000001,0x97F80620,0xD2540001,0xB6000622,0x29FC0620,0xFED80019,0xD5000001,0x97F80620,0xD2540001,0xB6000622,0x97F80620,0xD2540001,0xB6000622,0xB6000622,0x29FC0620,0xFED80019,0xD5000001,0x97F80620,0xD2540001,0xB6000622,0x97F80620,0xD2540001,0xB6000622,0xB6000622,0x97F80620, -0xD2540001,0xB6000622,0xB6000622,0xB6000622,0xFF5004E4,0x1880620,0xFF6C0515,0xFF200332,0xFED00195,0xFE580000,0xD2980001,0xD2080001,0xF94804E2,0xFF0802E4,0xDCA40000,0xB6000622,0x7BFC0620,0xA00620,0xA00620,0xA00620,0xA00620,0xA00620,0xA00620,0xA00620,0xA00620,0xA00620,0xA00620,0xDE680000,0xDE680000,0xDE680000,0xDE680000,0xDE680000, -0xDE680000,0x86680000,0x86680000,0x86680000,0x6A680001,0xEC0620,0xEC0620,0xEC0620,0xEC0620,0xEC0620,0xEC0620,0x9E000001,0x9E000001,0x9E000001,0x6C300001,0x1E40620,0x1E40620,0x1E40620,0x60000122,0x4E000622,0xFE8C03E8,0xA00620,0xA00620,0xFE8401A5,0xFE780080,0xFE680004,0xFE680004,0xBC680000,0xFE740328,0xFE640179,0xA4580000,0x9E000001, -0x1540620,}; -static const uint32_t g_etc1_to_bc7_m6_table177[] = { -0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x1680000, -0x1680000,0x1680000,0x1680000,0x3A000001,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x800000,0x800000,0x800000,0x2B00000,0xFC0000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000, -0x1580000,0x31F80000,0x31F80000,0x31F80000,0x72000001,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x31F80000,0x31F80000,0x31F80000,0x72000001,0x31F80000,0x31F80000,0x31F80000,0x72000001,0x72000001,0xF80000,0xE80000,0xE80000,0x30C0000,0x5200000,0x13C0000,0x13C0000,0x1840000,0x30C0000,0x5200000,0x1EC0000,0x31F80000, -0x1EC0000,0x1480000,0x1480000,0x1480000,0x1480000,0x1E80000,0x1E80000,0x1E80000,0x79F80000,0x79F80000,0xA2000001,0x1E80000,0x1E80000,0x1E80000,0x79F80000,0x79F80000,0xA2000001,0x79F80000,0x79F80000,0xA2000001,0xA2000001,0x1E80000,0x1E80000,0x1E80000,0x79F80000,0x79F80000,0xA2000001,0x79F80000,0x79F80000,0xA2000001,0xA2000001,0x79F80000, -0x79F80000,0xA2000001,0xA2000001,0xA2000001,0x37C0000,0x75C0000,0x1480000,0x3BC0000,0x21FC0000,0x55FC0000,0x67F80000,0x83FC0000,0x19C0000,0x1E80000,0x55FC0000,0xA2000001,0x55FC0000,0x1B80000,0x95FC0000,0xCBFC0000,0xDA000001,0x95FC0000,0xCBFC0000,0xDA000001,0xCBFC0000,0xDA000001,0xDA000001,0x95FC0000,0xCBFC0000,0xDA000001,0xCBFC0000,0xDA000001, -0xDA000001,0xCBFC0000,0xDA000001,0xDA000001,0xDA000001,0x95FC0000,0xCBFC0000,0xDA000001,0xCBFC0000,0xDA000001,0xDA000001,0xCBFC0000,0xDA000001,0xDA000001,0xDA000001,0xCBFC0000,0xDA000001,0xDA000001,0xDA000001,0xDA000001,0x55FC0000,0x3D40000,0x3D40000,0xABFC0000,0xC5FC0000,0xD3FC0000,0xDA000001,0xDA000001,0x7DFC0000,0xB5FC0000,0xDBC80000,0xDA000001, -0xBFF80000,0x1183680,0xFEF42170,0xFEE415A5,0xDAE4152D,0xFEDC1910,0xFEC008C1,0xE4C00931,0xF2B00C40,0xD4AC068A,0xBEB00C42,0xFEC41E10,0xFE9407E6,0xE49C0735,0xFE700651,0xDA7C0012,0xC0840686,0xDA78152B,0xCA680733,0xB8680933,0xA678152B,0x1A03680,0xFE641953,0xDC78152C,0xFE200E4A,0xDE30064F,0xBE4C0C42,0xF40016C3,0xD4000527,0xBC0006AF,0xA610152B,0x55F83680, -0xBE001AF9,0xAC001532,0x9C001E2C,0x8A003684,0xFEF8257D,0xFF0C3050,0xFF0C31F0,0xFED414FA,0xFEA4073E,0xFE7C001E,0xDE840086,0xD4700082,0xFEDC247F,0xFEB012E5,0xE45C049F,0xBC0006AF,0x27FC3680,0x14C152C,0xFF300A24,0xFF180489,0xDB180481,0xFF1809E8,0xFEF00061,0xDEF0007D,0xE4E80620,0xD0E00132,0xBEE80622,0x1F0152B,0xFEB805F6,0xDACC0481,0xFE640641,0xDA7C000E, -0xBEA00622,0x7DF8152B,0xD60004B9,0xBC0006AB,0xA600152B,0x1F0152B,0xFEB805F6,0xDACC0481,0xFE640641,0xDA7C000E,0xBEA00622,0x7DF8152B,0xD60004B9,0xBC0006AB,0xA600152B,0x7DF8152B,0xD60004B9,0xBC0006AB,0xA600152B,0xA600152B,0xFD300F89,0xFB4412E4,0xFD4812C4,0xFF0009C8,0xFEC803F2,0xFE84000D,0xDC9C0002,0xD84C003B,0xFF180FA2,0xFEE80905,0xE6480481,0xBC0006AB, -0x5BFC152B,0xE4152C,0xE4152C,0xE4152C,0xE4152C,0xFEBC0789,0xFEBC0789,0xFEBC0789,0xC8B00620,0xC8B00620,0xA2B00621,0xFE8C0586,0xFE8C0586,0xFE8C0586,0xD8780011,0xD8780011,0xA68C0131,0xB2780480,0xB2780480,0x9E70007A,0x8A780482,0x150152B,0x150152B,0x150152B,0xEA200621,0xEA200621,0xA2680621,0xCC0004B9,0xCC0004B9,0xA4140006,0x8A2C0482,0x2DF8152B, -0x2DF8152B,0x9600081B,0x8400082B,0x7000152B,0xFECC0D34,0xF6DC11D1,0xE4152C,0xFEAC0709,0xFE9401DD,0xFC7C000E,0xF07C0038,0xC8780001,0xFEB40C89,0xFE980632,0xDA640481,0xA4140006,0x1E0152B,0x1180480,0x1180480,0x1180480,0x1180480,0xFEE80004,0xFEE80004,0xFEE80004,0xBAE80000,0xBAE80000,0xA2E80001,0x1A00480,0x1A00480,0x1A00480,0xCE900001,0xCE900001, -0xA4B80001,0x55F80480,0x55F80480,0xA2280001,0x8A000482,0x1A00480,0x1A00480,0x1A00480,0xCE900001,0xCE900001,0xA4B80001,0x55F80480,0x55F80480,0xA2280001,0x8A000482,0x55F80480,0x55F80480,0xA2280001,0x8A000482,0x8A000482,0xF70002D2,0xFF0C0328,0x1180480,0xFEDC01A5,0xFEAC0061,0xF8880000,0xE0980000,0xCA700000,0xF8EC02F9,0xFEC40188,0x27FC0480,0xA2280001, -0x27FC0480,0x1800620,0xFF5C01CD,0xF7480000,0xDB480001,0x41FC0620,0xFEFC0041,0xDD100001,0xA1FC0620,0xDA640001,0xBE000622,0x41FC0620,0xFEFC0041,0xDD100001,0xA1FC0620,0xDA640001,0xBE000622,0xA1FC0620,0xDA640001,0xBE000622,0xBE000622,0x41FC0620,0xFEFC0041,0xDD100001,0xA1FC0620,0xDA640001,0xBE000622,0xA1FC0620,0xDA640001,0xBE000622,0xBE000622,0xA1FC0620, -0xDA640001,0xBE000622,0xBE000622,0xBE000622,0xF7680515,0x5980620,0xF77C0548,0xFF400372,0xFEFC01E5,0xFE84000D,0xDAA80001,0xDA180001,0xFD5804E4,0xFF200340,0xE4B40000,0xBE000622,0x89FC0620,0xB00620,0xB00620,0xB00620,0xB00620,0xB00620,0xB00620,0xB00620,0xB00620,0xB00620,0xB00620,0xE6780000,0xE6780000,0xE6780000,0xE6780000,0xE6780000, -0xE6780000,0x8E780000,0x8E780000,0x8E780000,0x72780001,0x1040620,0x1040620,0x1040620,0x1040620,0x1040620,0x1040620,0xA6100001,0xA6100001,0xA6100001,0x74400001,0x7FC0620,0x7FC0620,0x7FC0620,0x6C0000DA,0x56000622,0xFAA403F5,0xB00620,0xB00620,0xFE9001D4,0xFC8800A4,0xFC7C000D,0xFC7C000D,0xC4780000,0xFC8C0349,0xFE780190,0xAC680000,0xA6100001, -0x1740620,}; -static const uint32_t g_etc1_to_bc7_m6_table178[] = { -0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0x1980000, -0x1980000,0x1980000,0x1980000,0x42000001,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x900000,0x900000,0x900000,0xC80000,0x1200000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0xF80000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000, -0x1700000,0x3DF80000,0x3DF80000,0x3DF80000,0x7A000001,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x3DF80000,0x3DF80000,0x3DF80000,0x7A000001,0x3DF80000,0x3DF80000,0x3DF80000,0x7A000001,0x7A000001,0x1080000,0xF80000,0xF80000,0x1200000,0x5340000,0x1500000,0x1500000,0x1A00000,0x1200000,0x5340000,0x9FC0000,0x3DF80000, -0x9FC0000,0x1580000,0x1580000,0x1580000,0x1580000,0x3FC0000,0x3FC0000,0x3FC0000,0x85F80000,0x85F80000,0xAA000001,0x3FC0000,0x3FC0000,0x3FC0000,0x85F80000,0x85F80000,0xAA000001,0x85F80000,0x85F80000,0xAA000001,0xAA000001,0x3FC0000,0x3FC0000,0x3FC0000,0x85F80000,0x85F80000,0xAA000001,0x85F80000,0x85F80000,0xAA000001,0xAA000001,0x85F80000, -0x85F80000,0xAA000001,0xAA000001,0xAA000001,0x1900000,0xF6C0000,0x1580000,0x1D40000,0x33FC0000,0x63FC0000,0x75F80000,0x8FF80000,0x1B00000,0x3FC0000,0x63FC0000,0xAA000001,0x63FC0000,0x1C80000,0xAFFC0000,0xD7FC0000,0xE2000001,0xAFFC0000,0xD7FC0000,0xE2000001,0xD7FC0000,0xE2000001,0xE2000001,0xAFFC0000,0xD7FC0000,0xE2000001,0xD7FC0000,0xE2000001, -0xE2000001,0xD7FC0000,0xE2000001,0xE2000001,0xE2000001,0xAFFC0000,0xD7FC0000,0xE2000001,0xD7FC0000,0xE2000001,0xE2000001,0xD7FC0000,0xE2000001,0xE2000001,0xE2000001,0xD7FC0000,0xE2000001,0xE2000001,0xE2000001,0xE2000001,0x7DFC0000,0xBE40000,0xBE40000,0xBDFC0000,0xD3F80000,0xDDFC0000,0xE2000001,0xE2000001,0x9BFC0000,0xC7FC0000,0xE3D80000,0xE2000001, -0xCDFC0000,0x1283680,0xFF0C2270,0xFEF81640,0xE2F4152D,0xFEF41A90,0xFED409ED,0xECD00931,0xFAC00C40,0xDCBC068A,0xC6C00C42,0xFED01F3C,0xFEAC0936,0xECAC0735,0xFE880681,0xE28C0012,0xC8940686,0xE288152B,0xD2780733,0xC0780933,0xAE88152B,0x1B83680,0xFE881A5F,0xE488152C,0xFE380F5A,0xE640064F,0xC65C0C42,0xFC00164D,0xDE0004BA,0xC400067B,0xAE20152B,0x61F83680, -0xCA001A21,0xB8001422,0xA6001D6B,0x92003684,0xFF0C269A,0xF9203102,0xFB243245,0xFEDC16B2,0xFEB808F6,0xFE900086,0xE6940086,0xDC800082,0xFEF82596,0xFEC41488,0xEC6C049F,0xC400067B,0x37FC3680,0x15C152C,0xFF440AD1,0xFF2C04B9,0xE3280481,0xFF240A8C,0xFF0400E9,0xE700007D,0xECF80620,0xD8F00132,0xC6F80622,0xDFC152B,0xFECC06B1,0xE2DC0481,0xFE880681,0xE28C000E, -0xC6B00622,0x89F8152B,0xE000049B,0xC4000672,0xAE00152B,0xDFC152B,0xFECC06B1,0xE2DC0481,0xFE880681,0xE28C000E,0xC6B00622,0x89F8152B,0xE000049B,0xC4000672,0xAE00152B,0x89F8152B,0xE000049B,0xC4000672,0xAE00152B,0xAE00152B,0xFF3C1004,0xFF4C1324,0xF5581329,0xFF140A71,0xFEE804D9,0xFE980052,0xE4AC0002,0xE05C003B,0xFF34103A,0xFF0409B3,0xEE580481,0xC4000672, -0x69FC152B,0xF4152C,0xF4152C,0xF4152C,0xF4152C,0xFED007E4,0xFED007E4,0xFED007E4,0xD0C00620,0xD0C00620,0xAAC00621,0xFEA405E6,0xFEA405E6,0xFEA405E6,0xE0880011,0xE0880011,0xAE9C0131,0xBA880480,0xBA880480,0xA680007A,0x92880482,0x168152B,0x168152B,0x168152B,0xF2300621,0xF2300621,0xAA780621,0xD8000491,0xD8000491,0xAC240006,0x923C0482,0x39F8152B, -0x39F8152B,0x9C0007A3,0x8A000793,0x7800152B,0xFED80DAA,0xFEEC11D1,0xF4152C,0xFEC40794,0xFEAC0275,0xFE900022,0xF88C0038,0xD0880001,0xFEBC0D2A,0xFEB006D1,0xE2740481,0xAC240006,0x3FC152B,0x1280480,0x1280480,0x1280480,0x1280480,0xFCFC0014,0xFCFC0014,0xFCFC0014,0xC2F80000,0xC2F80000,0xAAF80001,0x1B80480,0x1B80480,0x1B80480,0xD6A00001,0xD6A00001, -0xACC80001,0x61F80480,0x61F80480,0xAA380001,0x92000482,0x1B80480,0x1B80480,0x1B80480,0xD6A00001,0xD6A00001,0xACC80001,0x61F80480,0x61F80480,0xAA380001,0x92000482,0x61F80480,0x61F80480,0xAA380001,0x92000482,0x92000482,0xFF1002D2,0xF9200349,0x1280480,0xFCF401E1,0xFEC80082,0xFC9C0001,0xE8A80000,0xD2800000,0xFEF802FD,0xFEDC01A5,0x37FC0480,0xAA380001, -0x37FC0480,0x1900620,0xFF74022D,0xFF580000,0xE3580001,0x59FC0620,0xFF140089,0xE5200001,0xADFC0620,0xE2740001,0xC6000622,0x59FC0620,0xFF140089,0xE5200001,0xADFC0620,0xE2740001,0xC6000622,0xADFC0620,0xE2740001,0xC6000622,0xC6000622,0x59FC0620,0xFF140089,0xE5200001,0xADFC0620,0xE2740001,0xC6000622,0xADFC0620,0xE2740001,0xC6000622,0xC6000622,0xADFC0620, -0xE2740001,0xC6000622,0xC6000622,0xC6000622,0xFF780515,0xDA80620,0xFF8C0548,0xFF5803C8,0xFF100249,0xFEAC0041,0xE2B80001,0xE2280001,0xFF700515,0xFF40037A,0xECC40000,0xC6000622,0x99FC0620,0xC00620,0xC00620,0xC00620,0xC00620,0xC00620,0xC00620,0xC00620,0xC00620,0xC00620,0xC00620,0xEE880000,0xEE880000,0xEE880000,0xEE880000,0xEE880000, -0xEE880000,0x96880000,0x96880000,0x96880000,0x7A880001,0x11C0620,0x11C0620,0x11C0620,0x11C0620,0x11C0620,0x11C0620,0xAE200001,0xAE200001,0xAE200001,0x7C500001,0x13FC0620,0x13FC0620,0x13FC0620,0x720000A2,0x5E000622,0xFEAC041D,0xC00620,0xC00620,0xFEA001F9,0xFC9C00C8,0xFE900019,0xFE900019,0xCC880000,0xFC9C0372,0xFC9001C2,0xB4780000,0xAE200001, -0x1980620,}; -static const uint32_t g_etc1_to_bc7_m6_table179[] = { -0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0x1CC0000, -0x1CC0000,0x1CC0000,0x1CC0000,0x4A000001,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x8A00000,0x8A00000,0x8A00000,0xE00000,0x1400000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000, -0x1880000,0x49F80000,0x49F80000,0x49F80000,0x82000001,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x49F80000,0x82000001,0x49F80000,0x49F80000,0x49F80000,0x82000001,0x82000001,0x5180000,0x1080000,0x1080000,0x1340000,0x14C0000,0x1680000,0x1680000,0x1BC0000,0x1340000,0x14C0000,0x19FC0000,0x49F80000, -0x19FC0000,0x1680000,0x1680000,0x1680000,0x1680000,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x91F80000,0x91F80000,0xB2000001,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x91F80000,0x91F80000,0xB2000001,0x91F80000,0x91F80000,0xB2000001,0xB2000001,0x1BFC0000,0x1BFC0000,0x1BFC0000,0x91F80000,0x91F80000,0xB2000001,0x91F80000,0x91F80000,0xB2000001,0xB2000001,0x91F80000, -0x91F80000,0xB2000001,0xB2000001,0xB2000001,0x7A00000,0x1800000,0x1680000,0x3E80000,0x47FC0000,0x73FC0000,0x81FC0000,0x99FC0000,0x1C40000,0x1BFC0000,0x73FC0000,0xB2000001,0x73FC0000,0x1D80000,0xC7FC0000,0xE3FC0000,0xEA000001,0xC7FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xEA000001,0xEA000001,0xC7FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xEA000001, -0xEA000001,0xE3FC0000,0xEA000001,0xEA000001,0xEA000001,0xC7FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xEA000001,0xEA000001,0xE3FC0000,0xEA000001,0xEA000001,0xEA000001,0xE3FC0000,0xEA000001,0xEA000001,0xEA000001,0xEA000001,0xA3FC0000,0x1F80000,0x1F80000,0xD1FC0000,0xDFFC0000,0xE7FC0000,0xEA000001,0xEA000001,0xB9FC0000,0xD7FC0000,0xEBE80000,0xEA000001, -0xDDF80000,0x1383680,0xFF1823A4,0xFF0816F9,0xEB04152D,0xFF001C08,0xFEE40B51,0xF4E00931,0xFED40C50,0xE4CC068A,0xCED00C42,0xFEE8206C,0xFEC00AD1,0xF4BC0735,0xFEA00711,0xEA9C0012,0xD0A40686,0xEA98152B,0xDA880733,0xC8880933,0xB698152B,0x1D03680,0xFEA01B7F,0xEC98152C,0xFE5810AA,0xEE50064F,0xCE6C0C42,0xFE14169F,0xEA00048A,0xCC10067B,0xB630152B,0x6DF83680, -0xD0001959,0xBE001302,0xAC001C83,0x9A003684,0xFF2027A2,0xFF2C311A,0xFF2C328D,0xFEF0188A,0xFECC0ADE,0xFEAC0156,0xEEA40086,0xE4900082,0xFF0026DC,0xFEDC1672,0xF47C049F,0xCC10067B,0x45FC3680,0x16C152C,0xFF500B91,0xFF380529,0xEB380481,0xFF3C0B4C,0xFF14019D,0xEF10007D,0xF5080620,0xE1000132,0xCF080622,0x25FC152B,0xFEF00771,0xEAEC0481,0xFEAC06F1,0xEA9C000E, -0xCEC00622,0x95F8152B,0xEA000489,0xCE000653,0xB600152B,0x25FC152B,0xFEF00771,0xEAEC0481,0xFEAC06F1,0xEA9C000E,0xCEC00622,0x95F8152B,0xEA000489,0xCE000653,0xB600152B,0x95F8152B,0xEA000489,0xCE000653,0xB600152B,0xB600152B,0xFF501055,0xFD681342,0xFD681329,0xFF300B69,0xFEFC05D5,0xFEC000CD,0xECBC0002,0xE86C003B,0xFF44109B,0xFF180AA9,0xF6680481,0xCE000653, -0x79FC152B,0x104152C,0x104152C,0x104152C,0x104152C,0xFEDC084C,0xFEDC084C,0xFEDC084C,0xD8D00620,0xD8D00620,0xB2D00621,0xFEB00662,0xFEB00662,0xFEB00662,0xE8980011,0xE8980011,0xB6AC0131,0xC2980480,0xC2980480,0xAE90007A,0x9A980482,0x180152B,0x180152B,0x180152B,0xFA400621,0xFA400621,0xB2880621,0xE6040481,0xE6040481,0xB4340006,0x9A4C0482,0x45F8152B, -0x45F8152B,0xA6000749,0x94000722,0x8000152B,0xFEE80E01,0xF6FC122C,0x104152C,0xFED40821,0xFEC00309,0xFEA40058,0xFCA0003D,0xD8980001,0xFED00D73,0xFEBC076A,0xEA840481,0xB4340006,0x13FC152B,0x1380480,0x1380480,0x1380480,0x1380480,0xFF0C0028,0xFF0C0028,0xFF0C0028,0xCB080000,0xCB080000,0xB3080001,0x1D00480,0x1D00480,0x1D00480,0xDEB00001,0xDEB00001, -0xB4D80001,0x6DF80480,0x6DF80480,0xB2480001,0x9A000482,0x1D00480,0x1D00480,0x1D00480,0xDEB00001,0xDEB00001,0xB4D80001,0x6DF80480,0x6DF80480,0xB2480001,0x9A000482,0x6DF80480,0x6DF80480,0xB2480001,0x9A000482,0x9A000482,0xFF2002F9,0xFF2C0355,0x1380480,0xFD040202,0xFEDC00AA,0xFEB40008,0xF0B80000,0xDA900000,0xFD100320,0xFEE801D4,0x45FC0480,0xB2480001, -0x45FC0480,0x1A00620,0xFF8002A1,0xFF6C001D,0xEB680001,0x71FC0620,0xFF3800E9,0xED300001,0xB9FC0620,0xEA840001,0xCE000622,0x71FC0620,0xFF3800E9,0xED300001,0xB9FC0620,0xEA840001,0xCE000622,0xB9FC0620,0xEA840001,0xCE000622,0xCE000622,0x71FC0620,0xFF3800E9,0xED300001,0xB9FC0620,0xEA840001,0xCE000622,0xB9FC0620,0xEA840001,0xCE000622,0xCE000622,0xB9FC0620, -0xEA840001,0xCE000622,0xCE000622,0xCE000622,0xFF8C0548,0x1BC0620,0xF79C057D,0xFF6C03F9,0xFF3C02B1,0xFED40092,0xEAC80001,0xEA380001,0xF7880548,0xFF5803DA,0xF4D40000,0xCE000622,0xA7FC0620,0xD00620,0xD00620,0xD00620,0xD00620,0xD00620,0xD00620,0xD00620,0xD00620,0xD00620,0xD00620,0xF6980000,0xF6980000,0xF6980000,0xF6980000,0xF6980000, -0xF6980000,0x9E980000,0x9E980000,0x9E980000,0x82980001,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0xB6300001,0xB6300001,0xB6300001,0x84600001,0x1FF80620,0x1FF80620,0x1FF80620,0x7E00006A,0x66000622,0xFAC40424,0xD00620,0xD00620,0xFCB80221,0xFEA800E9,0xFCA00034,0xFCA00034,0xD4980000,0xF8B0039D,0xFEA001E1,0xBC880000,0xB6300001, -0x1B80620,}; -static const uint32_t g_etc1_to_bc7_m6_table180[] = { -0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0x3F80000, -0x3F80000,0x3F80000,0x3F80000,0x54000000,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0x2B40000,0x2B40000,0x2B40000,0xFC0000,0x1680000,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000, -0x1A40000,0x57F80000,0x57F80000,0x57F80000,0x8C000000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x57F80000,0x57F80000,0x57F80000,0x8C000000,0x57F80000,0x57F80000,0x57F80000,0x8C000000,0x8C000000,0x12C0000,0x1180001,0x1180001,0x1480000,0x3600000,0x1800000,0x1800000,0x1D80000,0x1480000,0x3600000,0x29FC0000,0x57F80000, -0x29FC0000,0x1780001,0x1780001,0x1780001,0x1780001,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0x9DFC0000,0xBC000000,0xBC000000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0x9DFC0000,0xBC000000,0xBC000000,0x9DFC0000, -0x9DFC0000,0xBC000000,0xBC000000,0xBC000000,0x1B80000,0x1940000,0x1780001,0x9FC0000,0x5DFC0000,0x83FC0000,0x91FC0000,0xA5FC0000,0x3D80000,0x37FC0000,0x83FC0000,0xBC000000,0x83FC0000,0x1E80001,0xE3FC0000,0xF1F80000,0xF4000000,0xE3FC0000,0xF1F80000,0xF4000000,0xF1F80000,0xF4000000,0xF4000000,0xE3FC0000,0xF1F80000,0xF4000000,0xF1F80000,0xF4000000, -0xF4000000,0xF1F80000,0xF4000000,0xF4000000,0xF4000000,0xE3FC0000,0xF1F80000,0xF4000000,0xF1F80000,0xF4000000,0xF4000000,0xF1F80000,0xF4000000,0xF4000000,0xF4000000,0xF1F80000,0xF4000000,0xF4000000,0xF4000000,0xF4000000,0xD1FC0000,0x67FC0000,0x67FC0000,0xE7FC0000,0xEFFC0000,0xF3F80000,0xF4000000,0xF4000000,0xDBFC0000,0xEBFC0000,0xF5DC0000,0xF4000000, -0xEDFC0000,0x1483684,0xFF3024F4,0xFF1C182C,0xF514152B,0xFF181DD4,0xFEFC0D2B,0xFCF00933,0xFEE40CC2,0xEEE00686,0xD8E00C42,0xFF0021E4,0xFED80CD7,0xFCCC0733,0xFEB80823,0xF2AC0012,0xD8B4068A,0xF4A8152C,0xE2980735,0xD0980931,0xBEA8152D,0x3E83680,0xFEB81CE9,0xF4AC152B,0xFE7C1242,0xF8640651,0xD87C0C40,0xFE3817A1,0xF20C0485,0xD618067D,0xBE40152D,0x79FC3680, -0xDC001883,0xCA0011EA,0xB8001BA1,0xA4003680,0xFF3428DF,0xFB4431C4,0xFD4832DC,0xFF081AA2,0xFEE80D2F,0xFEC002B7,0xF8B80082,0xECA00086,0xFF1827ED,0xFEF418C3,0xFC90049F,0xD618067D,0x57FC3680,0x180152B,0xFF680C82,0xFF4C05EB,0xF5480482,0xFF500C19,0xFF2C02AA,0xF924007A,0xFD1C0621,0xEB140131,0xD9180621,0x41FC152B,0xFF080866,0xF4FC0480,0xFECC07B9,0xF2AC0011, -0xD8D00620,0xA1FC152B,0xF4000480,0xD6000631,0xBE00152C,0x41FC152B,0xFF080866,0xF4FC0480,0xFECC07B9,0xF2AC0011,0xD8D00620,0xA1FC152B,0xF4000480,0xD6000631,0xBE00152C,0xA1FC152B,0xF4000480,0xD6000631,0xBE00152C,0xBE00152C,0xFF64110D,0xF57813A3,0xF77C138B,0xFF400C54,0xFF100726,0xFEDC01AD,0xF4D00001,0xF2800038,0xFF5C10F2,0xFF2C0BE1,0xFE7C0484,0xD6000631, -0x89FC152B,0x114152B,0x114152B,0x114152B,0x114152B,0xFEF408D3,0xFEF408D3,0xFEF408D3,0xE0E40622,0xE0E40622,0xBCE00622,0xFED006DB,0xFED006DB,0xFED006DB,0xF2AC000E,0xF2AC000E,0xC0C00132,0xCAAC0481,0xCAAC0481,0xB6A0007D,0xA4A80481,0x398152B,0x398152B,0x398152B,0xFE580629,0xFE580629,0xBC980620,0xEE180481,0xEE180481,0xBC480005,0xA45C0480,0x51FC152B, -0x51FC152B,0xB20006E6,0x9C000690,0x8A00152C,0xFF040E83,0xFF0C1233,0x114152B,0xFEE808EA,0xFED403B6,0xFEBC00B2,0xFEB4004B,0xE0A80002,0xFEE40E19,0xFED007FD,0xF4940480,0xBC480005,0x23FC152B,0x1480482,0x1480482,0x1480482,0x1480482,0xFF24004A,0xFF24004A,0xFF24004A,0xD5180001,0xD5180001,0xBD180001,0x3E80480,0x3E80480,0x3E80480,0xE8C00001,0xE8C00001, -0xBCEC0000,0x79FC0480,0x79FC0480,0xBC540000,0xA4000480,0x3E80480,0x3E80480,0x3E80480,0xE8C00001,0xE8C00001,0xBCEC0000,0x79FC0480,0x79FC0480,0xBC540000,0xA4000480,0x79FC0480,0x79FC0480,0xBC540000,0xA4000480,0xA4000480,0xFB340322,0xFB440372,0x1480482,0xFF180225,0xFEF000E8,0xFED00022,0xF8CC0000,0xE4A00000,0xF9280349,0xFF040208,0x57FC0480,0xBC540000, -0x57FC0480,0x1B00622,0xFF980321,0xFF7C007A,0xF5780001,0x8DFC0620,0xFF580185,0xF5440000,0xC7FC0620,0xF4940000,0xD8000620,0x8DFC0620,0xFF580185,0xF5440000,0xC7FC0620,0xF4940000,0xD8000620,0xC7FC0620,0xF4940000,0xD8000620,0xD8000620,0x8DFC0620,0xFF580185,0xF5440000,0xC7FC0620,0xF4940000,0xD8000620,0xC7FC0620,0xF4940000,0xD8000620,0xD8000620,0xC7FC0620, -0xF4940000,0xD8000620,0xD8000620,0xD8000620,0xF7A4057D,0xFCC0620,0xFFAC0581,0xFF84045D,0xFF500335,0xFF040112,0xF4D40000,0xF4440000,0xFF98054A,0xFD800451,0xFCE80001,0xD8000620,0xB9FC0620,0xE00622,0xE00622,0xE00622,0xE00622,0xE00622,0xE00622,0xE00622,0xE00622,0xE00622,0xE00622,0xFCAC0001,0xFCAC0001,0xFCAC0001,0xFCAC0001,0xFCAC0001, -0xFCAC0001,0xA8A80001,0xA8A80001,0xA8A80001,0x8CA80001,0x1500620,0x1500620,0x1500620,0x1500620,0x1500620,0x1500620,0xC0400001,0xC0400001,0xC0400001,0x8C740000,0x2DF80620,0x2DF80620,0x2DF80620,0x88000041,0x70000620,0xF4D80451,0xE00622,0xE00622,0xFECC0242,0xFEBC0115,0xFEB4004A,0xFEB4004A,0xDCAC0001,0xFEBC03A9,0xFEB40202,0xC49C0000,0xC0400001, -0x1E00620,}; -static const uint32_t g_etc1_to_bc7_m6_table181[] = { -0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0xFF80000, -0xFF80000,0xFF80000,0xFF80000,0x5C000000,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xAC40000,0xAC40000,0xAC40000,0x1140000,0x18C0000,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000, -0x1BC0000,0x61FC0000,0x61FC0000,0x61FC0000,0x94000000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x61FC0000,0x61FC0000,0x61FC0000,0x94000000,0x61FC0000,0x61FC0000,0x61FC0000,0x94000000,0x94000000,0x73C0000,0x1280001,0x1280001,0x5580000,0x3740000,0x1940000,0x1940000,0x1F40000,0x5580000,0x3740000,0x39FC0000,0x61FC0000, -0x39FC0000,0x1880001,0x1880001,0x1880001,0x1880001,0x4FFC0000,0x4FFC0000,0x4FFC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0xA9FC0000,0xA9FC0000,0xC4000000,0xC4000000,0x4FFC0000,0x4FFC0000,0x4FFC0000,0xA9FC0000,0xA9FC0000,0xC4000000,0xA9FC0000,0xA9FC0000,0xC4000000,0xC4000000,0xA9FC0000, -0xA9FC0000,0xC4000000,0xC4000000,0xC4000000,0x5C80000,0x1A40000,0x1880001,0x27FC0000,0x71FC0000,0x93FC0000,0x9FF80000,0xB1F80000,0x3EC0000,0x4FFC0000,0x93FC0000,0xC4000000,0x93FC0000,0x1F80001,0xFBFC0000,0xFDF80000,0xFC000000,0xFBFC0000,0xFDF80000,0xFC000000,0xFDF80000,0xFC000000,0xFC000000,0xFBFC0000,0xFDF80000,0xFC000000,0xFDF80000,0xFC000000, -0xFC000000,0xFDF80000,0xFC000000,0xFC000000,0xFC000000,0xFBFC0000,0xFDF80000,0xFC000000,0xFDF80000,0xFC000000,0xFC000000,0xFDF80000,0xFC000000,0xFC000000,0xFC000000,0xFDF80000,0xFC000000,0xFC000000,0xFC000000,0xFC000000,0xF7FC0000,0xE7FC0000,0xE7FC0000,0xFBFC0000,0xFDF80000,0xFDF80000,0xFC000000,0xFC000000,0xF9FC0000,0xFBFC0000,0xFDEC0000,0xFC000000, -0xFDF80000,0x1583684,0xFF44261B,0xFF2C1953,0xFD24152B,0xFF241F94,0xFF100F1F,0xFF00095F,0xFEFC0D92,0xF6F00686,0xE0F00C42,0xFF18234C,0xFEF00EDF,0xFEDC0767,0xFECC099A,0xFABC0012,0xE0C4068A,0xFCB8152C,0xEAA80735,0xD8A80931,0xC6B8152D,0x7FC3680,0xFED81E87,0xFCBC152B,0xFE9413F2,0xFE700655,0xE08C0C40,0xFE5818EB,0xFA1C0485,0xDE28067D,0xC650152D,0x85FC3680, -0xE60017F0,0xD0001112,0xBE001AD5,0xAC003680,0xFF3C29CC,0xFF4C3204,0xFF4C3354,0xFF181C7A,0xFEFC0F77,0xFED40452,0xFECC0089,0xF4B00086,0xFF342916,0xFF101AAA,0xFEA404D3,0xDE28067D,0x65FC3680,0x190152B,0xFF740D62,0xFF6406C3,0xFD580482,0xFF680D01,0xFF4003E6,0xFF340081,0xFF2C0641,0xF3240131,0xE1280621,0x59FC152B,0xFF200966,0xFD0C0480,0xFEF00889,0xFABC0011, -0xE0E00620,0xADFC152B,0xFC100480,0xE0000624,0xC600152C,0x59FC152B,0xFF200966,0xFD0C0480,0xFEF00889,0xFABC0011,0xE0E00620,0xADFC152B,0xFC100480,0xE0000624,0xC600152C,0xADFC152B,0xFC100480,0xE0000624,0xC600152C,0xC600152C,0xFF781162,0xFD8813A3,0xFF8C138B,0xFF540D51,0xFF28086E,0xFEF002BB,0xFCE00001,0xFA900038,0xFD7411AE,0xFF480C8E,0xFEA004D1,0xE0000624, -0x99FC152B,0x124152B,0x124152B,0x124152B,0x124152B,0xFF00095B,0xFF00095B,0xFF00095B,0xE8F40622,0xE8F40622,0xC4F00622,0xFEDC0763,0xFEDC0763,0xFEDC0763,0xFABC000E,0xFABC000E,0xC8D00132,0xD2BC0481,0xD2BC0481,0xBEB0007D,0xACB80481,0x3B0152B,0x3B0152B,0x3B0152B,0xFE700651,0xFE700651,0xC4A80620,0xF6280481,0xF6280481,0xC4580005,0xAC6C0480,0x5DFC152B, -0x5DFC152B,0xBE0006A6,0xA6000631,0x9200152C,0xFF100EED,0xF9201286,0x124152B,0xFEF80996,0xFEE40481,0xFECC0139,0xFECC0085,0xE8B80002,0xFEF80E66,0xFEE808E2,0xFCA40480,0xC4580005,0x33FC152B,0x1580482,0x1580482,0x1580482,0x1580482,0xFF34007D,0xFF34007D,0xFF34007D,0xDD280001,0xDD280001,0xC5280001,0x7FC0480,0x7FC0480,0x7FC0480,0xF0D00001,0xF0D00001, -0xC4FC0000,0x85FC0480,0x85FC0480,0xC4640000,0xAC000480,0x7FC0480,0x7FC0480,0x7FC0480,0xF0D00001,0xF0D00001,0xC4FC0000,0x85FC0480,0x85FC0480,0xC4640000,0xAC000480,0x85FC0480,0x85FC0480,0xC4640000,0xAC000480,0xAC000480,0xF7480349,0xFF4C0392,0x1580482,0xFD300265,0xFD140120,0xFEEC003D,0xFCE00001,0xECB00000,0xFF34034D,0xFF18022D,0x65FC0480,0xC4640000, -0x65FC0480,0x1C00622,0xFFB003A9,0xFF9400FA,0xFD880001,0xA5FC0620,0xFF70021D,0xFD540000,0xD3FC0620,0xFCA40000,0xE0000620,0xA5FC0620,0xFF70021D,0xFD540000,0xD3FC0620,0xFCA40000,0xE0000620,0xD3FC0620,0xFCA40000,0xE0000620,0xE0000620,0xA5FC0620,0xFF70021D,0xFD540000,0xD3FC0620,0xFCA40000,0xE0000620,0xD3FC0620,0xFCA40000,0xE0000620,0xE0000620,0xD3FC0620, -0xFCA40000,0xE0000620,0xE0000620,0xE0000620,0xFFB4057D,0x1E00620,0xF9C005B2,0xFF9404B2,0xFF7C03A9,0xFF2C01BA,0xFCE40000,0xFC540000,0xFFAC0581,0xFF940488,0xFF10001D,0xE0000620,0xC7FC0620,0xF00622,0xF00622,0xF00622,0xF00622,0xF00622,0xF00622,0xF00622,0xF00622,0xF00622,0xF00622,0xFEBC0005,0xFEBC0005,0xFEBC0005,0xFEBC0005,0xFEBC0005, -0xFEBC0005,0xB0B80001,0xB0B80001,0xB0B80001,0x94B80001,0x1680620,0x1680620,0x1680620,0x1680620,0x1680620,0x1680620,0xC8500001,0xC8500001,0xC8500001,0x94840000,0x39F80620,0x39F80620,0x39F80620,0x90000020,0x78000620,0xFCE80451,0xF00622,0xF00622,0xFED80271,0xFED0013D,0xFEC4006A,0xFEC4006A,0xE4BC0001,0xFCD403C8,0xFAC80244,0xCCAC0000,0xC8500001, -0x3FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table182[] = { -0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x1BF80000, -0x1BF80000,0x1BF80000,0x1BF80000,0x64000000,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xD80000,0xD80000,0xD80000,0x12C0000,0x1AC0000,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x1380001,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000, -0x3D00000,0x6DFC0000,0x6DFC0000,0x6DFC0000,0x9C000000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x3D00000,0x6DFC0000,0x6DFC0000,0x6DFC0000,0x9C000000,0x6DFC0000,0x6DFC0000,0x6DFC0000,0x9C000000,0x9C000000,0xF4C0000,0x1380001,0x1380001,0x16C0000,0x3880000,0x1AC0000,0x1AC0000,0xFFC0000,0x16C0000,0x3880000,0x47FC0000,0x6DFC0000, -0x47FC0000,0x1980001,0x1980001,0x1980001,0x1980001,0x69FC0000,0x69FC0000,0x69FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0x69FC0000,0x69FC0000,0x69FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0xB5FC0000,0xB5FC0000,0xCC000000,0xCC000000,0x69FC0000,0x69FC0000,0x69FC0000,0xB5FC0000,0xB5FC0000,0xCC000000,0xB5FC0000,0xB5FC0000,0xCC000000,0xCC000000,0xB5FC0000, -0xB5FC0000,0xCC000000,0xCC000000,0xCC000000,0x1DC0000,0x3B40000,0x1980001,0x45FC0000,0x85FC0000,0xA1FC0000,0xABFC0000,0xBBFC0000,0xBFC0000,0x69FC0000,0xA1FC0000,0xCC000000,0xA1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x16832DC,0xFF50247F,0xFF381933,0xFF34152B,0xFF3C1E14,0xFF200F63,0xFF1809EB,0xFF080CD6,0xF9000656,0xE5000B06,0xFF24213C,0xFF040F22,0xFEF407FB,0xFEE40906,0xFED00012,0xE8D4055E,0xFECC12C5,0xEEBC0679,0xDCBC0799,0xCCC812C5,0x19FC32DC,0xFEE41DCF,0xFED0152B,0xFEB81322,0xFE940691,0xE4A00B04,0xFE701733,0xFE380481,0xE4400525,0xCC6412C4,0x8FF832DC, -0xF200169C,0xDC000E76,0xC4001765,0xB20032DC,0xFF502793,0xF9602F06,0xFB642FFB,0xFF2C1B7E,0xFF0C0F8A,0xFEE804E2,0xFEDC00E2,0xFAC4003B,0xFF3C26EC,0xFF1819CA,0xFEB804ED,0xE4400525,0x71FC32DC,0x19C12C3,0xFF800C56,0xFF7006A3,0xFF680482,0xFF740B9D,0xFF5803DE,0xFF4400A9,0xFF400533,0xF73400C2,0xE53804E5,0x6BFC12C3,0xFF3808E2,0xFF200482,0xFF080785,0xFCD80005, -0xE4F404E4,0xB7F812C3,0xFE380480,0xE41404E4,0xCC0012C4,0x6BFC12C3,0xFF3808E2,0xFF200482,0xFF080785,0xFCD80005,0xE4F404E4,0xB7F812C3,0xFE380480,0xE41404E4,0xCC0012C4,0xB7F812C3,0xFE380480,0xE41404E4,0xCC0012C4,0xCC0012C4,0xFF800FC5,0xFF8C1193,0xF59811A2,0xFF6C0C12,0xFF4807DA,0xFF1002DD,0xFEF8000D,0xFCB00018,0xFF780FAA,0xFF5C0B8A,0xFED004E3,0xE41404E4, -0xA3FC12C3,0x134152B,0x134152B,0x134152B,0x134152B,0xFF1809EB,0xFF1809EB,0xFF1809EB,0xF1040622,0xF1040622,0xCD000622,0xFEF407FB,0xFEF407FB,0xFEF407FB,0xFED00012,0xFED00012,0xD0E00132,0xDACC0481,0xDACC0481,0xC6C0007D,0xB4C80481,0x1C8152B,0x1C8152B,0x1C8152B,0xFE940691,0xFE940691,0xCCB80620,0xFE380481,0xFE380481,0xCC680005,0xB47C0480,0x69FC152B, -0x69FC152B,0xC4000672,0xAC0005E1,0x9A00152C,0xFF200F46,0xFF2C1292,0x134152B,0xFF100A32,0xFEF40542,0xFEE001CB,0xFEDC00E2,0xF0C80002,0xFF140ED2,0xFEF4097A,0xFEB80489,0xCC680005,0x41FC152B,0x1680482,0x1680482,0x1680482,0x1680482,0xFF4400A9,0xFF4400A9,0xFF4400A9,0xE5380001,0xE5380001,0xCD380001,0x1FFC0480,0x1FFC0480,0x1FFC0480,0xF8E00001,0xF8E00001, -0xCD0C0000,0x91FC0480,0x91FC0480,0xCC740000,0xB4000480,0x1FFC0480,0x1FFC0480,0x1FFC0480,0xF8E00001,0xF8E00001,0xCD0C0000,0x91FC0480,0x91FC0480,0xCC740000,0xB4000480,0x91FC0480,0x91FC0480,0xCC740000,0xB4000480,0xB4000480,0xFF580349,0xFB64039D,0x1680482,0xFF440288,0xFD280154,0xFEFC006D,0xFEF8000D,0xF4C00000,0xFD4C0372,0xFF300269,0x75FC0480,0xCC740000, -0x75FC0480,0x1CC04E2,0xFFBC0305,0xFFA000EA,0xFF980001,0xB5FC04E2,0xFF8801CD,0xFF680000,0xDBF804E2,0xFECC0000,0xE40004E4,0xB5FC04E2,0xFF8801CD,0xFF680000,0xDBF804E2,0xFECC0000,0xE40004E4,0xDBF804E2,0xFECC0000,0xE40004E4,0xE40004E4,0xB5FC04E2,0xFF8801CD,0xFF680000,0xDBF804E2,0xFECC0000,0xE40004E4,0xDBF804E2,0xFECC0000,0xE40004E4,0xE40004E4,0xDBF804E2, -0xFECC0000,0xE40004E4,0xE40004E4,0xE40004E4,0xF9C40480,0xDE804E2,0xFDC80482,0xFFB003CA,0xFF900305,0xFF480175,0xFF080000,0xFE840000,0xF3C40480,0xFFA003B5,0xFF300028,0xE40004E4,0xD1FC04E2,0x1000622,0x1000622,0x1000622,0x1000622,0x1000622,0x1000622,0x1000622,0x1000622,0x1000622,0x1000622,0xFED00012,0xFED00012,0xFED00012,0xFED00012,0xFED00012, -0xFED00012,0xB8C80001,0xB8C80001,0xB8C80001,0x9CC80001,0x1800620,0x1800620,0x1800620,0x1800620,0x1800620,0x1800620,0xD0600001,0xD0600001,0xD0600001,0x9C940000,0x45F80620,0x45F80620,0x45F80620,0x9A00000D,0x80000620,0xF4F80482,0x1000622,0x1000622,0xFEE8029A,0xFEE4016D,0xFEDC0091,0xFEDC0091,0xECCC0001,0xF8E803F5,0xFED80269,0xD4BC0000,0xD0600001, -0x13FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table183[] = { -0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x27F80000, -0x27F80000,0x27F80000,0x27F80000,0x6C000000,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xE80000,0xE80000,0xE80000,0x1440000,0x1D00000,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000, -0x3E80000,0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0xA4000000,0x1600000,0x1480001,0x1480001,0x1800000,0x39C0000,0x1C00000,0x1C00000,0x23FC0000,0x1800000,0x39C0000,0x57FC0000,0x79FC0000, -0x57FC0000,0x1A80001,0x1A80001,0x1A80001,0x1A80001,0x81FC0000,0x81FC0000,0x81FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0x81FC0000,0x81FC0000,0x81FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xC1FC0000,0xD4000000,0xD4000000,0x81FC0000,0x81FC0000,0x81FC0000,0xC1FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xC1FC0000,0xD4000000,0xD4000000,0xC1FC0000, -0xC1FC0000,0xD4000000,0xD4000000,0xD4000000,0x1F00000,0xBC40000,0x1A80001,0x63FC0000,0x99FC0000,0xB1FC0000,0xB9FC0000,0xC7F40000,0x33FC0000,0x81FC0000,0xB1FC0000,0xD4000000,0xB1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1742E54,0xFF5C2227,0xFF4C189C,0xFF44152B,0xFF441B96,0xFF2C0F3F,0xFF240A83,0xFF200BB6,0xFD10062A,0xE9100996,0xFF301E64,0xFF140EBF,0xFF0C08B3,0xFEF0080E,0xFEE40042,0xEAE40406,0xFEE00FFC,0xF2D005A9,0xE2C805B5,0xD2D80FD9,0x2BFC2E54,0xFEFC1C6F,0xFEE8152B,0xFECC11E6,0xFEAC06E9,0xE8B40994,0xFE9414BB,0xFE5804A2,0xE854039D,0xD2740FD9,0x97FC2E54, -0xF8001590,0xE0000BBC,0xCA001371,0xB8002E54,0xFF58245E,0xFF6C2AA6,0xFF6C2BC3,0xFF4019B9,0xFF1C0EF6,0xFEFC0522,0xFEF00173,0xFCD8000A,0xFF5023BA,0xFF30184B,0xFED00513,0xE854039D,0x7DF82E54,0x1A40FDB,0xFF8C0AC6,0xFF7C063B,0xFF780482,0xFF8009BD,0xFF64037E,0xFF5C00E1,0xFF5803EB,0xF944005E,0xE9480375,0x7BFC0FD8,0xFF4C0811,0xFF380482,0xFF200615,0xFEF00005, -0xE9080374,0xBFF80FD8,0xFE6C0480,0xE8340374,0xD2000FD8,0x7BFC0FD8,0xFF4C0811,0xFF380482,0xFF200615,0xFEF00005,0xE9080374,0xBFF80FD8,0xFE6C0480,0xE8340374,0xD2000FD8,0xBFF80FD8,0xFE6C0480,0xE8340374,0xD2000FD8,0xD2000FD8,0xFF940D34,0xF9A00ECD,0xFBA40ED6,0xFF780A71,0xFF5C06D6,0xFF2C0293,0xFF10002D,0xFECC0002,0xFF880D43,0xFF680A04,0xFEE404D1,0xE8340374, -0xADFC0FD8,0x144152B,0x144152B,0x144152B,0x144152B,0xFF240A83,0xFF240A83,0xFF240A83,0xF9140622,0xF9140622,0xD5100622,0xFF0C08B3,0xFF0C08B3,0xFF0C08B3,0xFEE40042,0xFEE40042,0xD8F00132,0xE2DC0481,0xE2DC0481,0xCED0007D,0xBCD80481,0x1E0152B,0x1E0152B,0x1E0152B,0xFEAC06E9,0xFEAC06E9,0xD4C80620,0xFE5804A2,0xFE5804A2,0xD4780005,0xBC8C0480,0x75FC152B, -0x75FC152B,0xD0000642,0xB8000581,0xA200152C,0xFF2C0FD1,0xF94012E3,0x144152B,0xFF180AF6,0xFF080612,0xFEF8026E,0xFEF00173,0xF8D80002,0xFF200F41,0xFF100A41,0xFED004C2,0xD4780005,0x51FC152B,0x1780482,0x1780482,0x1780482,0x1780482,0xFF5C00E1,0xFF5C00E1,0xFF5C00E1,0xED480001,0xED480001,0xD5480001,0x37FC0480,0x37FC0480,0x37FC0480,0xFCF80005,0xFCF80005, -0xD51C0000,0x9DFC0480,0x9DFC0480,0xD4840000,0xBC000480,0x37FC0480,0x37FC0480,0x37FC0480,0xFCF80005,0xFCF80005,0xD51C0000,0x9DFC0480,0x9DFC0480,0xD4840000,0xBC000480,0x9DFC0480,0x9DFC0480,0xD4840000,0xBC000480,0xBC000480,0xFB6C0372,0xFF6C03C5,0x1780482,0xFD5802AD,0xFF400188,0xFF2000A4,0xFF10002D,0xFCD00000,0xF564039D,0xFF48028A,0x83FC0480,0xD4840000, -0x83FC0480,0x1D40372,0xFFC40212,0xFFB400A9,0xFFA80001,0xC1FC0372,0xFF940145,0xFF800000,0xE1F80372,0xFEFC0000,0xE8000374,0xC1FC0372,0xFF940145,0xFF800000,0xE1F80372,0xFEFC0000,0xE8000374,0xE1F80372,0xFEFC0000,0xE8000374,0xE8000374,0xC1FC0372,0xFF940145,0xFF800000,0xE1F80372,0xFEFC0000,0xE8000374,0xE1F80372,0xFEFC0000,0xE8000374,0xE8000374,0xE1F80372, -0xFEFC0000,0xE8000374,0xE8000374,0xE8000374,0xFDCC0320,0x1F40372,0xFFCC0332,0xFFC002AD,0xFFA80221,0xFF5C0110,0xFF300000,0xFEC00000,0xF7CC0320,0xFFAC02A8,0xFF50001A,0xE8000374,0xD9FC0372,0x1100622,0x1100622,0x1100622,0x1100622,0x1100622,0x1100622,0x1100622,0x1100622,0x1100622,0x1100622,0xFEE0002D,0xFEE0002D,0xFEE0002D,0xFEE0002D,0xFEE0002D, -0xFEE0002D,0xC0D80001,0xC0D80001,0xC0D80001,0xA4D80001,0x1980620,0x1980620,0x1980620,0x1980620,0x1980620,0x1980620,0xD8700001,0xD8700001,0xD8700001,0xA4A40000,0x51F80620,0x51F80620,0x51F80620,0xA4000004,0x88000620,0xFD080482,0x1100622,0x1100622,0xFD0002D2,0xFEF801A5,0xFEE800C1,0xFEE800C1,0xF4DC0001,0xFEF403F9,0xFEE402A8,0xDCCC0000,0xD8700001, -0x21FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table184[] = { -0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x33FC0000, -0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xFC0000,0xFC0000,0xFC0000,0x35C0000,0x1F40000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x15C0000,0x9FC0000,0x9FC0000,0x9FC0000,0x9FC0000,0x9FC0000, -0x9FC0000,0x87FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x9FC0000,0x9FC0000,0x9FC0000,0x9FC0000,0x9FC0000,0x9FC0000,0x87FC0000,0x87FC0000,0x87FC0000,0xAC000001,0x87FC0000,0x87FC0000,0x87FC0000,0xAC000001,0xAC000001,0x1740000,0x15C0000,0x15C0000,0x1940000,0x1B40000,0x1D80000,0x1D80000,0x39FC0000,0x1940000,0x1B40000,0x67FC0000,0x87FC0000, -0x67FC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xDC000001,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xDC000001,0xCFF80000,0xCFF80000,0xDC000001,0xDC000001,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xDC000001,0xCFF80000,0xCFF80000,0xDC000001,0xDC000001,0xCFF80000, -0xCFF80000,0xDC000001,0xDC000001,0xDC000001,0x17FC0000,0x5D80000,0x1BC0000,0x85FC0000,0xAFFC0000,0xC1FC0000,0xC9F80000,0xD3F80000,0x5FFC0000,0x9BFC0000,0xC1FC0000,0xDC000001,0xC1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x18029AD,0xFF681FD0,0xFF581805,0xFF58152C,0xFF5C195D,0xFF400F2A,0xFF3C0B40,0xFF2C0AC5,0xFF240629,0xEF240841,0xFF441B46,0xFF2C0E8C,0xFF180984,0xFF080739,0xFEFC00B5,0xF0FC02D1,0xFEF80D65,0xF6E40502,0xE8E003EA,0xD8EC0CF6,0x41FC29AD,0xFF141B10,0xFF04152B,0xFEE41095,0xFECC0789,0xEEC80841,0xFEAC126A,0xFE7C04F9,0xEC740236,0xD88C0CF6,0xA1FC29AD, -0xFE00152B,0xE6000953,0xD4000F97,0xC00029AF,0xFF64212B,0xF77C26D9,0xF98027C5,0xFF5417DD,0xFF300E79,0xFF1805B7,0xFF080236,0xFEEC0009,0xFF5C209B,0xFF40169E,0xFEF0056C,0xEC740236,0x89FC29AD,0x1B00CF9,0xFFA40924,0xFF9405C1,0xFF8C0480,0xFF8C07FD,0xFF7C0332,0xFF740139,0xFF6402C1,0xFD580018,0xEF5C0221,0x8DFC0CF6,0xFF640723,0xFF540480,0xFF3804C5,0xFF14001D, -0xEF1C0221,0xC7FC0CF6,0xFEA00480,0xEE500221,0xD8000CF6,0x8DFC0CF6,0xFF640723,0xFF540480,0xFF3804C5,0xFF14001D,0xEF1C0221,0xC7FC0CF6,0xFEA00480,0xEE500221,0xD8000CF6,0xC7FC0CF6,0xFEA00480,0xEE500221,0xD8000CF6,0xD8000CF6,0xFFA00AE3,0xFFAC0BFD,0xFFAC0C24,0xFF9408AE,0xFF6805CD,0xFF48026C,0xFF280068,0xFEF40008,0xFF980AF2,0xFF840840,0xFF1004B3,0xEE500221, -0xB9FC0CF6,0x158152C,0x158152C,0x158152C,0x158152C,0xFF3C0B40,0xFF3C0B40,0xFF3C0B40,0xFF240629,0xFF240629,0xDD240621,0xFF180984,0xFF180984,0xFF180984,0xFEFC00B5,0xFEFC00B5,0xE1000131,0xECEC0480,0xECEC0480,0xD8E4007A,0xC4EC0482,0x1FC152B,0x1FC152B,0x1FC152B,0xFECC0789,0xFECC0789,0xDCDC0621,0xFE7C04F9,0xFE7C04F9,0xDE880006,0xC4A00482,0x83F8152B, -0x83F8152B,0xDC000629,0xC200053B,0xAA00152B,0xFD48103D,0xFF4C1304,0x158152C,0xFF340BC5,0xFF1C0715,0xFF100379,0xFF080236,0xFEEC0009,0xFF340FA9,0xFF240B2D,0xFEF0052C,0xDE880006,0x61FC152B,0x18C0480,0x18C0480,0x18C0480,0x18C0480,0xFF740139,0xFF740139,0xFF740139,0xF55C0000,0xF55C0000,0xDD5C0001,0x53FC0480,0x53FC0480,0x53FC0480,0xFF14001D,0xFF14001D, -0xDF2C0001,0xABF80480,0xABF80480,0xDC9C0001,0xC4000482,0x53FC0480,0x53FC0480,0x53FC0480,0xFF14001D,0xFF14001D,0xDF2C0001,0xABF80480,0xABF80480,0xDC9C0001,0xC4000482,0xABF80480,0xABF80480,0xDC9C0001,0xC4000482,0xC4000482,0xF780039D,0xFD8803C8,0x18C0480,0xFB7002F9,0xFF5401CA,0xFF3800E9,0xFF280068,0xFEF40008,0xFD74039D,0xFF5C02B9,0x95FC0480,0xDC9C0001, -0x95FC0480,0x1DC0221,0xFFD00145,0xFFC00068,0xFFBC0000,0xCDFC0221,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xFF340000,0xEE000221,0xCDFC0221,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xFF340000,0xEE000221,0xE7F80221,0xFF340000,0xEE000221,0xEE000221,0xCDFC0221,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xFF340000,0xEE000221,0xE7F80221,0xFF340000,0xEE000221,0xEE000221,0xE7F80221, -0xFF340000,0xEE000221,0xEE000221,0xEE000221,0xFFD001ED,0x1FC0221,0xF7DC0200,0xFFC001A8,0xFFA80152,0xFF8400A0,0xFF5C0000,0xFF040000,0xFBD401E1,0xFFC00190,0xFF700010,0xEE000221,0xDFFC0221,0x1240620,0x1240620,0x1240620,0x1240620,0x1240620,0x1240620,0x1240620,0x1240620,0x1240620,0x1240620,0xFEF40050,0xFEF40050,0xFEF40050,0xFEF40050,0xFEF40050, -0xFEF40050,0xC8EC0000,0xC8EC0000,0xC8EC0000,0xACEC0001,0x3B00620,0x3B00620,0x3B00620,0x3B00620,0x3B00620,0x3B00620,0xE0840001,0xE0840001,0xE0840001,0xAEB40001,0x5DFC0620,0x5DFC0620,0x5DFC0620,0xAC080001,0x90000622,0xF71C04B1,0x1240620,0x1240620,0xFF1002FD,0xFF0C01E1,0xFF0000F4,0xFF0000F4,0xFEEC0000,0xFD0C0422,0xFF0002D4,0xE6DC0000,0xE0840001, -0x33FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table185[] = { -0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3FFC0000, -0x3FFC0000,0x3FFC0000,0x3FFC0000,0x7C000001,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0x10C0000,0x10C0000,0x10C0000,0x3740000,0xDFC0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x23FC0000,0x23FC0000,0x23FC0000,0x23FC0000,0x23FC0000, -0x23FC0000,0x93FC0000,0x93FC0000,0x93FC0000,0xB4000001,0x23FC0000,0x23FC0000,0x23FC0000,0x23FC0000,0x23FC0000,0x23FC0000,0x93FC0000,0x93FC0000,0x93FC0000,0xB4000001,0x93FC0000,0x93FC0000,0x93FC0000,0xB4000001,0xB4000001,0x1840000,0x16C0000,0x16C0000,0x1A80000,0x1C80000,0x1F00000,0x1F00000,0x4DFC0000,0x1A80000,0x1C80000,0x77FC0000,0x93FC0000, -0x77FC0000,0x1CC0000,0x1CC0000,0x1CC0000,0x1CC0000,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xDBF80000,0xDBF80000,0xE4000001,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xDBF80000,0xDBF80000,0xE4000001,0xDBF80000,0xDBF80000,0xE4000001,0xE4000001,0xB5FC0000,0xB5FC0000,0xB5FC0000,0xDBF80000,0xDBF80000,0xE4000001,0xDBF80000,0xDBF80000,0xE4000001,0xE4000001,0xDBF80000, -0xDBF80000,0xE4000001,0xE4000001,0xE4000001,0x51FC0000,0xDE80000,0x1CC0000,0xA3FC0000,0xC3FC0000,0xD1FC0000,0xD5FC0000,0xDDFC0000,0x87FC0000,0xB5FC0000,0xD1FC0000,0xE4000001,0xD1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x18C25F1,0xFF801DF0,0xFF70177D,0xFF68152C,0xFF68179D,0xFF540F30,0xFF500BE9,0xFF400A4D,0xFF380659,0xF3340759,0xFF5C1916,0xFF3C0E80,0xFF300A44,0xFF2006D1,0xFF100159,0xF30C0209,0xFF080B86,0xFAF804A6,0xECF402A6,0xDEFC0AC2,0x53FC25F1,0xFF2C19F0,0xFF1C152B,0xFEFC0FAD,0xFEE40821,0xF2DC0759,0xFECC10EA,0xFE940579,0xF0880142,0xDE9C0AC2,0xABF825F1, -0xFE2C152B,0xEC0007C7,0xDA000C9B,0xC60025F3,0xFF781EA2,0xFD88233D,0xFF8C2439,0xFF5C168D,0xFF440E39,0xFF240649,0xFF1C031D,0xFF040051,0xFF701E24,0xFF501536,0xFEFC05F2,0xF0880142,0x95FC25F1,0x1BC0AC1,0xFFB007EC,0xFFA00569,0xFF9C0480,0xFFA406AD,0xFF88030E,0xFF800185,0xFF7C0209,0xFF6C0001,0xF36C0139,0x9BFC0AC1,0xFF7C066B,0xFF6C0480,0xFF5803FE,0xFF2C0055, -0xF3300139,0xCFF80AC1,0xFED40480,0xF2700139,0xDE000AC2,0x9BFC0AC1,0xFF7C066B,0xFF6C0480,0xFF5803FE,0xFF2C0055,0xF3300139,0xCFF80AC1,0xFED40480,0xF2700139,0xDE000AC2,0xCFF80AC1,0xFED40480,0xF2700139,0xDE000AC2,0xDE000AC2,0xFFB4091E,0xF5B80A25,0xF7BC0A41,0xFF98075D,0xFF7C0521,0xFF5C026D,0xFF4800B4,0xFF0C0032,0xFFA4093E,0xFF900722,0xFF3004A6,0xF2700139, -0xC1FC0AC1,0x168152C,0x168152C,0x168152C,0x168152C,0xFF500BE9,0xFF500BE9,0xFF500BE9,0xFF380659,0xFF380659,0xE5340621,0xFF300A44,0xFF300A44,0xFF300A44,0xFF100159,0xFF100159,0xE9100131,0xF4FC0480,0xF4FC0480,0xE0F4007A,0xCCFC0482,0x19FC152B,0x19FC152B,0x19FC152B,0xFEE40821,0xFEE40821,0xE4EC0621,0xFE940579,0xFE940579,0xE6980006,0xCCB00482,0x8FF8152B, -0x8FF8152B,0xE4000621,0xCA0004F6,0xB200152B,0xFF5810A1,0xFB641341,0x168152C,0xFF440C7A,0xFF300805,0xFF240465,0xFF1C031D,0xFF040051,0xFF501035,0xFF300BE1,0xFEFC05B2,0xE6980006,0x71FC152B,0x19C0480,0x19C0480,0x19C0480,0x19C0480,0xFF800185,0xFF800185,0xFF800185,0xFD6C0000,0xFD6C0000,0xE56C0001,0x6BFC0480,0x6BFC0480,0x6BFC0480,0xFF2C0055,0xFF2C0055, -0xE73C0001,0xB7F80480,0xB7F80480,0xE4AC0001,0xCC000482,0x6BFC0480,0x6BFC0480,0x6BFC0480,0xFF2C0055,0xFF2C0055,0xE73C0001,0xB7F80480,0xB7F80480,0xE4AC0001,0xCC000482,0xB7F80480,0xB7F80480,0xE4AC0001,0xCC000482,0xCC000482,0xFF90039D,0xF59803F5,0x19C0480,0xFD840320,0xFF700221,0xFF500151,0xFF4800B4,0xFF0C0032,0xFD8803C8,0xFF7402FD,0xA3FC0480,0xE4AC0001, -0xA3FC0480,0x1E40139,0xFFDC00B9,0xFFCC0040,0xFFCC0000,0xD9FC0139,0xFFC00074,0xFFB40000,0xEDF80139,0xFF640000,0xF2000139,0xD9FC0139,0xFFC00074,0xFFB40000,0xEDF80139,0xFF640000,0xF2000139,0xEDF80139,0xFF640000,0xF2000139,0xF2000139,0xD9FC0139,0xFFC00074,0xFFB40000,0xEDF80139,0xFF640000,0xF2000139,0xEDF80139,0xFF640000,0xF2000139,0xF2000139,0xEDF80139, -0xFF640000,0xF2000139,0xF2000139,0xF2000139,0xF5E40120,0x37FC0139,0xFBE40120,0xFFD800F2,0xFFBC00C2,0xFFA40061,0xFF840000,0xFF400000,0xFFDC0109,0xFFCC00E9,0xFF940009,0xF2000139,0xE7FC0139,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0x1340620,0xFF0C0080,0xFF0C0080,0xFF0C0080,0xFF0C0080,0xFF0C0080, -0xFF0C0080,0xD0FC0000,0xD0FC0000,0xD0FC0000,0xB4FC0001,0x1C80620,0x1C80620,0x1C80620,0x1C80620,0x1C80620,0x1C80620,0xE8940001,0xE8940001,0xE8940001,0xB6C40001,0x69FC0620,0x69FC0620,0x69FC0620,0xB4180001,0x98000622,0xFF2C04B1,0x1340620,0x1340620,0xFF200328,0xFF140220,0xFF100128,0xFF100128,0xFF000008,0xFD1C0451,0xFF1402F9,0xEEEC0000,0xE8940001, -0x41FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table186[] = { -0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x4BFC0000, -0x4BFC0000,0x4BFC0000,0x4BFC0000,0x84000001,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x71C0000,0x71C0000,0x71C0000,0x38C0000,0x1DF80000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x17C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000, -0x3BFC0000,0x9FF80000,0x9FF80000,0x9FF80000,0xBC000001,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x9FF80000,0x9FF80000,0x9FF80000,0xBC000001,0x9FF80000,0x9FF80000,0x9FF80000,0xBC000001,0xBC000001,0x3940000,0x17C0000,0x17C0000,0x5B80000,0x1DC0000,0xDFC0000,0xDFC0000,0x61FC0000,0x5B80000,0x1DC0000,0x85FC0000,0x9FF80000, -0x85FC0000,0x1DC0000,0x1DC0000,0x1DC0000,0x1DC0000,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xE7F80000,0xE7F80000,0xEC000001,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xE7F80000,0xE7F80000,0xEC000001,0xE7F80000,0xE7F80000,0xEC000001,0xEC000001,0xCDFC0000,0xCDFC0000,0xCDFC0000,0xE7F80000,0xE7F80000,0xEC000001,0xE7F80000,0xE7F80000,0xEC000001,0xEC000001,0xE7F80000, -0xE7F80000,0xEC000001,0xEC000001,0xEC000001,0x89FC0000,0x1FC0000,0x1DC0000,0xC1FC0000,0xD7FC0000,0xDFFC0000,0xE3FC0000,0xE9F40000,0xADFC0000,0xCDFC0000,0xDFFC0000,0xEC000001,0xDFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1982295,0xFF8C1C24,0xFF7C16F9,0xFF78152C,0xFF74162D,0xFF640F5A,0xFF5C0C99,0xFF4C0A19,0xFF4C06D0,0xF74406B1,0xFF68172A,0xFF500E8F,0xFF440B02,0xFF2C06C9,0xFF200231,0xF7200185,0xFF200A26,0xFF0C0482,0xF30001AE,0xE30C08E2,0x65FC2295,0xFF401914,0xFF34152B,0xFF140F05,0xFEFC08D9,0xF6F006B1,0xFEE40F9A,0xFEB80619,0xF49C0096,0xE2B008E2,0xB3FC2295, -0xFE60152B,0xF40006C7,0xE0000A17,0xCC002297,0xFF801C65,0xFF8C2049,0xF598216C,0xFF701581,0xFF540E23,0xFF3806FD,0xFF340421,0xFF1400E4,0xFF781BC6,0xFF5C147B,0xFF1806AC,0xF49C0096,0x9FFC2295,0x1C808E1,0xFFBC06E4,0xFFAC0529,0xFFAC0480,0xFFB00599,0xFF9C0300,0xFF9801E5,0xFF880191,0xFF7C0010,0xF77C0091,0xAFFC08E1,0xFF9405D3,0xFF840480,0xFF700356,0xFF4C00A9, -0xF7440091,0xD7FC08E1,0xFF040480,0xF6900091,0xE20008E2,0xAFFC08E1,0xFF9405D3,0xFF840480,0xFF700356,0xFF4C00A9,0xF7440091,0xD7FC08E1,0xFF040480,0xF6900091,0xE20008E2,0xD7FC08E1,0xFF040480,0xF6900091,0xE20008E2,0xE20008E2,0xFFBC07A1,0xFBC4084D,0xFBC40879,0xFFB00662,0xFF90049D,0xFF740269,0xFF640104,0xFF300074,0xFFB407AA,0xFFA40632,0xFF500499,0xF6900091, -0xCDFC08E1,0x178152C,0x178152C,0x178152C,0x178152C,0xFF5C0C99,0xFF5C0C99,0xFF5C0C99,0xFF4C06D0,0xFF4C06D0,0xED440621,0xFF440B02,0xFF440B02,0xFF440B02,0xFF200231,0xFF200231,0xF1200131,0xFD0C0480,0xFD0C0480,0xE904007A,0xD50C0482,0x31FC152B,0x31FC152B,0x31FC152B,0xFEFC08D9,0xFEFC08D9,0xECFC0621,0xFEB80619,0xFEB80619,0xEEA80006,0xD4C00482,0x9BF8152B, -0x9BF8152B,0xEC100621,0xD20004D2,0xBA00152B,0xFF6810FE,0xFF6C1369,0x178152C,0xFF540D39,0xFF440905,0xFF340565,0xFF340421,0xFF1400E4,0xFF5810BE,0xFF500C92,0xFF18067B,0xEEA80006,0x7FFC152B,0x1AC0480,0x1AC0480,0x1AC0480,0x1AC0480,0xFF9801E5,0xFF9801E5,0xFF9801E5,0xFF7C0010,0xFF7C0010,0xED7C0001,0x83FC0480,0x83FC0480,0x83FC0480,0xFF4C00A9,0xFF4C00A9, -0xEF4C0001,0xC3F80480,0xC3F80480,0xECBC0001,0xD4000482,0x83FC0480,0x83FC0480,0x83FC0480,0xFF4C00A9,0xFF4C00A9,0xEF4C0001,0xC3F80480,0xC3F80480,0xECBC0001,0xD4000482,0xC3F80480,0xC3F80480,0xECBC0001,0xD4000482,0xD4000482,0xFFA003CA,0xFDA803F5,0x1AC0480,0xFF980349,0xFF840269,0xFF6C019A,0xFF640104,0xFF300074,0xFF9403DA,0xFF840340,0xB3FC0480,0xECBC0001, -0xB3FC0480,0x1EC0091,0xFFE80055,0xFFE0001D,0xFFDC0000,0xE5FC0091,0xFFD80034,0xFFCC0000,0xF3F80091,0xFF940000,0xF6000091,0xE5FC0091,0xFFD80034,0xFFCC0000,0xF3F80091,0xFF940000,0xF6000091,0xF3F80091,0xFF940000,0xF6000091,0xF6000091,0xE5FC0091,0xFFD80034,0xFFCC0000,0xF3F80091,0xFF940000,0xF6000091,0xF3F80091,0xFF940000,0xF6000091,0xF6000091,0xF3F80091, -0xFF940000,0xF6000091,0xF6000091,0xF6000091,0xF9EC0080,0x77FC0091,0xFFEC0080,0xFDE80071,0xFFD0005A,0xFFC00028,0xFFA80000,0xFF7C0000,0xFFE80080,0xFFE00071,0xFFB40004,0xF6000091,0xEFFC0091,0x1440620,0x1440620,0x1440620,0x1440620,0x1440620,0x1440620,0x1440620,0x1440620,0x1440620,0x1440620,0xFF1800B4,0xFF1800B4,0xFF1800B4,0xFF1800B4,0xFF1800B4, -0xFF1800B4,0xD90C0000,0xD90C0000,0xD90C0000,0xBD0C0001,0x1E00620,0x1E00620,0x1E00620,0x1E00620,0x1E00620,0x1E00620,0xF0A40001,0xF0A40001,0xF0A40001,0xBED40001,0x75FC0620,0x75FC0620,0x75FC0620,0xBC280001,0xA0000622,0xF73C04E4,0x1440620,0x1440620,0xFF2C0371,0xFF280254,0xFF240171,0xFF240171,0xFF140020,0xF9300480,0xFF200332,0xF6FC0000,0xF0A40001, -0x51FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table187[] = { -0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x57FC0000, -0x57FC0000,0x57FC0000,0x57FC0000,0x8C000001,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0xF2C0000,0xF2C0000,0xF2C0000,0x3A40000,0x2BFC0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000, -0x53FC0000,0xABF80000,0xABF80000,0xABF80000,0xC4000001,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xABF80000,0xC4000001,0xABF80000,0xABF80000,0xABF80000,0xC4000001,0xC4000001,0xBA40000,0x18C0000,0x18C0000,0x1CC0000,0x1F00000,0x2BFC0000,0x2BFC0000,0x73FC0000,0x1CC0000,0x1F00000,0x95FC0000,0xABF80000, -0x95FC0000,0x1EC0000,0x1EC0000,0x1EC0000,0x1EC0000,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xF3F80000,0xF3F80000,0xF4000001,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xF3F80000,0xF3F80000,0xF4000001,0xF3F80000,0xF3F80000,0xF4000001,0xF4000001,0xE5FC0000,0xE5FC0000,0xE5FC0000,0xF3F80000,0xF3F80000,0xF4000001,0xF3F80000,0xF3F80000,0xF4000001,0xF4000001,0xF3F80000, -0xF3F80000,0xF4000001,0xF4000001,0xF4000001,0xC3FC0000,0x77FC0000,0x1EC0000,0xDFFC0000,0xEBFC0000,0xEFFC0000,0xF1FC0000,0xF3FC0000,0xD5FC0000,0xE5FC0000,0xEFFC0000,0xF4000001,0xEFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1A41F99,0xFF981A90,0xFF881695,0xFF88152C,0xFF80150D,0xFF740F8A,0xFF680D79,0xFF640A11,0xFF58076C,0xFB540649,0xFF7415A6,0xFF600EC8,0xFF5C0BF2,0xFF40071A,0xFF380339,0xFD2C0139,0xFF2C0946,0xFF200496,0xF71400FA,0xE91C0756,0x77FC1F99,0xFF58182C,0xFF4C152B,0xFF2C0E9D,0xFF1409B1,0xFB040649,0xFF080EA6,0xFED80706,0xFAB0002A,0xE8C40756,0xBDF81F99, -0xFE90152B,0xFA080649,0xE600080B,0xD2001F9B,0xFF901A71,0xF9A01DC1,0xFBA41E94,0xFF80147F,0xFF640E3A,0xFF4C0805,0xFF3C0548,0xFF3001B8,0xFF9019F6,0xFF7413B6,0xFF300766,0xFAB0002A,0xABFC1F99,0x1D00759,0xFFC40609,0xFFC004EC,0xFFBC0480,0xFFBC04CD,0xFFB0030E,0xFFA40249,0xFFA00169,0xFF940050,0xFB8C0029,0xBDFC0756,0xFFAC055B,0xFF9C0480,0xFF8802EE,0xFF700115, -0xFB580029,0xDFF80756,0xFF340480,0xFAB00029,0xE8000756,0xBDFC0756,0xFFAC055B,0xFF9C0480,0xFF8802EE,0xFF700115,0xFB580029,0xDFF80756,0xFF340480,0xFAB00029,0xE8000756,0xDFF80756,0xFF340480,0xFAB00029,0xE8000756,0xE8000756,0xFDCC067A,0xFFCC06D5,0xFFCC0711,0xFFC0058C,0xFFA40441,0xFF8402B0,0xFF7C0172,0xFF5000DD,0xFFC4067D,0xFFB0057E,0xFF700490,0xFAB00029, -0xD7FC0756,0x188152C,0x188152C,0x188152C,0x188152C,0xFF680D79,0xFF680D79,0xFF680D79,0xFF58076C,0xFF58076C,0xF5540621,0xFF5C0BF2,0xFF5C0BF2,0xFF5C0BF2,0xFF380339,0xFF380339,0xF9300131,0xFF200496,0xFF200496,0xF114007A,0xDD1C0482,0x49FC152B,0x49FC152B,0x49FC152B,0xFF1409B1,0xFF1409B1,0xF50C0621,0xFED80706,0xFED80706,0xF6B80006,0xDCD00482,0xA7F8152B, -0xA7F8152B,0xF4200621,0xDC0004A6,0xC200152B,0xFF741194,0xFB8413A0,0x188152C,0xFF680E19,0xFF580A15,0xFF4C06C1,0xFF3C0548,0xFF3001B8,0xFF741148,0xFF5C0D82,0xFF300742,0xF6B80006,0x8FFC152B,0x1BC0480,0x1BC0480,0x1BC0480,0x1BC0480,0xFFA40249,0xFFA40249,0xFFA40249,0xFF940050,0xFF940050,0xF58C0001,0x9BFC0480,0x9BFC0480,0x9BFC0480,0xFF700115,0xFF700115, -0xF75C0001,0xCFF80480,0xCFF80480,0xF4CC0001,0xDC000482,0x9BFC0480,0x9BFC0480,0x9BFC0480,0xFF700115,0xFF700115,0xF75C0001,0xCFF80480,0xCFF80480,0xF4CC0001,0xDC000482,0xCFF80480,0xCFF80480,0xF4CC0001,0xDC000482,0xDC000482,0xFBB403F5,0xF5B80424,0x1BC0480,0xFFA40384,0xFF9802B9,0xFF7C020A,0xFF7C0172,0xFF5000DD,0xFDB003F5,0xFF980371,0xC1FC0480,0xF4CC0001, -0xC1FC0480,0x1F40029,0xFFF40019,0xFFF00008,0xFFEC0000,0xF1FC0029,0xFFE40010,0xFFE40000,0xF9F80029,0xFFC80000,0xFA000029,0xF1FC0029,0xFFE40010,0xFFE40000,0xF9F80029,0xFFC80000,0xFA000029,0xF9F80029,0xFFC80000,0xFA000029,0xFA000029,0xF1FC0029,0xFFE40010,0xFFE40000,0xF9F80029,0xFFC80000,0xFA000029,0xF9F80029,0xFFC80000,0xFA000029,0xFA000029,0xF9F80029, -0xFFC80000,0xFA000029,0xFA000029,0xFA000029,0xFDF40020,0xB7FC0029,0xF3F40029,0xFFEC001D,0xFFE80014,0xFFDC000A,0xFFD00000,0xFFB80000,0xFFF00022,0xFFF00020,0xFFD80001,0xFA000029,0xF7FC0029,0x1540620,0x1540620,0x1540620,0x1540620,0x1540620,0x1540620,0x1540620,0x1540620,0x1540620,0x1540620,0xFF3000F4,0xFF3000F4,0xFF3000F4,0xFF3000F4,0xFF3000F4, -0xFF3000F4,0xE11C0000,0xE11C0000,0xE11C0000,0xC51C0001,0x1F80620,0x1F80620,0x1F80620,0x1F80620,0x1F80620,0x1F80620,0xF8B40001,0xF8B40001,0xF8B40001,0xC6E40001,0x81FC0620,0x81FC0620,0x81FC0620,0xC4380001,0xA8000622,0xFF4C04E4,0x1540620,0x1540620,0xFD48039D,0xFF3C0290,0xFF3401B1,0xFF3401B1,0xFF240050,0xFF3C0488,0xFF340355,0xFF0C0000,0xF8B40001, -0x5FFC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table188[] = { -0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x65F80000, -0x65F80000,0x65F80000,0x65F80000,0x96000000,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x9400000,0x9400000,0x9400000,0x1C00000,0x3DF80000,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x19C0001,0x6FFC0000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0x6FFC0000, -0x6FFC0000,0xB9F80000,0xB9F80000,0xB9F80000,0xCE000000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0x6FFC0000,0xB9F80000,0xB9F80000,0xB9F80000,0xCE000000,0xB9F80000,0xB9F80000,0xB9F80000,0xCE000000,0xCE000000,0x5B80000,0x19C0001,0x19C0001,0x3E00000,0x15FC0000,0x4DFC0000,0x4DFC0000,0x8BFC0000,0x3E00000,0x15FC0000,0xA5FC0000,0xB9F80000, -0xA5FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1B01CB4,0xFFA4190F,0xFF9C1633,0xFF98152B,0xFF98140A,0xFF8C0FFF,0xFF800E56,0xFF700A74,0xFF700863,0xFF640622,0xFF8C144D,0xFF740F22,0xFF680D11,0xFF5807AB,0xFF4C04BA,0xFF44013D,0xFF4C08DC,0xFF380519,0xFB28008D,0xEF2C0601,0x8DFC1CB0,0xFF701751,0xFF68152C,0xFF4C0EB2,0xFF380AC2,0xFF1C0620,0xFF200DF9,0xFEFC0829,0xFECC0005,0xEED80600,0xC7FC1CB0, -0xFEC8152B,0xFE2C0620,0xEC00064C,0xD8001CB0,0xFFA0185A,0xFFAC1AFA,0xFFAC1BE7,0xFF9413DF,0xFF780E8B,0xFF680924,0xFF5C06CB,0xFF400302,0xFF98183A,0xFF801312,0xFF3C08BF,0xFECC0005,0xB9FC1CB0,0x1DC0603,0xFFD40556,0xFFCC04C2,0xFFCC0482,0xFFD00433,0xFFC40336,0xFFBC02C5,0xFFAC0183,0xFFAC00DA,0xFF9C0001,0xCFFC0600,0xFFC004F6,0xFFB80480,0xFFA002C2,0xFF8801A9, -0xFF700000,0xE7FC0600,0xFF6C0480,0xFED80000,0xEE000600,0xCFFC0600,0xFFC004F6,0xFFB80480,0xFFA002C2,0xFF8801A9,0xFF700000,0xE7FC0600,0xFF6C0480,0xFED80000,0xEE000600,0xE7FC0600,0xFF6C0480,0xFED80000,0xEE000600,0xEE000600,0xFFD80565,0xF7DC05C1,0xF7DC05E2,0xFFC404EB,0xFFC003FE,0xFFA802E1,0xFFA00212,0xFF7C0172,0xFFD00575,0xFFC804AC,0xFF980489,0xFED80000, -0xE1FC0600,0x198152B,0x198152B,0x198152B,0x198152B,0xFF800E56,0xFF800E56,0xFF800E56,0xFF700863,0xFF700863,0xFF640622,0xFF680D11,0xFF680D11,0xFF680D11,0xFF4C04BA,0xFF4C04BA,0xFF44013D,0xFF380519,0xFF380519,0xF924007D,0xE72C0481,0x65FC152B,0x65FC152B,0x65FC152B,0xFF380AC2,0xFF380AC2,0xFF1C0620,0xFEFC0829,0xFEFC0829,0xFECC0005,0xE6E00480,0xB3FC152B, -0xB3FC152B,0xFE2C0620,0xE6000490,0xCC00152C,0xFF901212,0xFF8C13EB,0x198152B,0xFF800EF9,0xFF6C0B5E,0xFF5C082E,0xFF5C06CB,0xFF400302,0xFF8011D1,0xFF740E66,0xFF3C089B,0xFECC0005,0x9FFC152B,0x1CC0482,0x1CC0482,0x1CC0482,0x1CC0482,0xFFBC02C5,0xFFBC02C5,0xFFBC02C5,0xFFAC00DA,0xFFAC00DA,0xFF9C0001,0xB7FC0480,0xB7FC0480,0xB7FC0480,0xFF8801A9,0xFF8801A9, -0xFF700000,0xDDF40480,0xDDF40480,0xFED80000,0xE6000480,0xB7FC0480,0xB7FC0480,0xB7FC0480,0xFF8801A9,0xFF8801A9,0xFF700000,0xDDF40480,0xDDF40480,0xFED80000,0xE6000480,0xDDF40480,0xDDF40480,0xFED80000,0xE6000480,0xE6000480,0xFDC80422,0xFFCC0422,0x1CC0482,0xFDC003CA,0xFFAC0321,0xFFA0028D,0xFFA00212,0xFF7C0172,0xFFC40422,0xFFB003C5,0xD3FC0480,0xFED80000, -0xD3FC0480,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1640622,0x1640622,0x1640622,0x1640622,0x1640622,0x1640622,0x1640622,0x1640622,0x1640622,0x1640622,0xFF44013D,0xFF44013D,0xFF44013D,0xFF44013D,0xFF44013D, -0xFF44013D,0xEB2C0001,0xEB2C0001,0xEB2C0001,0xCF2C0001,0x19FC0620,0x19FC0620,0x19FC0620,0x19FC0620,0x19FC0620,0x19FC0620,0xFECC0005,0xFECC0005,0xFECC0005,0xCEF80000,0x8FF80620,0x8FF80620,0x8FF80620,0xCE480000,0xB2000620,0xF9600515,0x1640622,0x1640622,0xFF5803CA,0xFF5002DA,0xFF4C0202,0xFF4C0202,0xFF400091,0xFD5404B1,0xFF50039D,0xFF24000D,0xFECC0005, -0x71FC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table189[] = { -0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x71F80000, -0x71F80000,0x71F80000,0x71F80000,0x9E000000,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x1540000,0x1540000,0x1540000,0x1D80000,0x4BFC0000,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x1AC0001,0x87FC0000,0x87FC0000,0x87FC0000,0x87FC0000,0x87FC0000, -0x87FC0000,0xC5F80000,0xC5F80000,0xC5F80000,0xD6000000,0x87FC0000,0x87FC0000,0x87FC0000,0x87FC0000,0x87FC0000,0x87FC0000,0xC5F80000,0xC5F80000,0xC5F80000,0xD6000000,0xC5F80000,0xC5F80000,0xC5F80000,0xD6000000,0xD6000000,0xDC80000,0x1AC0001,0x1AC0001,0x1F40000,0x3DFC0000,0x6BFC0000,0x6BFC0000,0x9DFC0000,0x1F40000,0x3DFC0000,0xB5FC0000,0xC5F80000, -0xB5FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1B81834,0xFFB01547,0xFFA812FF,0xFFA4122B,0xFFA4114A,0xFF980E07,0xFF8C0CB6,0xFF880994,0xFF7C07EB,0xFF740622,0xFF981115,0xFF800CE2,0xFF800B29,0xFF7006D3,0xFF64046A,0xFF500195,0xFF580704,0xFF4C03F3,0xFD380035,0xF13C042D,0x99FC1830,0xFF7C13E9,0xFF78122B,0xFF580CF2,0xFF4C09E9,0xFF340620,0xFF380B89,0xFF1406C9,0xFEE40025,0xF0EC042D,0xCDFC1830, -0xFEEC122B,0xFE600620,0xF0000435,0xDC001830,0xFFA814D6,0xFFAC171A,0xF5B817AC,0xFF9810D6,0xFF880C93,0xFF700806,0xFF68061E,0xFF5802DE,0xFFA014B2,0xFF901042,0xFF58074F,0xFEE40025,0xBFFC1830,0x1E4042B,0xFFDC03AB,0xFFD80346,0xFFD40322,0xFFD002E3,0xFFC8023E,0xFFC401E2,0xFFB8010B,0xFFB80092,0xFFAC0001,0xD9FC042B,0xFFCC0372,0xFFC00322,0xFFAC01E2,0xFFA00121, -0xFF880000,0xEDF8042B,0xFF840320,0xFF080000,0xF000042C,0xD9FC042B,0xFFCC0372,0xFFC00322,0xFFAC01E2,0xFFA00121,0xFF880000,0xEDF8042B,0xFF840320,0xFF080000,0xF000042C,0xEDF8042B,0xFF840320,0xFF080000,0xF000042C,0xF000042C,0xFFD803C5,0xF9E003F9,0xFBE40412,0xFFD40355,0xFFC802BD,0xFFB801F5,0xFFA80161,0xFF8C0105,0xFFDC03C5,0xFFC8034C,0xFFA80329,0xFF080000, -0xE7FC042B,0x1A4122B,0x1A4122B,0x1A4122B,0x1A4122B,0xFF8C0CB6,0xFF8C0CB6,0xFF8C0CB6,0xFF7C07EB,0xFF7C07EB,0xFF740622,0xFF800B29,0xFF800B29,0xFF800B29,0xFF64046A,0xFF64046A,0xFF500195,0xFF4C03F3,0xFF4C03F3,0xFB3C002A,0xEB3C0321,0x77FC122B,0x77FC122B,0x77FC122B,0xFF4C09E9,0xFF4C09E9,0xFF340620,0xFF1406C9,0xFF1406C9,0xFEE40025,0xEAF40320,0xBDF8122B, -0xBDF8122B,0xFE600620,0xEA040320,0xD000122C,0xFD9C0FA9,0xF9A01122,0x1A4122B,0xFF900D02,0xFF8009FE,0xFF700742,0xFF68061E,0xFF5802DE,0xFF940F4C,0xFF800CA1,0xFF580736,0xFEE40025,0xABFC122B,0x1D40322,0x1D40322,0x1D40322,0x1D40322,0xFFC401E2,0xFFC401E2,0xFFC401E2,0xFFB80092,0xFFB80092,0xFFAC0001,0xC3FC0320,0xC3FC0320,0xC3FC0320,0xFFA00121,0xFFA00121, -0xFF880000,0xE1FC0320,0xE1FC0320,0xFF080000,0xEA000320,0xC3FC0320,0xC3FC0320,0xC3FC0320,0xFFA00121,0xFFA00121,0xFF880000,0xE1FC0320,0xE1FC0320,0xFF080000,0xEA000320,0xE1FC0320,0xE1FC0320,0xFF080000,0xEA000320,0xEA000320,0xFBD002D4,0xFFCC02F2,0x1D40322,0xFFC4029A,0xFFC00225,0xFFB001BD,0xFFA80161,0xFF8C0105,0xFDCC02D4,0xFFC80288,0xDBFC0320,0xFF080000, -0xDBFC0320,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1740622,0x1740622,0x1740622,0x1740622,0x1740622,0x1740622,0x1740622,0x1740622,0x1740622,0x1740622,0xFF500195,0xFF500195,0xFF500195,0xFF500195,0xFF500195, -0xFF500195,0xF33C0001,0xF33C0001,0xF33C0001,0xD73C0001,0x31FC0620,0x31FC0620,0x31FC0620,0x31FC0620,0x31FC0620,0x31FC0620,0xFEE40025,0xFEE40025,0xFEE40025,0xD7080000,0x9BF80620,0x9BF80620,0x9BF80620,0xD6580000,0xBA000620,0xFF6C0521,0x1740622,0x1740622,0xFF6803F9,0xFF640322,0xFF5C024A,0xFF5C024A,0xFF4C00DA,0xF96804E2,0xFF5803E8,0xFF38002D,0xFEE40025, -0x7FFC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table190[] = { -0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x7DF80000, -0x7DF80000,0x7DF80000,0x7DF80000,0xA6000000,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x1640000,0x1640000,0x1640000,0x1F00000,0x5BFC0000,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x1BC0001,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000, -0x9FFC0000,0xD1F80000,0xD1F80000,0xD1F80000,0xDE000000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0x9FFC0000,0xD1F80000,0xD1F80000,0xD1F80000,0xDE000000,0xD1F80000,0xD1F80000,0xD1F80000,0xDE000000,0xDE000000,0x1DC0000,0x1BC0001,0x1BC0001,0x1FFC0000,0x63FC0000,0x89FC0000,0x89FC0000,0xB1FC0000,0x1FFC0000,0x63FC0000,0xC3FC0000,0xD1F80000, -0xC3FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1C01434,0xFFBC11F7,0xFFB4102B,0xFFAC0F83,0xFFB00EDA,0xFFA40C47,0xFF980B46,0xFF9408C4,0xFF88078B,0xFF840622,0xFFA40E45,0xFF8C0AF2,0xFF8C0989,0xFF7C0613,0xFF700432,0xFF6801ED,0xFF64058C,0xFF58030B,0xFD4C000A,0xF54C02AD,0xA5FC1430,0xFF9410D1,0xFF880F80,0xFF700B62,0xFF640911,0xFF4C0620,0xFF4C09AB,0xFF2C05A9,0xFF080059,0xF50002AD,0xD3FC1430, -0xFF080F80,0xFE900620,0xF40C02AC,0xE0001430,0xFFB4117B,0xF9C01344,0xF9C013BC,0xFFAC0E6E,0xFF940AD2,0xFF7C073E,0xFF7805B3,0xFF6C02C3,0xFFB4111B,0xFF980DEE,0xFF70060B,0xFF080059,0xC7FC1430,0x1E802AB,0xFDE40263,0xFFE0021B,0xFFDC0202,0xFFDC01D3,0xFFD4016E,0xFFD00132,0xFFCC00B1,0xFFC00065,0xFFBC0001,0xDFFC02AB,0xFFD80236,0xFFCC0202,0xFFB80132,0xFFAC00B9, -0xFFA00000,0xEFFC02AB,0xFF9C0200,0xFF380000,0xF40002AC,0xDFFC02AB,0xFFD80236,0xFFCC0202,0xFFB80132,0xFFAC00B9,0xFFA00000,0xEFFC02AB,0xFF9C0200,0xFF380000,0xF40002AC,0xEFFC02AB,0xFF9C0200,0xFF380000,0xF40002AC,0xF40002AC,0xFFE4026D,0xFDE80281,0xFDE80296,0xFFDC0215,0xFFD401C2,0xFFBC0152,0xFFB800E8,0xFFA8009D,0xFFE00272,0xFFDC020E,0xFFB80204,0xFF380000, -0xEBFC02AB,0x1AC0F83,0x1AC0F83,0x1AC0F83,0x1AC0F83,0xFF980B46,0xFF980B46,0xFF980B46,0xFF88078B,0xFF88078B,0xFF840622,0xFF8C0989,0xFF8C0989,0xFF8C0989,0xFF700432,0xFF700432,0xFF6801ED,0xFF58030B,0xFF58030B,0xFD4C0006,0xEF4C0201,0x87FC0F80,0x87FC0F80,0x87FC0F80,0xFF640911,0xFF640911,0xFF4C0620,0xFF2C05A9,0xFF2C05A9,0xFF080059,0xEF080200,0xC5F80F80, -0xC5F80F80,0xFE900620,0xEE280200,0xD6000F80,0xFFA00D61,0xFFAC0E96,0x1AC0F83,0xFF980B42,0xFF8C08EE,0xFF7C0695,0xFF7805B3,0xFF6C02C3,0xFFA00D29,0xFF900AF9,0xFF7005FB,0xFF080059,0xB5FC0F80,0x1DC0202,0x1DC0202,0x1DC0202,0x1DC0202,0xFFD00132,0xFFD00132,0xFFD00132,0xFFC00065,0xFFC00065,0xFFBC0001,0xCFFC0200,0xCFFC0200,0xCFFC0200,0xFFAC00B9,0xFFAC00B9, -0xFFA00000,0xE7FC0200,0xE7FC0200,0xFF380000,0xEE000200,0xCFFC0200,0xCFFC0200,0xCFFC0200,0xFFAC00B9,0xFFAC00B9,0xFFA00000,0xE7FC0200,0xE7FC0200,0xFF380000,0xEE000200,0xE7FC0200,0xE7FC0200,0xFF380000,0xEE000200,0xEE000200,0xFFD801C4,0xF7DC01E1,0x1DC0202,0xFDD801A5,0xFFC80164,0xFFBC0121,0xFFB800E8,0xFFA8009D,0xFFD001D4,0xFBD401A5,0xE1FC0200,0xFF380000, -0xE1FC0200,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1840622,0x1840622,0x1840622,0x1840622,0x1840622,0x1840622,0x1840622,0x1840622,0x1840622,0x1840622,0xFF6801ED,0xFF6801ED,0xFF6801ED,0xFF6801ED,0xFF6801ED, -0xFF6801ED,0xFB4C0001,0xFB4C0001,0xFB4C0001,0xDF4C0001,0x49FC0620,0x49FC0620,0x49FC0620,0x49FC0620,0x49FC0620,0x49FC0620,0xFF080059,0xFF080059,0xFF080059,0xDF180000,0xA7F80620,0xA7F80620,0xA7F80620,0xDE680000,0xC2000620,0xF980054A,0x1840622,0x1840622,0xFF740442,0xFF780372,0xFF7002B1,0xFF7002B1,0xFF5C0131,0xFF7404EA,0xFD740422,0xFF500075,0xFF080059, -0x8FFC0620,}; -static const uint32_t g_etc1_to_bc7_m6_table191[] = { -0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0x89F80000, -0x89F80000,0x89F80000,0x89F80000,0xAE000000,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x3740000,0x3740000,0x3740000,0xDFC0000,0x69FC0000,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000, -0xB7FC0000,0xDDF40000,0xDDF40000,0xDDF40000,0xE6000000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xDDF40000,0xE6000000,0xDDF40000,0xDDF40000,0xDDF40000,0xE6000000,0xE6000000,0x1EC0000,0x1CC0001,0x1CC0001,0x57FC0000,0x8BFC0000,0xA7FC0000,0xA7FC0000,0xC5FC0000,0x57FC0000,0x8BFC0000,0xD3FC0000,0xDDF40000, -0xD3FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1C810B4,0xFFC40EF4,0xFFB80DA4,0xFFB80D2B,0xFFB00CBA,0xFFB00ABF,0xFFA40A06,0xFFA00814,0xFF9C0732,0xFF940622,0xFFB00BDD,0xFF980952,0xFF980831,0xFF88058B,0xFF84041A,0xFF74025D,0xFF7C045C,0xFF700263,0xFF600005,0xF75C0181,0xB1FC10B0,0xFFA00E21,0xFF980D2C,0xFF7C0A12,0xFF700851,0xFF640620,0xFF6407F3,0xFF3804E9,0xFF2000A9,0xF7180180,0xD9FC10B0, -0xFF280D2B,0xFEC00620,0xF6380180,0xE40010B0,0xFFBC0E86,0xFDC80FE4,0xFDC8104C,0xFFAC0C2E,0xFFA00963,0xFF90068E,0xFF900555,0xFF7402DE,0xFFB40E4B,0xFFB00BC7,0xFF7C0521,0xFF2000A9,0xCFFC10B0,0x1EC0183,0xFFE80153,0xFFE40132,0xFFE40122,0xFFE8010B,0xFFDC00CE,0xFFDC00AA,0xFFD80061,0xFFD4003A,0xFFCC0001,0xE9FC0180,0xFFE00141,0xFFD80122,0xFFCC00B1,0xFFC0006D, -0xFFB80000,0xF3FC0180,0xFFB40120,0xFF6C0000,0xF6000180,0xE9FC0180,0xFFE00141,0xFFD80122,0xFFCC00B1,0xFFC0006D,0xFFB80000,0xF3FC0180,0xFFB40120,0xFF6C0000,0xF6000180,0xF3FC0180,0xFFB40120,0xFF6C0000,0xF6000180,0xF6000180,0xFBEC0161,0xFFEC0161,0xFFEC0172,0xFFE00143,0xFFDC00F9,0xFFD000C3,0xFFD00082,0xFFB8005A,0xF9EC0161,0xFFDC012E,0xFFD00123,0xFF6C0000, -0xF1FC0180,0x1B80D2B,0x1B80D2B,0x1B80D2B,0x1B80D2B,0xFFA40A06,0xFFA40A06,0xFFA40A06,0xFF9C0732,0xFF9C0732,0xFF940622,0xFF980831,0xFF980831,0xFF980831,0xFF84041A,0xFF84041A,0xFF74025D,0xFF700263,0xFF700263,0xFF600005,0xF35C0121,0x95FC0D2B,0x95FC0D2B,0x95FC0D2B,0xFF700851,0xFF700851,0xFF640620,0xFF3804E9,0xFF3804E9,0xFF2000A9,0xF31C0120,0xCBFC0D2B, -0xCBFC0D2B,0xFEC00620,0xF2480120,0xDC000D2C,0xFFAC0B7E,0xF5B80CA3,0x1B80D2B,0xFFA409EB,0xFF9407DE,0xFF900615,0xFF900555,0xFF7402DE,0xFDB00B5E,0xFF9809A5,0xFF7C0511,0xFF2000A9,0xBFF80D2B,0x1E40122,0x1E40122,0x1E40122,0x1E40122,0xFFDC00AA,0xFFDC00AA,0xFFDC00AA,0xFFD4003A,0xFFD4003A,0xFFCC0001,0xDBFC0120,0xDBFC0120,0xDBFC0120,0xFFC0006D,0xFFC0006D, -0xFFB80000,0xEDFC0120,0xEDFC0120,0xFF6C0000,0xF2000120,0xDBFC0120,0xDBFC0120,0xDBFC0120,0xFFC0006D,0xFFC0006D,0xFFB80000,0xEDFC0120,0xEDFC0120,0xFF6C0000,0xF2000120,0xEDFC0120,0xEDFC0120,0xFF6C0000,0xF2000120,0xF2000120,0xF7E40109,0xFBE40109,0x1E40122,0xFFDC00E1,0xFFD400C1,0xFFD000AA,0xFFD00082,0xFFB8005A,0xF5E40109,0xFFDC00DD,0xE9FC0120,0xFF6C0000, -0xE9FC0120,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1940622,0x1940622,0x1940622,0x1940622,0x1940622,0x1940622,0x1940622,0x1940622,0x1940622,0x1940622,0xFF74025D,0xFF74025D,0xFF74025D,0xFF74025D,0xFF74025D, -0xFF74025D,0xFF600005,0xFF600005,0xFF600005,0xE75C0001,0x63FC0620,0x63FC0620,0x63FC0620,0x63FC0620,0x63FC0620,0x63FC0620,0xFF2000A9,0xFF2000A9,0xFF2000A9,0xE7280000,0xB3F80620,0xB3F80620,0xB3F80620,0xE6780000,0xCA000620,0xFF8C055A,0x1940622,0x1940622,0xFF840479,0xFF8003C5,0xFF800305,0xFF800305,0xFF700195,0xFD8C0515,0xFF80045D,0xFF6000CD,0xFF2000A9, -0x9FF80620,}; -static const uint32_t g_etc1_to_bc7_m6_table192[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x400001,0x400001,0x400001,0x400001,0x600000,0x600000,0x600000,0xC40000,0xC40000,0x20000000,0x600000,0x600000,0x600000,0xC40000,0xC40000,0x20000000,0xC40000,0xC40000,0x20000000,0x20000000,0x600000,0x600000,0x600000,0xC40000,0xC40000,0x20000000,0xC40000,0xC40000,0x20000000,0x20000000,0xC40000, -0xC40000,0x20000000,0x20000000,0x20000000,0x4C0000,0xA440000,0x400001,0x580000,0x26C0000,0x8C0000,0xA00000,0xF00000,0x4500000,0x600000,0x8C0000,0x20000000,0x8C0000,0xD40000,0x13C0000,0x21FC0000,0x68000001,0x13C0000,0x21FC0000,0x68000001,0x21FC0000,0x68000001,0x68000001,0x13C0000,0x21FC0000,0x68000001,0x21FC0000,0x68000001, -0x68000001,0x21FC0000,0x68000001,0x68000001,0x68000001,0x13C0000,0x21FC0000,0x68000001,0x21FC0000,0x68000001,0x68000001,0x21FC0000,0x68000001,0x68000001,0x68000001,0x21FC0000,0x68000001,0x68000001,0x68000001,0x68000001,0x3080000,0x8E00000,0x8E00000,0x1640000,0x5FC0000,0x45F40000,0x68000001,0x68000001,0x1200000,0x18C0000,0x61D40000,0x68000001, -0x1C00000,0x441D49,0xFE1C039A,0x981402D9,0x681402DA,0xD0000A69,0x92000112,0x68000002,0x66000A69,0x560003DA,0x44000A69,0x8A0016FD,0x7A000882,0x62000432,0x58000E66,0x520006FB,0x40000C4A,0x440016FD,0x44000E46,0x38001145,0x2E0016FE,0x681D47,0x68000DD2,0x580007C3,0x52001187,0x4C000994,0x40000E03,0x400018C6,0x3E001027,0x360012AA,0x2E0017DF,0xD01D47, -0x380014C2,0x3200161D,0x26001A42,0x22001D47,0xFE140B92,0xF4381671,0xF8401611,0xC80006E0,0x8A000732,0x660006FD,0x5A0004DA,0x4A000929,0xF2000CF6,0x9E00098E,0x52000B32,0x360012AA,0x941D47,0x5C16FD,0xFE240289,0x94200222,0x68200222,0xD0000A69,0x92000112,0x68000002,0x66000A69,0x560003DA,0x44000A69,0x8816FD,0x7A000882,0x62000432,0x58000E66,0x520006FB, -0x40000C4A,0x11416FD,0x44000E46,0x38001145,0x2E0016FE,0x8816FD,0x7A000882,0x62000432,0x58000E66,0x520006FB,0x40000C4A,0x11416FD,0x44000E46,0x38001145,0x2E0016FE,0x11416FD,0x44000E46,0x38001145,0x2E0016FE,0x2E0016FE,0xFE140B2E,0xFC481271,0xFE4C1121,0xC80006E0,0x8A000732,0x660006FD,0x5A0004DA,0x4A000929,0xFA000BFE,0x9E00092A,0x52000B19,0x38001145, -0xC016FD,0x1402D9,0x1402D9,0x1402D9,0x1402D9,0x64000000,0x64000000,0x64000000,0x30000000,0x30000000,0x20000000,0x30000221,0x30000221,0x30000221,0x280000C2,0x280000C2,0x1E000068,0x18000221,0x18000221,0x16000145,0x10000221,0x2002D6,0x2002D6,0x2002D6,0x22000143,0x22000143,0x180000C0,0x1200025D,0x1200025D,0x14000185,0xE00023E,0x3C02D6, -0x3C02D6,0x100001F2,0xE000289,0xA0002D6,0xC40000A9,0xFE0C00C1,0x1402D9,0x640000E8,0x3C0000D0,0x2E0000D0,0x2E0000A9,0x220000F5,0x64000178,0x44000138,0x1E000225,0x14000185,0x2C02D6,0x200221,0x200221,0x200221,0x200221,0x64000000,0x64000000,0x64000000,0x30000000,0x30000000,0x20000000,0x300221,0x300221,0x300221,0x280000C2,0x280000C2, -0x1E000068,0x5C0221,0x5C0221,0x16000145,0x10000221,0x300221,0x300221,0x300221,0x280000C2,0x280000C2,0x1E000068,0x5C0221,0x5C0221,0x16000145,0x10000221,0x5C0221,0x5C0221,0x16000145,0x10000221,0x10000221,0xC40000A9,0xFE0C009D,0x200221,0x640000E8,0x3C0000D0,0x2E0000D0,0x2E0000A9,0x220000F5,0x74000151,0x4A000121,0x400221,0x16000145, -0x400221,0x8C0A69,0xFC440001,0x8C440001,0x68400002,0xCC0A69,0x92000112,0x68000002,0x1A00A69,0x560003DA,0x44000A69,0xCC0A69,0x92000112,0x68000002,0x1A00A69,0x560003DA,0x44000A69,0x1A00A69,0x560003DA,0x44000A69,0x44000A69,0xCC0A69,0x92000112,0x68000002,0x1A00A69,0x560003DA,0x44000A69,0x1A00A69,0x560003DA,0x44000A69,0x44000A69,0x1A00A69, -0x560003DA,0x44000A69,0x44000A69,0x44000A69,0xFE3406B2,0x940A69,0xF8800745,0xDE000385,0x96000410,0x720003D4,0x5E00028A,0x54000502,0xFE180659,0xBA000454,0x64000232,0x44000A69,0x1240A69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table193[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x500001,0x500001,0x500001,0x500001,0x780000,0x780000,0x780000,0xF40000,0xF40000,0x28000000,0x780000,0x780000,0x780000,0xF40000,0xF40000,0x28000000,0xF40000,0xF40000,0x28000000,0x28000000,0x780000,0x780000,0x780000,0xF40000,0xF40000,0x28000000,0xF40000,0xF40000,0x28000000,0x28000000,0xF40000, -0xF40000,0x28000000,0x28000000,0x28000000,0x600000,0x580000,0x500001,0x700000,0x880000,0xAC0000,0xC80000,0x12C0000,0x4640000,0x780000,0xAC0000,0x28000000,0xAC0000,0xE40000,0x3500000,0x2DFC0000,0x70000001,0x3500000,0x2DFC0000,0x70000001,0x2DFC0000,0x70000001,0x70000001,0x3500000,0x2DFC0000,0x70000001,0x2DFC0000,0x70000001, -0x70000001,0x2DFC0000,0x70000001,0x70000001,0x70000001,0x3500000,0x2DFC0000,0x70000001,0x2DFC0000,0x70000001,0x70000001,0x2DFC0000,0x70000001,0x70000001,0x70000001,0x2DFC0000,0x70000001,0x70000001,0x70000001,0x70000001,0x31C0000,0xF40000,0xF40000,0x1800000,0x13F80000,0x4FF40000,0x70000001,0x70000001,0x3340000,0x1AC0000,0x69E40000,0x70000001, -0x1E40000,0x4C21E1,0xFE2405DD,0xA21C0461,0x701C0462,0xEA000A69,0xA20000A0,0x7200000A,0x72000A69,0x60000361,0x4C000A69,0x9C001A0D,0x860009AA,0x68000506,0x68000F41,0x58000723,0x46000CCE,0x4C001A0D,0x4A001006,0x3E0012F1,0x32001A0E,0x7421DF,0x7400101A,0x62000932,0x62001345,0x52000A54,0x46000EDF,0x46001C46,0x44001257,0x3C0014AA,0x30001B22,0xE821DF, -0x3E0017F2,0x320018ED,0x2C001E16,0x260021DF,0xFE140E42,0xF8401A29,0xFC481A39,0xDE000716,0x9A000789,0x7000072D,0x5E0004BB,0x560009B3,0xFE000ECD,0xB6000A4B,0x56000C76,0x3C0014AA,0xA421DF,0x681A0D,0xFE300425,0x9E28034A,0x7028034A,0xEA000A69,0xA20000A0,0x72040009,0x72000A69,0x60000361,0x4C000A69,0x2981A0D,0x860009AA,0x68000506,0x68000F41,0x58000723, -0x46000CCE,0x1381A0D,0x4A001006,0x3E0012F1,0x32001A0E,0x2981A0D,0x860009AA,0x68000506,0x68000F41,0x58000723,0x46000CCE,0x1381A0D,0x4A001006,0x3E0012F1,0x32001A0E,0x1381A0D,0x4A001006,0x3E0012F1,0x32001A0E,0x32001A0E,0xFE200D73,0xFE4C1521,0xF860142A,0xDE000716,0x9A000789,0x7000072D,0x5E0004BB,0x560009B3,0xFE000DCD,0xBC0009CE,0x56000C5D,0x3E0012F1, -0xDC1A0D,0x1C0461,0x1C0461,0x1C0461,0x1C0461,0x7C000000,0x7C000000,0x7C000000,0x3C000000,0x3C000000,0x28000000,0x3C000349,0x3C000349,0x3C000349,0x2E000132,0x2E000132,0x2200009D,0x1E000349,0x1E000349,0x1C0001F9,0x14000349,0x280461,0x280461,0x280461,0x280001FB,0x280001FB,0x22000116,0x180003A1,0x180003A1,0x1A000259,0x12000371,0x500461, -0x500461,0x16000306,0x100003DA,0xC000462,0xF6000105,0xFE0C01B1,0x1C0461,0x7A000161,0x50000140,0x40000145,0x38000112,0x2A000172,0x82000248,0x500001DD,0x2400034D,0x1A000259,0x380461,0x280349,0x280349,0x280349,0x280349,0x7C000000,0x7C000000,0x7C000000,0x3C000000,0x3C000000,0x28000000,0x3C0349,0x3C0349,0x3C0349,0x2E000132,0x2E000132, -0x2200009D,0x740349,0x740349,0x1C0001F9,0x14000349,0x3C0349,0x3C0349,0x3C0349,0x2E000132,0x2E000132,0x2200009D,0x740349,0x740349,0x1C0001F9,0x14000349,0x740349,0x740349,0x1C0001F9,0x14000349,0x14000349,0xF6000105,0xF4180154,0x280349,0x7A000161,0x50000140,0x40000145,0x38000112,0x2A000172,0x82000208,0x5A0001BD,0x540349,0x1C0001F9, -0x540349,0x9C0A69,0xFE540005,0x94540001,0x70500002,0xE40A69,0xA20000A0,0x700C0001,0x1D00A69,0x60000361,0x4C000A69,0xE40A69,0xA20000A0,0x700C0001,0x1D00A69,0x60000361,0x4C000A69,0x1D00A69,0x60000361,0x4C000A69,0x4C000A69,0xE40A69,0xA20000A0,0x700C0001,0x1D00A69,0x60000361,0x4C000A69,0x1D00A69,0x60000361,0x4C000A69,0x4C000A69,0x1D00A69, -0x60000361,0x4C000A69,0x4C000A69,0x4C000A69,0xFE5006CD,0xA40A69,0xFE8C0749,0xF4000304,0xA0000384,0x7C000335,0x66000209,0x5C000492,0xFE2C0694,0xCC0003E8,0x6E0001A8,0x4C000A69,0x1480A69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table194[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x600001,0x600001,0x600001,0x600001,0x900000,0x900000,0x900000,0x1240000,0x1240000,0x30000000,0x900000,0x900000,0x900000,0x1240000,0x1240000,0x30000000,0x1240000,0x1240000,0x30000000,0x30000000,0x900000,0x900000,0x900000,0x1240000,0x1240000,0x30000000,0x1240000,0x1240000,0x30000000,0x30000000,0x1240000, -0x1240000,0x30000000,0x30000000,0x30000000,0x2700000,0x680000,0x600001,0x840000,0xA40000,0xD00000,0xEC0000,0x1680000,0x4780000,0x900000,0xD00000,0x30000000,0xD00000,0xF40000,0x3680000,0x39FC0000,0x78000001,0x3680000,0x39FC0000,0x78000001,0x39FC0000,0x78000001,0x78000001,0x3680000,0x39FC0000,0x78000001,0x39FC0000,0x78000001, -0x78000001,0x39FC0000,0x78000001,0x78000001,0x78000001,0x3680000,0x39FC0000,0x78000001,0x39FC0000,0x78000001,0x78000001,0x39FC0000,0x78000001,0x78000001,0x78000001,0x39FC0000,0x78000001,0x78000001,0x78000001,0x78000001,0x3300000,0x1040000,0x1040000,0x1980000,0x1FFC0000,0x59F40000,0x78000001,0x78000001,0x14C0000,0x1C80000,0x71F40000,0x78000001, -0x5FC0000,0x5426F9,0xFE3008D5,0xAC200642,0x78200642,0xFE000A6D,0xAE000050,0x7A04003A,0x7E000A69,0x6C0002E9,0x54000A69,0xAC001D72,0x92000B12,0x6E000632,0x6E001055,0x62000755,0x52000D4E,0x54001D72,0x5000120E,0x440014CD,0x38001D72,0x8026F7,0x7A0012C2,0x68000B0A,0x62001515,0x5E000B3C,0x4C000FDB,0x4C00202E,0x4A0014D7,0x440016DE,0x36001EC2,0x10026F7, -0x44001B8A,0x38001C09,0x32002262,0x2A0026F7,0xFE201173,0xFC481E61,0xFE4C1EE5,0xF4000768,0xA20007D3,0x7C000746,0x660004D2,0x60000A46,0xFE00117D,0xC6000B19,0x5E000E2A,0x440016DE,0xB426F7,0x701D75,0xFE3C0631,0xA83004B2,0x783004B2,0xFE000A6D,0xAE000050,0x7C080032,0x7E000A69,0x6C0002E9,0x54000A69,0xA81D72,0x92000B12,0x6E000632,0x6E001055,0x62000755, -0x52000D4E,0x1581D72,0x5000120E,0x440014CD,0x38001D72,0xA81D72,0x92000B12,0x6E000632,0x6E001055,0x62000755,0x52000D4E,0x1581D72,0x5000120E,0x440014CD,0x38001D72,0x1581D72,0x5000120E,0x440014CD,0x38001D72,0x38001D72,0xFE340FF2,0xF8601819,0xFC68174A,0xF4000768,0xA20007D3,0x7C000746,0x660004D2,0x60000A46,0xFE08103E,0xC6000A89,0x5E000E06,0x440014CD, -0xF01D72,0x200641,0x200641,0x200641,0x200641,0x94000000,0x94000000,0x94000000,0x48000000,0x48000000,0x30000000,0x480004B1,0x480004B1,0x480004B1,0x3A0001BA,0x3A0001BA,0x2E0000E5,0x220004B1,0x220004B1,0x200002E4,0x180004B1,0x300641,0x300641,0x300641,0x2E0002E3,0x2E0002E3,0x28000192,0x2200052A,0x2200052A,0x1C00035D,0x180004F1,0x5C0641, -0x5C0641,0x1C000462,0x1400058D,0x10000642,0xF60001A5,0xF4180304,0x200641,0x900001F4,0x5E0001CD,0x480001CD,0x44000184,0x2E00022D,0x9600034E,0x720002BB,0x2C0004BA,0x1C00035D,0x400641,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x94000000,0x94000000,0x94000000,0x48000000,0x48000000,0x30000000,0x4804B1,0x4804B1,0x4804B1,0x3A0001BA,0x3A0001BA, -0x2E0000E5,0x8C04B1,0x8C04B1,0x200002E4,0x180004B1,0x4804B1,0x4804B1,0x4804B1,0x3A0001BA,0x3A0001BA,0x2E0000E5,0x8C04B1,0x8C04B1,0x200002E4,0x180004B1,0x8C04B1,0x8C04B1,0x200002E4,0x180004B1,0x180004B1,0xF60001A5,0xF8200244,0x3004B1,0x900001F4,0x5E0001CD,0x480001CD,0x44000184,0x2E00022D,0xA40002F2,0x7200028A,0x6404B1,0x200002E4, -0x6404B1,0xAC0A69,0xFE680012,0x9C640001,0x78600002,0xFC0A69,0xAE000050,0x781C0001,0x3F80A69,0x6C0002E9,0x54000A69,0xFC0A69,0xAE000050,0x781C0001,0x3F80A69,0x6C0002E9,0x54000A69,0x3F80A69,0x6C0002E9,0x54000A69,0x54000A69,0xFC0A69,0xAE000050,0x781C0001,0x3F80A69,0x6C0002E9,0x54000A69,0x3F80A69,0x6C0002E9,0x54000A69,0x54000A69,0x3F80A69, -0x6C0002E9,0x54000A69,0x54000A69,0x54000A69,0xF6680708,0xB80A69,0xF8A00782,0xFC0002AD,0xB600031A,0x860002D5,0x70000195,0x6400042A,0xF44806CD,0xDE000361,0x76000128,0x54000A69,0x1680A69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table195[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x700001,0x700001,0x700001,0x700001,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x38000000,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x38000000,0x1580000,0x1580000,0x38000000,0x38000000,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x38000000,0x1580000,0x1580000,0x38000000,0x38000000,0x1580000, -0x1580000,0x38000000,0x38000000,0x38000000,0x840000,0x4780000,0x700001,0x2980000,0xC00000,0xF00000,0x1140000,0x1A40000,0x48C0000,0xA80000,0xF00000,0x38000000,0xF00000,0x1040000,0x3800000,0x45FC0000,0x80000001,0x3800000,0x45FC0000,0x80000001,0x45FC0000,0x80000001,0x80000001,0x3800000,0x45FC0000,0x80000001,0x45FC0000,0x80000001, -0x80000001,0x45FC0000,0x80000001,0x80000001,0x80000001,0x3800000,0x45FC0000,0x80000001,0x45FC0000,0x80000001,0x80000001,0x45FC0000,0x80000001,0x80000001,0x80000001,0x45FC0000,0x80000001,0x80000001,0x80000001,0x80000001,0x3440000,0x3140000,0x3140000,0x1B40000,0x2DFC0000,0x63F40000,0x80000001,0x80000001,0x1600000,0x1E80000,0x7BC80000,0x80000001, -0x15FC0000,0x5C2C91,0xFE300C45,0xB6280879,0x8024087A,0xFE0C0AED,0xBA000020,0x8208009A,0x8A000A69,0x72000271,0x5C000A69,0xBC00212D,0xA2000C99,0x7A000792,0x7A001185,0x680007B9,0x58000DDA,0x5C00212D,0x5600145E,0x4A0016D9,0x3E00212E,0x8C2C8F,0x860015BA,0x6E000D42,0x6E001735,0x62000C25,0x520010F7,0x5200247E,0x500017A7,0x4A00194A,0x3A0022B7,0x1182C8F, -0x44001F8A,0x3E001F75,0x38002726,0x2E002C8F,0xFE28156D,0xFE4C2325,0xFE4C2475,0xFE00082D,0xB6000833,0x880007C9,0x740004FA,0x60000AF6,0xFE08151E,0xDA000C0E,0x6600103A,0x4A00194A,0xC82C8F,0x7C212D,0xFE4408A6,0xB238065A,0x8038065A,0xFE0C0AC9,0xBA000020,0x840C007E,0x8A000A69,0x72000271,0x5C000A69,0xB8212D,0xA2000C99,0x7A000792,0x7A001185,0x680007B9, -0x58000DDA,0x174212D,0x5600145E,0x4A0016D9,0x3E00212E,0xB8212D,0xA2000C99,0x7A000792,0x7A001185,0x680007B9,0x58000DDA,0x174212D,0x5600145E,0x4A0016D9,0x3E00212E,0x174212D,0x5600145E,0x4A0016D9,0x3E00212E,0x3E00212E,0xFE3412F2,0xFE6C1B49,0xFE6C1AEE,0xFE00082D,0xB6000833,0x880007C9,0x740004FA,0x60000AF6,0xFE18134D,0xDA000B4A,0x66001016,0x4A0016D9, -0x108212D,0x240879,0x240879,0x240879,0x240879,0xAC000000,0xAC000000,0xAC000000,0x54000000,0x54000000,0x38000000,0x54000659,0x54000659,0x54000659,0x40000262,0x40000262,0x34000131,0x28000659,0x28000659,0x260003E8,0x1C000659,0x380876,0x380876,0x380876,0x3A0003F3,0x3A0003F3,0x2E000226,0x220006FA,0x220006FA,0x24000491,0x1A0006AE,0x700876, -0x700876,0x1C0005E2,0x16000776,0x12000876,0xFE0402B1,0xF61C0498,0x240879,0xAC0002B9,0x72000275,0x5600028A,0x4C000209,0x380002F2,0xB400047A,0x720003AB,0x34000662,0x24000491,0x500876,0x380659,0x380659,0x380659,0x380659,0xAC000000,0xAC000000,0xAC000000,0x54000000,0x54000000,0x38000000,0x540659,0x540659,0x540659,0x40000262,0x40000262, -0x34000131,0xA40659,0xA40659,0x260003E8,0x1C000659,0x540659,0x540659,0x540659,0x40000262,0x40000262,0x34000131,0xA40659,0xA40659,0x260003E8,0x1C000659,0xA40659,0xA40659,0x260003E8,0x1C000659,0x1C000659,0xFA0802AD,0xFC280374,0x380659,0xAC0002B9,0x72000275,0x5600028A,0x4C000209,0x380002F2,0xC20003FA,0x7C000371,0x740659,0x260003E8, -0x740659,0xBC0A69,0xFE78002D,0xA4740001,0x80700002,0x1140A69,0xBA000020,0x802C0001,0xFF80A69,0x72000271,0x5C000A69,0x1140A69,0xBA000020,0x802C0001,0xFF80A69,0x72000271,0x5C000A69,0xFF80A69,0x72000271,0x5C000A69,0x5C000A69,0x1140A69,0xBA000020,0x802C0001,0xFF80A69,0x72000271,0x5C000A69,0xFF80A69,0x72000271,0x5C000A69,0x5C000A69,0xFF80A69, -0x72000271,0x5C000A69,0x5C000A69,0x5C000A69,0xFE780708,0xC80A69,0xFEAC078A,0xFE1402D4,0xC000029A,0x90000254,0x7A000131,0x720003BA,0xFC5806CD,0xF40002F2,0x820000DA,0x5C000A69,0x18C0A69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table196[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x840000,0x840000,0x840000,0x840000,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x40000001,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x40000001,0x18C0000,0x18C0000,0x40000001,0x40000001,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x40000001,0x18C0000,0x18C0000,0x40000001,0x40000001,0x18C0000, -0x18C0000,0x40000001,0x40000001,0x40000001,0x2980000,0x8C0000,0x840000,0xB40000,0xDC0000,0x1180000,0x1400000,0x1E80000,0xA40000,0xC40000,0x1180000,0x40000001,0x1180000,0x1140001,0x19C0000,0x53FC0000,0x8A000000,0x19C0000,0x53FC0000,0x8A000000,0x53FC0000,0x8A000000,0x8A000000,0x19C0000,0x53FC0000,0x8A000000,0x53FC0000,0x8A000000, -0x8A000000,0x53FC0000,0x8A000000,0x8A000000,0x8A000000,0x19C0000,0x53FC0000,0x8A000000,0x53FC0000,0x8A000000,0x8A000000,0x53FC0000,0x8A000000,0x8A000000,0x8A000000,0x53FC0000,0x8A000000,0x8A000000,0x8A000000,0x8A000000,0x15C0000,0x1280000,0x1280000,0x1D40000,0x3DF80000,0x6FF00000,0x8A000000,0x8A000000,0x3780000,0x9FC0000,0x83F80000,0x8A000000, -0x25FC0000,0x683375,0xFE3C10E1,0xC22C0B59,0x8A2C0B58,0xFE0C0C55,0xCC000002,0x8E080130,0x98000A69,0x7E0001F9,0x66000A69,0xCE0025C5,0xA8000EBB,0x86000984,0x86001301,0x74000831,0x62000E81,0x640025C5,0x5C001758,0x50001969,0x440025C6,0x983373,0x92001984,0x7A001024,0x7A0019E1,0x6E000D81,0x5E00125B,0x5E0029BE,0x5C001B19,0x50001C42,0x4000279F,0x1303373, -0x5000247C,0x440023B5,0x38002CEA,0x32003373,0xFE341A28,0xFE4C299D,0xF8602B08,0xFE0009DD,0xC00008C1,0x92000865,0x7C000545,0x6C000BD8,0xFE081A0A,0xDE000D62,0x7400128E,0x50001C42,0xD83373,0x8825C5,0xFE500BF4,0xBE400884,0x8A400884,0xFE180BD5,0xCC000002,0x8E140104,0x98000A69,0x7E0001F9,0x66000A69,0xC825C5,0xA8000EBB,0x86000984,0x86001301,0x74000831, -0x62000E81,0x19825C5,0x5C001758,0x50001969,0x440025C6,0xC825C5,0xA8000EBB,0x86000984,0x86001301,0x74000831,0x62000E81,0x19825C5,0x5C001758,0x50001969,0x440025C6,0x19825C5,0x5C001758,0x50001969,0x440025C6,0x440025C6,0xFE5016DA,0xFE6C1FA5,0xF8801F85,0xFE0009DD,0xC00008C1,0x92000865,0x7C000545,0x6C000BD8,0xFE24174D,0xE8000C89,0x7400125D,0x50001969, -0x12025C5,0x2C0B58,0x2C0B58,0x2C0B58,0x2C0B58,0xC8000000,0xC8000000,0xC8000000,0x60000001,0x60000001,0x40000001,0x64000882,0x64000882,0x64000882,0x4C000335,0x4C000335,0x3A00019A,0x30000882,0x30000882,0x2C00053D,0x20000882,0x400B58,0x400B58,0x400B58,0x40000556,0x40000556,0x340002EB,0x2800095D,0x2800095D,0x2A00061E,0x1E0008EE,0x800B58, -0x800B58,0x20000809,0x1C000A0B,0x14000B5B,0xFC0C044E,0xF82006C9,0x2C0B58,0xC200039D,0x7C000352,0x6200034D,0x5A0002D0,0x400003E8,0xC200060D,0x900004DE,0x3E000892,0x2A00061E,0x5C0B58,0x400884,0x400884,0x400884,0x400884,0xC8000000,0xC8000000,0xC8000000,0x60000001,0x60000001,0x40000001,0x600882,0x600882,0x600882,0x4C000335,0x4C000335, -0x3A00019A,0xC40882,0xC40882,0x2C00053D,0x20000882,0x600882,0x600882,0x600882,0x4C000335,0x4C000335,0x3A00019A,0xC40882,0xC40882,0x2C00053D,0x20000882,0xC40882,0xC40882,0x2C00053D,0x20000882,0x20000882,0xFE100422,0xFE2C052D,0x400884,0xC200039D,0x7C000352,0x6200034D,0x5A0002D0,0x400003E8,0xD6000568,0x9000048D,0x8C0882,0x2C00053D, -0x8C0882,0xCC0A69,0xFE8C0050,0xAE840000,0x8A840000,0x1300A69,0xCC000002,0x8A3C0000,0x1DF40A69,0x7E0001F9,0x66000A69,0x1300A69,0xCC000002,0x8A3C0000,0x1DF40A69,0x7E0001F9,0x66000A69,0x1DF40A69,0x7E0001F9,0x66000A69,0x66000A69,0x1300A69,0xCC000002,0x8A3C0000,0x1DF40A69,0x7E0001F9,0x66000A69,0x1DF40A69,0x7E0001F9,0x66000A69,0x66000A69,0x1DF40A69, -0x7E0001F9,0x66000A69,0x66000A69,0x66000A69,0xFC900745,0xDC0A69,0xFAC407C1,0xFE300322,0xD6000232,0x9E0001D4,0x840000CD,0x7A000340,0xFE700708,0xFC0402AD,0x8E00007D,0x66000A69,0x1B00A69,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table197[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x180000,0x180000,0x180000,0x180000,0x180000, -0x180000,0x2C0000,0x2C0000,0x2C0000,0x6000001,0x180000,0x180000,0x180000,0x180000,0x180000,0x180000,0x2C0000,0x2C0000,0x2C0000,0x6000001,0x2C0000,0x2C0000,0x2C0000,0x6000001,0x6000001,0x100000,0x100000,0x100000,0x4100000,0x140000,0x140000,0x140000,0x180000,0x4100000,0x140000,0x200000,0x2C0000, -0x200000,0x940000,0x940000,0x940000,0x940000,0xDC0000,0xDC0000,0xDC0000,0x1BC0000,0x1BC0000,0x48000001,0xDC0000,0xDC0000,0xDC0000,0x1BC0000,0x1BC0000,0x48000001,0x1BC0000,0x1BC0000,0x48000001,0x48000001,0xDC0000,0xDC0000,0xDC0000,0x1BC0000,0x1BC0000,0x48000001,0x1BC0000,0x1BC0000,0x48000001,0x48000001,0x1BC0000, -0x1BC0000,0x48000001,0x48000001,0x48000001,0xAC0000,0x69C0000,0x940000,0xC80000,0xF80000,0x1380000,0x1680000,0x9F80000,0xB80000,0xDC0000,0x1380000,0x48000001,0x1380000,0x1240001,0x1B40000,0x5FF80000,0x92000000,0x1B40000,0x5FF80000,0x92000000,0x5FF80000,0x92000000,0x92000000,0x1B40000,0x5FF80000,0x92000000,0x5FF80000,0x92000000, -0x92000000,0x5FF80000,0x92000000,0x92000000,0x92000000,0x1B40000,0x5FF80000,0x92000000,0x5FF80000,0x92000000,0x92000000,0x5FF80000,0x92000000,0x92000000,0x92000000,0x5FF80000,0x92000000,0x92000000,0x92000000,0x92000000,0x1700000,0x5380000,0x5380000,0x3EC0000,0x49FC0000,0x79F00000,0x92000000,0x92000000,0x1900000,0x19FC0000,0x8DCC0000,0x92000000, -0x35FC0000,0x7436D9,0xFE4413A8,0xCC380CE4,0x92380CE4,0xFE180DB5,0xD8080020,0x981001A8,0xA2080A89,0x860401D9,0x6E080A89,0xE60025C5,0xBA000D5B,0x8C0008D8,0x920011B1,0x80000671,0x68000D49,0x700025C5,0x6C001626,0x5C001831,0x4C0025C6,0xA836D7,0xA20019F4,0x800010AC,0x86001A01,0x74000CC5,0x620011B1,0x68002A9E,0x66001AB6,0x56001BC6,0x48002826,0x15836D7, -0x560025F8,0x500024DD,0x44002EAA,0x380036D7,0xFE3C1CD5,0xFA642CB1,0xFE6C2E38,0xFE080A6B,0xD000070E,0x9E000678,0x880003A5,0x760009F9,0xFE181C4A,0xFC000B9A,0x7E00111A,0x56001BC6,0xF036D7,0x9825C5,0xFE680C84,0xC6500884,0x92500884,0xFE300C45,0xD4100002,0x96240104,0xA0100A69,0x860401D5,0x6E100A69,0xE025C5,0xBA000D5B,0x8C0008D8,0x920011B1,0x80000671, -0x68000D49,0x1CC25C5,0x6C001626,0x5C001831,0x4C0025C6,0xE025C5,0xBA000D5B,0x8C0008D8,0x920011B1,0x80000671,0x68000D49,0x1CC25C5,0x6C001626,0x5C001831,0x4C0025C6,0x1CC25C5,0x6C001626,0x5C001831,0x4C0025C6,0x4C0025C6,0xFE581771,0xFC881FBD,0xFE8C1F95,0xFE080A5B,0xD000070E,0x9E000678,0x880003A5,0x760009F9,0xFE3417D5,0xFC000A9A,0x7E0010DA,0x5C001831, -0x14025C5,0x380CE4,0x380CE4,0x380CE4,0x380CE4,0xD8080020,0xD8080020,0xD8080020,0x6A080021,0x6A080021,0x48080021,0x7C000882,0x7C000882,0x7C000882,0x62000271,0x62000271,0x460000EA,0x3C000882,0x3C000882,0x380004A5,0x28000882,0x500CE3,0x500CE3,0x500CE3,0x4C000576,0x4C000576,0x400002B3,0x340009D5,0x340009D5,0x320005D6,0x2800092B,0xA00CE3, -0xA00CE3,0x260008B1,0x20000AE6,0x1A000CE3,0xFE1004E2,0xFE2C0801,0x380CE4,0xE40002E9,0x9A00028A,0x6E00029A,0x6A0001F4,0x4C000332,0xF40005C5,0xB200046A,0x4C00089B,0x320005D6,0x700CE3,0x500884,0x500884,0x500884,0x500884,0xD0100000,0xD0100000,0xD0100000,0x68100001,0x68100001,0x48100001,0x780882,0x780882,0x780882,0x62000271,0x62000271, -0x460000EA,0xF40882,0xF40882,0x380004A5,0x28000882,0x780882,0x780882,0x780882,0x62000271,0x62000271,0x460000EA,0xF40882,0xF40882,0x380004A5,0x28000882,0xF40882,0xF40882,0x380004A5,0x28000882,0x28000882,0xFE200451,0xFA440548,0x500884,0xE40002E9,0x9A00028A,0x6E00029A,0x6A0001F4,0x4C000332,0xF40004E4,0xB20003F1,0xAC0882,0x380004A5, -0xAC0882,0xDC0A69,0xFEA40080,0xB6940000,0x92940000,0x1480A69,0xD8080000,0x924C0000,0x27FC0A69,0x840001A5,0x6E000A69,0x1480A69,0xD8080000,0x924C0000,0x27FC0A69,0x840001A5,0x6E000A69,0x27FC0A69,0x840001A5,0x6E000A69,0x6E000A69,0x1480A69,0xD8080000,0x924C0000,0x27FC0A69,0x840001A5,0x6E000A69,0x27FC0A69,0x840001A5,0x6E000A69,0x6E000A69,0x27FC0A69, -0x840001A5,0x6E000A69,0x6E000A69,0x6E000A69,0xFE940781,0xEC0A69,0xFECC07D9,0xFE400361,0xE00001CA,0xA8000190,0x8C000088,0x820002E4,0xF6880745,0xFE1402E4,0x9600003D,0x6E000A69,0x1D40A69,0x80020,0x80020,0x80020,0x80020,0x80020,0x80020,0x80020,0x80020,0x80020,0x80020,0x16000000,0x16000000,0x16000000,0x16000000,0x16000000, -0x16000000,0xA000001,0xA000001,0xA000001,0x6000001,0xC0020,0xC0020,0xC0020,0xC0020,0xC0020,0xC0020,0x600000D,0x600000D,0x600000D,0x6000005,0x140020,0x140020,0x140020,0x4000012,0x2000022,0x78000000,0x80020,0x80020,0x36000000,0x24000000,0x1C000000,0x1C000000,0x12000000,0x36000009,0x24000004,0xE000001,0x600000D, -0x100020,}; -static const uint32_t g_etc1_to_bc7_m6_table198[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x200000,0x300000,0x300000,0x300000,0x300000,0x300000, -0x300000,0x5C0000,0x5C0000,0x5C0000,0xE000001,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x5C0000,0x5C0000,0x5C0000,0xE000001,0x5C0000,0x5C0000,0x5C0000,0xE000001,0xE000001,0x8200000,0x200000,0x200000,0x240000,0x280000,0x2C0000,0x2C0000,0x340000,0x240000,0x280000,0x400000,0x5C0000, -0x400000,0xA40000,0xA40000,0xA40000,0xA40000,0xF40000,0xF40000,0xF40000,0x1F00000,0x1F00000,0x50000001,0xF40000,0xF40000,0xF40000,0x1F00000,0x1F00000,0x50000001,0x1F00000,0x1F00000,0x50000001,0x50000001,0xF40000,0xF40000,0xF40000,0x1F00000,0x1F00000,0x50000001,0x1F00000,0x1F00000,0x50000001,0x50000001,0x1F00000, -0x1F00000,0x50000001,0x50000001,0x50000001,0x6BC0000,0xEAC0000,0xA40000,0x2DC0000,0x1140000,0x15C0000,0x1900000,0x15F40000,0x2CC0000,0xF40000,0x15C0000,0x50000001,0x15C0000,0x1340001,0x1CC0000,0x6BF80000,0x9A000000,0x1CC0000,0x6BF80000,0x9A000000,0x6BF80000,0x9A000000,0x9A000000,0x1CC0000,0x6BF80000,0x9A000000,0x6BF80000,0x9A000000, -0x9A000000,0x6BF80000,0x9A000000,0x9A000000,0x9A000000,0x1CC0000,0x6BF80000,0x9A000000,0x6BF80000,0x9A000000,0x9A000000,0x6BF80000,0x9A000000,0x9A000000,0x9A000000,0x6BF80000,0x9A000000,0x9A000000,0x9A000000,0x9A000000,0x1840000,0xD480000,0xD480000,0xBFC0000,0x57FC0000,0x83F00000,0x9A000000,0x9A000000,0x3A40000,0x2BFC0000,0x95DC0000,0x9A000000, -0x43FC0000,0x803A9D,0xFE5016F4,0xD6400EC4,0x9A400EC4,0xFE300F95,0xE4100082,0x9E1C0268,0xAA100AE9,0x900C020D,0x76100AE9,0xFE0025C5,0xCC000C2B,0x98000888,0xA2001052,0x860004F1,0x74000C51,0x7C0025C5,0x720014E2,0x66001742,0x540025C6,0xBC3A9B,0xAE001B0C,0x8C00119C,0x92001A61,0x80000C45,0x6E001179,0x74002BBE,0x6C001A56,0x60001B66,0x520028A3,0x17C3A9B, -0x5C0027DC,0x56002631,0x4A00308E,0x3E003A9B,0xFE501FDA,0xFE6C3029,0xFE6C3258,0xFE140B8E,0xE2000578,0xAE0004FD,0x9200026A,0x8000085D,0xFE241F6E,0xFC000ADA,0x86000FF4,0x60001B66,0x10C3A9B,0xA825C5,0xFE740D24,0xCE600884,0x9A600884,0xFE440CB5,0xDC200002,0x9E340104,0xA8200A69,0x8E1401D5,0x76200A69,0xF825C5,0xCC000C2B,0x98000888,0xA2001052,0x860004F1, -0x74000C51,0x1FC25C5,0x720014E2,0x66001742,0x540025C6,0xF825C5,0xCC000C2B,0x98000888,0xA2001052,0x860004F1,0x74000C51,0x1FC25C5,0x720014E2,0x66001742,0x540025C6,0x1FC25C5,0x720014E2,0x66001742,0x540025C6,0x540025C6,0xFC74181E,0xFE8C2035,0xF8A02004,0xFE140B2A,0xE2000578,0xAE0004FD,0x9200026A,0x8000085D,0xFE44186E,0xFC0009DA,0x86000FB4,0x66001742, -0x16425C5,0x400EC4,0x400EC4,0x400EC4,0x400EC4,0xE8100080,0xE8100080,0xE8100080,0x74100081,0x74100081,0x50100081,0x94000882,0x94000882,0x94000882,0x680001BD,0x680001BD,0x4C00006A,0x48000882,0x48000882,0x3E00040D,0x30000882,0x600EC3,0x600EC3,0x600EC3,0x580005D6,0x580005D6,0x460002BB,0x40000A6D,0x40000A6D,0x3A0005BA,0x2E00096B,0xC40EC3, -0xC40EC3,0x32000989,0x26000BEE,0x20000EC3,0xFE2005E1,0xF43809E0,0x400EC4,0xFA00024A,0xB20001E1,0x880001E1,0x8000015D,0x6000028A,0xFE000614,0xC40003F1,0x5C0008A6,0x3A0005BA,0x8C0EC3,0x600884,0x600884,0x600884,0x600884,0xD8200000,0xD8200000,0xD8200000,0x70200001,0x70200001,0x50200001,0x900882,0x900882,0x900882,0x680001BD,0x680001BD, -0x4C00006A,0x1240882,0x1240882,0x3E00040D,0x30000882,0x900882,0x900882,0x900882,0x680001BD,0x680001BD,0x4C00006A,0x1240882,0x1240882,0x3E00040D,0x30000882,0x1240882,0x1240882,0x3E00040D,0x30000882,0x30000882,0xFA340480,0xFE4C0568,0x600884,0xFA00024A,0xB20001E1,0x880001E1,0x8000015D,0x6000028A,0xFE0C04E2,0xD000034D,0xD00882,0x3E00040D, -0xD00882,0xEC0A69,0xFEB000B4,0xBEA40000,0x9AA40000,0x1600A69,0xE0180000,0x9A5C0000,0x33FC0A69,0x90000145,0x76000A69,0x1600A69,0xE0180000,0x9A5C0000,0x33FC0A69,0x90000145,0x76000A69,0x33FC0A69,0x90000145,0x76000A69,0x76000A69,0x1600A69,0xE0180000,0x9A5C0000,0x33FC0A69,0x90000145,0x76000A69,0x33FC0A69,0x90000145,0x76000A69,0x76000A69,0x33FC0A69, -0x90000145,0x76000A69,0x76000A69,0x76000A69,0xFEB40782,0xFC0A69,0xFAE40800,0xFE5803B5,0xF6000184,0xB6000132,0x94000048,0x8A000290,0xFE980745,0xFE2C0340,0xA200001D,0x76000A69,0x1F40A69,0x100080,0x100080,0x100080,0x100080,0x100080,0x100080,0x100080,0x100080,0x100080,0x100080,0x30000000,0x30000000,0x30000000,0x30000000,0x30000000, -0x30000000,0x16000001,0x16000001,0x16000001,0xE000001,0x180080,0x180080,0x180080,0x180080,0x180080,0x180080,0x1200002D,0x1200002D,0x1200002D,0xC000019,0x2C0080,0x2C0080,0x2C0080,0xA00004A,0x6000082,0xF8000000,0x100080,0x100080,0x6E000000,0x4C000000,0x3A000000,0x3A000000,0x26000000,0x60000028,0x42000014,0x1E000004,0x1200002D, -0x200080,}; -static const uint32_t g_etc1_to_bc7_m6_table199[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x300000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000, -0x2440000,0x8C0000,0x8C0000,0x8C0000,0x16000001,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x2440000,0x8C0000,0x8C0000,0x8C0000,0x16000001,0x8C0000,0x8C0000,0x8C0000,0x16000001,0x16000001,0x340000,0x300000,0x300000,0x380000,0x3C0000,0x400000,0x400000,0x500000,0x380000,0x3C0000,0x640000,0x8C0000, -0x640000,0xB40000,0xB40000,0xB40000,0xB40000,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0x58000001,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0x58000001,0xBF80000,0xBF80000,0x58000001,0x58000001,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0x58000001,0xBF80000,0xBF80000,0x58000001,0x58000001,0xBF80000, -0xBF80000,0x58000001,0x58000001,0x58000001,0xD00000,0xC00000,0xB40000,0xF40000,0x32C0000,0x17C0000,0x1B80000,0x1FF80000,0x2E00000,0x10C0000,0x17C0000,0x58000001,0x17C0000,0x1440001,0x1E40000,0x77F80000,0xA2000000,0x1E40000,0x77F80000,0xA2000000,0x77F80000,0xA2000000,0xA2000000,0x1E40000,0x77F80000,0xA2000000,0x77F80000,0xA2000000, -0xA2000000,0x77F80000,0xA2000000,0xA2000000,0xA2000000,0x1E40000,0x77F80000,0xA2000000,0x77F80000,0xA2000000,0xA2000000,0x77F80000,0xA2000000,0xA2000000,0xA2000000,0x77F80000,0xA2000000,0xA2000000,0xA2000000,0xA2000000,0x1980000,0x15C0000,0x15C0000,0x1DFC0000,0x65FC0000,0x8DF00000,0xA2000000,0xA2000000,0x1BC0000,0x3BFC0000,0x9DEC0000,0xA2000000, -0x53FC0000,0x8C3EC1,0xFE5C1AB8,0xDE4C10F9,0xA24C10F8,0xFE3C1205,0xEC180130,0xA8240370,0xB4180B89,0x98100285,0x7E180B89,0xFE0C2621,0xE2000B28,0xA204088E,0xAE000F3A,0x92000391,0x7A000B81,0x880025C5,0x7E0013B2,0x6C00162E,0x5C0025C6,0xCC3EBF,0xBA001C84,0x9800130C,0xA2001ACB,0x8C000C25,0x74001185,0x80002CFE,0x76001A25,0x66001B26,0x5800292F,0x1A03EBF, -0x66002A4B,0x5C0027D5,0x500032AA,0x44003EBF,0xFE582361,0xF8803495,0xFA843661,0xFE180DAD,0xF6000408,0xBC000398,0x9E000164,0x8A0006D0,0xFE342275,0xFE000B6D,0x94000EAC,0x66001B26,0x1243EBF,0xB825C5,0xFE8C0DD4,0xD6700884,0xA2700884,0xFE500D49,0xE4300002,0xA6440104,0xB0300A69,0x962401D5,0x7E300A69,0x11025C5,0xE2000B28,0xA2080884,0xAE000F3A,0x92000391, -0x7A000B81,0xDFC25C5,0x7E0013B2,0x6C00162E,0x5C0025C6,0x11025C5,0xE2000B28,0xA2080884,0xAE000F3A,0x92000391,0x7A000B81,0xDFC25C5,0x7E0013B2,0x6C00162E,0x5C0025C6,0xDFC25C5,0x7E0013B2,0x6C00162E,0x5C0025C6,0x5C0025C6,0xFE78188A,0xFCA82039,0xFEAC2018,0xFE300C02,0xF6000408,0xBC000398,0x9E000164,0x8A0006D0,0xFE5C18B6,0xFE040A46,0x94000E5B,0x6C00162E, -0x18825C5,0x4C10F8,0x4C10F8,0x4C10F8,0x4C10F8,0xF8180120,0xF8180120,0xF8180120,0x7E180121,0x7E180121,0x58180121,0xAC000882,0xAC000882,0xAC000882,0x7A000131,0x7A000131,0x5800001A,0x54000882,0x54000882,0x4A000385,0x38000882,0x7010F8,0x7010F8,0x7010F8,0x62000651,0x62000651,0x52000313,0x4C000B25,0x4C000B25,0x420005AE,0x340009C3,0xE410F8, -0xE410F8,0x38000AA9,0x2C000D26,0x240010FB,0xFE2C0756,0xFA440BCC,0x4C10F8,0xFE08025A,0xC6000151,0x9A000161,0x8C0000CD,0x6A0001E2,0xFE000734,0xDA000398,0x660008AE,0x420005AE,0xA010F8,0x700884,0x700884,0x700884,0x700884,0xE0300000,0xE0300000,0xE0300000,0x78300001,0x78300001,0x58300001,0xA80882,0xA80882,0xA80882,0x7A000131,0x7A000131, -0x5800001A,0x1580882,0x1580882,0x4A000385,0x38000882,0xA80882,0xA80882,0xA80882,0x7A000131,0x7A000131,0x5800001A,0x1580882,0x1580882,0x4A000385,0x38000882,0x1580882,0x1580882,0x4A000385,0x38000882,0x38000882,0xFE3C04A0,0xFA64057D,0x700884,0xFE08024A,0xC6000151,0x9A000161,0x8C0000CD,0x6A0001E2,0xFE140514,0xEC0002D0,0xF00882,0x4A000385, -0xF00882,0xFC0A69,0xFEC400E9,0xC6B40000,0xA2B40000,0x1780A69,0xE8280000,0xA26C0000,0x3FFC0A69,0x9A000104,0x7E000A69,0x1780A69,0xE8280000,0xA26C0000,0x3FFC0A69,0x9A000104,0x7E000A69,0x3FFC0A69,0x9A000104,0x7E000A69,0x7E000A69,0x1780A69,0xE8280000,0xA26C0000,0x3FFC0A69,0x9A000104,0x7E000A69,0x3FFC0A69,0x9A000104,0x7E000A69,0x7E000A69,0x3FFC0A69, -0x9A000104,0x7E000A69,0x7E000A69,0x7E000A69,0xFAC807C1,0x10C0A69,0xFEEC0820,0xFE6C03FA,0xFA040152,0xBE0000F2,0x9E000020,0x9400022D,0xFEAC0784,0xFE4C037A,0xAC000005,0x7E000A69,0xDFC0A69,0x180120,0x180120,0x180120,0x180120,0x180120,0x180120,0x180120,0x180120,0x180120,0x180120,0x48000000,0x48000000,0x48000000,0x48000000,0x48000000, -0x48000000,0x22000000,0x22000000,0x22000000,0x16000001,0x240120,0x240120,0x240120,0x240120,0x240120,0x240120,0x1E00006D,0x1E00006D,0x1E00006D,0x1400003A,0x440120,0x440120,0x440120,0x100000AA,0xA000122,0xFC080020,0x180120,0x180120,0xA8000000,0x74000000,0x58000000,0x58000000,0x3A000000,0x84000059,0x6400002D,0x2C000009,0x1E00006D, -0x300120,}; -static const uint32_t g_etc1_to_bc7_m6_table200[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x400001,0x600000,0x600000,0x600000,0x600000,0x600000, -0x600000,0xC40000,0xC40000,0xC40000,0x20000000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0xC40000,0xC40000,0xC40000,0x20000000,0xC40000,0xC40000,0xC40000,0x20000000,0x20000000,0xA440000,0x400001,0x400001,0x4C0000,0x4500000,0x580000,0x580000,0x26C0000,0x4C0000,0x4500000,0x8C0000,0xC40000, -0x8C0000,0xC40001,0xC40001,0xC40001,0xC40001,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x62000000,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x62000000,0x17FC0000,0x17FC0000,0x62000000,0x62000000,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x62000000,0x17FC0000,0x17FC0000,0x62000000,0x62000000,0x17FC0000, -0x17FC0000,0x62000000,0x62000000,0x62000000,0x4E40000,0xD40000,0xC40001,0x10C0000,0x14C0000,0x1A40000,0x1E40000,0x2BF80000,0xF80000,0x3240000,0x1A40000,0x62000000,0x1A40000,0x1580000,0x3FC0000,0x85F80000,0xAA000001,0x3FC0000,0x85F80000,0xAA000001,0x85F80000,0xAA000001,0xAA000001,0x3FC0000,0x85F80000,0xAA000001,0x85F80000,0xAA000001, -0xAA000001,0x85F80000,0xAA000001,0xAA000001,0xAA000001,0x3FC0000,0x85F80000,0xAA000001,0x85F80000,0xAA000001,0xAA000001,0x85F80000,0xAA000001,0xAA000001,0xAA000001,0x85F80000,0xAA000001,0xAA000001,0xAA000001,0xAA000001,0x1B00000,0xF6C0000,0xF6C0000,0x33FC0000,0x75F80000,0x97F80000,0xAA000001,0xAA000001,0x1D40000,0x4FFC0000,0xA7E00000,0xAA000001, -0x63FC0000,0x9843DA,0xFE741F87,0xEA5813DA,0xAA5813DB,0xFE441546,0xF824023F,0xB43004F3,0xC0200C8A,0xA020035E,0x86200C8A,0xFE1C2759,0xEE000A1B,0xAC0C08D9,0xC0000E29,0x9E000252,0x86000AE2,0x960025C5,0x8A001275,0x7800150D,0x640025C5,0xE043DA,0xCC001E91,0xA200151E,0xA8001BBA,0x92000C52,0x800011F2,0x8C002E81,0x80001A11,0x72001AE5,0x620029D5,0x1CC43DA, -0x6C002D36,0x66002A52,0x56003551,0x4A0043DE,0xFE6427D8,0xFE8C3942,0xFE8C3B6A,0xFE301079,0xFC000338,0xC8000260,0xA6000092,0x96000559,0xFE4426F1,0xFE040DC1,0x9E000D7F,0x72001AE5,0x14043DA,0xCC25C6,0xFE980EA3,0xDE840883,0xAA840883,0xFE680DF2,0xEE400003,0xAE540103,0xB8400A6A,0xA03801D6,0x86400A6A,0x12C25C5,0xEE000A1B,0xAA1C0883,0xC0000E29,0x9E000252, -0x86000AE2,0x1BF825C5,0x8A001275,0x7800150D,0x640025C5,0x12C25C5,0xEE000A1B,0xAA1C0883,0xC0000E29,0x9E000252,0x86000AE2,0x1BF825C5,0x8A001275,0x7800150D,0x640025C5,0x1BF825C5,0x8A001275,0x7800150D,0x640025C5,0x640025C5,0xFE941919,0xF6BC20B2,0xFAC42082,0xFE440D24,0xFC000338,0xC8000260,0xA6000092,0x96000559,0xFE781975,0xFE240B83,0x9E000D1B,0x7800150D, -0x1AC25C5,0x5813DA,0x5813DA,0x5813DA,0x5813DA,0xFE24022E,0xFE24022E,0xFE24022E,0x8A200221,0x8A200221,0x62200221,0xC8000882,0xC8000882,0xC8000882,0x860000B9,0x860000B9,0x62000001,0x60000884,0x60000884,0x500002FD,0x40000884,0x28013DA,0x28013DA,0x28013DA,0x7400074D,0x7400074D,0x580003BD,0x58000C13,0x58000C13,0x4C0005BE,0x40000A3D,0x10813DA, -0x10813DA,0x3E000C45,0x32000EC8,0x2A0013DD,0xFC380952,0xFE4C0E5E,0x5813DA,0xFE100315,0xDE0000D0,0xAE0000CD,0xA2000068,0x78000164,0xFE1408DB,0xFC000344,0x7C0008C2,0x4C0005BE,0xB813DA,0x840882,0x840882,0x840882,0x840882,0xE6440001,0xE6440001,0xE6440001,0x82400001,0x82400001,0x62400001,0xC40882,0xC40882,0xC40882,0x860000B9,0x860000B9, -0x62000001,0x18C0882,0x18C0882,0x500002FD,0x40000884,0xC40882,0xC40882,0xC40882,0x860000B9,0x860000B9,0x62000001,0x18C0882,0x18C0882,0x500002FD,0x40000884,0x18C0882,0x18C0882,0x500002FD,0x40000884,0x40000884,0xFE5804B1,0xF47805B2,0x840882,0xFE240288,0xDE0000D0,0xAE0000CD,0xA2000068,0x78000164,0xFE340515,0xFC000244,0x1180882,0x500002FD, -0x1180882,0x1100A69,0xFEDC013D,0xCEC80001,0xAAC40002,0x1900A69,0xF03C0000,0xAA800001,0x4DFC0A69,0xA40000C1,0x86000A69,0x1900A69,0xF03C0000,0xAA800001,0x4DFC0A69,0xA40000C1,0x86000A69,0x4DFC0A69,0xA40000C1,0x86000A69,0x86000A69,0x1900A69,0xF03C0000,0xAA800001,0x4DFC0A69,0xA40000C1,0x86000A69,0x4DFC0A69,0xA40000C1,0x86000A69,0x86000A69,0x4DFC0A69, -0xA40000C1,0x86000A69,0x86000A69,0x86000A69,0xFED007FD,0x1200A69,0xFD080841,0xFE940451,0xFE100172,0xD00000A9,0xA800000A,0x9C0001E1,0xF6CC07C1,0xFE6403E8,0xB6080000,0x86000A69,0x1FF80A69,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x200221,0x64000000,0x64000000,0x64000000,0x64000000,0x64000000, -0x64000000,0x30000000,0x30000000,0x30000000,0x20000000,0x300221,0x300221,0x300221,0x300221,0x300221,0x300221,0x280000C2,0x280000C2,0x280000C2,0x1E000068,0x5C0221,0x5C0221,0x5C0221,0x16000145,0x10000221,0xFE0C009D,0x200221,0x200221,0xE8000000,0xA0000000,0x7A000000,0x7A000000,0x50000000,0xC40000A9,0x96000055,0x3E000010,0x280000C2, -0x400221,}; -static const uint32_t g_etc1_to_bc7_m6_table201[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x500001,0x780000,0x780000,0x780000,0x780000,0x780000, -0x780000,0xF40000,0xF40000,0xF40000,0x28000000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0xF40000,0xF40000,0xF40000,0x28000000,0xF40000,0xF40000,0xF40000,0x28000000,0x28000000,0x580000,0x500001,0x500001,0x600000,0x4640000,0x700000,0x700000,0x880000,0x600000,0x4640000,0xAC0000,0xF40000, -0xAC0000,0xD40001,0xD40001,0xD40001,0xD40001,0x33C0000,0x33C0000,0x33C0000,0x23FC0000,0x23FC0000,0x6A000000,0x33C0000,0x33C0000,0x33C0000,0x23FC0000,0x23FC0000,0x6A000000,0x23FC0000,0x23FC0000,0x6A000000,0x6A000000,0x33C0000,0x33C0000,0x33C0000,0x23FC0000,0x23FC0000,0x6A000000,0x23FC0000,0x23FC0000,0x6A000000,0x6A000000,0x23FC0000, -0x23FC0000,0x6A000000,0x6A000000,0x6A000000,0xF80000,0xE40000,0xD40001,0x1240000,0x1680000,0x1C80000,0x7F80000,0x37F40000,0x10C0000,0x33C0000,0x1C80000,0x6A000000,0x1C80000,0x1680000,0x1BFC0000,0x91F80000,0xB2000001,0x1BFC0000,0x91F80000,0xB2000001,0x91F80000,0xB2000001,0xB2000001,0x1BFC0000,0x91F80000,0xB2000001,0x91F80000,0xB2000001, -0xB2000001,0x91F80000,0xB2000001,0xB2000001,0xB2000001,0x1BFC0000,0x91F80000,0xB2000001,0x91F80000,0xB2000001,0xB2000001,0x91F80000,0xB2000001,0xB2000001,0xB2000001,0x91F80000,0xB2000001,0xB2000001,0xB2000001,0xB2000001,0x1C40000,0x1800000,0x1800000,0x47FC0000,0x81FC0000,0xA1FC0000,0xB2000001,0xB2000001,0x3E80000,0x61FC0000,0xAFF00000,0xB2000001, -0x73FC0000,0xA448CA,0xFE802443,0xF26416C6,0xB26416C7,0xFE5018EA,0xFE300393,0xBA3C069F,0xCA280DB2,0xA824045E,0x8E280DB2,0xFE30290A,0xFA00097B,0xB6140951,0xCC000D49,0xA800016E,0x8E000A8D,0xA20025C6,0x9000116D,0x7E001419,0x6C0025C5,0xF448CA,0xE20020BF,0xAE00178E,0xB4001CE2,0xA2000CB3,0x86001292,0x98003001,0x8A001A29,0x7A001AD5,0x68002A81,0x1F048CA, -0x7800301E,0x6C002C86,0x5C0037E9,0x500048CE,0xFE782C61,0xFE8C3E62,0xF8A040BB,0xFE401395,0xFE0403A8,0xD6000182,0xB0000031,0xA0000422,0xFE542B17,0xFE1810AE,0xA6000CB9,0x7A001AD5,0x15C48CA,0xDC25C6,0xFEB00F63,0xE6940883,0xB2940883,0xFE800E9A,0xF6500003,0xB6640103,0xC0500A6A,0xA84801D6,0x8E500A6A,0x14425C5,0xFA00097B,0xB22C0883,0xCC000D49,0xA800016E, -0x8E000A8D,0x27F825C5,0x9000116D,0x7E001419,0x6C0025C5,0x14425C5,0xFA00097B,0xB22C0883,0xCC000D49,0xA800016E,0x8E000A8D,0x27F825C5,0x9000116D,0x7E001419,0x6C0025C5,0x27F825C5,0x9000116D,0x7E001419,0x6C0025C5,0x6C0025C5,0xFEA019C8,0xFECC20B2,0xFECC20B2,0xFE5C0DFE,0xFE100393,0xD6000182,0xB0000031,0xA0000422,0xFE8819FE,0xFE400C4D,0xAC000C4E,0x7E001419, -0x1D025C5,0x6416C6,0x6416C6,0x6416C6,0x6416C6,0xFE300392,0xFE300392,0xFE300392,0x94280349,0x94280349,0x6A280349,0xE0000882,0xE0000882,0xE0000882,0x98000061,0x98000061,0x6C040018,0x6C000884,0x6C000884,0x5C00027D,0x48000884,0x9016C5,0x9016C5,0x9016C5,0x80000875,0x80000875,0x62000491,0x62000CE4,0x62000CE4,0x540005F4,0x46000AA5,0x12416C5, -0x12416C5,0x44000E01,0x3E001058,0x300016C5,0xFE3C0B76,0xF458115D,0x6416C6,0xFE18042D,0xFC000074,0xC0000074,0xAE000022,0x840000FA,0xFE200AF6,0xFE00038A,0x860008CA,0x540005F4,0xD016C5,0x940882,0x940882,0x940882,0x940882,0xEE540001,0xEE540001,0xEE540001,0x8A500001,0x8A500001,0x6A500001,0xDC0882,0xDC0882,0xDC0882,0x98000061,0x98000061, -0x6A100001,0x1BC0882,0x1BC0882,0x5C00027D,0x48000884,0xDC0882,0xDC0882,0xDC0882,0x98000061,0x98000061,0x6A100001,0x1BC0882,0x1BC0882,0x5C00027D,0x48000884,0x1BC0882,0x1BC0882,0x5C00027D,0x48000884,0x48000884,0xFA6C04E2,0xFC8805B2,0x940882,0xFE3402B1,0xFC000074,0xC0000074,0xAE000022,0x840000FA,0xFA48054A,0xFC140265,0x1380882,0x5C00027D, -0x1380882,0x1200A69,0xFEE80195,0xD6D80001,0xB2D40002,0x1A80A69,0xF84C0000,0xB2900001,0x59FC0A69,0xAC000082,0x8E000A69,0x1A80A69,0xF84C0000,0xB2900001,0x59FC0A69,0xAC000082,0x8E000A69,0x59FC0A69,0xAC000082,0x8E000A69,0x8E000A69,0x1A80A69,0xF84C0000,0xB2900001,0x59FC0A69,0xAC000082,0x8E000A69,0x59FC0A69,0xAC000082,0x8E000A69,0x8E000A69,0x59FC0A69, -0xAC000082,0x8E000A69,0x8E000A69,0x8E000A69,0xFAF00802,0x1300A69,0xFF0C087D,0xFEAC04B1,0xFE3C01C4,0xDA00006A,0xB2040001,0xA800019A,0xFEDC07C1,0xFE880424,0xBE180000,0x8E000A69,0x2DFC0A69,0x280349,0x280349,0x280349,0x280349,0x280349,0x280349,0x280349,0x280349,0x280349,0x280349,0x7C000000,0x7C000000,0x7C000000,0x7C000000,0x7C000000, -0x7C000000,0x3C000000,0x3C000000,0x3C000000,0x28000000,0x3C0349,0x3C0349,0x3C0349,0x3C0349,0x3C0349,0x3C0349,0x2E000132,0x2E000132,0x2E000132,0x2200009D,0x740349,0x740349,0x740349,0x1C0001F9,0x14000349,0xF4180154,0x280349,0x280349,0xFE04000D,0xC8000000,0x98000000,0x98000000,0x64000000,0xF6000105,0xB4000089,0x46000019,0x2E000132, -0x540349,}; -static const uint32_t g_etc1_to_bc7_m6_table202[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x600001,0x900000,0x900000,0x900000,0x900000,0x900000, -0x900000,0x1240000,0x1240000,0x1240000,0x30000000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x1240000,0x1240000,0x1240000,0x30000000,0x1240000,0x1240000,0x1240000,0x30000000,0x30000000,0x680000,0x600001,0x600001,0x2700000,0x4780000,0x840000,0x840000,0xA40000,0x2700000,0x4780000,0xD00000,0x1240000, -0xD00000,0xE40001,0xE40001,0xE40001,0xE40001,0x1540000,0x1540000,0x1540000,0x2FFC0000,0x2FFC0000,0x72000000,0x1540000,0x1540000,0x1540000,0x2FFC0000,0x2FFC0000,0x72000000,0x2FFC0000,0x2FFC0000,0x72000000,0x72000000,0x1540000,0x1540000,0x1540000,0x2FFC0000,0x2FFC0000,0x72000000,0x2FFC0000,0x2FFC0000,0x72000000,0x72000000,0x2FFC0000, -0x2FFC0000,0x72000000,0x72000000,0x72000000,0x10C0000,0x2F40000,0xE40001,0x1380000,0x3800000,0x1E80000,0x15F80000,0x41F80000,0x1200000,0x1540000,0x1E80000,0x72000000,0x1E80000,0x1780000,0x35FC0000,0x9DF40000,0xBA000001,0x35FC0000,0x9DF40000,0xBA000001,0x9DF40000,0xBA000001,0xBA000001,0x35FC0000,0x9DF40000,0xBA000001,0x9DF40000,0xBA000001, -0xBA000001,0x9DF40000,0xBA000001,0xBA000001,0xBA000001,0x35FC0000,0x9DF40000,0xBA000001,0x9DF40000,0xBA000001,0xBA000001,0x9DF40000,0xBA000001,0xBA000001,0xBA000001,0x9DF40000,0xBA000001,0xBA000001,0xBA000001,0xBA000001,0x1D80000,0x1900000,0x1900000,0x5BFC0000,0x8FFC0000,0xABFC0000,0xBA000001,0xBA000001,0x5FC0000,0x71FC0000,0xB9C40000,0xBA000001, -0x81FC0000,0xB04E1A,0xFE8C2977,0xFC6C1A06,0xBA6C1A07,0xFE5C1D1E,0xFE3C0597,0xC24408A6,0xD4300F1A,0xB22C059E,0x96300F1A,0xFE3C2B5E,0xFE080993,0xC01C0A01,0xD8000C89,0xB40000C6,0x96000A6A,0xAE0025C6,0x9C001065,0x8A001331,0x740025C5,0x1044E1A,0xE800231B,0xB4001A6E,0xC0001E4A,0xA8000D5F,0x8C001392,0xA200315F,0x92001A55,0x82001ADB,0x6E002B4D,0x7FC4E1A, -0x7E003356,0x72002F0A,0x66003AC6,0x56004E1E,0xFE803152,0xFAA443AA,0xFEAC45DF,0xFE441768,0xFE100503,0xE20000CE,0xBC00000B,0xAA00032A,0xFE5C2FFA,0xFE241464,0xB6000BBD,0x82001ADB,0x1744E1A,0xEC25C6,0xFEC41026,0xEEA40883,0xBAA40883,0xFE980F62,0xFE600003,0xBE740103,0xC8600A6A,0xB05801D6,0x96600A6A,0x15C25C5,0xFE080983,0xBA3C0883,0xD8000C89,0xB40000C6, -0x96000A6A,0x33F825C5,0x9C001065,0x8A001331,0x740025C5,0x15C25C5,0xFE080983,0xBA3C0883,0xD8000C89,0xB40000C6,0x96000A6A,0x33F825C5,0x9C001065,0x8A001331,0x740025C5,0x33F825C5,0x9C001065,0x8A001331,0x740025C5,0x740025C5,0xFEB41A2D,0xF8E0212E,0xFAE42103,0xFE780F0E,0xFE24046B,0xE20000CE,0xBC00000B,0xAA00032A,0xFE981A99,0xFE480D53,0xB6000B44,0x8A001331, -0x1F025C5,0x6C1A06,0x6C1A06,0x6C1A06,0x6C1A06,0xFE3C0566,0xFE3C0566,0xFE3C0566,0x9E3004B1,0x9E3004B1,0x723004B1,0xF8000882,0xF8000882,0xF8000882,0xA8000025,0xA8000025,0x76080051,0x78000884,0x78000884,0x66000220,0x50000884,0xA41A05,0xA41A05,0xA41A05,0x8C0009DD,0x8C0009DD,0x680005C9,0x6E000DF4,0x6E000DF4,0x5E000632,0x4C000B25,0x14C1A05, -0x14C1A05,0x50001001,0x44001218,0x36001A05,0xFE4C0DF1,0xFA641455,0x6C1A06,0xFE2C05C9,0xFE040078,0xD200003A,0xC0000004,0x960000A0,0xFC300D65,0xFE0004CA,0x960008DB,0x5E000632,0xE81A05,0xA40882,0xA40882,0xA40882,0xA40882,0xF6640001,0xF6640001,0xF6640001,0x92600001,0x92600001,0x72600001,0xF40882,0xF40882,0xF40882,0xA8000025,0xA8000025, -0x72200001,0x1F00882,0x1F00882,0x66000220,0x50000884,0xF40882,0xF40882,0xF40882,0xA8000025,0xA8000025,0x72200001,0x1F00882,0x1F00882,0x66000220,0x50000884,0x1F00882,0x1F00882,0x66000220,0x50000884,0x50000884,0xFE740502,0xF49805E9,0xA40882,0xFE4402E4,0xFE040074,0xD200003A,0xC0000004,0x960000A0,0xFE50057A,0xFE24028A,0x15C0882,0x66000220, -0x15C0882,0x1300A69,0xFF0001ED,0xDEE80001,0xBAE40002,0x1C00A69,0xFE600002,0xBAA00001,0x65F80A69,0xB6000059,0x96000A69,0x1C00A69,0xFE600002,0xBAA00001,0x65F80A69,0xB6000059,0x96000A69,0x65F80A69,0xB6000059,0x96000A69,0x96000A69,0x1C00A69,0xFE600002,0xBAA00001,0x65F80A69,0xB6000059,0x96000A69,0x65F80A69,0xB6000059,0x96000A69,0x96000A69,0x65F80A69, -0xB6000059,0x96000A69,0x96000A69,0x96000A69,0xFEF80832,0x1440A69,0xFD280882,0xFEC004EA,0xFE500220,0xE6000050,0xBA140001,0xB2000151,0xFEF00800,0xFEA00488,0xC6280000,0x96000A69,0x3DF80A69,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x3004B1,0x94000000,0x94000000,0x94000000,0x94000000,0x94000000, -0x94000000,0x48000000,0x48000000,0x48000000,0x30000000,0x4804B1,0x4804B1,0x4804B1,0x4804B1,0x4804B1,0x4804B1,0x3A0001BA,0x3A0001BA,0x3A0001BA,0x2E0000E5,0x8C04B1,0x8C04B1,0x8C04B1,0x200002E4,0x180004B1,0xF8200244,0x3004B1,0x3004B1,0xFC0C0064,0xEE000000,0xB6000000,0xB6000000,0x78000000,0xF60001A5,0xD60000C2,0x56000022,0x3A0001BA, -0x6404B1,}; -static const uint32_t g_etc1_to_bc7_m6_table203[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0x700001,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000, -0xA80000,0x1580000,0x1580000,0x1580000,0x38000000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0xA80000,0x1580000,0x1580000,0x1580000,0x38000000,0x1580000,0x1580000,0x1580000,0x38000000,0x38000000,0x4780000,0x700001,0x700001,0x840000,0x48C0000,0x2980000,0x2980000,0xC00000,0x840000,0x48C0000,0xF00000,0x1580000, -0xF00000,0xF40001,0xF40001,0xF40001,0xF40001,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x3BFC0000,0x7A000000,0x7A000000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x3BFC0000,0x7A000000,0x7A000000,0x3BFC0000, -0x3BFC0000,0x7A000000,0x7A000000,0x7A000000,0x51C0000,0xB040000,0xF40001,0x34C0000,0x19C0000,0x7FC0000,0x21FC0000,0x4BFC0000,0x1340000,0x16C0000,0x7FC0000,0x7A000000,0x7FC0000,0x1880000,0x4DFC0000,0xA7FC0000,0xC2000001,0x4DFC0000,0xA7FC0000,0xC2000001,0xA7FC0000,0xC2000001,0xC2000001,0x4DFC0000,0xA7FC0000,0xC2000001,0xA7FC0000,0xC2000001, -0xC2000001,0xA7FC0000,0xC2000001,0xC2000001,0xC2000001,0x4DFC0000,0xA7FC0000,0xC2000001,0xA7FC0000,0xC2000001,0xC2000001,0xA7FC0000,0xC2000001,0xC2000001,0xC2000001,0xA7FC0000,0xC2000001,0xC2000001,0xC2000001,0xC2000001,0x1EC0000,0x9A00000,0x9A00000,0x6FFC0000,0x9DF80000,0xB5FC0000,0xC2000001,0xC2000001,0x23FC0000,0x83FC0000,0xC1D40000,0xC2000001, -0x91FC0000,0xBC53CA,0xFE982F23,0xFE781DB3,0xC2781D9B,0xFE6821E2,0xFE480853,0xCC4C0AE2,0xDE3810C2,0xBA34072F,0x9E3810C2,0xFE442E39,0xFE140A9F,0xCA240AE9,0xE2000BDE,0xBE000056,0x9E040A76,0xBA0025C6,0xA6000F93,0x9000124D,0x7C0025C5,0x11853CA,0xF400260B,0xC0001DBE,0xCC001FF2,0xB4000E7F,0x980014B2,0xA8003317,0x9E001AAD,0x8C001AFD,0x7A002C15,0x11F853CA, -0x840036F6,0x780031DE,0x6C003DB6,0x5C0053CE,0xFE8C36AE,0xFEAC491A,0xFEAC4BCF,0xFE541B8E,0xFE24073F,0xEE000058,0xC6080023,0xB6000243,0xFE703553,0xFE301879,0xBE000B25,0x8C001AFD,0x19053CA,0xFC25C6,0xFED010EE,0xF6B40883,0xC2B40883,0xFEA41022,0xFE780023,0xC6840103,0xD0700A6A,0xB86801D6,0x9E700A6A,0x17425C5,0xFE200A0B,0xC24C0883,0xE2000BDE,0xBE000056, -0x9E0C0A6A,0x3FF825C5,0xA6000F93,0x9000124D,0x7C0025C5,0x17425C5,0xFE200A0B,0xC24C0883,0xE2000BDE,0xBE000056,0x9E0C0A6A,0x3FF825C5,0xA6000F93,0x9000124D,0x7C0025C5,0x3FF825C5,0xA6000F93,0x9000124D,0x7C0025C5,0x7C0025C5,0xFED01ACD,0xFEEC2132,0xFEEC213B,0xFE940FE5,0xFE38056B,0xEE000058,0xC410000B,0xB6000243,0xFEB41B45,0xFE680E81,0xBE000A95,0x9000124D, -0xBFC25C5,0x781D9A,0x781D9A,0x781D9A,0x781D9A,0xFE440795,0xFE440795,0xFE440795,0xA8380659,0xA8380659,0x7A380659,0xFE0C08AE,0xFE0C08AE,0xFE0C08AE,0xB4000005,0xB4000005,0x7E0C00AD,0x84000884,0x84000884,0x6C0001C4,0x58000884,0x2B01D9A,0x2B01D9A,0x2B01D9A,0x98000B85,0x98000B85,0x74000731,0x74000F18,0x74000F18,0x6800068C,0x52000BBD,0x1681D9A, -0x1681D9A,0x56001235,0x4A001408,0x3A001D9D,0xFE5810F1,0xFE6C17AD,0x781D9A,0xFE3407B5,0xFE140116,0xE200000D,0xD0000002,0xA0000059,0xFE341005,0xFE100696,0xA60008E8,0x6800068C,0xFC1D9A,0xB40882,0xB40882,0xB40882,0xB40882,0xFE740001,0xFE740001,0xFE740001,0x9A700001,0x9A700001,0x7A700001,0x10C0882,0x10C0882,0x10C0882,0xB4000005,0xB4000005, -0x7A300001,0xBF80882,0xBF80882,0x6C0001C4,0x58000884,0x10C0882,0x10C0882,0x10C0882,0xB4000005,0xB4000005,0x7A300001,0xBF80882,0xBF80882,0x6C0001C4,0x58000884,0xBF80882,0xBF80882,0x6C0001C4,0x58000884,0x58000884,0xFE900515,0xFCA805E9,0xB40882,0xFE5C02FD,0xFE1C009D,0xE200000D,0xCC080000,0xA0000059,0xFA70057D,0xFA4002D2,0x17C0882,0x6C0001C4, -0x17C0882,0x1400A69,0xFF0C025D,0xE6F80001,0xC2F40002,0x1D80A69,0xFE7C0014,0xC2B00001,0x71F80A69,0xBE000032,0x9E000A69,0x1D80A69,0xFE7C0014,0xC2B00001,0x71F80A69,0xBE000032,0x9E000A69,0x71F80A69,0xBE000032,0x9E000A69,0x9E000A69,0x1D80A69,0xFE7C0014,0xC2B00001,0x71F80A69,0xBE000032,0x9E000A69,0x71F80A69,0xBE000032,0x9E000A69,0x9E000A69,0x71F80A69, -0xBE000032,0x9E000A69,0x9E000A69,0x9E000A69,0xFF140845,0x1540A69,0xF53808C5,0xFED80550,0xFE68028A,0xF2000028,0xC2240001,0xBA000115,0xF7080841,0xFEC004E2,0xCE380000,0x9E000A69,0x4BFC0A69,0x380659,0x380659,0x380659,0x380659,0x380659,0x380659,0x380659,0x380659,0x380659,0x380659,0xAC000000,0xAC000000,0xAC000000,0xAC000000,0xAC000000, -0xAC000000,0x54000000,0x54000000,0x54000000,0x38000000,0x540659,0x540659,0x540659,0x540659,0x540659,0x540659,0x40000262,0x40000262,0x40000262,0x34000131,0xA40659,0xA40659,0xA40659,0x260003E8,0x1C000659,0xFC280374,0x380659,0x380659,0xFE100104,0xFA040014,0xD4000000,0xD4000000,0x8C000000,0xFA0802AD,0xF4000112,0x66000028,0x40000262, -0x740659,}; -static const uint32_t g_etc1_to_bc7_m6_table204[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0x840000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000, -0xC40000,0x18C0000,0x18C0000,0x18C0000,0x40000001,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0xC40000,0x18C0000,0x18C0000,0x18C0000,0x40000001,0x18C0000,0x18C0000,0x18C0000,0x40000001,0x40000001,0x8C0000,0x840000,0x840000,0x2980000,0xA40000,0xB40000,0xB40000,0xDC0000,0x2980000,0xA40000,0x1180000,0x18C0000, -0x1180000,0x1080000,0x1080000,0x1080000,0x1080000,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x82000001,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x82000001,0x49F80000,0x49F80000,0x82000001,0x82000001,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x82000001,0x49F80000,0x49F80000,0x82000001,0x82000001,0x49F80000, -0x49F80000,0x82000001,0x82000001,0x82000001,0x1340000,0x5180000,0x1080000,0x1680000,0x1BC0000,0x19FC0000,0x31FC0000,0x59F40000,0x14C0000,0x1880000,0x19FC0000,0x82000001,0x19FC0000,0x1980001,0x69FC0000,0xB5FC0000,0xCC000000,0x69FC0000,0xB5FC0000,0xCC000000,0xB5FC0000,0xCC000000,0xCC000000,0x69FC0000,0xB5FC0000,0xCC000000,0xB5FC0000,0xCC000000, -0xCC000000,0xB5FC0000,0xCC000000,0xCC000000,0xCC000000,0x69FC0000,0xB5FC0000,0xCC000000,0xB5FC0000,0xCC000000,0xCC000000,0xB5FC0000,0xCC000000,0xCC000000,0xCC000000,0xB5FC0000,0xCC000000,0xCC000000,0xCC000000,0xCC000000,0xBFC0000,0x3B40000,0x3B40000,0x85FC0000,0xABFC0000,0xC1F40000,0xCC000000,0xCC000000,0x45FC0000,0x95FC0000,0xCBC80000,0xCC000000, -0xA1FC0000,0xC85AA5,0xFEA4360C,0xFE88228D,0xCC842208,0xFE8027E1,0xFE540C44,0xD8580DC5,0xE84412ED,0xC43C0938,0xA84012ED,0xFE503266,0xFE200CC4,0xD6240C2A,0xF4000B45,0xCA000015,0xAA080AB6,0xC60025C5,0xB2000E98,0x9C001162,0x860025C6,0x12C5AA3,0xFA002A18,0xCC00220B,0xE20021ED,0xBA00100A,0xA2001647,0xBA00351E,0xA8001B25,0x92001B46,0x80002CFE,0x1BF85AA3, -0x90003B5B,0x84003543,0x7200414F,0x64005AA3,0xFEA03D3B,0xF8C05071,0xFAC452C9,0xFE6C216E,0xFE280A9E,0xFC00000E,0xD00C0071,0xC0000184,0xFE783BC2,0xFE441DA3,0xCE000A96,0x92001B46,0x1AC5AA3,0x10C25C5,0xFEE811FD,0xFEC80885,0xCCC40884,0xFEBC1115,0xFE880086,0xD0980104,0xDA840A69,0xC07801D5,0xA8840A69,0x38C25C5,0xFE380AD4,0xCC5C0884,0xF4000B45,0xCA000015, -0xA8200A69,0x4BFC25C5,0xB2000E98,0x9C001162,0x860025C6,0x38C25C5,0xFE380AD4,0xCC5C0884,0xF4000B45,0xCA000015,0xA8200A69,0x4BFC25C5,0xB2000E98,0x9C001162,0x860025C6,0x4BFC25C5,0xB2000E98,0x9C001162,0x860025C6,0x860025C6,0xFEE41BB9,0xF90021AD,0xFD082185,0xFE981149,0xFE5C06AE,0xFC00000E,0xCE24000C,0xC0000184,0xFEC41BE9,0xFE840F78,0xCE0009ED,0x9C001162, -0x1DF825C5,0x842208,0x842208,0x842208,0x842208,0xFE500A9D,0xFE500A9D,0xFE500A9D,0xB4400884,0xB4400884,0x82400885,0xFE180974,0xFE180974,0xFE180974,0xC4000001,0xC4000001,0x88140141,0x92000882,0x92000882,0x7800015A,0x62000882,0xC42208,0xC42208,0xC42208,0xA2000D86,0xA2000D86,0x8000092D,0x80001086,0x80001086,0x6E00071A,0x5E000C63,0x18C2208, -0x18C2208,0x5C001505,0x5000166E,0x4000220B,0xFE6814BA,0xF67C1C38,0x842208,0xFE440A76,0xFE1C025D,0xF8000000,0xDE04001E,0xAE000022,0xFE3C13E0,0xFE180932,0xB6000903,0x6E00071A,0x1182208,0xC40884,0xC40884,0xC40884,0xC40884,0xFC88000D,0xFC88000D,0xFC88000D,0xA2840001,0xA2840001,0x82840001,0x3240882,0x3240882,0x3240882,0xC0080001,0xC0080001, -0x82440001,0x17FC0882,0x17FC0882,0x7800015A,0x62000882,0x3240882,0x3240882,0x3240882,0xC0080001,0xC0080001,0x82440001,0x17FC0882,0x17FC0882,0x7800015A,0x62000882,0x17FC0882,0x17FC0882,0x7800015A,0x62000882,0x62000882,0xFEA0054A,0xF6BC0620,0xC40884,0xFE780349,0xFC3C00CA,0xF8000000,0xD21C0001,0xAE000022,0xF88805B2,0xFC5802F9,0x1A40882,0x7800015A, -0x1A40882,0x1500A69,0xFF2402D5,0xF1080000,0xCD080000,0x1F40A69,0xFEA0004A,0xCCC00000,0x7FF80A69,0xCA000014,0xA8000A69,0x1F40A69,0xFEA0004A,0xCCC00000,0x7FF80A69,0xCA000014,0xA8000A69,0x7FF80A69,0xCA000014,0xA8000A69,0xA8000A69,0x1F40A69,0xFEA0004A,0xCCC00000,0x7FF80A69,0xCA000014,0xA8000A69,0x7FF80A69,0xCA000014,0xA8000A69,0xA8000A69,0x7FF80A69, -0xCA000014,0xA8000A69,0xA8000A69,0xA8000A69,0xFB2C0884,0x1680A69,0xFF4C08C5,0xFEEC05A5,0xFE900304,0xFC00000D,0xCC340000,0xC20000DD,0xFF180845,0xFED80550,0xD64C0001,0xA8000A69,0x5DF80A69,0x400884,0x400884,0x400884,0x400884,0x400884,0x400884,0x400884,0x400884,0x400884,0x400884,0xC8000000,0xC8000000,0xC8000000,0xC8000000,0xC8000000, -0xC8000000,0x60000001,0x60000001,0x60000001,0x40000001,0x600882,0x600882,0x600882,0x600882,0x600882,0x600882,0x4C000335,0x4C000335,0x4C000335,0x3A00019A,0xC40882,0xC40882,0xC40882,0x2C00053D,0x20000882,0xFE2C052D,0x400884,0x400884,0xFE200200,0xFE0C0075,0xF6000000,0xF6000000,0xA2000000,0xFE100422,0xFE0001C4,0x7600003A,0x4C000335, -0x8C0882,}; -static const uint32_t g_etc1_to_bc7_m6_table205[] = { -0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x2000000,0x2000000,0x2000000,0x2000000,0x2000000,0x2000000,0x2000000,0x2000000,0x2000000,0x2000000,0x0, -0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x8000000,0x8000000,0x8000000,0x2000000,0x0,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000, -0xDC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x48000001,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0xDC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x48000001,0x1BC0000,0x1BC0000,0x1BC0000,0x48000001,0x48000001,0x69C0000,0x940000,0x940000,0xAC0000,0xB80000,0xC80000,0xC80000,0xF80000,0xAC0000,0xB80000,0x1380000,0x1BC0000, -0x1380000,0x1180000,0x1180000,0x1180000,0x1180000,0x1A00000,0x1A00000,0x1A00000,0x55F80000,0x55F80000,0x8A000001,0x1A00000,0x1A00000,0x1A00000,0x55F80000,0x55F80000,0x8A000001,0x55F80000,0x55F80000,0x8A000001,0x8A000001,0x1A00000,0x1A00000,0x1A00000,0x55F80000,0x55F80000,0x8A000001,0x55F80000,0x55F80000,0x8A000001,0x8A000001,0x55F80000, -0x55F80000,0x8A000001,0x8A000001,0x8A000001,0x3440000,0xD280000,0x1180000,0x17C0000,0x3D40000,0x27FC0000,0x3FF80000,0x63F80000,0x1600000,0x1A00000,0x27FC0000,0x8A000001,0x27FC0000,0x1A80001,0x81FC0000,0xC1FC0000,0xD4000000,0x81FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xD4000000,0xD4000000,0x81FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xD4000000, -0xD4000000,0xC1FC0000,0xD4000000,0xD4000000,0xD4000000,0x81FC0000,0xC1FC0000,0xD4000000,0xC1FC0000,0xD4000000,0xD4000000,0xC1FC0000,0xD4000000,0xD4000000,0xD4000000,0xC1FC0000,0xD4000000,0xD4000000,0xD4000000,0xD4000000,0x33FC0000,0xBC40000,0xBC40000,0x99FC0000,0xB9FC0000,0xCBF40000,0xD4000000,0xD4000000,0x63FC0000,0xA7FC0000,0xD3D80000,0xD4000000, -0xB1FC0000,0xD4604E,0xFEB03C09,0xFE9426F6,0xD49025C5,0xFE8C2D3E,0xFE641023,0xDE641046,0xF24C14D2,0xCE440B09,0xB04C14D2,0xFE68364F,0xFE2C0F61,0xE02C0D53,0xFC040B0A,0xD2040012,0xB20C0B07,0xD20025C6,0xB8000DD5,0xA60010C2,0x8E0025C7,0x33C604A,0xFE042E6B,0xD40425C6,0xE800235E,0xC6001139,0xA80017A6,0xC0003691,0xAE001B58,0x9E001B37,0x86002D9F,0x23FC604A, -0x96003EDE,0x8A0037DE,0x7E004416,0x6A00604A,0xFEA0430C,0xFECC55D2,0xFECC5866,0xFE702686,0xFE3C0E17,0xFE08006C,0xDA1400D9,0xCA0000F6,0xFE904155,0xFE50227D,0xD60009ED,0x9E001B37,0x1C8604A,0x11C25C5,0xFEF412E5,0xFED808A8,0xD4D40884,0xFED011E1,0xFEA0010E,0xD8A80104,0xE2940A69,0xC88801D5,0xB0940A69,0x3A425C5,0xFE580BA3,0xD46C0884,0xFC040B09,0xD2040011, -0xB0300A69,0x57FC25C5,0xB8000DD4,0xA60010C1,0x8E0025C6,0x3A425C5,0xFE580BA3,0xD46C0884,0xFC040B09,0xD2040011,0xB0300A69,0x57FC25C5,0xB8000DD4,0xA60010C1,0x8E0025C6,0x57FC25C5,0xB8000DD4,0xA60010C1,0x8E0025C6,0x8E0025C6,0xFEF81C2C,0xFF0C21C5,0xFF0C21E5,0xFEC01224,0xFE6807CD,0xFE18003B,0xD634000C,0xCA0000F5,0xFEDC1C41,0xFE9810B6,0xD600095D,0xA60010C1, -0x2BFC25C5,0x9025C5,0x9025C5,0x9025C5,0x9025C5,0xFE5C0D6A,0xFE5C0D6A,0xFE5C0D6A,0xBC4C0A6A,0xBC4C0A6A,0x8A4C0A6A,0xFE240A95,0xFE240A95,0xFE240A95,0xD204000E,0xD204000E,0x901801D6,0x9E000883,0x9E000883,0x84000113,0x6A000883,0xD425C5,0xD425C5,0xD425C5,0xAE000F45,0xAE000F45,0x86000AD6,0x8C00118B,0x8C00118B,0x7A000763,0x62000CC3,0x1B025C5, -0x1B025C5,0x66001782,0x56001853,0x460025C6,0xFE681813,0xFC881FBD,0x9025C5,0xFE4C0D02,0xFE2C03E3,0xFE08001B,0xEC08004D,0xBC00000B,0xFE5016E0,0xFE300BA2,0xC60008FD,0x7A000763,0x13025C5,0xD40884,0xD40884,0xD40884,0xD40884,0xFE98001D,0xFE98001D,0xFE98001D,0xAA940001,0xAA940001,0x8A940001,0x33C0882,0x33C0882,0x33C0882,0xC8180001,0xC8180001, -0x8A540001,0x23FC0882,0x23FC0882,0x84000112,0x6A000882,0x33C0882,0x33C0882,0x33C0882,0xC8180001,0xC8180001,0x8A540001,0x23FC0882,0x23FC0882,0x84000112,0x6A000882,0x23FC0882,0x23FC0882,0x84000112,0x6A000882,0x6A000882,0xFAB4057D,0xFECC0620,0xD40884,0xFE880374,0xFE5400F2,0xFE100001,0xDA2C0001,0xBC00000A,0xFE9405BA,0xFE680322,0x1C80882,0x84000112, -0x1C80882,0x1600A69,0xFF3C0355,0xF9180000,0xD5180000,0xFFC0A69,0xFEB80092,0xD4D00000,0x8BF80A69,0xD2000008,0xB0000A69,0xFFC0A69,0xFEB80092,0xD4D00000,0x8BF80A69,0xD2000008,0xB0000A69,0x8BF80A69,0xD2000008,0xB0000A69,0xB0000A69,0xFFC0A69,0xFEB80092,0xD4D00000,0x8BF80A69,0xD2000008,0xB0000A69,0x8BF80A69,0xD2000008,0xB0000A69,0xB0000A69,0x8BF80A69, -0xD2000008,0xB0000A69,0xB0000A69,0xB0000A69,0xFF3408B4,0x1780A69,0xF75C0908,0xFF040611,0xFEBC037A,0xFE180032,0xD4440000,0xCE0000B4,0xFF2C088A,0xFEF005C4,0xDE5C0001,0xB0000A69,0x6BFC0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0x4C0A69,0xDC040001,0xDC040001,0xDC040001,0xDC040001,0xDC040001, -0xDC040001,0x6C040001,0x6C040001,0x6C040001,0x48000002,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x580003D4,0x580003D4,0x580003D4,0x400001E1,0xDC0A69,0xDC0A69,0xDC0A69,0x32000652,0x24000A69,0xF63C06CD,0x4C0A69,0x4C0A69,0xFE200321,0xFE140115,0xFE080012,0xFE080012,0xB2040001,0xFE1005A5,0xFE0002C5,0x86000035,0x580003D4, -0x9C0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table206[] = { -0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x2180000,0x300000, -0x300000,0x300000,0x300000,0x8000000,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x100001,0x140000,0x140000,0x140000,0x2180000,0x240000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xA40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000, -0xF40000,0x1F00000,0x1F00000,0x1F00000,0x50000001,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0xF40000,0x1F00000,0x1F00000,0x1F00000,0x50000001,0x1F00000,0x1F00000,0x1F00000,0x50000001,0x50000001,0xEAC0000,0xA40000,0xA40000,0x6BC0000,0x2CC0000,0x2DC0000,0x2DC0000,0x1140000,0x6BC0000,0x2CC0000,0x15C0000,0x1F00000, -0x15C0000,0x1280000,0x1280000,0x1280000,0x1280000,0x1B80000,0x1B80000,0x1B80000,0x61F80000,0x61F80000,0x92000001,0x1B80000,0x1B80000,0x1B80000,0x61F80000,0x61F80000,0x92000001,0x61F80000,0x61F80000,0x92000001,0x92000001,0x1B80000,0x1B80000,0x1B80000,0x61F80000,0x61F80000,0x92000001,0x61F80000,0x61F80000,0x92000001,0x92000001,0x61F80000, -0x61F80000,0x92000001,0x92000001,0x92000001,0x1580000,0x13C0000,0x1280000,0x3900000,0x1F00000,0x37FC0000,0x4BFC0000,0x6DFC0000,0x1740000,0x1B80000,0x37FC0000,0x92000001,0x37FC0000,0x1B80001,0x99FC0000,0xCDFC0000,0xDC000000,0x99FC0000,0xCDFC0000,0xDC000000,0xCDFC0000,0xDC000000,0xDC000000,0x99FC0000,0xCDFC0000,0xDC000000,0xCDFC0000,0xDC000000, -0xDC000000,0xCDFC0000,0xDC000000,0xDC000000,0xDC000000,0x99FC0000,0xCDFC0000,0xDC000000,0xCDFC0000,0xDC000000,0xDC000000,0xCDFC0000,0xDC000000,0xDC000000,0xDC000000,0xCDFC0000,0xDC000000,0xDC000000,0xDC000000,0xDC000000,0x5BFC0000,0x1D80000,0x1D80000,0xADFC0000,0xC7F80000,0xD5F40000,0xDC000000,0xDC000000,0x81FC0000,0xB7FC0000,0xDBE80000,0xDC000000, -0xBFFC0000,0xE4604E,0xFEC43D66,0xFEA027D6,0xDCA025C5,0xFE982F3A,0xFE7811D1,0xE6741046,0xFA5C14D2,0xD6540B09,0xB85C14D2,0xFE7437E7,0xFE40114C,0xE83C0D53,0xFE140B5E,0xDA140012,0xBA1C0B07,0xDA1025C6,0xC4000D55,0xAC001046,0x961025C7,0x154604A,0xFE082F3D,0xDC1425C6,0xF4002116,0xD2000F41,0xB4001656,0xD20034A5,0xBA001888,0xA800188D,0x92002BD7,0x2FFC604A, -0xA0003D3D,0x960035A6,0x8400424A,0x7200604A,0xFEBC4462,0xFECC56D2,0xF8E05915,0xFE8028C4,0xFE501077,0xFE240126,0xE22400D9,0xD40800DB,0xFE9842FE,0xFE5C2552,0xE4000921,0xA800188D,0x1E8604A,0x12C25C5,0xFF0C13F5,0xFEEC090D,0xDCE40884,0xFEE812E1,0xFEB801D6,0xE0B80104,0xEAA40A69,0xD09801D5,0xB8A40A69,0x3BC25C5,0xFE700C8B,0xDC7C0884,0xFE140B5D,0xDA140011, -0xB8400A69,0x63FC25C5,0xC4000D04,0xAC000FF5,0x960025C6,0x3BC25C5,0xFE700C8B,0xDC7C0884,0xFE140B5D,0xDA140011,0xB8400A69,0x63FC25C5,0xC4000D04,0xAC000FF5,0x960025C6,0x63FC25C5,0xC4000D04,0xAC000FF5,0x960025C6,0x960025C6,0xFF001CF1,0xFB242229,0xFD282208,0xFED41351,0xFE90091D,0xFE2C00B1,0xDE44000C,0xD4000099,0xFEF81D1D,0xFEC01208,0xE4000908,0xAC000FF5, -0x3BFC25C5,0xA025C5,0xA025C5,0xA025C5,0xA025C5,0xFE680E06,0xFE680E06,0xFE680E06,0xC45C0A6A,0xC45C0A6A,0x925C0A6A,0xFE300B25,0xFE300B25,0xFE300B25,0xDA14000E,0xDA14000E,0x982801D6,0xA6100883,0xA6100883,0x8A0C0103,0x72100883,0xEC25C5,0xEC25C5,0xEC25C5,0xC0000E11,0xC0000E11,0x92000A76,0x98001033,0x98001033,0x800005C3,0x6E000B7B,0x1E425C5, -0x1E425C5,0x6C001642,0x5C001743,0x4E0025C6,0xFE841892,0xFE8C201D,0xA025C5,0xFE5C0DCE,0xFE40049B,0xFE1C004D,0xF418004D,0xC410000B,0xFE6417AD,0xFE3C0C7D,0xD6000894,0x800005C3,0x15425C5,0xE40884,0xE40884,0xE40884,0xE40884,0xFEB0003D,0xFEB0003D,0xFEB0003D,0xB2A40001,0xB2A40001,0x92A40001,0x1540882,0x1540882,0x1540882,0xD0280001,0xD0280001, -0x92640001,0x2FFC0882,0x2FFC0882,0x8A0000CA,0x72000882,0x1540882,0x1540882,0x1540882,0xD0280001,0xD0280001,0x92640001,0x2FFC0882,0x2FFC0882,0x8A0000CA,0x72000882,0x2FFC0882,0x2FFC0882,0x8A0000CA,0x72000882,0x72000882,0xFEBC05A5,0xF6DC0659,0xE40884,0xFE9803A9,0xFC6C0139,0xFE2C0008,0xE23C0001,0xC8000000,0xFAAC05E9,0xFE740371,0x1E80882,0x8A0000CA, -0x1E80882,0x1700A69,0xFF5003D0,0xFF280001,0xDD280000,0x29FC0A69,0xFED80104,0xDCE00000,0x97F80A69,0xDC000000,0xB8000A69,0x29FC0A69,0xFED80104,0xDCE00000,0x97F80A69,0xDC000000,0xB8000A69,0x97F80A69,0xDC000000,0xB8000A69,0xB8000A69,0x29FC0A69,0xFED80104,0xDCE00000,0x97F80A69,0xDC000000,0xB8000A69,0x97F80A69,0xDC000000,0xB8000A69,0xB8000A69,0x97F80A69, -0xDC000000,0xB8000A69,0xB8000A69,0xB8000A69,0xFF5008C9,0x1880A69,0xFF6C0908,0xFF200671,0xFED003FA,0xFE480074,0xDC540000,0xD4000080,0xF74C08C5,0xFF080601,0xE66C0001,0xB8000A69,0x7BFC0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0x5C0A69,0xE4140001,0xE4140001,0xE4140001,0xE4140001,0xE4140001, -0xE4140001,0x74140001,0x74140001,0x74140001,0x50100002,0x840A69,0x840A69,0x840A69,0x840A69,0x840A69,0x840A69,0x680002EA,0x680002EA,0x680002EA,0x4C000119,0x10C0A69,0x10C0A69,0x10C0A69,0x3E0005AA,0x2C000A69,0xFE4C06CD,0x5C0A69,0x5C0A69,0xFE3C0349,0xFE28013D,0xFE180022,0xFE180022,0xBA140001,0xFE2005E4,0xFE1402E4,0x9A000001,0x680002EA, -0xBC0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table207[] = { -0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x2300000,0x640000, -0x640000,0x640000,0x640000,0x10000000,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x200001,0x240000,0x240000,0x240000,0x2300000,0x480000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0xB40000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000, -0x10C0000,0xBF80000,0xBF80000,0xBF80000,0x58000001,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0xBF80000,0xBF80000,0xBF80000,0x58000001,0xBF80000,0xBF80000,0xBF80000,0x58000001,0x58000001,0xC00000,0xB40000,0xB40000,0xD00000,0x2E00000,0xF40000,0xF40000,0x32C0000,0xD00000,0x2E00000,0x17C0000,0xBF80000, -0x17C0000,0x1380000,0x1380000,0x1380000,0x1380000,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x9A000001,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x9A000001,0x6DF80000,0x6DF80000,0x9A000001,0x9A000001,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x9A000001,0x6DF80000,0x6DF80000,0x9A000001,0x9A000001,0x6DF80000, -0x6DF80000,0x9A000001,0x9A000001,0x9A000001,0x7680000,0x14C0000,0x1380000,0x1A80000,0xDFC0000,0x45FC0000,0x59FC0000,0x79F80000,0x1880000,0x1D00000,0x45FC0000,0x9A000001,0x45FC0000,0x1C80001,0xB1FC0000,0xD9FC0000,0xE4000000,0xB1FC0000,0xD9FC0000,0xE4000000,0xD9FC0000,0xE4000000,0xE4000000,0xB1FC0000,0xD9FC0000,0xE4000000,0xD9FC0000,0xE4000000, -0xE4000000,0xD9FC0000,0xE4000000,0xE4000000,0xE4000000,0xB1FC0000,0xD9FC0000,0xE4000000,0xD9FC0000,0xE4000000,0xE4000000,0xD9FC0000,0xE4000000,0xE4000000,0xE4000000,0xD9FC0000,0xE4000000,0xE4000000,0xE4000000,0xE4000000,0x81FC0000,0x1E80000,0x1E80000,0xC1FC0000,0xD5F80000,0xDFF80000,0xE4000000,0xE4000000,0x9FFC0000,0xC9FC0000,0xE3F80000,0xE4000000, -0xCFFC0000,0xF4604E,0xFED03EDE,0xFEB828D6,0xE4B025C5,0xFEB03142,0xFE8813AF,0xEE841046,0xFE6C14EA,0xDE640B09,0xC06C14D2,0xFE8C397F,0xFE58135C,0xF04C0D53,0xFE2C0C2E,0xE2240012,0xC22C0B07,0xE22025C6,0xCE080D51,0xB4101046,0x9E2025C7,0x16C604A,0xFE2C30C9,0xE42425C6,0xFA001F7A,0xDE000DA9,0xBC00157A,0xE20032CB,0xC60015F8,0xAE00161D,0x98002A5B,0x3BFC604A, -0xAC003B6D,0x9C003362,0x8A0040B6,0x7A00604A,0xFED045E7,0xFEEC56D6,0xFEEC5931,0xFE982B12,0xFE6812F6,0xFE38023E,0xEA3400D9,0xDC1800DB,0xFEB4443B,0xFE802784,0xEE0008BF,0xAE00161D,0x7FC604A,0x13C25C5,0xFF1814ED,0xFEFC0994,0xE4F40884,0xFEF413E5,0xFECC02E0,0xE8C80104,0xF2B40A69,0xD8A801D5,0xC0B40A69,0x1D425C5,0xFE940D8B,0xE48C0884,0xFE380C01,0xE2240011, -0xC0500A69,0x6FFC25C5,0xD0000C54,0xB2000F59,0x9E0025C6,0x1D425C5,0xFE940D8B,0xE48C0884,0xFE380C01,0xE2240011,0xC0500A69,0x6FFC25C5,0xD0000C54,0xB2000F59,0x9E0025C6,0x6FFC25C5,0xD0000C54,0xB2000F59,0x9E0025C6,0x9E0025C6,0xFF141D5E,0xFF2C2251,0xFF2C2274,0xFEEC1476,0xFEA40A79,0xFE480164,0xE654000C,0xE0000062,0xFF081D9A,0xFEC812EA,0xEE0008BB,0xB2000F59, -0x49FC25C5,0xB025C5,0xB025C5,0xB025C5,0xB025C5,0xFE800E8E,0xFE800E8E,0xFE800E8E,0xCC6C0A6A,0xCC6C0A6A,0x9A6C0A6A,0xFE440BA3,0xFE440BA3,0xFE440BA3,0xE224000E,0xE224000E,0xA03801D6,0xAE200883,0xAE200883,0x921C0103,0x7A200883,0x10425C5,0x10425C5,0x10425C5,0xD2000D0D,0xD2000D0D,0x9A080A6A,0xA8000EC8,0xA8000EC8,0x8C000443,0x74000A83,0x7FC25C5, -0x7FC25C5,0x7800151A,0x66001632,0x560025C6,0xFE901926,0xFCA82036,0xB025C5,0xFE700EB6,0xFE540563,0xFE34009A,0xFC28004D,0xCC20000B,0xFE78181A,0xFE500D1D,0xE4040883,0x8C000443,0x17425C5,0xF40884,0xF40884,0xF40884,0xF40884,0xFEBC0061,0xFEBC0061,0xFEBC0061,0xBAB40001,0xBAB40001,0x9AB40001,0x16C0882,0x16C0882,0x16C0882,0xD8380001,0xD8380001, -0x9A740001,0x3BFC0882,0x3BFC0882,0x96000092,0x7A000882,0x16C0882,0x16C0882,0x16C0882,0xD8380001,0xD8380001,0x9A740001,0x3BFC0882,0x3BFC0882,0x96000092,0x7A000882,0x3BFC0882,0x3BFC0882,0x96000092,0x7A000882,0x7A000882,0xFED805B2,0xFEEC0659,0xF40884,0xFEB403F5,0xFE80016D,0xFE480020,0xEA4C0001,0xD0100000,0xFEB40611,0xFE98039D,0x7FC0882,0x96000092, -0x7FC0882,0x1800A69,0xFF5C0454,0xFF380024,0xE5380000,0x41FC0A69,0xFEF00184,0xE4F00000,0xA1FC0A69,0xE40C0000,0xC0000A69,0x41FC0A69,0xFEF00184,0xE4F00000,0xA1FC0A69,0xE40C0000,0xC0000A69,0xA1FC0A69,0xE40C0000,0xC0000A69,0xC0000A69,0x41FC0A69,0xFEF00184,0xE4F00000,0xA1FC0A69,0xE40C0000,0xC0000A69,0xA1FC0A69,0xE40C0000,0xC0000A69,0xC0000A69,0xA1FC0A69, -0xE40C0000,0xC0000A69,0xC0000A69,0xC0000A69,0xFD680908,0x19C0A69,0xF77C094D,0xFF4006CD,0xFEE80484,0xFE7000E8,0xE4640000,0xE0000061,0xFF5C08C5,0xFF200681,0xEE7C0001,0xC0000A69,0x89FC0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0x6C0A69,0xEC240001,0xEC240001,0xEC240001,0xEC240001,0xEC240001, -0xEC240001,0x7C240001,0x7C240001,0x7C240001,0x58200002,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x74000232,0x74000232,0x74000232,0x58000091,0x13C0A69,0x13C0A69,0x13C0A69,0x44000502,0x34000A69,0xF65C070A,0x6C0A69,0x6C0A69,0xFE4C0372,0xFE3C016D,0xFE2C003D,0xFE2C003D,0xC2240001,0xFE3C05E9,0xFA2C0322,0xA2100001,0x74000232, -0xE00A69,}; -static const uint32_t g_etc1_to_bc7_m6_table208[] = { -0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x4C0000,0x980000, -0x980000,0x980000,0x980000,0x18000001,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x340000,0x380000,0x380000,0x380000,0x4C0000,0x6C0000,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0xC40001,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000, -0x3240000,0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x3240000,0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0x17FC0000,0x17FC0000,0x17FC0000,0x62000000,0x62000000,0xD40000,0xC40001,0xC40001,0x4E40000,0xF80000,0x10C0000,0x10C0000,0x14C0000,0x4E40000,0xF80000,0x1A40000,0x17FC0000, -0x1A40000,0x1480001,0x1480001,0x1480001,0x1480001,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0xA4000000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0xA4000000,0x79FC0000,0x79FC0000,0xA4000000,0xA4000000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0xA4000000,0x79FC0000,0x79FC0000,0xA4000000,0xA4000000,0x79FC0000, -0x79FC0000,0xA4000000,0xA4000000,0xA4000000,0x1800000,0x1600000,0x1480001,0x1C00000,0x23FC0000,0x57FC0000,0x69F80000,0x85F80000,0x39C0000,0x3E80000,0x57FC0000,0xA4000000,0x57FC0000,0x1DC0000,0xCDFC0000,0xE7F80000,0xEC000001,0xCDFC0000,0xE7F80000,0xEC000001,0xE7F80000,0xEC000001,0xEC000001,0xCDFC0000,0xE7F80000,0xEC000001,0xE7F80000,0xEC000001, -0xEC000001,0xE7F80000,0xEC000001,0xEC000001,0xEC000001,0xCDFC0000,0xE7F80000,0xEC000001,0xE7F80000,0xEC000001,0xEC000001,0xE7F80000,0xEC000001,0xEC000001,0xEC000001,0xE7F80000,0xEC000001,0xEC000001,0xEC000001,0xEC000001,0xADFC0000,0x1FC0000,0x1FC0000,0xD7FC0000,0xE3FC0000,0xEBF00000,0xEC000001,0xEC000001,0xC1FC0000,0xDBFC0000,0xEDEC0000,0xEC000001, -0xDFFC0000,0x108604A,0xFEE840B6,0xFECC2A5B,0xECC025C7,0xFEC43362,0xFEA0161D,0xF6941046,0xFE84157A,0xE8780B07,0xC87C14D2,0xFEA43B6D,0xFE7015F8,0xFA600D51,0xFE400DA9,0xEC380012,0xCC400B09,0xEC3425C6,0xD81C0D53,0xBC201046,0xA63425C5,0x188604A,0xFE3832CB,0xEC3825C6,0xFE081F7A,0xE8000C2E,0xC60014EA,0xE80030C9,0xD200135C,0xBA0013AF,0xA20028D6,0x49F8604A, -0xB800397F,0xA6003142,0x96003EDE,0x8200604E,0xFEE44782,0xF90057DA,0xFB0459DA,0xFEAC2DF6,0xFE7C160E,0xFE4803FF,0xF24400DB,0xE42800D9,0xFED0463D,0xFE902A56,0xF81008BB,0xBA0013AF,0x19FC604A,0x15025C6,0xFF301632,0xFF140A83,0xED080883,0xFF0C151A,0xFEE40443,0xF0D80103,0xFAC40A6A,0xE2BC01D6,0xC8C40A6A,0x1F025C5,0xFEAC0EC8,0xECA00883,0xFE580D0D,0xEC38000E, -0xC8600A6A,0x7DF825C5,0xDC000BA3,0xBE000E8E,0xA60025C5,0x1F025C5,0xFEAC0EC8,0xECA00883,0xFE580D0D,0xEC38000E,0xC8600A6A,0x7DF825C5,0xDC000BA3,0xBE000E8E,0xA60025C5,0x7DF825C5,0xDC000BA3,0xBE000E8E,0xA60025C5,0xA60025C5,0xFF341E13,0xFD4822AA,0xFF4C228E,0xFF0015CE,0xFEBC0C34,0xFE70027E,0xEE64000B,0xE800004D,0xFF181E3E,0xFEDC1481,0xFC00088B,0xBE000E8E, -0x5BFC25C5,0xC025C6,0xC025C6,0xC025C6,0xC025C6,0xFE980F59,0xFE980F59,0xFE980F59,0xD67C0A69,0xD67C0A69,0xA47C0A69,0xFE5C0C54,0xFE5C0C54,0xFE5C0C54,0xEA340011,0xEA340011,0xAA4C01D5,0xB6340884,0xB6340884,0x9A2C0104,0x82340884,0x12025C5,0x12025C5,0x12025C5,0xE2000C01,0xE2000C01,0xA4180A69,0xB4000D8B,0xB4000D8B,0x980002E0,0x80000994,0x15F825C5, -0x15F825C5,0x840013E5,0x720014ED,0x600025C5,0xFEA019B4,0xF6BC20B2,0xC025C6,0xFE880F9E,0xFE6C0669,0xFE480126,0xFE3C0062,0xD430000C,0xFE9018F2,0xFE680E59,0xEC180882,0x980002E0,0x19C25C5,0x1080882,0x1080882,0x1080882,0x1080882,0xFED00092,0xFED00092,0xFED00092,0xC4C40001,0xC4C40001,0xA4C40001,0x1880882,0x1880882,0x1880882,0xE04C0001,0xE04C0001, -0xA4840001,0x49F80882,0x49F80882,0xA0000061,0x82000884,0x1880882,0x1880882,0x1880882,0xE04C0001,0xE04C0001,0xA4840001,0x49F80882,0x49F80882,0xA0000061,0x82000884,0x49F80882,0x49F80882,0xA0000061,0x82000884,0x82000884,0xFAEC05E9,0xF9000692,0x1080882,0xFEC4042A,0xFE9801A9,0xFE64003D,0xF65C0000,0xD8240001,0xFED00628,0xFEA403E8,0x19FC0882,0xA0000061, -0x19FC0882,0x1940A69,0xFF740502,0xFF4C0091,0xED480002,0x5BFC0A69,0xFF140232,0xED040001,0xAFFC0A69,0xEC240001,0xC8000A69,0x5BFC0A69,0xFF140232,0xED040001,0xAFFC0A69,0xEC240001,0xC8000A69,0xAFFC0A69,0xEC240001,0xC8000A69,0xC8000A69,0x5BFC0A69,0xFF140232,0xED040001,0xAFFC0A69,0xEC240001,0xC8000A69,0xAFFC0A69,0xEC240001,0xC8000A69,0xC8000A69,0xAFFC0A69, -0xEC240001,0xC8000A69,0xC8000A69,0xC8000A69,0xFF780910,0x1AC0A69,0xFF8C0951,0xFF580749,0xFF10052A,0xFE98018D,0xEC780001,0xE800003D,0xFF70090A,0xFF4006E5,0xF88C0000,0xC8000A69,0x9BFC0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0x7C0A69,0xF6340000,0xF6340000,0xF6340000,0xF6340000,0xF6340000, -0xF6340000,0x86340000,0x86340000,0x86340000,0x62340000,0xB80A69,0xB80A69,0xB80A69,0xB80A69,0xB80A69,0xB80A69,0x86000184,0x86000184,0x86000184,0x62000024,0x1740A69,0x1740A69,0x1740A69,0x50000454,0x3E000A69,0xFE6C0710,0x7C0A69,0x7C0A69,0xFE5803B5,0xFE5001A5,0xFE3C0061,0xFE3C0061,0xCC340000,0xFA500622,0xFE3C0355,0xAC200000,0x86000184, -0x1080A69,}; -static const uint32_t g_etc1_to_bc7_m6_table209[] = { -0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0xCC0000, -0xCC0000,0xCC0000,0xCC0000,0x20000001,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x480000,0x480000,0x480000,0x640000,0x900000,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0xD40001,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000, -0x33C0000,0x23FC0000,0x23FC0000,0x23FC0000,0x6A000000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x33C0000,0x23FC0000,0x23FC0000,0x23FC0000,0x6A000000,0x23FC0000,0x23FC0000,0x23FC0000,0x6A000000,0x6A000000,0xE40000,0xD40001,0xD40001,0xF80000,0x10C0000,0x1240000,0x1240000,0x1680000,0xF80000,0x10C0000,0x1C80000,0x23FC0000, -0x1C80000,0x1580001,0x1580001,0x1580001,0x1580001,0x7FC0000,0x7FC0000,0x7FC0000,0x85FC0000,0x85FC0000,0xAC000000,0x7FC0000,0x7FC0000,0x7FC0000,0x85FC0000,0x85FC0000,0xAC000000,0x85FC0000,0x85FC0000,0xAC000000,0xAC000000,0x7FC0000,0x7FC0000,0x7FC0000,0x85FC0000,0x85FC0000,0xAC000000,0x85FC0000,0x85FC0000,0xAC000000,0xAC000000,0x85FC0000, -0x85FC0000,0xAC000000,0xAC000000,0xAC000000,0x5900000,0x1700000,0x1580001,0x3D40000,0x37FC0000,0x65FC0000,0x75FC0000,0x91F40000,0x3B00000,0x7FC0000,0x65FC0000,0xAC000000,0x65FC0000,0x1EC0000,0xE5FC0000,0xF3F80000,0xF4000001,0xE5FC0000,0xF3F80000,0xF4000001,0xF3F80000,0xF4000001,0xF4000001,0xE5FC0000,0xF3F80000,0xF4000001,0xF3F80000,0xF4000001, -0xF4000001,0xF3F80000,0xF4000001,0xF4000001,0xF4000001,0xE5FC0000,0xF3F80000,0xF4000001,0xF3F80000,0xF4000001,0xF4000001,0xF3F80000,0xF4000001,0xF4000001,0xF4000001,0xF3F80000,0xF4000001,0xF4000001,0xF4000001,0xF4000001,0xD5FC0000,0x77FC0000,0x77FC0000,0xEBFC0000,0xF1FC0000,0xF5F00000,0xF4000001,0xF4000001,0xDFFC0000,0xEDFC0000,0xF5FC0000,0xF4000001, -0xEFFC0000,0x118604A,0xFEF4424A,0xFED82BD7,0xF4D025C7,0xFED035A6,0xFEAC188D,0xFEA41046,0xFE941656,0xF0880B07,0xD08C14D2,0xFEBC3D3D,0xFE881888,0xFE740D55,0xFE580F41,0xF4480012,0xD4500B09,0xF44425C6,0xE02C0D53,0xC4301046,0xAE4425C5,0x1A0604A,0xFE5834A5,0xF44825C6,0xFE142116,0xF4000B5E,0xD00414D2,0xFA002F3D,0xDE00114C,0xC20011D1,0xAE0027D6,0x55F8604A, -0xC40037E7,0xB2002F3A,0x9C003D66,0x8A00604E,0xFEF44912,0xFF0C57EA,0xFF0C5A1A,0xFEC4307A,0xFE901902,0xFE5C05EA,0xFA5400DB,0xEC3800D9,0xFEDC478F,0xFEB02D65,0xFE2008C1,0xC20011D1,0x27FC604A,0x16025C6,0xFF441743,0xFF200B7B,0xF5180883,0xFF241642,0xFEF005C3,0xF8E80103,0xFED80A76,0xEACC01D6,0xD0D40A6A,0xDFC25C5,0xFECC1033,0xF4B00883,0xFE7C0E11,0xF448000E, -0xD0700A6A,0x89F825C5,0xE6000B25,0xCA000E06,0xAE0025C5,0xDFC25C5,0xFECC1033,0xF4B00883,0xFE7C0E11,0xF448000E,0xD0700A6A,0x89F825C5,0xE6000B25,0xCA000E06,0xAE0025C5,0x89F825C5,0xE6000B25,0xCA000E06,0xAE0025C5,0xAE0025C5,0xFF3C1EC2,0xFF4C22FE,0xF75C2313,0xFF1416C1,0xFEDC0DD4,0xFE8403CB,0xF674000B,0xF010004D,0xFF341F0E,0xFF0415B5,0xFE1408A6,0xCA000E06, -0x69FC25C5,0xD025C6,0xD025C6,0xD025C6,0xD025C6,0xFEA40FF5,0xFEA40FF5,0xFEA40FF5,0xDE8C0A69,0xDE8C0A69,0xAC8C0A69,0xFE740D04,0xFE740D04,0xFE740D04,0xF2440011,0xF2440011,0xB25C01D5,0xBE440884,0xBE440884,0xA23C0104,0x8A440884,0x13825C5,0x13825C5,0x13825C5,0xF4000B5D,0xF4000B5D,0xAC280A69,0xC6000C8B,0xC6000C8B,0xA20001D6,0x8800090D,0x21F825C5, -0x21F825C5,0x8A0012E1,0x780013F5,0x680025C5,0xFEBC1A59,0xFECC20B2,0xD025C6,0xFE981069,0xFE800755,0xFE5C01A9,0xFE540099,0xDC40000C,0xFEA01966,0xFE740F25,0xF4280882,0xA20001D6,0x1BC25C5,0x1180882,0x1180882,0x1180882,0x1180882,0xFEE800CA,0xFEE800CA,0xFEE800CA,0xCCD40001,0xCCD40001,0xACD40001,0x1A00882,0x1A00882,0x1A00882,0xE85C0001,0xE85C0001, -0xAC940001,0x55F80882,0x55F80882,0xA600003D,0x8A000884,0x1A00882,0x1A00882,0x1A00882,0xE85C0001,0xE85C0001,0xAC940001,0x55F80882,0x55F80882,0xA600003D,0x8A000884,0x55F80882,0x55F80882,0xA600003D,0x8A000884,0x8A000884,0xFEF40611,0xFF0C069A,0x1180882,0xFEDC0451,0xFEAC01ED,0xFE7C0064,0xFE6C0000,0xE0340001,0xF8EC0659,0xFEC40422,0x27FC0882,0xA600003D, -0x27FC0882,0x1A40A69,0xFF8005AA,0xFF640119,0xF5580002,0x75FC0A69,0xFF2C02EA,0xF5140001,0xBBFC0A69,0xF4340001,0xD0000A69,0x75FC0A69,0xFF2C02EA,0xF5140001,0xBBFC0A69,0xF4340001,0xD0000A69,0xBBFC0A69,0xF4340001,0xD0000A69,0xD0000A69,0x75FC0A69,0xFF2C02EA,0xF5140001,0xBBFC0A69,0xF4340001,0xD0000A69,0xBBFC0A69,0xF4340001,0xD0000A69,0xD0000A69,0xBBFC0A69, -0xF4340001,0xD0000A69,0xD0000A69,0xD0000A69,0xFD90094D,0x1C00A69,0xF9A00992,0xFF6C0794,0xFF3C05C4,0xFEC80235,0xF4880001,0xF2000022,0xF98C094D,0xFF58076D,0xFEA00004,0xD0000A69,0xA9FC0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0x8C0A69,0xFE440000,0xFE440000,0xFE440000,0xFE440000,0xFE440000, -0xFE440000,0x8E440000,0x8E440000,0x8E440000,0x6A440000,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0x92000104,0x92000104,0x92000104,0x6A000001,0x1A40A69,0x1A40A69,0x1A40A69,0x560003D0,0x46000A69,0xF8800745,0x8C0A69,0x8C0A69,0xFE6803E8,0xFE6401E1,0xFE540080,0xFE540080,0xD4440000,0xFE580652,0xFE50037A,0xB4300000,0x92000104, -0x1280A69,}; -static const uint32_t g_etc1_to_bc7_m6_table210[] = { -0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0x7C0000,0xFC0000, -0xFC0000,0xFC0000,0xFC0000,0x28000001,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x540000,0x4580000,0x4580000,0x4580000,0x7C0000,0xB00000,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0xE40001,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000, -0x1540000,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x72000000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x1540000,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x72000000,0x2FFC0000,0x2FFC0000,0x2FFC0000,0x72000000,0x72000000,0x2F40000,0xE40001,0xE40001,0x10C0000,0x1200000,0x1380000,0x1380000,0x3800000,0x10C0000,0x1200000,0x1E80000,0x2FFC0000, -0x1E80000,0x1680001,0x1680001,0x1680001,0x1680001,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x91FC0000,0x91FC0000,0xB4000000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x91FC0000,0x91FC0000,0xB4000000,0x91FC0000,0x91FC0000,0xB4000000,0xB4000000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x91FC0000,0x91FC0000,0xB4000000,0x91FC0000,0x91FC0000,0xB4000000,0xB4000000,0x91FC0000, -0x91FC0000,0xB4000000,0xB4000000,0xB4000000,0x1A40000,0x9800000,0x1680001,0x1EC0000,0x4BFC0000,0x75FC0000,0x83FC0000,0x9BF80000,0x3C40000,0x1FFC0000,0x75FC0000,0xB4000000,0x75FC0000,0x1FC0000,0xFDFC0000,0xFFF80000,0xFC000001,0xFDFC0000,0xFFF80000,0xFC000001,0xFFF80000,0xFC000001,0xFC000001,0xFDFC0000,0xFFF80000,0xFC000001,0xFFF80000,0xFC000001, -0xFC000001,0xFFF80000,0xFC000001,0xFC000001,0xFC000001,0xFDFC0000,0xFFF80000,0xFC000001,0xFFF80000,0xFC000001,0xFC000001,0xFFF80000,0xFC000001,0xFC000001,0xFC000001,0xFFF80000,0xFC000001,0xFC000001,0xFC000001,0xFC000001,0xFDFC0000,0xF7FC0000,0xF7FC0000,0xFDFC0000,0xFFF80000,0xFFF00000,0xFC000001,0xFC000001,0xFDFC0000,0xFDFC0000,0xFFD00000,0xFC000001, -0xFFF80000,0x128604A,0xFF004416,0xFEF02D9F,0xFCE025C7,0xFEE837DE,0xFEC01B37,0xFEB010C2,0xFEAC17A6,0xF8980B07,0xD89C14D2,0xFED03EDE,0xFEA01B58,0xFE8C0DD5,0xFE701139,0xFC580012,0xDC600B09,0xFC5425C6,0xE83C0D53,0xCC401046,0xB65425C5,0x1B8604A,0xFE7C3691,0xFC5825C6,0xFE2C235E,0xFC040B0A,0xD81414D2,0xFC002E6B,0xE8000F61,0xCC001023,0xB40026F6,0x61F8604A, -0xCA00364F,0xB8002D3E,0xA6003C09,0x9200604E,0xFF004A76,0xF92058E2,0xFB245AA3,0xFED432EA,0xFEA81C14,0xFE7C0838,0xFE6800F6,0xF44800D9,0xFEF0492C,0xFEC02FD3,0xFE38092D,0xCC001023,0x37FC604A,0x17025C6,0xFF501853,0xFF380CC3,0xFD280883,0xFF301782,0xFF080763,0xFEF40113,0xFEF00AD6,0xF2DC01D6,0xD8E40A6A,0x25FC25C5,0xFEE4118B,0xFCC00883,0xFEA00F45,0xFC58000E, -0xD8800A6A,0x95F825C5,0xEC000A95,0xD0000D6A,0xB60025C5,0x25FC25C5,0xFEE4118B,0xFCC00883,0xFEA00F45,0xFC58000E,0xD8800A6A,0x95F825C5,0xEC000A95,0xD0000D6A,0xB60025C5,0x95F825C5,0xEC000A95,0xD0000D6A,0xB60025C5,0xB60025C5,0xFF501F35,0xFD68232A,0xFF6C2313,0xFF30183D,0xFEE80F6B,0xFEAC055A,0xFE84000B,0xF820004D,0xFF441F99,0xFF101711,0xFE34092B,0xD0000D6A, -0x79FC25C5,0xE025C6,0xE025C6,0xE025C6,0xE025C6,0xFEB010C1,0xFEB010C1,0xFEB010C1,0xE69C0A69,0xE69C0A69,0xB49C0A69,0xFE8C0DD4,0xFE8C0DD4,0xFE8C0DD4,0xFA540011,0xFA540011,0xBA6C01D5,0xC6540884,0xC6540884,0xAA4C0104,0x92540884,0x15025C5,0x15025C5,0x15025C5,0xFC040B09,0xFC040B09,0xB4380A69,0xD2000BA3,0xD2000BA3,0xAE00010E,0x920008A8,0x2DF825C5, -0x2DF825C5,0x960011E1,0x840012E5,0x700025C5,0xFECC1ACA,0xF6DC212D,0xE025C6,0xFEAC116D,0xFE88084E,0xFE700251,0xFE6800F5,0xE450000C,0xFEB419D9,0xFE901016,0xFC380882,0xAE00010E,0x1E025C5,0x1280882,0x1280882,0x1280882,0x1280882,0xFEF40112,0xFEF40112,0xFEF40112,0xD4E40001,0xD4E40001,0xB4E40001,0x1B80882,0x1B80882,0x1B80882,0xF06C0001,0xF06C0001, -0xB4A40001,0x61F80882,0x61F80882,0xB200001D,0x92000884,0x1B80882,0x1B80882,0x1B80882,0xF06C0001,0xF06C0001,0xB4A40001,0x61F80882,0x61F80882,0xB200001D,0x92000884,0x61F80882,0x61F80882,0xB200001D,0x92000884,0x92000884,0xFF100620,0xF92006CD,0x1280882,0xFCF404B1,0xFEC00239,0xFE9400AA,0xFE84000A,0xE8440001,0xFEF8065D,0xFEDC0451,0x37FC0882,0xB200001D, -0x37FC0882,0x1B40A69,0xFF980652,0xFF7C01E1,0xFD680002,0x8DFC0A69,0xFF4C03D4,0xFD240001,0xC7FC0A69,0xFC440001,0xD8000A69,0x8DFC0A69,0xFF4C03D4,0xFD240001,0xC7FC0A69,0xFC440001,0xD8000A69,0xC7FC0A69,0xFC440001,0xD8000A69,0xD8000A69,0x8DFC0A69,0xFF4C03D4,0xFD240001,0xC7FC0A69,0xFC440001,0xD8000A69,0xC7FC0A69,0xFC440001,0xD8000A69,0xD8000A69,0xC7FC0A69, -0xFC440001,0xD8000A69,0xD8000A69,0xD8000A69,0xFDA40992,0x1D00A69,0xFFAC099A,0xFF840812,0xFF500668,0xFEF0031D,0xFC980001,0xFA000012,0xFF980951,0xFF7007FD,0xFED00049,0xD8000A69,0xB9FC0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0x9C0A69,0xFC580008,0xFC580008,0xFC580008,0xFC580008,0xFC580008, -0xFC580008,0x96540000,0x96540000,0x96540000,0x72540000,0xE80A69,0xE80A69,0xE80A69,0xE80A69,0xE80A69,0xE80A69,0xA2000092,0xA2000092,0xA2000092,0x720C0000,0x1D80A69,0x1D80A69,0x1D80A69,0x60000355,0x4E000A69,0xFE8C0751,0x9C0A69,0x9C0A69,0xFC800424,0xFE6C0220,0xFE6000B4,0xFE6000B4,0xDC540000,0xFE740659,0xFE6403CA,0xBC400000,0xA2000092, -0x14C0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table211[] = { -0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x940000,0x12C0000, -0x12C0000,0x12C0000,0x12C0000,0x30000001,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0x640000,0xC680000,0xC680000,0xC680000,0x940000,0xD40000,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0xF40001,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000, -0x16C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x16C0000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x3BFC0000,0x3BFC0000,0x3BFC0000,0x7A000000,0x7A000000,0xB040000,0xF40001,0xF40001,0x51C0000,0x1340000,0x34C0000,0x34C0000,0x19C0000,0x51C0000,0x1340000,0x7FC0000,0x3BFC0000, -0x7FC0000,0x1780001,0x1780001,0x1780001,0x1780001,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0x9DFC0000,0xBC000000,0xBC000000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0x9DFC0000,0xBC000000,0xBC000000,0x9DFC0000, -0x9DFC0000,0xBC000000,0xBC000000,0xBC000000,0x1B80000,0x1940000,0x1780001,0x9FC0000,0x5DFC0000,0x83FC0000,0x91FC0000,0xA5FC0000,0x3D80000,0x37FC0000,0x83FC0000,0xBC000000,0x83FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1345AA3,0xFF18414F,0xFEFC2CFE,0xFEF025C6,0xFEF43543,0xFED41B46,0xFEC41162,0xFEB81647,0xFAA80AB6,0xDCAC12ED,0xFEDC3B5B,0xFEAC1B25,0xFE980E98,0xFE88100A,0xFE680015,0xDE700938,0xFE64220B,0xEA4C0C2A,0xD24C0DC5,0xBC642208,0x1C85AA3,0xFE88351E,0xFE7025C5,0xFE3821ED,0xFE140B45,0xDC2812ED,0xFE082A18,0xEE000CC4,0xD4000C44,0xBA00228D,0x69FC5AA3, -0xD6003266,0xBE0027E1,0xAC00360C,0x9A005AA5,0xFF0C469D,0xFF2C536D,0xFF2C555E,0xFEEC313E,0xFEBC1BA5,0xFE9008D1,0xFE7C0184,0xF85C0071,0xFEF84551,0xFED02DDA,0xFE50093C,0xD4000C44,0x41FC5AA3,0x178220B,0xFF5C166E,0xFF400C63,0xFF380882,0xFF441505,0xFF20071A,0xFF0C015A,0xFEFC092D,0xF4EC0141,0xDCF40885,0x37FC2208,0xFEFC1086,0xFED80882,0xFEB80D86,0xFE740001, -0xDE940884,0x9DFC2208,0xF2000974,0xD6000A9D,0xBC002208,0x37FC2208,0xFEFC1086,0xFED80882,0xFEB80D86,0xFE740001,0xDE940884,0x9DFC2208,0xF2000974,0xD6000A9D,0xBC002208,0x9DFC2208,0xF2000974,0xD6000A9D,0xBC002208,0xBC002208,0xFF581C81,0xFF6C1FAD,0xFF6C1FDA,0xFF401614,0xFEFC0E52,0xFEC00532,0xFEA00022,0xFC40001E,0xFD581C9A,0xFF24153E,0xFE58092B,0xD6000A9D, -0x83FC2208,0xF025C6,0xF025C6,0xF025C6,0xF025C6,0xFEC41162,0xFEC41162,0xFEC41162,0xEEAC0A69,0xEEAC0A69,0xBCAC0A69,0xFE980E98,0xFE980E98,0xFE980E98,0xFE680015,0xFE680015,0xC27C01D5,0xCE640884,0xCE640884,0xB25C0104,0x9A640884,0x16825C5,0x16825C5,0x16825C5,0xFE140B45,0xFE140B45,0xBC480A69,0xE2000AD4,0xE2000AD4,0xBA000086,0x9A000885,0x39F825C5, -0x39F825C5,0x9C001115,0x8A0011FD,0x780025C5,0xFED81B58,0xFEEC212D,0xF025C6,0xFEBC1244,0xFE9C0952,0xFE7C0334,0xFE7C0184,0xEC60000C,0xFEBC1A8C,0xFEA41121,0xFE500893,0xBA000086,0x3FC25C5,0x1380882,0x1380882,0x1380882,0x1380882,0xFF0C015A,0xFF0C015A,0xFF0C015A,0xDCF40001,0xDCF40001,0xBCF40001,0x1D00882,0x1D00882,0x1D00882,0xF87C0001,0xF87C0001, -0xBCB40001,0x6DF80882,0x6DF80882,0xBA00000D,0x9A000884,0x1D00882,0x1D00882,0x1D00882,0xF87C0001,0xF87C0001,0xBCB40001,0x6DF80882,0x6DF80882,0xBA00000D,0x9A000884,0x6DF80882,0x6DF80882,0xBA00000D,0x9A000884,0x9A000884,0xFF200659,0xFF2C06D9,0x1380882,0xFD0404E4,0xFED4028D,0xFEB000E1,0xFEA00022,0xF0540001,0xFD100692,0xFEE80492,0x45FC0882,0xBA00000D, -0x45FC0882,0x1BC0882,0xFFA4053D,0xFF88019A,0xFF780001,0x9BFC0882,0xFF640335,0xFF380001,0xCFF80882,0xFE6C0000,0xDC000884,0x9BFC0882,0xFF640335,0xFF380001,0xCFF80882,0xFE6C0000,0xDC000884,0xCFF80882,0xFE6C0000,0xDC000884,0xDC000884,0x9BFC0882,0xFF640335,0xFF380001,0xCFF80882,0xFE6C0000,0xDC000884,0xCFF80882,0xFE6C0000,0xDC000884,0xDC000884,0xCFF80882, -0xFE6C0000,0xDC000884,0xDC000884,0xDC000884,0xFDB007C1,0x5D80882,0xF5B80802,0xFF94069A,0xFF68053D,0xFF1802A1,0xFEB80000,0xFE0C0000,0xFDA807C1,0xFF880665,0xFEF00049,0xDC000884,0xC1FC0882,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xAC0A69,0xFE680014,0xFE680014,0xFE680014,0xFE680014,0xFE680014, -0xFE680014,0x9E640000,0x9E640000,0x9E640000,0x7A640000,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0xAE00004A,0xAE00004A,0xAE00004A,0x7A1C0000,0x5F80A69,0x5F80A69,0x5F80A69,0x6C0002D5,0x56000A69,0xF8A00784,0xAC0A69,0xAC0A69,0xFE900455,0xFE800254,0xFE7800DD,0xFE7800DD,0xE4640000,0xFA880692,0xFE7803F5,0xC4500000,0xAE00004A, -0x16C0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table212[] = { -0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0xB00000,0x1640000, -0x1640000,0x1640000,0x1640000,0x3A000000,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x740001,0x67C0000,0x67C0000,0x67C0000,0xB00000,0xF80000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1080000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000, -0x1880000,0x49F80000,0x49F80000,0x49F80000,0x82000001,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x1880000,0x49F80000,0x49F80000,0x49F80000,0x82000001,0x49F80000,0x49F80000,0x49F80000,0x82000001,0x82000001,0x5180000,0x1080000,0x1080000,0x1340000,0x14C0000,0x1680000,0x1680000,0x1BC0000,0x1340000,0x14C0000,0x19FC0000,0x49F80000, -0x19FC0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xC4000001,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xC4000001,0xABF80000,0xABF80000,0xC4000001,0xC4000001,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xC4000001,0xABF80000,0xABF80000,0xC4000001,0xC4000001,0xABF80000, -0xABF80000,0xC4000001,0xC4000001,0xC4000001,0x1CC0000,0xBA40000,0x18C0000,0x2BFC0000,0x73FC0000,0x95FC0000,0x9FFC0000,0xB3F40000,0x1F00000,0x53FC0000,0x95FC0000,0xC4000001,0x95FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x14053CE,0xFF243DB6,0xFF082C15,0xFF0425C5,0xFF0C31DE,0xFEE41AFD,0xFEDC124D,0xFECC14B2,0xFCC00A76,0xE2C010C2,0xFEF436F6,0xFEC01AAD,0xFEB00F93,0xFE940E7F,0xFE800056,0xE488072F,0xFE7C1DBE,0xEC680AE9,0xD8640AE2,0xC2741D9B,0x3DC53CA,0xFEA03317,0xFE8825C6,0xFE641FF2,0xFE2C0BDE,0xE23C10C2,0xFE14260B,0xF4000A9F,0xDA000853,0xC2001DB3,0x73FC53CA, -0xDC002E39,0xCA0021E2,0xB2002F23,0xA00053CA,0xFF204186,0xFF2C4DB2,0xF9404F7E,0xFF002E66,0xFED01ABC,0xFEA4092A,0xFE900243,0xFA700023,0xFF10407E,0xFEDC2BAA,0xFE700975,0xDA000853,0x4FFC53CA,0x1841D9D,0xFF681408,0xFF580BBD,0xFF480884,0xFF501235,0xFF2C068C,0xFF2401C4,0xFF140731,0xF90000AD,0xE3080659,0x49FC1D9A,0xFF140F18,0xFEF00884,0xFECC0B85,0xFE940005, -0xE2AC0659,0xA7F81D9A,0xF80008AE,0xDC000795,0xC2001D9A,0x49FC1D9A,0xFF140F18,0xFEF00884,0xFECC0B85,0xFE940005,0xE2AC0659,0xA7F81D9A,0xF80008AE,0xDC000795,0xC2001D9A,0xA7F81D9A,0xF80008AE,0xDC000795,0xC2001D9A,0xC2001D9A,0xFF7418F9,0xF9801BAD,0xFB841BC5,0xFF40137A,0xFF100CD4,0xFEDC04E3,0xFEBC0059,0xFE5C0002,0xFF5C18D2,0xFF401296,0xFE7C0912,0xDC000795, -0x8FFC1D9A,0x10425C5,0x10425C5,0x10425C5,0x10425C5,0xFEDC124D,0xFEDC124D,0xFEDC124D,0xF6C00A6A,0xF6C00A6A,0xC4C00A6A,0xFEB00F93,0xFEB00F93,0xFEB00F93,0xFE800056,0xFE800056,0xCA8C01D6,0xD8740883,0xD8740883,0xBC700103,0xA4740883,0x38025C5,0x38025C5,0x38025C5,0xFE2C0BDE,0xFE2C0BDE,0xC45C0A6A,0xEE000A0B,0xEE000A0B,0xC2000023,0xA40C0883,0x45FC25C5, -0x45FC25C5,0xAC001022,0x960010EE,0x800025C6,0xFEE81BE6,0xF6FC21AD,0x10425C5,0xFECC134A,0xFEB00A91,0xFE98043A,0xFE900243,0xF674000B,0xFED01B16,0xFEB01226,0xFE6808D8,0xC2000023,0x15FC25C5,0x1480884,0x1480884,0x1480884,0x1480884,0xFF2401C4,0xFF2401C4,0xFF2401C4,0xE5080001,0xE5080001,0xC5080001,0x3E80882,0x3E80882,0x3E80882,0xFE940005,0xFE940005, -0xC4C80001,0x79FC0882,0x79FC0882,0xC4000001,0xA4000882,0x3E80882,0x3E80882,0x3E80882,0xFE940005,0xFE940005,0xC4C80001,0x79FC0882,0x79FC0882,0xC4000001,0xA4000882,0x79FC0882,0x79FC0882,0xC4000001,0xA4000882,0xA4000882,0xFB340694,0xFB440708,0x1480884,0xFF180519,0xFEF002F2,0xFEC80151,0xFEBC0059,0xFA640000,0xF92806CD,0xFF0404EA,0x57FC0882,0xC4000001, -0x57FC0882,0x1C40659,0xFFB003E8,0xFF940131,0xFF8C0000,0xA9FC0659,0xFF700262,0xFF540000,0xD5F80659,0xFEA00000,0xE2000659,0xA9FC0659,0xFF700262,0xFF540000,0xD5F80659,0xFEA00000,0xE2000659,0xD5F80659,0xFEA00000,0xE2000659,0xE2000659,0xA9FC0659,0xFF700262,0xFF540000,0xD5F80659,0xFEA00000,0xE2000659,0xD5F80659,0xFEA00000,0xE2000659,0xE2000659,0xD5F80659, -0xFEA00000,0xE2000659,0xE2000659,0xE2000659,0xFFB405BA,0x1E40659,0xFBC405E9,0xFFA004F4,0xFF7C03E8,0xFF2C01F9,0xFEE40000,0xFE500000,0xFFAC05C4,0xFF9404C9,0xFF100032,0xE2000659,0xC9FC0659,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xC00A69,0xFE800032,0xFE800032,0xFE800032,0xFE800032,0xFE800032, -0xFE800032,0xA6780001,0xA6780001,0xA6780001,0x82740002,0x11C0A69,0x11C0A69,0x11C0A69,0x11C0A69,0x11C0A69,0x11C0A69,0xC0000014,0xC0000014,0xC0000014,0x82300001,0x11FC0A69,0x11FC0A69,0x11FC0A69,0x7800025D,0x5E000A69,0xFEAC07A2,0xC00A69,0xC00A69,0xFEA00492,0xFE94029A,0xFE880115,0xFE880115,0xEC780001,0xFE9006C4,0xFC900451,0xCC640001,0xC0000014, -0x1940A69,}; -static const uint32_t g_etc1_to_bc7_m6_table213[] = { -0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x2C40000,0x1940000, -0x1940000,0x1940000,0x1940000,0x42000000,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0x840001,0xE8C0000,0xE8C0000,0xE8C0000,0x2C40000,0x11C0000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1180000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000, -0x1A00000,0x55F80000,0x55F80000,0x55F80000,0x8A000001,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x55F80000,0x55F80000,0x55F80000,0x8A000001,0x55F80000,0x55F80000,0x55F80000,0x8A000001,0x8A000001,0xD280000,0x1180000,0x1180000,0x3440000,0x1600000,0x17C0000,0x17C0000,0x3D40000,0x3440000,0x1600000,0x27FC0000,0x55F80000, -0x27FC0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0xB7F80000,0xB7F80000,0xCC000001,0x6BFC0000,0x6BFC0000,0x6BFC0000,0xB7F80000,0xB7F80000,0xCC000001,0xB7F80000,0xB7F80000,0xCC000001,0xCC000001,0x6BFC0000,0x6BFC0000,0x6BFC0000,0xB7F80000,0xB7F80000,0xCC000001,0xB7F80000,0xB7F80000,0xCC000001,0xCC000001,0xB7F80000, -0xB7F80000,0xCC000001,0xCC000001,0xCC000001,0x1E00000,0x1B80000,0x19C0000,0x49FC0000,0x87FC0000,0xA3FC0000,0xADFC0000,0xBDF80000,0x11FC0000,0x6BFC0000,0xA3FC0000,0xCC000001,0xA3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x14C4E1E,0xFF303AC6,0xFF202B4D,0xFF1425C5,0xFF182F0A,0xFEF81ADB,0xFEE81331,0xFED81392,0xFED00A6A,0xE6D00F1A,0xFF003356,0xFED81A55,0xFEC41065,0xFEAC0D5F,0xFE9400C6,0xE898059E,0xFE941A6E,0xF07C0A01,0xDC7808A6,0xC8841A07,0x1F04E1A,0xFEB8315F,0xFEA025C6,0xFE7C1E4A,0xFE4C0C89,0xE6500F1A,0xFE2C231B,0xFA000993,0xE0000597,0xC8041A06,0x7DF84E1A, -0xE0002B5E,0xD0001D1E,0xB8002977,0xA6004E1A,0xFF343DC5,0xFD48484A,0xFF4C4A16,0xFF082C34,0xFEE01A1E,0xFEB809A4,0xFEA4032A,0xFE84000B,0xFF183CC9,0xFEF429C3,0xFE7C09C3,0xE0000597,0x5BFC4E1A,0x1901A05,0xFF741218,0xFF640B25,0xFF580884,0xFF5C1001,0xFF400632,0xFF300220,0xFF2005C9,0xFB100051,0xE71804B1,0x59FC1A05,0xFF200DF4,0xFF080884,0xFEE409DD,0xFEAC0025, -0xE6C004B1,0xADFC1A05,0xFE080882,0xE0000566,0xC8001A06,0x59FC1A05,0xFF200DF4,0xFF080884,0xFEE409DD,0xFEAC0025,0xE6C004B1,0xADFC1A05,0xFE080882,0xE0000566,0xC8001A06,0xADFC1A05,0xFE080882,0xE0000566,0xC8001A06,0xC8001A06,0xFF7815DA,0xFF8C182D,0xFF8C185D,0xFF5C114D,0xFF280B9E,0xFEF0049D,0xFED000A0,0xFE7C0004,0xFD74161E,0xFF481074,0xFEA008FB,0xE0000566, -0x99FC1A05,0x11425C5,0x11425C5,0x11425C5,0x11425C5,0xFEE81331,0xFEE81331,0xFEE81331,0xFED00A6A,0xFED00A6A,0xCCD00A6A,0xFEC41065,0xFEC41065,0xFEC41065,0xFE9400C6,0xFE9400C6,0xD29C01D6,0xE0840883,0xE0840883,0xC4800103,0xAC840883,0x39825C5,0x39825C5,0x39825C5,0xFE4C0C89,0xFE4C0C89,0xCC6C0A6A,0xFA000983,0xFA000983,0xCE000003,0xAC1C0883,0x51FC25C5, -0x51FC25C5,0xB2000F62,0x9C001026,0x880025C6,0xFD001CA9,0xFF0C21AD,0x11425C5,0xFEDC144E,0xFEC40BB5,0xFEAC053E,0xFEA4032A,0xFE84000B,0xFEE41BE5,0xFED012ED,0xFE7C0933,0xCE000003,0x23FC25C5,0x1580884,0x1580884,0x1580884,0x1580884,0xFF300220,0xFF300220,0xFF300220,0xED180001,0xED180001,0xCD180001,0x7FC0882,0x7FC0882,0x7FC0882,0xFEAC0025,0xFEAC0025, -0xCCD80001,0x85FC0882,0x85FC0882,0xCC0C0001,0xAC000882,0x7FC0882,0x7FC0882,0x7FC0882,0xFEAC0025,0xFEAC0025,0xCCD80001,0x85FC0882,0x85FC0882,0xCC0C0001,0xAC000882,0x85FC0882,0x85FC0882,0xCC0C0001,0xAC000882,0xAC000882,0xFF3C06C4,0xFF4C0728,0x1580884,0xFF24057A,0xFF040352,0xFEE4019A,0xFED000A0,0xFE7C0004,0xFF3406D1,0xFF180521,0x65FC0882,0xCC0C0001, -0x65FC0882,0x1CC04B1,0xFFBC02E4,0xFFA000E5,0xFF9C0000,0xB5FC04B1,0xFF8801BA,0xFF6C0000,0xDBF804B1,0xFED40000,0xE60004B1,0xB5FC04B1,0xFF8801BA,0xFF6C0000,0xDBF804B1,0xFED40000,0xE60004B1,0xDBF804B1,0xFED40000,0xE60004B1,0xE60004B1,0xB5FC04B1,0xFF8801BA,0xFF6C0000,0xDBF804B1,0xFED40000,0xE60004B1,0xDBF804B1,0xFED40000,0xE60004B1,0xE60004B1,0xDBF804B1, -0xFED40000,0xE60004B1,0xE60004B1,0xE60004B1,0xF9C40451,0x1EC04B1,0xFFCC0451,0xFFB003A1,0xFF9002E4,0xFF480168,0xFF0C0000,0xFE8C0000,0xF3C40451,0xFFA00392,0xFF300025,0xE60004B1,0xD1FC04B1,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xD00A69,0xFE900059,0xFE900059,0xFE900059,0xFE900059,0xFE900059, -0xFE900059,0xAE880001,0xAE880001,0xAE880001,0x8A840002,0x1340A69,0x1340A69,0x1340A69,0x1340A69,0x1340A69,0x1340A69,0xCE000002,0xCE000002,0xCE000002,0x8A400001,0x1DFC0A69,0x1DFC0A69,0x1DFC0A69,0x7E0001ED,0x66000A69,0xFAC407C1,0xD00A69,0xD00A69,0xFCB804E2,0xFEA802DA,0xFE980151,0xFE980151,0xF4880001,0xFEAC0708,0xFEA00480,0xD4740001,0xCE000002, -0x1B40A69,}; -static const uint32_t g_etc1_to_bc7_m6_table214[] = { -0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x2DC0000,0x1C40000, -0x1C40000,0x1C40000,0x1C40000,0x4A000000,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0x940001,0xA00000,0xA00000,0xA00000,0x2DC0000,0x13C0000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000, -0x1B80000,0x61F80000,0x61F80000,0x61F80000,0x92000001,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x61F80000,0x61F80000,0x61F80000,0x92000001,0x61F80000,0x61F80000,0x61F80000,0x92000001,0x92000001,0x13C0000,0x1280000,0x1280000,0x1580000,0x1740000,0x3900000,0x3900000,0x1F00000,0x1580000,0x1740000,0x37FC0000,0x61F80000, -0x37FC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x83FC0000,0x83FC0000,0x83FC0000,0xC3F80000,0xC3F80000,0xD4000001,0x83FC0000,0x83FC0000,0x83FC0000,0xC3F80000,0xC3F80000,0xD4000001,0xC3F80000,0xC3F80000,0xD4000001,0xD4000001,0x83FC0000,0x83FC0000,0x83FC0000,0xC3F80000,0xC3F80000,0xD4000001,0xC3F80000,0xC3F80000,0xD4000001,0xD4000001,0xC3F80000, -0xC3F80000,0xD4000001,0xD4000001,0xD4000001,0x3F00000,0x1C80000,0x1AC0000,0x67FC0000,0x9BFC0000,0xB3FC0000,0xBBFC0000,0xC7FC0000,0x37FC0000,0x83FC0000,0xB3FC0000,0xD4000001,0xB3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x15848CE,0xFF4437E9,0xFF2C2A81,0xFF2425C5,0xFF242C86,0xFF081AD5,0xFF001419,0xFEF01292,0xFEE00A8D,0xEAE00DB2,0xFF0C301E,0xFEE41A29,0xFEDC116D,0xFEB80CB3,0xFEAC016E,0xEAA8045E,0xFEA0178E,0xF4900951,0xE088069F,0xCC9416C7,0x7FC48CA,0xFECC3001,0xFEB825C6,0xFE941CE2,0xFE640D49,0xEA640DB2,0xFE3820BF,0xFE08097B,0xE6000393,0xCC1816C6,0x85FC48CA, -0xE600290A,0xD60018EA,0xBE002443,0xAC0048CA,0xFF3C39F6,0xFF4C436A,0xFF4C4586,0xFF182A0A,0xFEF419AA,0xFEC80A63,0xFEBC0422,0xFE9C0031,0xFF34391E,0xFF0027C6,0xFE940A51,0xE6000393,0x65FC48CA,0x19C16C5,0xFF801058,0xFF700AA5,0xFF680884,0xFF740E01,0xFF5405F4,0xFF44027D,0xFF380491,0xFD240018,0xEB280349,0x6BFC16C5,0xFF380CE4,0xFF200884,0xFEFC0875,0xFECC0061, -0xEAD40349,0xB7F816C5,0xFE380882,0xE6000392,0xCC0016C6,0x6BFC16C5,0xFF380CE4,0xFF200884,0xFEFC0875,0xFECC0061,0xEAD40349,0xB7F816C5,0xFE380882,0xE6000392,0xCC0016C6,0xB7F816C5,0xFE380882,0xE6000392,0xCC0016C6,0xCC0016C6,0xFF80136D,0xFF8C154D,0xF59815A4,0xFF6C0F72,0xFF480A86,0xFF040496,0xFEE800FA,0xFEA00022,0xFF781352,0xFF5C0EC6,0xFED008E5,0xE6000392, -0xA3FC16C5,0x12425C5,0x12425C5,0x12425C5,0x12425C5,0xFF001419,0xFF001419,0xFF001419,0xFEE00A8D,0xFEE00A8D,0xD4E00A6A,0xFEDC116D,0xFEDC116D,0xFEDC116D,0xFEAC016E,0xFEAC016E,0xDAAC01D6,0xE8940883,0xE8940883,0xCC900103,0xB4940883,0x3B025C5,0x3B025C5,0x3B025C5,0xFE640D49,0xFE640D49,0xD47C0A6A,0xFE08097B,0xFE08097B,0xD6100003,0xB42C0883,0x5DFC25C5, -0x5DFC25C5,0xBE000E9A,0xA6000F63,0x900025C6,0xFF101D2B,0xF920222A,0x12425C5,0xFEF81556,0xFED80CE9,0xFEBC0666,0xFEBC0422,0xFE9C0031,0xFEF81C56,0xFEDC1421,0xFE9409D8,0xD6100003,0x33FC25C5,0x1680884,0x1680884,0x1680884,0x1680884,0xFF44027D,0xFF44027D,0xFF44027D,0xF5280001,0xF5280001,0xD5280001,0x1FFC0882,0x1FFC0882,0x1FFC0882,0xFECC0061,0xFECC0061, -0xD4E80001,0x91FC0882,0x91FC0882,0xD41C0001,0xB4000882,0x1FFC0882,0x1FFC0882,0x1FFC0882,0xFECC0061,0xFECC0061,0xD4E80001,0x91FC0882,0x91FC0882,0xD41C0001,0xB4000882,0x91FC0882,0x91FC0882,0xD41C0001,0xB4000882,0xB4000882,0xFF5806CD,0xFB640745,0x1680884,0xFF4405B2,0xFF1803BA,0xFEFC01F9,0xFEE800FA,0xFEA00022,0xFD4C0708,0xFF300581,0x75FC0882,0xD41C0001, -0x75FC0882,0x1D40349,0xFFC401F9,0xFFB8009D,0xFFAC0000,0xC1FC0349,0xFFA00132,0xFF840000,0xE1F80349,0xFF040000,0xEA000349,0xC1FC0349,0xFFA00132,0xFF840000,0xE1F80349,0xFF040000,0xEA000349,0xE1F80349,0xFF040000,0xEA000349,0xEA000349,0xC1FC0349,0xFFA00132,0xFF840000,0xE1F80349,0xFF040000,0xEA000349,0xE1F80349,0xFF040000,0xEA000349,0xEA000349,0xE1F80349, -0xFF040000,0xEA000349,0xEA000349,0xEA000349,0xFDCC02F9,0x1F40349,0xFFCC0311,0xFFC00288,0xFFA80202,0xFF700104,0xFF340000,0xFEC80000,0xF7CC02F9,0xFDBC0288,0xFF500019,0xEA000349,0xD9FC0349,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xE00A69,0xFEA40082,0xFEA40082,0xFEA40082,0xFEA40082,0xFEA40082, -0xFEA40082,0xB6980001,0xB6980001,0xB6980001,0x92940002,0x1480A69,0x1480A69,0x1480A69,0x1480A69,0x1480A69,0x1480A69,0xD80C0000,0xD80C0000,0xD80C0000,0x92500001,0x29FC0A69,0x29FC0A69,0x29FC0A69,0x8A000195,0x6E000A69,0xFECC07E9,0xE00A69,0xE00A69,0xFCC80515,0xFEB40321,0xFEAC019A,0xFEAC019A,0xFC980001,0xFEBC070A,0xFEB404B1,0xDC840001,0xD80C0000, -0x1D80A69,}; -static const uint32_t g_etc1_to_bc7_m6_table215[] = { -0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x2F40000,0x1F40000, -0x1F40000,0x1F40000,0x1F40000,0x52000000,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xA40001,0xB00000,0xB00000,0xB00000,0x2F40000,0x1600000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1380000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000, -0x1D00000,0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x1D00000,0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x6DF80000,0x6DF80000,0x6DF80000,0x9A000001,0x9A000001,0x14C0000,0x1380000,0x1380000,0x7680000,0x1880000,0x1A80000,0x1A80000,0xDFC0000,0x7680000,0x1880000,0x45FC0000,0x6DF80000, -0x45FC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xDC000001,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xDC000001,0xCFF80000,0xCFF80000,0xDC000001,0xDC000001,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xDC000001,0xCFF80000,0xCFF80000,0xDC000001,0xDC000001,0xCFF80000, -0xCFF80000,0xDC000001,0xDC000001,0xDC000001,0x17FC0000,0x5D80000,0x1BC0000,0x85FC0000,0xAFFC0000,0xC1FC0000,0xC9F80000,0xD3F80000,0x5FFC0000,0x9BFC0000,0xC1FC0000,0xDC000001,0xC1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x16443DE,0xFF503551,0xFF3829D5,0xFF3425C5,0xFF302A52,0xFF181AE5,0xFF0C150D,0xFEFC11F2,0xFEF00AE2,0xEEF00C8A,0xFF242D36,0xFEFC1A11,0xFEE81275,0xFED80C52,0xFEC00252,0xEEBC035E,0xFEB8151E,0xF8A408D9,0xE69404F3,0xD2A413DB,0x19FC43DA,0xFEE42E81,0xFED025C5,0xFEAC1BBA,0xFE7C0E29,0xEE780C8A,0xFE641E91,0xFE200A1B,0xEC0C023F,0xD22813DA,0x8FF843DA, -0xF0002759,0xDC001546,0xC4001F87,0xB20043DA,0xFF4C36D3,0xF9603F4E,0xFB6440F5,0xFF2C286E,0xFF04195C,0xFEDC0B1C,0xFED00559,0xFEB00092,0xFF3435BE,0xFF102642,0xFEB00AE7,0xEC0C023F,0x71FC43DA,0x1A413DD,0xFF8C0EC8,0xFF7C0A3D,0xFF780884,0xFF800C45,0xFF6405BE,0xFF5C02FD,0xFF4C03BD,0xFF380001,0xEF380221,0x7BFC13DA,0xFF4C0C13,0xFF380884,0xFF14074D,0xFEE400B9, -0xEEE80221,0xBFF813DA,0xFE6C0882,0xEC00022E,0xD20013DA,0x7BFC13DA,0xFF4C0C13,0xFF380884,0xFF14074D,0xFEE400B9,0xEEE80221,0xBFF813DA,0xFE6C0882,0xEC00022E,0xD20013DA,0xBFF813DA,0xFE6C0882,0xEC00022E,0xD20013DA,0xD20013DA,0xFF9410EE,0xF9A01299,0xFBA412D8,0xFF780DD1,0xFF5C09A6,0xFF240491,0xFF0C0164,0xFEB80068,0xFF8810FD,0xFF680D52,0xFEE408D3,0xEC00022E, -0xADFC13DA,0x13425C5,0x13425C5,0x13425C5,0x13425C5,0xFF0C150D,0xFF0C150D,0xFF0C150D,0xFEF00AE2,0xFEF00AE2,0xDCF00A6A,0xFEE81275,0xFEE81275,0xFEE81275,0xFEC00252,0xFEC00252,0xE2BC01D6,0xF0A40883,0xF0A40883,0xD4A00103,0xBCA40883,0x1C825C5,0x1C825C5,0x1C825C5,0xFE7C0E29,0xFE7C0E29,0xDC8C0A6A,0xFE200A1B,0xFE200A1B,0xDE200003,0xBC3C0883,0x69FC25C5, -0x69FC25C5,0xCA000DF2,0xB2000EA3,0x980025C6,0xFF201DA6,0xFF2C222E,0x13425C5,0xFF081643,0xFEEC0E2D,0xFED407CE,0xFED00559,0xFEB00092,0xFF141D18,0xFEF41512,0xFEB00A83,0xDE200003,0x41FC25C5,0x1780884,0x1780884,0x1780884,0x1780884,0xFF5C02FD,0xFF5C02FD,0xFF5C02FD,0xFD380001,0xFD380001,0xDD380001,0x37FC0882,0x37FC0882,0x37FC0882,0xFEE400B9,0xFEE400B9, -0xDCF80001,0x9DFC0882,0x9DFC0882,0xDC2C0001,0xBC000882,0x37FC0882,0x37FC0882,0x37FC0882,0xFEE400B9,0xFEE400B9,0xDCF80001,0x9DFC0882,0x9DFC0882,0xDC2C0001,0xBC000882,0x9DFC0882,0x9DFC0882,0xDC2C0001,0xBC000882,0xBC000882,0xFB6C0708,0xFF6C076D,0x1780884,0xFD5805E9,0xFF400422,0xFF20028A,0xFF0C0164,0xFEB80068,0xF5640745,0xFF4805B4,0x83FC0882,0xDC2C0001, -0x83FC0882,0x1DC0221,0xFFD00145,0xFFC00068,0xFFBC0000,0xCDFC0221,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xFF340000,0xEE000221,0xCDFC0221,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xFF340000,0xEE000221,0xE7F80221,0xFF340000,0xEE000221,0xEE000221,0xCDFC0221,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xFF340000,0xEE000221,0xE7F80221,0xFF340000,0xEE000221,0xEE000221,0xE7F80221, -0xFF340000,0xEE000221,0xEE000221,0xEE000221,0xFFD001ED,0x1FC0221,0xF7DC0200,0xFFC001A8,0xFFA80152,0xFF8400A0,0xFF5C0000,0xFF040000,0xFBD401E1,0xFFC00190,0xFF700010,0xEE000221,0xDFFC0221,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xF00A69,0xFEB400C1,0xFEB400C1,0xFEB400C1,0xFEB400C1,0xFEB400C1, -0xFEB400C1,0xBEA80001,0xBEA80001,0xBEA80001,0x9AA40002,0x1600A69,0x1600A69,0x1600A69,0x1600A69,0x1600A69,0x1600A69,0xE01C0000,0xE01C0000,0xE01C0000,0x9A600001,0x35FC0A69,0x35FC0A69,0x35FC0A69,0x9000013D,0x76000A69,0xFAE40802,0xF00A69,0xF00A69,0xFED8054A,0xFED00372,0xFEC401E1,0xFEC401E1,0xFCA8000A,0xFAD00745,0xFEBC0502,0xE4940001,0xE01C0000, -0x1F80A69,}; -static const uint32_t g_etc1_to_bc7_m6_table216[] = { -0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0x1100000,0xDFC0000, -0xDFC0000,0xDFC0000,0xDFC0000,0x5A000001,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xB80000,0xC40000,0xC40000,0xC40000,0x1100000,0x1880000,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x1480001,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000, -0x3E80000,0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x3E80000,0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0x79FC0000,0x79FC0000,0x79FC0000,0xA4000000,0xA4000000,0x1600000,0x1480001,0x1480001,0x1800000,0x39C0000,0x1C00000,0x1C00000,0x23FC0000,0x1800000,0x39C0000,0x57FC0000,0x79FC0000, -0x57FC0000,0x1CC0001,0x1CC0001,0x1CC0001,0x1CC0001,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xE6000000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xE6000000,0xDDF40000,0xDDF40000,0xE6000000,0xE6000000,0xB7FC0000,0xB7FC0000,0xB7FC0000,0xDDF40000,0xDDF40000,0xE6000000,0xDDF40000,0xDDF40000,0xE6000000,0xE6000000,0xDDF40000, -0xDDF40000,0xE6000000,0xE6000000,0xE6000000,0x57FC0000,0x1EC0000,0x1CC0001,0xA7FC0000,0xC5FC0000,0xD3FC0000,0xD7FC0000,0xDFF80000,0x8BFC0000,0xB7FC0000,0xD3FC0000,0xE6000000,0xD3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1743EBF,0xFF5C32AA,0xFF4C292F,0xFF4425C6,0xFF4427D5,0xFF301B26,0xFF24162E,0xFF141185,0xFF080B81,0xF3000B89,0xFF302A4B,0xFF101A25,0xFF0013B2,0xFEE40C25,0xFED80391,0xF6CC0285,0xFECC130C,0xFCB8088E,0xEAA80370,0xD8B810F8,0x2FFC3EBF,0xFEFC2CFE,0xFEEC25C5,0xFEB81ACB,0xFEA00F3A,0xF2900B89,0xFE881C84,0xFE380B28,0xF0200130,0xD83C10F9,0x99FC3EBF, -0xF8002621,0xE0001205,0xD0001AB8,0xB8003EC1,0xFF583335,0xFF6C3A65,0xFF6C3C36,0xFF4026D4,0xFF181935,0xFEF00C2B,0xFEE806D0,0xFEC00164,0xFF50326B,0xFF3024FE,0xFEBC0BFE,0xF0200130,0x7FF83EBF,0x1B010FB,0xFFA40D26,0xFF9409C3,0xFF8C0882,0xFF8C0AA9,0xFF7405AE,0xFF680385,0xFF580313,0xFF4C001A,0xF3480121,0x8DFC10F8,0xFF640B25,0xFF540882,0xFF2C0651,0xFF080131, -0xF2FC0121,0xC7FC10F8,0xFEA00882,0xF2080120,0xD80010F8,0x8DFC10F8,0xFF640B25,0xFF540882,0xFF2C0651,0xFF080131,0xF2FC0121,0xC7FC10F8,0xFEA00882,0xF2080120,0xD80010F8,0xC7FC10F8,0xFEA00882,0xF2080120,0xD80010F8,0xD80010F8,0xFFA00E9D,0xFFAC0FC9,0xFFAC1026,0xFF880C23,0xFF6808C1,0xFF380495,0xFF2801E2,0xFEE400CD,0xFF980EBE,0xFF840BB2,0xFF1008B5,0xF2080120, -0xB9FC10F8,0x14425C6,0x14425C6,0x14425C6,0x14425C6,0xFF24162E,0xFF24162E,0xFF24162E,0xFF080B81,0xFF080B81,0xE7000A69,0xFF0013B2,0xFF0013B2,0xFF0013B2,0xFED80391,0xFED80391,0xECD001D5,0xF8B80884,0xF8B80884,0xDCB00104,0xC4B80884,0x1E425C5,0x1E425C5,0x1E425C5,0xFEA00F3A,0xFEA00F3A,0xE69C0A69,0xFE380B28,0xFE380B28,0xE6340002,0xC4500884,0x77F825C5, -0x77F825C5,0xD6000D49,0xB8000DD4,0xA20025C5,0xFF2C1E68,0xF94022AA,0x14425C6,0xFF181761,0xFF000FB2,0xFEF00952,0xFEE806D0,0xFEC00164,0xFF201DB2,0xFF101682,0xFEBC0B9A,0xE6340002,0x53FC25C5,0x18C0882,0x18C0882,0x18C0882,0x18C0882,0xFF680385,0xFF680385,0xFF680385,0xFF4C001A,0xFF4C001A,0xE7480001,0x53FC0882,0x53FC0882,0x53FC0882,0xFF080131,0xFF080131, -0xE7080001,0xABF80882,0xABF80882,0xE63C0000,0xC4000884,0x53FC0882,0x53FC0882,0x53FC0882,0xFF080131,0xFF080131,0xE7080001,0xABF80882,0xABF80882,0xE63C0000,0xC4000884,0xABF80882,0xABF80882,0xE63C0000,0xC4000884,0xC4000884,0xFF74073A,0xFD880782,0x18C0882,0xFB700659,0xFF540488,0xFF300304,0xFF2801E2,0xFEE400CD,0xFD740745,0xFF5C05F5,0x95FC0882,0xE63C0000, -0x95FC0882,0x1E40122,0xFFDC00AA,0xFFD4003A,0xFFCC0001,0xDBFC0120,0xFFC0006D,0xFFB80000,0xEDFC0120,0xFF6C0000,0xF2000120,0xDBFC0120,0xFFC0006D,0xFFB80000,0xEDFC0120,0xFF6C0000,0xF2000120,0xEDFC0120,0xFF6C0000,0xF2000120,0xF2000120,0xDBFC0120,0xFFC0006D,0xFFB80000,0xEDFC0120,0xFF6C0000,0xF2000120,0xEDFC0120,0xFF6C0000,0xF2000120,0xF2000120,0xEDFC0120, -0xFF6C0000,0xF2000120,0xF2000120,0xF2000120,0xF5E40109,0x47FC0120,0xFBE40109,0xFFD800DD,0xFFCC00B5,0xFFAC0059,0xFF880000,0xFF480000,0xFFDC00F4,0xFFCC00DA,0xFF980009,0xF2000120,0xE9FC0120,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0x1000A69,0xFEC80104,0xFEC80104,0xFEC80104,0xFEC80104,0xFEC80104, -0xFEC80104,0xC8B80000,0xC8B80000,0xC8B80000,0xA4B80000,0x17C0A69,0x17C0A69,0x17C0A69,0x17C0A69,0x17C0A69,0x17C0A69,0xEA2C0000,0xEA2C0000,0xEA2C0000,0xA4700000,0x43F80A69,0x43F80A69,0x43F80A69,0x9C0000E9,0x80000A69,0xF4F80841,0x1000A69,0x1000A69,0xFEE80589,0xFEE403C8,0xFED4022D,0xFED4022D,0xFEC00020,0xFED80781,0xFED0053D,0xEEA40000,0xEA2C0000, -0x11FC0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table217[] = { -0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x1280000,0x19FC0000, -0x19FC0000,0x19FC0000,0x19FC0000,0x62000001,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0x2D40000,0x2D40000,0x2D40000,0x1280000,0x1A80000,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x1580001,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000, -0x7FC0000,0x85FC0000,0x85FC0000,0x85FC0000,0xAC000000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x7FC0000,0x85FC0000,0x85FC0000,0x85FC0000,0xAC000000,0x85FC0000,0x85FC0000,0x85FC0000,0xAC000000,0xAC000000,0x1700000,0x1580001,0x1580001,0x5900000,0x3B00000,0x3D40000,0x3D40000,0x37FC0000,0x5900000,0x3B00000,0x65FC0000,0x85FC0000, -0x65FC0000,0x1DC0001,0x1DC0001,0x1DC0001,0x1DC0001,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xE7FC0000,0xE7FC0000,0xEE000000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xE7FC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xE7FC0000,0xEE000000,0xEE000000,0xCFFC0000,0xCFFC0000,0xCFFC0000,0xE7FC0000,0xE7FC0000,0xEE000000,0xE7FC0000,0xE7FC0000,0xEE000000,0xEE000000,0xE7FC0000, -0xE7FC0000,0xEE000000,0xEE000000,0xEE000000,0x91FC0000,0x7FC0000,0x1DC0001,0xC5FC0000,0xD9FC0000,0xE1FC0000,0xE5FC0000,0xE9FC0000,0xB3FC0000,0xCFFC0000,0xE1FC0000,0xEE000000,0xE1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1803A9B,0xFF68308E,0xFF5828A3,0xFF5425C6,0xFF502631,0xFF3C1B66,0xFF301742,0xFF201179,0xFF140C51,0xF7100AE9,0xFF4427DC,0xFF241A56,0xFF1814E2,0xFEFC0C45,0xFEE404F1,0xF8DC020D,0xFEE4119C,0xFECC0888,0xEEBC0268,0xDEC80EC4,0x41FC3A9B,0xFF142BBE,0xFF0425C5,0xFED81A61,0xFEB81052,0xF6A40AE9,0xFEA01B0C,0xFE640C2B,0xF6340082,0xDE500EC4,0xA1FC3A9B, -0xFE0025C5,0xE6000F95,0xD60016F4,0xBE003A9D,0xFF643075,0xFF6C3735,0xF77C38AF,0xFF442569,0xFF281942,0xFEFC0D81,0xFEF8085D,0xFED8026A,0xFF542FDE,0xFF4023EC,0xFEDC0D0E,0xF6340082,0x89FC3A9B,0x1BC0EC3,0xFFB00BEE,0xFFA0096B,0xFF9C0882,0xFF980989,0xFF8405BA,0xFF80040D,0xFF7002BB,0xFF64006A,0xF7580081,0x9BFC0EC3,0xFF7C0A6D,0xFF6C0882,0xFF4C05D6,0xFF2C01BD, -0xF7100081,0xCFF80EC3,0xFED40882,0xF6280080,0xDE000EC4,0x9BFC0EC3,0xFF7C0A6D,0xFF6C0882,0xFF4C05D6,0xFF2C01BD,0xF7100081,0xCFF80EC3,0xFED40882,0xF6280080,0xDE000EC4,0xCFF80EC3,0xFED40882,0xF6280080,0xDE000EC4,0xDE000EC4,0xFFB40CEA,0xF5B80E03,0xF7BC0E43,0xFF980AE1,0xFF7C0839,0xFF5804EB,0xFF3C028A,0xFEFC015D,0xFFA40D0A,0xFF900AA6,0xFF3008A8,0xF6280080, -0xC1FC0EC3,0x15425C6,0x15425C6,0x15425C6,0x15425C6,0xFF301742,0xFF301742,0xFF301742,0xFF140C51,0xFF140C51,0xEF100A69,0xFF1814E2,0xFF1814E2,0xFF1814E2,0xFEE404F1,0xFEE404F1,0xF4E001D5,0xFECC0888,0xFECC0888,0xE4C00104,0xCCC80884,0x1FC25C5,0x1FC25C5,0x1FC25C5,0xFEB81052,0xFEB81052,0xEEAC0A69,0xFE640C2B,0xFE640C2B,0xEE440002,0xCC600884,0x83F825C5, -0x83F825C5,0xDC000CB5,0xC4000D24,0xAA0025C5,0xFF3C1EFE,0xFF4C22BE,0x15425C6,0xFF2C188D,0xFF141116,0xFEFC0ADD,0xFEF8085D,0xFED8026A,0xFF341E29,0xFF18178E,0xFEDC0CBD,0xEE440002,0x61FC25C5,0x19C0882,0x19C0882,0x19C0882,0x19C0882,0xFF80040D,0xFF80040D,0xFF80040D,0xFF64006A,0xFF64006A,0xEF580001,0x6BFC0882,0x6BFC0882,0x6BFC0882,0xFF2C01BD,0xFF2C01BD, -0xEF180001,0xB7F80882,0xB7F80882,0xEE4C0000,0xCC000884,0x6BFC0882,0x6BFC0882,0x6BFC0882,0xFF2C01BD,0xFF2C01BD,0xEF180001,0xB7F80882,0xB7F80882,0xEE4C0000,0xCC000884,0xB7F80882,0xB7F80882,0xEE4C0000,0xCC000884,0xCC000884,0xFF900745,0xF59807C1,0x19C0882,0xFF780681,0xFF700515,0xFF5003B5,0xFF3C028A,0xFEFC015D,0xFD880782,0xFF74065D,0xA3FC0882,0xEE4C0000, -0xA3FC0882,0x1EC0082,0xFFE8004A,0xFFE40019,0xFFDC0001,0xE9FC0080,0xFFD8002D,0xFFCC0001,0xF3FC0080,0xFF9C0000,0xF6000080,0xE9FC0080,0xFFD8002D,0xFFCC0001,0xF3FC0080,0xFF9C0000,0xF6000080,0xF3FC0080,0xFF9C0000,0xF6000080,0xF6000080,0xE9FC0080,0xFFD8002D,0xFFCC0001,0xF3FC0080,0xFF9C0000,0xF6000080,0xF3FC0080,0xFF9C0000,0xF6000080,0xF6000080,0xF3FC0080, -0xFF9C0000,0xF6000080,0xF6000080,0xF6000080,0xF9EC0071,0x87FC0080,0xFFEC0071,0xFDE80062,0xFDE00055,0xFFC80022,0xFFB00000,0xFF840000,0xFDEC0071,0xFFE40062,0xFFB80004,0xF6000080,0xF1FC0080,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0x1100A69,0xFEDC0145,0xFEDC0145,0xFEDC0145,0xFEDC0145,0xFEDC0145, -0xFEDC0145,0xD0C80000,0xD0C80000,0xD0C80000,0xACC80000,0x1940A69,0x1940A69,0x1940A69,0x1940A69,0x1940A69,0x1940A69,0xF23C0000,0xF23C0000,0xF23C0000,0xAC800000,0x4FF80A69,0x4FF80A69,0x4FF80A69,0xA60000B4,0x88000A69,0xFD080841,0x1100A69,0x1100A69,0xFEF405E4,0xFEEC041D,0xFEE80290,0xFEE80290,0xFED40048,0xFEF40784,0xFEE40595,0xF6B40000,0xF23C0000, -0x1FFC0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table218[] = { -0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x1400000,0x25F80000, -0x25F80000,0x25F80000,0x25F80000,0x6A000001,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xD80000,0xAE40000,0xAE40000,0xAE40000,0x1400000,0x1CC0000,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1680001,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000, -0x1FFC0000,0x91FC0000,0x91FC0000,0x91FC0000,0xB4000000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x1FFC0000,0x91FC0000,0x91FC0000,0x91FC0000,0xB4000000,0x91FC0000,0x91FC0000,0x91FC0000,0xB4000000,0xB4000000,0x9800000,0x1680001,0x1680001,0x1A40000,0x3C40000,0x1EC0000,0x1EC0000,0x4BFC0000,0x1A40000,0x3C40000,0x75FC0000,0x91FC0000, -0x75FC0000,0x1EC0001,0x1EC0001,0x1EC0001,0x1EC0001,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xF3FC0000,0xF3FC0000,0xF6000000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xF3FC0000,0xF3FC0000,0xF6000000,0xF3FC0000,0xF3FC0000,0xF6000000,0xF6000000,0xE9FC0000,0xE9FC0000,0xE9FC0000,0xF3FC0000,0xF3FC0000,0xF6000000,0xF3FC0000,0xF3FC0000,0xF6000000,0xF6000000,0xF3FC0000, -0xF3FC0000,0xF6000000,0xF6000000,0xF6000000,0xC9FC0000,0x87FC0000,0x1EC0001,0xE3FC0000,0xEDFC0000,0xF1FC0000,0xF3F80000,0xF5F80000,0xDBFC0000,0xE9FC0000,0xF1FC0000,0xF6000000,0xF1FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x18C36D7,0xFF742EAA,0xFF6C2826,0xFF6425C6,0xFF5C24DD,0xFF501BC6,0xFF441831,0xFF3811B1,0xFF2C0D49,0xFB200A89,0xFF5025F8,0xFF301AB6,0xFF241626,0xFF140CC5,0xFEFC0671,0xFCF001D9,0xFEFC10AC,0xFEE408D8,0xF4C801A8,0xE2D80CE4,0x53FC36D7,0xFF2C2A9E,0xFF1C25C5,0xFEF01A01,0xFED811B1,0xFAB80A89,0xFEB819F4,0xFE880D5B,0xFA4C0020,0xE2640CE4,0xABF836D7, -0xFE2C25C5,0xEC000DB5,0xDC0013A8,0xC40036D9,0xFF742E0F,0xFD883393,0xFD88351B,0xFF54242D,0xFF381982,0xFF180EB9,0xFF1009F9,0xFEEC03A5,0xFF702D9A,0xFF5022A2,0xFEF40E18,0xFA4C0020,0x95FC36D7,0x1C80CE3,0xFFBC0AE6,0xFFAC092B,0xFFAC0882,0xFFA408B1,0xFF9805D6,0xFF8C04A5,0xFF7C02B3,0xFF7000EA,0xFB680021,0xAFFC0CE3,0xFF9409D5,0xFF840882,0xFF640576,0xFF380271, -0xFB240021,0xD7FC0CE3,0xFF040882,0xFA4C0020,0xE2000CE4,0xAFFC0CE3,0xFF9409D5,0xFF840882,0xFF640576,0xFF380271,0xFB240021,0xD7FC0CE3,0xFF040882,0xFA4C0020,0xE2000CE4,0xD7FC0CE3,0xFF040882,0xFA4C0020,0xE2000CE4,0xE2000CE4,0xFFBC0B6D,0xFBC40C2B,0xFBC40C7B,0xFFB00A0A,0xFF9007D9,0xFF6C0515,0xFF640332,0xFF2801F4,0xFFB40B76,0xFF9809BE,0xFF50089B,0xFA4C0020, -0xCDFC0CE3,0x16425C6,0x16425C6,0x16425C6,0x16425C6,0xFF441831,0xFF441831,0xFF441831,0xFF2C0D49,0xFF2C0D49,0xF7200A69,0xFF241626,0xFF241626,0xFF241626,0xFEFC0671,0xFEFC0671,0xFCF001D5,0xFEE408D8,0xFEE408D8,0xECD00104,0xD4D80884,0x19FC25C5,0x19FC25C5,0x19FC25C5,0xFED811B1,0xFED811B1,0xF6BC0A69,0xFE880D5B,0xFE880D5B,0xF6540002,0xD4700884,0x8FF825C5, -0x8FF825C5,0xE6000C45,0xCA000C84,0xB20025C5,0xFF4C1F85,0xF960232D,0x16425C6,0xFF3C1996,0xFF2C12AC,0xFF180CA8,0xFF1009F9,0xFEEC03A5,0xFD4C1F0B,0xFF30188D,0xFEF40DD8,0xF6540002,0x71FC25C5,0x1AC0882,0x1AC0882,0x1AC0882,0x1AC0882,0xFF8C04A5,0xFF8C04A5,0xFF8C04A5,0xFF7000EA,0xFF7000EA,0xF7680001,0x83FC0882,0x83FC0882,0x83FC0882,0xFF380271,0xFF380271, -0xF7280001,0xC3F80882,0xC3F80882,0xF65C0000,0xD4000884,0x83FC0882,0x83FC0882,0x83FC0882,0xFF380271,0xFF380271,0xF7280001,0xC3F80882,0xC3F80882,0xF65C0000,0xD4000884,0xC3F80882,0xC3F80882,0xF65C0000,0xD4000884,0xD4000884,0xFFA00784,0xFDA807C1,0x1AC0882,0xFF9806CD,0xFF840581,0xFF640431,0xFF640332,0xFF2801F4,0xFF940794,0xFF8406B2,0xB3FC0882,0xF65C0000, -0xB3FC0882,0x1F40022,0xFFF40012,0xFFF00005,0xFFEC0001,0xF5FC0020,0xFFEC000D,0xFFE40001,0xF9FC0020,0xFFCC0000,0xFA000020,0xF5FC0020,0xFFEC000D,0xFFE40001,0xF9FC0020,0xFFCC0000,0xFA000020,0xF9FC0020,0xFFCC0000,0xFA000020,0xFA000020,0xF5FC0020,0xFFEC000D,0xFFE40001,0xF9FC0020,0xFFCC0000,0xFA000020,0xF9FC0020,0xFFCC0000,0xFA000020,0xFA000020,0xF9FC0020, -0xFFCC0000,0xFA000020,0xFA000020,0xFA000020,0xFDF40019,0xC7FC0020,0xF3F40022,0xFFF00019,0xFFE80011,0xFFDC0009,0xFFD80000,0xFFC00000,0xFFF0001D,0xFFF00019,0xFFDC0001,0xFA000020,0xF9FC0020,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0x1200A69,0xFEF401A5,0xFEF401A5,0xFEF401A5,0xFEF401A5,0xFEF401A5, -0xFEF401A5,0xD8D80000,0xD8D80000,0xD8D80000,0xB4D80000,0x1AC0A69,0x1AC0A69,0x1AC0A69,0x1AC0A69,0x1AC0A69,0x1AC0A69,0xFA4C0000,0xFA4C0000,0xFA4C0000,0xB4900000,0x5BF80A69,0x5BF80A69,0x5BF80A69,0xAC000080,0x90000A69,0xF5180884,0x1200A69,0x1200A69,0xFF100620,0xFF000469,0xFEF802E4,0xFEF802E4,0xFEE40088,0xFB0807C1,0xFEF805C4,0xFEC40000,0xFA4C0000, -0x2FFC0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table219[] = { -0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x1580000,0x31F80000, -0x31F80000,0x31F80000,0x31F80000,0x72000001,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xE80000,0xF80000,0xF80000,0xF80000,0x1580000,0x1EC0000,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x1780001,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000, -0x37FC0000,0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x37FC0000,0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0x9DFC0000,0x9DFC0000,0x9DFC0000,0xBC000000,0xBC000000,0x1940000,0x1780001,0x1780001,0x1B80000,0x3D80000,0x9FC0000,0x9FC0000,0x5DFC0000,0x1B80000,0x3D80000,0x83FC0000,0x9DFC0000, -0x83FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1983373,0xFF8C2CEA,0xFF7C279F,0xFF7425C6,0xFF7423B5,0xFF5C1C42,0xFF5C1969,0xFF40125B,0xFF380E81,0xFF300A69,0xFF5C247C,0xFF441B19,0xFF441758,0xFF200D81,0xFF140831,0xFF0001F9,0xFF081024,0xFEF00984,0xF8DC0130,0xE8E80B58,0x65FC3373,0xFF4029BE,0xFF3425C5,0xFF0819E1,0xFEF01301,0xFECC0A69,0xFED81984,0xFEA00EBB,0xFE640002,0xE8740B59,0xB3FC3373, -0xFE6025C5,0xF6000C55,0xE00010E1,0xCA003375,0xFF802BE9,0xFF8C3087,0xFF8C323F,0xFF70239D,0xFF4C19E6,0xFF2C1017,0xFF240BD8,0xFF040545,0xFF782B2A,0xFF5C221F,0xFF100FAE,0xFE640002,0x9FFC3373,0x1D00B5B,0xFFC40A0B,0xFFC008EE,0xFFBC0882,0xFFBC0809,0xFFA4061E,0xFFA4053D,0xFF9402EB,0xFF88019A,0xFF780001,0xBDFC0B58,0xFFAC095D,0xFF9C0882,0xFF7C0556,0xFF640335, -0xFF380001,0xDFF80B58,0xFF340882,0xFE6C0000,0xE8000B58,0xBDFC0B58,0xFFAC095D,0xFF9C0882,0xFF7C0556,0xFF640335,0xFF380001,0xDFF80B58,0xFF340882,0xFE6C0000,0xE8000B58,0xDFF80B58,0xFF340882,0xFE6C0000,0xE8000B58,0xE8000B58,0xFDCC0A58,0xFFCC0AB3,0xFFCC0B13,0xFFB40941,0xFFA407A1,0xFF7C0571,0xFF7C03E8,0xFF4802D0,0xFFC40A5B,0xFFB00926,0xFF700892,0xFE6C0000, -0xD7FC0B58,0x17425C6,0x17425C6,0x17425C6,0x17425C6,0xFF5C1969,0xFF5C1969,0xFF5C1969,0xFF380E81,0xFF380E81,0xFF300A69,0xFF441758,0xFF441758,0xFF441758,0xFF140831,0xFF140831,0xFF0001F9,0xFEF00984,0xFEF00984,0xF4E00104,0xDCE80884,0x31FC25C5,0x31FC25C5,0x31FC25C5,0xFEF01301,0xFEF01301,0xFECC0A69,0xFEA00EBB,0xFEA00EBB,0xFE640002,0xDC800884,0x9BF825C5, -0x9BF825C5,0xF2000BD5,0xD6000BF4,0xBA0025C5,0xFF682010,0xFF6C2345,0x17425C6,0xFF541A99,0xFF401434,0xFF2C0E5E,0xFF240BD8,0xFF040545,0xFF501F9B,0xFF4419D4,0xFEFC0F78,0xFE640002,0x7FFC25C5,0x1BC0882,0x1BC0882,0x1BC0882,0x1BC0882,0xFFA4053D,0xFFA4053D,0xFFA4053D,0xFF88019A,0xFF88019A,0xFF780001,0x9BFC0882,0x9BFC0882,0x9BFC0882,0xFF640335,0xFF640335, -0xFF380001,0xCFF80882,0xCFF80882,0xFE6C0000,0xDC000884,0x9BFC0882,0x9BFC0882,0x9BFC0882,0xFF640335,0xFF640335,0xFF380001,0xCFF80882,0xCFF80882,0xFE6C0000,0xDC000884,0xCFF80882,0xCFF80882,0xFE6C0000,0xDC000884,0xDC000884,0xFBB407C1,0xF5B80802,0x1BC0882,0xFFA4071A,0xFF9805F5,0xFF7C04C8,0xFF7C03E8,0xFF4802D0,0xFDB007C1,0xFF9806F5,0xC1FC0882,0xFE6C0000, -0xC1FC0882,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0x1300A69,0xFF0001F9,0xFF0001F9,0xFF0001F9,0xFF0001F9,0xFF0001F9, -0xFF0001F9,0xE0E80000,0xE0E80000,0xE0E80000,0xBCE80000,0x1C40A69,0x1C40A69,0x1C40A69,0x1C40A69,0x1C40A69,0x1C40A69,0xFE640002,0xFE640002,0xFE640002,0xBCA00000,0x67F80A69,0x67F80A69,0x67F80A69,0xB8000050,0x98000A69,0xFD280884,0x1300A69,0x1300A69,0xFF200659,0xFF1404BD,0xFF080340,0xFF080340,0xFEF400CD,0xFF1007E9,0xFD100622,0xFED8000A,0xFE640002, -0x3FF80A69,}; -static const uint32_t g_etc1_to_bc7_m6_table220[] = { -0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0x1740000,0x1740000,0x1740000,0x1740000,0x1740000,0x1740000,0x1740000,0x1740000,0x1740000,0x1740000,0x3FF80000, -0x3FF80000,0x3FF80000,0x3FF80000,0x7C000000,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xF80001,0xD080000,0xD080000,0xD080000,0x1740000,0xBFC0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000, -0x53FC0000,0xABF80000,0xABF80000,0xABF80000,0xC4000001,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0x53FC0000,0xABF80000,0xABF80000,0xABF80000,0xC4000001,0xABF80000,0xABF80000,0xABF80000,0xC4000001,0xC4000001,0xBA40000,0x18C0000,0x18C0000,0x1CC0000,0x1F00000,0x2BFC0000,0x2BFC0000,0x73FC0000,0x1CC0000,0x1F00000,0x95FC0000,0xABF80000, -0x95FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1A02C8F,0xFF8C2726,0xFF8822B7,0xFF80212E,0xFF801F75,0xFF68194A,0xFF6816D9,0xFF5810F7,0xFF4C0DDA,0xFF440A69,0xFF681F8A,0xFF5017A7,0xFF50145E,0xFF380C25,0xFF2C07B9,0xFF180271,0xFF200D42,0xFF080792,0xFAF8009A,0xEAF8087A,0x71FC2C8F,0xFF58247E,0xFF44212D,0xFF201735,0xFF081185,0xFEE80A69,0xFEF015BA,0xFEB80C99,0xFE880020,0xEA900879,0xB9FC2C8F, -0xFE84212D,0xF8000AED,0xE6000C45,0xD0002C91,0xFF8C262B,0xF79C2A69,0xF9A02B7E,0xFF701F1D,0xFF5816D7,0xFF3C0E7E,0xFF3C0AF6,0xFF1404FA,0xFF8025C2,0xFF681E1D,0xFF1C0D7A,0xFE880020,0xA7FC2C8F,0x1D80876,0xFFD00776,0xFFC806AE,0xFFC40659,0xFFC405E2,0xFFB00491,0xFFB003E8,0xFFA00226,0xFF940131,0xFF8C0000,0xC7FC0876,0xFFB806FA,0xFFA80659,0xFF8803F3,0xFF700262, -0xFF540000,0xE3FC0876,0xFF4C0659,0xFEA00000,0xEA000879,0xC7FC0876,0xFFB806FA,0xFFA80659,0xFF8803F3,0xFF700262,0xFF540000,0xE3FC0876,0xFF4C0659,0xFEA00000,0xEA000879,0xE3FC0876,0xFF4C0659,0xFEA00000,0xEA000879,0xEA000879,0xFFD0079D,0xFFCC0822,0xF5D80851,0xFFC006D9,0xFFAC05A1,0xFFA0042C,0xFF8C02F2,0xFF640209,0xFFD007BE,0xFFC006B9,0xFF840669,0xFEA00000, -0xDDF80876,0x180212E,0x180212E,0x180212E,0x180212E,0xFF6816D9,0xFF6816D9,0xFF6816D9,0xFF4C0DDA,0xFF4C0DDA,0xFF440A69,0xFF50145E,0xFF50145E,0xFF50145E,0xFF2C07B9,0xFF2C07B9,0xFF180271,0xFF080792,0xFF080792,0xF8F4007E,0xE2F8065A,0x43FC212D,0x43FC212D,0x43FC212D,0xFF081185,0xFF081185,0xFEE80A69,0xFEB80C99,0xFEB80C99,0xFE880020,0xE294065A,0xA3FC212D, -0xA3FC212D,0xF8000AC9,0xDC0008A6,0xC000212D,0xFF741C62,0xF9801F46,0x180212E,0xFF5C17A3,0xFF541226,0xFF3C0CEE,0xFF3C0AF6,0xFF1404FA,0xFF641BFE,0xFF5016B4,0xFF1C0D49,0xFE880020,0x8BFC212D,0x1C40659,0x1C40659,0x1C40659,0x1C40659,0xFFB003E8,0xFFB003E8,0xFFB003E8,0xFF940131,0xFF940131,0xFF8C0000,0xA9FC0659,0xA9FC0659,0xA9FC0659,0xFF700262,0xFF700262, -0xFF540000,0xD5F80659,0xD5F80659,0xFEA00000,0xE2000659,0xA9FC0659,0xA9FC0659,0xA9FC0659,0xFF700262,0xFF700262,0xFF540000,0xD5F80659,0xD5F80659,0xFEA00000,0xE2000659,0xD5F80659,0xD5F80659,0xFEA00000,0xE2000659,0xE2000659,0xFFBC05B4,0xFBC405E9,0x1C40659,0xFFB4054A,0xFFAC0480,0xFF9403B5,0xFF8C02F2,0xFF640209,0xFFB405BA,0xFFA4053D,0xC9FC0659,0xFEA00000, -0xC9FC0659,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0x1440A69,0xFF180271,0xFF180271,0xFF180271,0xFF180271,0xFF180271, -0xFF180271,0xE8FC0001,0xE8FC0001,0xE8FC0001,0xC4F80002,0x1E00A69,0x1E00A69,0x1E00A69,0x1E00A69,0x1E00A69,0x1E00A69,0xFE880020,0xFE880020,0xFE880020,0xC4B40001,0x73FC0A69,0x73FC0A69,0x73FC0A69,0xC200002D,0xA0000A69,0xF73C08C5,0x1440A69,0x1440A69,0xFF2C06B2,0xFF280521,0xFF1803BA,0xFF1803BA,0xFF080131,0xF9300841,0xFF200665,0xFEF0002D,0xFE880020, -0x4FFC0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table221[] = { -0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x18C0000,0x4BF80000, -0x4BF80000,0x4BF80000,0x4BF80000,0x84000000,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x1080001,0x11C0000,0x11C0000,0x11C0000,0x18C0000,0x1BFC0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x19C0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000, -0x6BFC0000,0xB7F80000,0xB7F80000,0xB7F80000,0xCC000001,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0x6BFC0000,0xB7F80000,0xB7F80000,0xB7F80000,0xCC000001,0xB7F80000,0xB7F80000,0xB7F80000,0xCC000001,0xCC000001,0x1B80000,0x19C0000,0x19C0000,0x1E00000,0x11FC0000,0x49FC0000,0x49FC0000,0x87FC0000,0x1E00000,0x11FC0000,0xA3FC0000,0xB7F80000, -0xA3FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1A826F7,0xFF982262,0xFF901EC2,0xFF8C1D72,0xFF8C1C09,0xFF7416DE,0xFF7414CD,0xFF640FDB,0xFF580D4E,0xFF540A69,0xFF741B8A,0xFF6814D7,0xFF5C120E,0xFF400B3C,0xFF380755,0xFF2402E9,0xFF2C0B0A,0xFF200632,0xFD08003A,0xEF080642,0x7DFC26F7,0xFF64202E,0xFF541D72,0xFF2C1515,0xFF201055,0xFF000A69,0xFEFC12C2,0xFED80B12,0xFEA00050,0xEEA00642,0xBFFC26F7, -0xFEA01D72,0xFE000A6D,0xE60008D5,0xD40026F9,0xFFA021AB,0xFBA42501,0xFDA825FE,0xFF801B4F,0xFF6C146F,0xFF540D63,0xFF3C0A46,0xFF2804D2,0xFF9020F8,0xFF741A72,0xFF300B96,0xFEA00050,0xAFFC26F7,0x1DC0642,0xFFD4058D,0xFFCC04F1,0xFFCC04B1,0xFFC40462,0xFFBC035D,0xFFBC02E4,0xFFAC0192,0xFFA000E5,0xFF9C0000,0xCFFC0641,0xFFB8052A,0xFFB404B1,0xFFA002E3,0xFF8801BA, -0xFF6C0000,0xE7FC0641,0xFF6404B1,0xFED40000,0xEE000641,0xCFFC0641,0xFFB8052A,0xFFB404B1,0xFFA002E3,0xFF8801BA,0xFF6C0000,0xE7FC0641,0xFF6404B1,0xFED40000,0xEE000641,0xE7FC0641,0xFF6404B1,0xFED40000,0xEE000641,0xEE000641,0xFFD805A2,0xF7DC0600,0xF7DC0621,0xFFC4051A,0xFFC0042D,0xFFA80302,0xFFA0022D,0xFF740184,0xFFD005AE,0xFFC804E1,0xFF9404BA,0xFED40000, -0xE1FC0641,0x18C1D72,0x18C1D72,0x18C1D72,0x18C1D72,0xFF7414CD,0xFF7414CD,0xFF7414CD,0xFF580D4E,0xFF580D4E,0xFF540A69,0xFF5C120E,0xFF5C120E,0xFF5C120E,0xFF380755,0xFF380755,0xFF2402E9,0xFF200632,0xFF200632,0xFB040032,0xE70804B2,0x53FC1D72,0x53FC1D72,0x53FC1D72,0xFF201055,0xFF201055,0xFF000A69,0xFED80B12,0xFED80B12,0xFEA00050,0xE6A804B2,0xABF81D72, -0xABF81D72,0xFC000A6D,0xE0000631,0xC4001D75,0xFF841959,0xFD881BB6,0x18C1D72,0xFF701549,0xFF581073,0xFF4C0C25,0xFF3C0A46,0xFF2804D2,0xFF7818E3,0xFF5C14A8,0xFF300B72,0xFEA00050,0x95FC1D72,0x1CC04B1,0x1CC04B1,0x1CC04B1,0x1CC04B1,0xFFBC02E4,0xFFBC02E4,0xFFBC02E4,0xFFA000E5,0xFFA000E5,0xFF9C0000,0xB5FC04B1,0xB5FC04B1,0xB5FC04B1,0xFF8801BA,0xFF8801BA, -0xFF6C0000,0xDBF804B1,0xDBF804B1,0xFED40000,0xE60004B1,0xB5FC04B1,0xB5FC04B1,0xB5FC04B1,0xFF8801BA,0xFF8801BA,0xFF6C0000,0xDBF804B1,0xDBF804B1,0xFED40000,0xE60004B1,0xDBF804B1,0xDBF804B1,0xFED40000,0xE60004B1,0xE60004B1,0xF7C80451,0xFFCC0451,0x1CC04B1,0xFDC003F5,0xFFAC0340,0xFFA002A8,0xFFA0022D,0xFF740184,0xF9C40451,0xFFB003E8,0xD1FC04B1,0xFED40000, -0xD1FC04B1,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0x1540A69,0xFF2402E9,0xFF2402E9,0xFF2402E9,0xFF2402E9,0xFF2402E9, -0xFF2402E9,0xF10C0001,0xF10C0001,0xF10C0001,0xCD080002,0x1F80A69,0x1F80A69,0x1F80A69,0x1F80A69,0x1F80A69,0x1F80A69,0xFEA00050,0xFEA00050,0xFEA00050,0xCCC40001,0x7FFC0A69,0x7FFC0A69,0x7FFC0A69,0xCA000012,0xA8000A69,0xFF4C08C5,0x1540A69,0x1540A69,0xFF3C06F5,0xFF34057A,0xFF34042A,0xFF34042A,0xFF1C0195,0xFF3C0845,0xFF34069A,0xFEFC007A,0xFEA00050, -0x5FF80A69,}; -static const uint32_t g_etc1_to_bc7_m6_table222[] = { -0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x1A40000,0x57F80000, -0x57F80000,0x57F80000,0x57F80000,0x8C000000,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x1180001,0x12C0000,0x12C0000,0x12C0000,0x1A40000,0x29FC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x1AC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000, -0x83FC0000,0xC3F80000,0xC3F80000,0xC3F80000,0xD4000001,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0x83FC0000,0xC3F80000,0xC3F80000,0xC3F80000,0xD4000001,0xC3F80000,0xC3F80000,0xC3F80000,0xD4000001,0xD4000001,0x1C80000,0x1AC0000,0x1AC0000,0x3F00000,0x37FC0000,0x67FC0000,0x67FC0000,0x9BFC0000,0x3F00000,0x37FC0000,0xB3FC0000,0xC3F80000, -0xB3FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1B021DF,0xFFA41E16,0xFF9C1B22,0xFF981A0E,0xFF9818ED,0xFF8014AA,0xFF8012F1,0xFF700EDF,0xFF700CCE,0xFF640A69,0xFF8017F2,0xFF741257,0xFF681006,0xFF580A54,0xFF4C0723,0xFF3C0361,0xFF380932,0xFF2C0506,0xFF18000A,0xF1180462,0x89FC21DF,0xFF701C46,0xFF641A0D,0xFF381345,0xFF2C0F41,0xFF180A69,0xFF14101A,0xFEF009AA,0xFEB800A0,0xF0B80461,0xC5FC21DF, -0xFEC01A0D,0xFE200A69,0xEC0005DD,0xD80021E1,0xFFA01D2B,0xFFAC2019,0xFFAC2106,0xFF881837,0xFF78124A,0xFF5C0C29,0xFF5009B3,0xFF4004BB,0xFF941CEE,0xFF801747,0xFF3C0A2E,0xFEB800A0,0xB7FC21DF,0x1E40462,0xFFDC03DA,0xFFD80371,0xFFD40349,0xFFD00306,0xFFC80259,0xFFC401F9,0xFFB80116,0xFFB8009D,0xFFAC0000,0xD5FC0461,0xFFCC03A1,0xFFC00349,0xFFAC01FB,0xFFA00132, -0xFF840000,0xEBF80461,0xFF7C0349,0xFF040000,0xF0000461,0xD5FC0461,0xFFCC03A1,0xFFC00349,0xFFAC01FB,0xFFA00132,0xFF840000,0xEBF80461,0xFF7C0349,0xFF040000,0xF0000461,0xEBF80461,0xFF7C0349,0xFF040000,0xF0000461,0xF0000461,0xFFD803F2,0xF9E0042C,0xF9E00449,0xFFD40382,0xFFC802E2,0xFFB80212,0xFFA80172,0xFF8C0112,0xFFDC03F8,0xFFC80371,0xFFA40352,0xFF040000, -0xE5FC0461,0x1981A0E,0x1981A0E,0x1981A0E,0x1981A0E,0xFF8012F1,0xFF8012F1,0xFF8012F1,0xFF700CCE,0xFF700CCE,0xFF640A69,0xFF681006,0xFF681006,0xFF681006,0xFF4C0723,0xFF4C0723,0xFF3C0361,0xFF2C0506,0xFF2C0506,0xFD180009,0xEB18034A,0x63FC1A0D,0x63FC1A0D,0x63FC1A0D,0xFF2C0F41,0xFF2C0F41,0xFF180A69,0xFEF009AA,0xFEF009AA,0xFEB800A0,0xEABC034A,0xB3F81A0D, -0xB3F81A0D,0xFE200A69,0xE6000425,0xCA001A0D,0xFF841689,0xFF8C18AA,0x1981A0E,0xFF801316,0xFF6C0EEB,0xFF5C0B29,0xFF5009B3,0xFF4004BB,0xFF80163E,0xFF741269,0xFF3C0A0A,0xFEB800A0,0x9FF81A0D,0x1D40349,0x1D40349,0x1D40349,0x1D40349,0xFFC401F9,0xFFC401F9,0xFFC401F9,0xFFB8009D,0xFFB8009D,0xFFAC0000,0xC1FC0349,0xC1FC0349,0xC1FC0349,0xFFA00132,0xFFA00132, -0xFF840000,0xE1F80349,0xE1F80349,0xFF040000,0xEA000349,0xC1FC0349,0xC1FC0349,0xC1FC0349,0xFFA00132,0xFFA00132,0xFF840000,0xE1F80349,0xE1F80349,0xFF040000,0xEA000349,0xE1F80349,0xE1F80349,0xFF040000,0xEA000349,0xEA000349,0xFBD002F9,0xFFCC0311,0x1D40349,0xFFC402B9,0xFFC00244,0xFFB001D4,0xFFA80172,0xFF8C0112,0xFDCC02F9,0xFFC402AD,0xD9FC0349,0xFF040000, -0xD9FC0349,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0x1640A69,0xFF3C0361,0xFF3C0361,0xFF3C0361,0xFF3C0361,0xFF3C0361, -0xFF3C0361,0xF91C0001,0xF91C0001,0xF91C0001,0xD5180002,0x13FC0A69,0x13FC0A69,0x13FC0A69,0x13FC0A69,0x13FC0A69,0x13FC0A69,0xFEB800A0,0xFEB800A0,0xFEB800A0,0xD4D40001,0x8BFC0A69,0x8BFC0A69,0x8BFC0A69,0xD4000005,0xB0000A69,0xF75C090A,0x1640A69,0x1640A69,0xFF4C073A,0xFF5005E9,0xFF440492,0xFF440492,0xFF300209,0xFB500884,0xFD4C0708,0xFF1800CD,0xFEB800A0, -0x6DFC0A69,}; -static const uint32_t g_etc1_to_bc7_m6_table223[] = { -0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x61FC0000, -0x61FC0000,0x61FC0000,0x61FC0000,0x94000000,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x1280001,0x73C0000,0x73C0000,0x73C0000,0x1BC0000,0x39FC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x1BC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000, -0x9BFC0000,0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0x9BFC0000,0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0xCFF80000,0xCFF80000,0xCFF80000,0xDC000001,0xDC000001,0x5D80000,0x1BC0000,0x1BC0000,0x17FC0000,0x5FFC0000,0x85FC0000,0x85FC0000,0xAFFC0000,0x17FC0000,0x5FFC0000,0xC1FC0000,0xCFF80000, -0xC1FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1B81D47,0xFFB01A42,0xFFA017DF,0xFFA016FE,0xFF98161D,0xFF9012AA,0xFF8C1145,0xFF7C0E03,0xFF7C0C4A,0xFF740A69,0xFF8C14C2,0xFF801027,0xFF740E46,0xFF640994,0xFF5806FB,0xFF5003DA,0xFF4C07C3,0xFF380432,0xFF2C0002,0xF32802DA,0x95FC1D47,0xFF7C18C6,0xFF7416FD,0xFF581187,0xFF400E66,0xFF300A69,0xFF2C0DD2,0xFF080882,0xFED80112,0xF4CC02D9,0xCBFC1D47, -0xFEE416FD,0xFE540A69,0xF000039A,0xDC001D49,0xFFA8198F,0xFFAC1C09,0xF5B81CBF,0xFF981527,0xFF801057,0xFF700B37,0xFF680929,0xFF4804DA,0xFFA01957,0xFF90147F,0xFF50092A,0xFED80112,0xBFF81D47,0x1E802D6,0xFFE00289,0xFFE0023E,0xFFDC0221,0xFFDC01F2,0xFFD00185,0xFFD00145,0xFFCC00C0,0xFFC00068,0xFFBC0000,0xDFFC02D6,0xFFD8025D,0xFFCC0221,0xFFB80143,0xFFAC00C2, -0xFF9C0000,0xEFFC02D6,0xFF940221,0xFF340000,0xF20002D9,0xDFFC02D6,0xFFD8025D,0xFFCC0221,0xFFB80143,0xFFAC00C2,0xFF9C0000,0xEFFC02D6,0xFF940221,0xFF340000,0xF20002D9,0xEFFC02D6,0xFF940221,0xFF340000,0xF20002D9,0xF20002D9,0xFFE40296,0xFDE802AC,0xFDE802C1,0xFFDC0238,0xFFD401E1,0xFFB80162,0xFFB800F5,0xFFA000A9,0xFFDC0298,0xFFDC0233,0xFFB40225,0xFF340000, -0xEBFC02D6,0x1A016FE,0x1A016FE,0x1A016FE,0x1A016FE,0xFF8C1145,0xFF8C1145,0xFF8C1145,0xFF7C0C4A,0xFF7C0C4A,0xFF740A69,0xFF740E46,0xFF740E46,0xFF740E46,0xFF5806FB,0xFF5806FB,0xFF5003DA,0xFF380432,0xFF380432,0xFF2C0002,0xEF280222,0x75FC16FD,0x75FC16FD,0x75FC16FD,0xFF400E66,0xFF400E66,0xFF300A69,0xFF080882,0xFF080882,0xFED80112,0xEED00222,0xBBFC16FD, -0xBBFC16FD,0xFE540A69,0xEC000289,0xD00016FD,0xFF901433,0xF9A015ED,0x1A016FE,0xFF88111E,0xFF800DB3,0xFF680A6E,0xFF680929,0xFF4804DA,0xFF9013B8,0xFF8010A6,0xFF500911,0xFED80112,0xA9FC16FD,0x1DC0221,0x1DC0221,0x1DC0221,0x1DC0221,0xFFD00145,0xFFD00145,0xFFD00145,0xFFC00068,0xFFC00068,0xFFBC0000,0xCDFC0221,0xCDFC0221,0xCDFC0221,0xFFAC00C2,0xFFAC00C2, -0xFF9C0000,0xE7F80221,0xE7F80221,0xFF340000,0xEE000221,0xCDFC0221,0xCDFC0221,0xCDFC0221,0xFFAC00C2,0xFFAC00C2,0xFF9C0000,0xE7F80221,0xE7F80221,0xFF340000,0xEE000221,0xE7F80221,0xE7F80221,0xFF340000,0xEE000221,0xEE000221,0xFFD801E1,0xF7DC0200,0x1DC0221,0xFFD401C2,0xFFC80179,0xFFB80131,0xFFB800F5,0xFFA000A9,0xFFD001ED,0xFFC801BD,0xDFFC0221,0xFF340000, -0xDFFC0221,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0x1740A69,0xFF5003DA,0xFF5003DA,0xFF5003DA,0xFF5003DA,0xFF5003DA, -0xFF5003DA,0xFF2C0002,0xFF2C0002,0xFF2C0002,0xDD280002,0x2BFC0A69,0x2BFC0A69,0x2BFC0A69,0x2BFC0A69,0x2BFC0A69,0x2BFC0A69,0xFED80112,0xFED80112,0xFED80112,0xDCE40001,0x97FC0A69,0x97FC0A69,0x97FC0A69,0xDC040001,0xB8000A69,0xFF6C090A,0x1740A69,0x1740A69,0xFF680782,0xFF580652,0xFF540502,0xFF540502,0xFF40028A,0xFF5808B4,0xFF500750,0xFF300132,0xFED80112, -0x7DF80A69,}; -static const uint32_t g_etc1_to_bc7_m6_table224[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x5C0001,0x5C0001,0x5C0001,0x5C0001,0x8C0000,0x8C0000,0x8C0000,0x1180000,0x1180000,0x2E000000,0x8C0000,0x8C0000,0x8C0000,0x1180000,0x1180000,0x2E000000,0x1180000,0x1180000,0x2E000000,0x2E000000,0x8C0000,0x8C0000,0x8C0000,0x1180000,0x1180000,0x2E000000,0x1180000,0x1180000,0x2E000000,0x2E000000,0x1180000, -0x1180000,0x2E000000,0x2E000000,0x2E000000,0x6C0000,0x640000,0x5C0001,0x800000,0x9C0000,0xC80000,0xE40000,0x15C0000,0x2740000,0x8C0000,0xC80000,0x2E000000,0xC80000,0x16C0001,0x25FC0000,0x95F80000,0xB6000000,0x25FC0000,0x95F80000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0x25FC0000,0x95F80000,0xB6000000,0x95F80000,0xB6000000, -0xB6000000,0x95F80000,0xB6000000,0xB6000000,0xB6000000,0x25FC0000,0x95F80000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0xB6000000,0x95F80000,0xB6000000,0xB6000000,0xB6000000,0xB6000000,0x1CC0000,0xB840000,0xB840000,0x4FFC0000,0x87F80000,0xA5F80000,0xB6000000,0xB6000000,0x3F00000,0x67FC0000,0xB3D80000,0xB6000000, -0x79FC0000,0x7457CA,0xFE442041,0xFE2005E5,0xB62005C1,0xFE182962,0xF4000585,0xB4000094,0xAA002420,0x96000F64,0x72002420,0xEA004691,0xCC001B02,0xA2000CAD,0x98002F04,0x88001816,0x6E002950,0x72004691,0x72002CBD,0x5C0036EC,0x4C004691,0xA857CA,0xAE002A47,0x92001711,0x860037C0,0x80001F6C,0x68002DF0,0x68004B75,0x6C0031E9,0x56003AAD,0x480048F9,0x15857CA, -0x5C003E8D,0x500043F0,0x44004F85,0x380057CA,0xFE3438A1,0xFA644CC8,0xFE6C4B89,0xFE001F2A,0xE200192D,0xAC001816,0x92001141,0x82001EEA,0xFE1837C5,0xFC002039,0x86002331,0x56003AAD,0xF057CA,0x984692,0xFE5C1A55,0xFE300461,0xB6300451,0xFE302822,0xF4000585,0xB4000094,0xAA002420,0x96000F64,0x72002420,0xE44691,0xCC001B02,0xA2000CAD,0x98002F04,0x88001816, -0x6E002950,0x1D04691,0x72002CBD,0x5C0036EC,0x4C004691,0xE44691,0xCC001B02,0xA2000CAD,0x98002F04,0x88001816,0x6E002950,0x1D04691,0x72002CBD,0x5C0036EC,0x4C004691,0x1D04691,0x72002CBD,0x5C0036EC,0x4C004691,0x4C004691,0xFE503353,0xFC883FC2,0xFE8C3D0E,0xFE001F2A,0xE200192D,0xAC001816,0x92001141,0x82001EEA,0xFE3433C8,0xFC001F39,0x860022F1,0x5C0036EC, -0x1484691,0x2005C1,0x2005C1,0x2005C1,0x2005C1,0x8E000000,0x8E000000,0x8E000000,0x44000001,0x44000001,0x2E000000,0x44000451,0x44000451,0x44000451,0x3400019A,0x3400019A,0x280000CD,0x22000451,0x22000451,0x200002A8,0x16000451,0x3005C1,0x3005C1,0x3005C1,0x2E0002A3,0x2E0002A3,0x28000176,0x1E0004C1,0x1E0004C1,0x1C000311,0x1400048E,0x5C05C1, -0x5C05C1,0x16000402,0x1000051E,0xE0005C2,0xF6000171,0xF21402AC,0x2005C1,0x900001D0,0x5A0001A8,0x440001A8,0x40000161,0x2E0001F9,0x9600030A,0x66000286,0x2A00045A,0x1C000311,0x4005C1,0x300451,0x300451,0x300451,0x300451,0x8E000000,0x8E000000,0x8E000000,0x44000001,0x44000001,0x2E000000,0x440451,0x440451,0x440451,0x3400019A,0x3400019A, -0x280000CD,0x880451,0x880451,0x200002A8,0x16000451,0x440451,0x440451,0x440451,0x3400019A,0x3400019A,0x280000CD,0x880451,0x880451,0x200002A8,0x16000451,0x880451,0x880451,0x200002A8,0x16000451,0x16000451,0xF6000171,0xF8200200,0x300451,0x900001D0,0x5A0001A8,0x440001A8,0x40000161,0x2E0001F9,0x960002B9,0x6C00025D,0x600451,0x200002A8, -0x600451,0xE42422,0xFE980C49,0xF8600001,0xB65C0001,0x1542420,0xF4000585,0xB4000094,0x2FFC2420,0x96000F64,0x72002420,0x1542420,0xF4000585,0xB4000094,0x2FFC2420,0x96000F64,0x72002420,0x2FFC2420,0x96000F64,0x72002420,0x72002420,0x1542420,0xF4000585,0xB4000094,0x2FFC2420,0x96000F64,0x72002420,0x2FFC2420,0x96000F64,0x72002420,0x72002420,0x2FFC2420, -0x96000F64,0x72002420,0x72002420,0x72002420,0xFAAC1E85,0x2F42420,0xF6DC1F81,0xFE4015A0,0xF6001009,0xBC000EF9,0x9E000AE1,0x9000133D,0xFE901E08,0xFE14145D,0xA6000988,0x72002420,0x1E82420,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table225[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x6C0001,0x6C0001,0x6C0001,0x6C0001,0xA40000,0xA40000,0xA40000,0x14C0000,0x14C0000,0x36000000,0xA40000,0xA40000,0xA40000,0x14C0000,0x14C0000,0x36000000,0x14C0000,0x14C0000,0x36000000,0x36000000,0xA40000,0xA40000,0xA40000,0x14C0000,0x14C0000,0x36000000,0x14C0000,0x14C0000,0x36000000,0x36000000,0x14C0000, -0x14C0000,0x36000000,0x36000000,0x36000000,0x800000,0x2740000,0x6C0001,0x940000,0xB80000,0xE80000,0x10C0000,0x1980000,0x2880000,0xA40000,0xE80000,0x36000000,0xE80000,0x17C0001,0x3DFC0000,0xA1F80000,0xBE000000,0x3DFC0000,0xA1F80000,0xBE000000,0xA1F80000,0xBE000000,0xBE000000,0x3DFC0000,0xA1F80000,0xBE000000,0xA1F80000,0xBE000000, -0xBE000000,0xA1F80000,0xBE000000,0xBE000000,0xBE000000,0x3DFC0000,0xA1F80000,0xBE000000,0xA1F80000,0xBE000000,0xBE000000,0xA1F80000,0xBE000000,0xBE000000,0xBE000000,0xA1F80000,0xBE000000,0xBE000000,0xBE000000,0xBE000000,0x1E00000,0x1980000,0x1980000,0x63FC0000,0x95F80000,0xAFF80000,0xBE000000,0xBE000000,0xFFC0000,0x77FC0000,0xBBE80000,0xBE000000, -0x87FC0000,0x7C5F3A,0xFE442651,0xFE280892,0xBE2407E1,0xFE242C5A,0xFA0004BD,0xBA000034,0xB6002420,0x9C000E48,0x7A002420,0xF8004B86,0xE2001C71,0xA8000DB5,0xA200306B,0x92001820,0x74002A0C,0x78004B89,0x78002F69,0x660039D9,0x50004B89,0xB45F3A,0xBA002DB7,0xA2001906,0x92003AA0,0x86002070,0x6E002F60,0x6E005129,0x72003541,0x60003DE9,0x4C004E42,0x1705F3A, -0x5C0043BD,0x56004888,0x440055C5,0x3C005F3A,0xFE503ED3,0xFE6C5368,0xFE6C52D9,0xFE142325,0xF600193D,0xBC0017ED,0x9E0010D5,0x8A001F71,0xFE183E05,0xFC002279,0x9400251B,0x60003DE9,0x1005F3A,0xA44B86,0xFE681ED9,0xFE38064D,0xBE3805E9,0xFE3C2A76,0xFA0004BD,0xBA000034,0xB6002420,0x9C000E48,0x7A002420,0xF44B86,0xE2001C71,0xA8000DB5,0xA200306B,0x92001820, -0x74002A0C,0x1F04B86,0x78002F69,0x660039D9,0x50004B89,0xF44B86,0xE2001C71,0xA8000DB5,0xA200306B,0x92001820,0x74002A0C,0x1F04B86,0x78002F69,0x660039D9,0x50004B89,0x1F04B86,0x78002F69,0x660039D9,0x50004B89,0x50004B89,0xFE64380A,0xFE8C4466,0xFE8C426E,0xFE1422C1,0xF600193D,0xBC0017ED,0x9E0010D5,0x8A001F71,0xFE443845,0xFC002179,0x940024CA,0x660039D9, -0x15C4B86,0x2407E1,0x2407E1,0x2407E1,0x2407E1,0xA6000000,0xA6000000,0xA6000000,0x50000001,0x50000001,0x36000000,0x500005E9,0x500005E9,0x500005E9,0x40000232,0x40000232,0x2E000121,0x280005E9,0x280005E9,0x260003A4,0x1A0005E9,0x3407E1,0x3407E1,0x3407E1,0x340003AB,0x340003AB,0x2E000202,0x2200067A,0x2200067A,0x20000441,0x18000635,0x6807E1, -0x6807E1,0x1C000576,0x160006F2,0x120007E2,0xF8040269,0xF61C042C,0x2407E1,0xA400028A,0x68000249,0x4C000254,0x4C0001E1,0x380002BA,0xA400042E,0x72000363,0x320005F2,0x20000441,0x4C07E1,0x3805E9,0x3805E9,0x3805E9,0x3805E9,0xA6000000,0xA6000000,0xA6000000,0x50000001,0x50000001,0x36000000,0x5005E9,0x5005E9,0x5005E9,0x40000232,0x40000232, -0x2E000121,0xA005E9,0xA005E9,0x260003A4,0x1A0005E9,0x5005E9,0x5005E9,0x5005E9,0x40000232,0x40000232,0x2E000121,0xA005E9,0xA005E9,0x260003A4,0x1A0005E9,0xA005E9,0xA005E9,0x260003A4,0x1A0005E9,0x1A0005E9,0xF8040265,0xFC280320,0x3805E9,0xA400028A,0x68000249,0x4C000254,0x4C0001E1,0x380002BA,0xB40003B5,0x72000332,0x7005E9,0x260003A4, -0x7005E9,0xF42422,0xFEB00D41,0xFE700002,0xBE6C0001,0x16C2420,0xFA0004BD,0xBA000034,0x3BFC2420,0x9C000E48,0x7A002420,0x16C2420,0xFA0004BD,0xBA000034,0x3BFC2420,0x9C000E48,0x7A002420,0x3BFC2420,0x9C000E48,0x7A002420,0x7A002420,0x16C2420,0xFA0004BD,0xBA000034,0x3BFC2420,0x9C000E48,0x7A002420,0x3BFC2420,0x9C000E48,0x7A002420,0x7A002420,0x3BFC2420, -0x9C000E48,0x7A002420,0x7A002420,0x7A002420,0xFEB41EAD,0xB042420,0xFEEC1F81,0xFE6C1661,0xF6000F79,0xBC000E29,0xA80009CD,0x94001248,0xFE981E3A,0xFE401528,0xB400084A,0x7A002420,0x7FC2420,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table226[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x7C0001,0x7C0001,0x7C0001,0x7C0001,0xBC0000,0xBC0000,0xBC0000,0x17C0000,0x17C0000,0x3E000000,0xBC0000,0xBC0000,0xBC0000,0x17C0000,0x17C0000,0x3E000000,0x17C0000,0x17C0000,0x3E000000,0x3E000000,0xBC0000,0xBC0000,0xBC0000,0x17C0000,0x17C0000,0x3E000000,0x17C0000,0x17C0000,0x3E000000,0x3E000000,0x17C0000, -0x17C0000,0x3E000000,0x3E000000,0x3E000000,0x4900000,0xA840000,0x7C0001,0xAC0000,0xD40000,0x10C0000,0x1340000,0x1D40000,0x29C0000,0xBC0000,0x10C0000,0x3E000000,0x10C0000,0x18C0001,0x55FC0000,0xADF80000,0xC6000000,0x55FC0000,0xADF80000,0xC6000000,0xADF80000,0xC6000000,0xC6000000,0x55FC0000,0xADF80000,0xC6000000,0xADF80000,0xC6000000, -0xC6000000,0xADF80000,0xC6000000,0xC6000000,0xC6000000,0x55FC0000,0xADF80000,0xC6000000,0xADF80000,0xC6000000,0xC6000000,0xADF80000,0xC6000000,0xC6000000,0xC6000000,0xADF80000,0xC6000000,0xC6000000,0xC6000000,0xC6000000,0x1F40000,0x1A80000,0x1A80000,0x77FC0000,0xA1FC0000,0xB9F80000,0xC6000000,0xC6000000,0x2FFC0000,0x89FC0000,0xC3F80000,0xC6000000, -0x97FC0000,0x84672A,0xFE502CD1,0xFE2C0BE9,0xC6280A59,0xFE303022,0xFE0404C5,0xC6000004,0xC2002420,0xA6000D61,0x82002420,0xFE0450E5,0xE8001E1D,0xB4000EED,0xAE003223,0x98001848,0x7A002AE0,0x800050D1,0x7E00325D,0x6C003CB9,0x560050D1,0xC0672A,0xC6003187,0xA2001B66,0xA2003D84,0x920021A0,0x740030F0,0x74005745,0x780038E9,0x6600415D,0x520053E2,0x188672A, -0x66004956,0x5C004D70,0x4A005C5D,0x4000672A,0xFE504513,0xFE6C5AE8,0xF67C5B12,0xFE142775,0xF60019AD,0xBC00181D,0xA60010A0,0x90002036,0xFE3444C8,0xFE0025AA,0x96002723,0x6600415D,0x114672A,0xB050D2,0xFE7423CD,0xFE4008E2,0xC64007C1,0xFE442D24,0xFE0404C1,0xC6000004,0xC2002420,0xA6000D61,0x82002420,0x30050D1,0xE8001E1D,0xB4000EED,0xAE003223,0x98001848, -0x7A002AE0,0x5FC50D1,0x7E00325D,0x6C003CB9,0x560050D1,0x30050D1,0xE8001E1D,0xB4000EED,0xAE003223,0x98001848,0x7A002AE0,0x5FC50D1,0x7E00325D,0x6C003CB9,0x560050D1,0x5FC50D1,0x7E00325D,0x6C003CB9,0x560050D1,0x560050D1,0xFE783CC9,0xF8A049A0,0xFCA84789,0xFE142711,0xF60019AD,0xBC00181D,0xA60010A0,0x90002036,0xFC583D2B,0xFE0424A1,0x960026D2,0x6C003CB9, -0x17050D1,0x280A59,0x280A59,0x280A59,0x280A59,0xBE000000,0xBE000000,0xBE000000,0x5C000001,0x5C000001,0x3E000000,0x5C0007C1,0x5C0007C1,0x5C0007C1,0x4C0002EA,0x4C0002EA,0x3A000179,0x2E0007C1,0x2E0007C1,0x2C0004C8,0x1E0007C1,0x23C0A56,0x23C0A56,0x23C0A56,0x400004DB,0x400004DB,0x340002A6,0x28000882,0x28000882,0x2600058D,0x1E000825,0x7C0A56, -0x7C0A56,0x2000074C,0x1A00092D,0x14000A56,0xFA0803B9,0xF8200600,0x280A59,0xBA00034D,0x7C000301,0x62000308,0x5600028A,0x40000385,0xC200057A,0x9000047B,0x3A0007D1,0x2600058D,0x580A56,0x4007C1,0x4007C1,0x4007C1,0x4007C1,0xBE000000,0xBE000000,0xBE000000,0x5C000001,0x5C000001,0x3E000000,0x5C07C1,0x5C07C1,0x5C07C1,0x4C0002EA,0x4C0002EA, -0x3A000179,0xB807C1,0xB807C1,0x2C0004C8,0x1E0007C1,0x5C07C1,0x5C07C1,0x5C07C1,0x4C0002EA,0x4C0002EA,0x3A000179,0xB807C1,0xB807C1,0x2C0004C8,0x1E0007C1,0xB807C1,0xB807C1,0x2C0004C8,0x1E0007C1,0x1E0007C1,0xFC0C039D,0xFE2C0488,0x4007C1,0xBA00034D,0x7C000301,0x62000308,0x5600028A,0x40000385,0xC20004EA,0x9000042A,0x8007C1,0x2C0004C8, -0x8007C1,0x1042422,0xFEC40E2A,0xFE84002D,0xC67C0001,0x1842420,0xFE0804B5,0xC6000004,0x47FC2420,0xA6000D61,0x82002420,0x1842420,0xFE0804B5,0xC6000004,0x47FC2420,0xA6000D61,0x82002420,0x47FC2420,0xA6000D61,0x82002420,0x82002420,0x1842420,0xFE0804B5,0xC6000004,0x47FC2420,0xA6000D61,0x82002420,0x47FC2420,0xA6000D61,0x82002420,0x82002420,0x47FC2420, -0xA6000D61,0x82002420,0x82002420,0x82002420,0xFED01F04,0x1182420,0xF6FC2002,0xFE6C1711,0xFE0C0F79,0xD0000D00,0xB00008C8,0x9C001174,0xFEAC1EC1,0xFE4C15DD,0xBE000734,0x82002420,0x17FC2420,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table227[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0x8C0001,0x8C0001,0x8C0001,0x8C0001,0x2D00000,0x2D00000,0x2D00000,0x1AC0000,0x1AC0000,0x46000000,0x2D00000,0x2D00000,0x2D00000,0x1AC0000,0x1AC0000,0x46000000,0x1AC0000,0x1AC0000,0x46000000,0x46000000,0x2D00000,0x2D00000,0x2D00000,0x1AC0000,0x1AC0000,0x46000000,0x1AC0000,0x1AC0000,0x46000000,0x46000000,0x1AC0000, -0x1AC0000,0x46000000,0x46000000,0x46000000,0xA40000,0x980000,0x8C0001,0xC00000,0x2EC0000,0x12C0000,0x15C0000,0x5F80000,0x2B00000,0x2D00000,0x12C0000,0x46000000,0x12C0000,0x19C0001,0x6FFC0000,0xB9F80000,0xCE000000,0x6FFC0000,0xB9F80000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0x6FFC0000,0xB9F80000,0xCE000000,0xB9F80000,0xCE000000, -0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0x6FFC0000,0xB9F80000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0xB9F80000,0xCE000000,0xCE000000,0xCE000000,0xCE000000,0x15FC0000,0x5B80000,0x5B80000,0x8BFC0000,0xAFFC0000,0xC3F80000,0xCE000000,0xCE000000,0x4DFC0000,0x99FC0000,0xCDCC0000,0xCE000000, -0xA5FC0000,0x8C6F9A,0xFE5C3409,0xFE380FFD,0xCE300D21,0xFE303482,0xFE080585,0xD0000008,0xCE002420,0xAC000C6D,0x8A002420,0xFE0C56D6,0xF4002035,0xBA00107D,0xB40033FB,0xA200187A,0x80002BCC,0x8A005671,0x84003599,0x72003FC9,0x5C005671,0xCC6F9A,0xD20035B7,0xAE001E26,0xA20040A4,0x980022EC,0x7A0032A0,0x80005DB5,0x7E003CE1,0x6C004509,0x580059E2,0x1A06F9A, -0x6C004F2A,0x5C0052B0,0x5000636D,0x44006F9A,0xFE504C53,0xF8806322,0xFA846322,0xFE142CC5,0xFC001ADA,0xCC001898,0xAE001085,0x980020F9,0xFE344BA8,0xFE0029CA,0x9E0029C1,0x6C004509,0x1246F9A,0xB85672,0xFE802931,0xFE4C0BF6,0xCE4809D9,0xFE503080,0xFE080575,0xCE040008,0xCE002420,0xAC000C6D,0x8A002420,0x1145671,0xF4002035,0xBA00107D,0xB40033FB,0xA200187A, -0x80002BCC,0xFF85671,0x84003599,0x72003FC9,0x5C005671,0x1145671,0xF4002035,0xBA00107D,0xB40033FB,0xA200187A,0x80002BCC,0xFF85671,0x84003599,0x72003FC9,0x5C005671,0xFF85671,0x84003599,0x72003FC9,0x5C005671,0x5C005671,0xFE7841F9,0xFEAC4ECC,0xFEAC4D09,0xFE302BF5,0xFC001ADA,0xCC001898,0xAE001085,0x980020F9,0xFE5C422B,0xFE0428A1,0x9E00295D,0x72003FC9, -0x18C5671,0x300D21,0x300D21,0x300D21,0x300D21,0xD6000000,0xD6000000,0xD6000000,0x68000000,0x68000000,0x46000000,0x6A0009D9,0x6A0009D9,0x6A0009D9,0x520003BA,0x520003BA,0x400001DD,0x340009D9,0x340009D9,0x32000614,0x220009D9,0x2440D21,0x2440D21,0x2440D21,0x46000633,0x46000633,0x3A000362,0x2E000AD2,0x2E000AD2,0x2C000709,0x22000A52,0x8C0D21, -0x8C0D21,0x26000948,0x1C000B96,0x16000D22,0xFC0C0561,0xFA24082C,0x300D21,0xD000042A,0x860003D9,0x6A0003D4,0x62000334,0x4A000484,0xE4000704,0x900005AB,0x400009E9,0x2C000709,0x640D21,0x4809D9,0x4809D9,0x4809D9,0x4809D9,0xD6000000,0xD6000000,0xD6000000,0x68000000,0x68000000,0x46000000,0x6809D9,0x6809D9,0x6809D9,0x520003BA,0x520003BA, -0x400001DD,0xD009D9,0xD009D9,0x32000614,0x220009D9,0x6809D9,0x6809D9,0x6809D9,0x520003BA,0x520003BA,0x400001DD,0xD009D9,0xD009D9,0x32000614,0x220009D9,0xD009D9,0xD009D9,0x32000614,0x220009D9,0x220009D9,0xFE100521,0xF4380659,0x4809D9,0xD000042A,0x860003D9,0x6A0003D4,0x62000334,0x4A000484,0xF400063D,0x9A000551,0x9409D9,0x32000614, -0x9409D9,0x1142422,0xFED00F3A,0xFE940082,0xCE8C0001,0x19C2420,0xFE080565,0xCE080000,0x53FC2420,0xAC000C6D,0x8A002420,0x19C2420,0xFE080565,0xCE080000,0x53FC2420,0xAC000C6D,0x8A002420,0x53FC2420,0xAC000C6D,0x8A002420,0x8A002420,0x19C2420,0xFE080565,0xCE080000,0x53FC2420,0xAC000C6D,0x8A002420,0x53FC2420,0xAC000C6D,0x8A002420,0x8A002420,0x53FC2420, -0xAC000C6D,0x8A002420,0x8A002420,0x8A002420,0xF6E81F81,0x1282420,0xFF0C2002,0xFE9417C2,0xFE100FE9,0xDA000BE9,0xB40007B4,0xA800109D,0xFCD01F02,0xFE6416CD,0xC6000659,0x8A002420,0x25FC2420,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table228[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0xA00000,0xA00000,0xA00000,0xA00000,0xEC0000,0xEC0000,0xEC0000,0x1E40000,0x1E40000,0x4E000001,0xEC0000,0xEC0000,0xEC0000,0x1E40000,0x1E40000,0x4E000001,0x1E40000,0x1E40000,0x4E000001,0x4E000001,0xEC0000,0xEC0000,0xEC0000,0x1E40000,0x1E40000,0x4E000001,0x1E40000,0x1E40000,0x4E000001,0x4E000001,0x1E40000, -0x1E40000,0x4E000001,0x4E000001,0x4E000001,0x4B80000,0xCA80000,0xA00000,0xD80000,0x10C0000,0x1540000,0x1880000,0x11FC0000,0xC80000,0xEC0000,0x1540000,0x4E000001,0x1540000,0x1B00000,0x89FC0000,0xC5FC0000,0xD6000001,0x89FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0x89FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xD6000001, -0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0x89FC0000,0xC5FC0000,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0xC5FC0000,0xD6000001,0xD6000001,0xD6000001,0xD6000001,0x41FC0000,0x1CC0000,0x1CC0000,0xA1FC0000,0xBFF80000,0xCFF40000,0xD6000001,0xD6000001,0x6FFC0000,0xADFC0000,0xD5FC0000,0xD6000001, -0xB7FC0000,0x9479B0,0xFE5C3CE5,0xFE381579,0xD63410AD,0xFE3C3A48,0xFE08077D,0xD804003A,0xDC002420,0xB8000B51,0x92002422,0xFE185E40,0xFA0022E9,0xC6001283,0xC0003629,0xAE0018E6,0x8C002CC6,0x92005D2B,0x90003993,0x78004373,0x62005D2B,0xDC79B0,0xE2003A6D,0xB40021B4,0xAE00448A,0xA200246F,0x86003492,0x8600656B,0x840041BB,0x7200496F,0x5E006114,0x1BC79B0, -0x72005634,0x66005924,0x56006BE7,0x480079B4,0xFE645556,0xFC886C60,0xFE8C6CD0,0xFE1833EE,0xFC001D3E,0xDA0018C5,0xBC00109D,0xA00021F6,0xFE345496,0xFE042F97,0xA6002D3F,0x7200496F,0x13879B0,0xC45D2C,0xFE8C2FC1,0xFE581024,0xD6500C81,0xFE5C34E6,0xFE140759,0xDA080032,0xDC002420,0xB8000B51,0x92002422,0x3245D2B,0xFA0022E9,0xC6001283,0xC0003629,0xAE0018E6, -0x8C002CC6,0x17FC5D2B,0x90003993,0x78004373,0x62005D2B,0x3245D2B,0xFA0022E9,0xC6001283,0xC0003629,0xAE0018E6,0x8C002CC6,0x17FC5D2B,0x90003993,0x78004373,0x62005D2B,0x17FC5D2B,0x90003993,0x78004373,0x62005D2B,0x62005D2B,0xFE9448B3,0xFEAC5556,0xF8C05444,0xFE4031C3,0xFC001D3E,0xDA0018C5,0xBC00109D,0xA00021F6,0xFE5C48FD,0xFE042E53,0xA6002CDB,0x78004373, -0x1A45D2B,0x3410AC,0x3410AC,0x3410AC,0x3410AC,0xF2000000,0xF2000000,0xF2000000,0x76000000,0x76000000,0x4E000001,0x78000C80,0x78000C80,0x78000C80,0x620004A9,0x620004A9,0x46000262,0x3A000C80,0x3A000C80,0x380007B5,0x26000C82,0x5010AB,0x5010AB,0x5010AB,0x4C0007F2,0x4C0007F2,0x40000453,0x34000DC1,0x34000DC1,0x320008EE,0x24000D22,0xA010AB, -0xA010AB,0x2C000BD1,0x20000EC6,0x1A0010AB,0xFE1007AA,0xFE2C0B01,0x3410AC,0xEC000562,0x9E0004E1,0x800004FD,0x6E00040D,0x560005C9,0xF40008E9,0xB2000742,0x46000C98,0x320008EE,0x7010AB,0x500C80,0x500C80,0x500C80,0x500C80,0xF2000000,0xF2000000,0xF2000000,0x76000000,0x76000000,0x4E000001,0x2740C80,0x2740C80,0x2740C80,0x620004A9,0x620004A9, -0x46000262,0xF00C80,0xF00C80,0x380007B5,0x26000C82,0x2740C80,0x2740C80,0x2740C80,0x620004A9,0x620004A9,0x46000262,0xF00C80,0xF00C80,0x380007B5,0x26000C82,0xF00C80,0xF00C80,0x380007B5,0x26000C82,0x26000C82,0xFE200745,0xF8400884,0x500C80,0xEC000562,0x9E0004E1,0x800004FD,0x6E00040D,0x560005C9,0xF4000808,0xB20006C9,0xA80C80,0x380007B5, -0xA80C80,0x1282420,0xFEE81074,0xFEAC0124,0xD6A00001,0x1B82420,0xFE2C069D,0xD61C0001,0x61F82420,0xB8000B51,0x92002422,0x1B82420,0xFE2C069D,0xD61C0001,0x61F82420,0xB8000B51,0x92002422,0x61F82420,0xB8000B51,0x92002422,0x92002422,0x1B82420,0xFE2C069D,0xD61C0001,0x61F82420,0xB8000B51,0x92002422,0x61F82420,0xB8000B51,0x92002422,0x92002422,0x61F82420, -0xB8000B51,0x92002422,0x92002422,0x92002422,0xFEF81F85,0x13C2420,0xF9202081,0xFEB018A0,0xFE281109,0xE8000B14,0xBE0006B2,0xB2000F82,0xFEDC1F22,0xFE881771,0xD4000541,0x92002422,0x37FC2420,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table229[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x1,0xB00000,0xB00000,0xB00000,0xB00000,0x1040000,0x1040000,0x1040000,0x7FC0000,0x7FC0000,0x56000001,0x1040000,0x1040000,0x1040000,0x7FC0000,0x7FC0000,0x56000001,0x7FC0000,0x7FC0000,0x56000001,0x56000001,0x1040000,0x1040000,0x1040000,0x7FC0000,0x7FC0000,0x56000001,0x7FC0000,0x7FC0000,0x56000001,0x56000001,0x7FC0000, -0x7FC0000,0x56000001,0x56000001,0x56000001,0xCC0000,0xBC0000,0xB00000,0xF00000,0x1280000,0x1740000,0x1AC0000,0x1DF40000,0xDC0000,0x1040000,0x1740000,0x56000001,0x1740000,0x1C00000,0xA3FC0000,0xD1FC0000,0xDE000001,0xA3FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xDE000001,0xDE000001,0xA3FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xDE000001, -0xDE000001,0xD1FC0000,0xDE000001,0xDE000001,0xDE000001,0xA3FC0000,0xD1FC0000,0xDE000001,0xD1FC0000,0xDE000001,0xDE000001,0xD1FC0000,0xDE000001,0xDE000001,0xDE000001,0xD1FC0000,0xDE000001,0xDE000001,0xDE000001,0xDE000001,0x69FC0000,0x7DC0000,0x7DC0000,0xB3FC0000,0xCBFC0000,0xD9F40000,0xDE000001,0xDE000001,0x8DFC0000,0xBDFC0000,0xDFD00000,0xDE000001, -0xC5FC0000,0x9C8330,0xFE684541,0xFE401B24,0xDE3C142D,0xFE443FEA,0xFE140A2D,0xE008009A,0xE6002422,0xC4000A69,0x9A002422,0xFE246584,0xFA002639,0xCC0014AB,0xCC003831,0xB4001956,0x92002DC2,0x9A006380,0x96003D53,0x7E0046EB,0x66006383,0xE88330,0xE8003F39,0xC0002534,0xBA00483A,0xA8002617,0x8C00366A,0x8C006CB7,0x8A00465F,0x78004D93,0x620067CB,0x1D88330, -0x78005CE4,0x6C005F04,0x5C0073EF,0x4C008334,0xFE645DA6,0xFE8C7530,0xFE8C7650,0xFE303A6D,0xFE04205E,0xDE001961,0xC40010B2,0xAA002336,0xFE445CDB,0xFE0435B7,0xB600301B,0x78004D93,0x14C8330,0xD06380,0xFE983611,0xFE641478,0xDE580F21,0xFE683962,0xFE2009C5,0xE20C007E,0xE6002422,0xC4000A69,0x9A002422,0x1346380,0xFA002639,0xCC0014AB,0xCC003831,0xB4001956, -0x92002DC2,0x1FF86380,0x96003D53,0x7E0046EB,0x66006383,0x1346380,0xFA002639,0xCC0014AB,0xCC003831,0xB4001956,0x92002DC2,0x1FF86380,0x96003D53,0x7E0046EB,0x66006383,0x1FF86380,0x96003D53,0x7E0046EB,0x66006383,0x66006383,0xFE944E93,0xFAC45BA4,0xFCC85A64,0xFE403763,0xFE04205A,0xDE001961,0xC40010B2,0xAA002336,0xFE784F21,0xFE18341D,0xB6002FA2,0x7E0046EB, -0x1B86380,0x3C142C,0x3C142C,0x3C142C,0x3C142C,0xFE000010,0xFE000010,0xFE000010,0x82000000,0x82000000,0x56000001,0x84000F20,0x84000F20,0x84000F20,0x680005A5,0x680005A5,0x4C0002EA,0x40000F20,0x40000F20,0x3E000955,0x2A000F22,0x54142B,0x54142B,0x54142B,0x580009A2,0x580009A2,0x46000543,0x3A0010A9,0x3A0010A9,0x38000ACE,0x28000FDB,0xAC142B, -0xAC142B,0x2C000E41,0x240011F3,0x1C00142B,0xFE100A3A,0xFE2C0DF1,0x3C142C,0xFA000682,0xA80005ED,0x840005EA,0x800004FD,0x56000709,0xF4000B09,0xB20008D2,0x52000F39,0x38000ACE,0x78142B,0x580F20,0x580F20,0x580F20,0x580F20,0xFE04000D,0xFE04000D,0xFE04000D,0x82000000,0x82000000,0x56000001,0x2800F20,0x2800F20,0x2800F20,0x680005A5,0x680005A5, -0x4C0002EA,0x1080F20,0x1080F20,0x3E000955,0x2A000F22,0x2800F20,0x2800F20,0x2800F20,0x680005A5,0x680005A5,0x4C0002EA,0x1080F20,0x1080F20,0x3E000955,0x2A000F22,0x1080F20,0x1080F20,0x3E000955,0x2A000F22,0x2A000F22,0xFE200965,0xFC480AB4,0x580F20,0xFA000682,0xA80005ED,0x840005EA,0x800004FD,0x56000709,0xF6040A20,0xBC000848,0xB80F20,0x3E000955, -0xB80F20,0x1382420,0xFF0011A4,0xFEB801F4,0xDEB00001,0x1D02420,0xFE4C07F9,0xDE2C0001,0x6DF82420,0xC4000A69,0x9A002422,0x1D02420,0xFE4C07F9,0xDE2C0001,0x6DF82420,0xC4000A69,0x9A002422,0x6DF82420,0xC4000A69,0x9A002422,0x9A002422,0x1D02420,0xFE4C07F9,0xDE2C0001,0x6DF82420,0xC4000A69,0x9A002422,0x6DF82420,0xC4000A69,0x9A002422,0x9A002422,0x6DF82420, -0xC4000A69,0x9A002422,0x9A002422,0x9A002422,0xFD102000,0x14C2420,0xFF2C208D,0xFEC01945,0xFE501231,0xF6000A12,0xC80005D2,0xBA000EBA,0xFEF01FA9,0xFEA01865,0xDE000465,0x9A002422,0x45FC2420,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table230[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000, -0x40000,0x80000,0x80000,0x80000,0x1,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x80000,0x80000,0x80000,0x1,0x80000,0x80000,0x80000,0x1,0x1,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x40000,0x80000,0x80000, -0x80000,0xC00000,0xC00000,0xC00000,0xC00000,0x11C0000,0x11C0000,0x11C0000,0x13FC0000,0x13FC0000,0x5E000001,0x11C0000,0x11C0000,0x11C0000,0x13FC0000,0x13FC0000,0x5E000001,0x13FC0000,0x13FC0000,0x5E000001,0x5E000001,0x11C0000,0x11C0000,0x11C0000,0x13FC0000,0x13FC0000,0x5E000001,0x13FC0000,0x13FC0000,0x5E000001,0x5E000001,0x13FC0000, -0x13FC0000,0x5E000001,0x5E000001,0x5E000001,0xE00000,0xCC0000,0xC00000,0x1040000,0x3400000,0x1980000,0x1D40000,0x27F80000,0xF00000,0x11C0000,0x1980000,0x5E000001,0x1980000,0x1D00000,0xBBFC0000,0xDDFC0000,0xE6000001,0xBBFC0000,0xDDFC0000,0xE6000001,0xDDFC0000,0xE6000001,0xE6000001,0xBBFC0000,0xDDFC0000,0xE6000001,0xDDFC0000,0xE6000001, -0xE6000001,0xDDFC0000,0xE6000001,0xE6000001,0xE6000001,0xBBFC0000,0xDDFC0000,0xE6000001,0xDDFC0000,0xE6000001,0xE6000001,0xDDFC0000,0xE6000001,0xE6000001,0xE6000001,0xDDFC0000,0xE6000001,0xE6000001,0xE6000001,0xE6000001,0x91FC0000,0xFEC0000,0xFEC0000,0xC7FC0000,0xD9FC0000,0xE3F40000,0xE6000001,0xE6000001,0xABFC0000,0xCFFC0000,0xE7E00000,0xE6000001, -0xD5FC0000,0xA48BEC,0xFE744D71,0xFE4C20D8,0xE6401785,0xFE5045F6,0xFE140D79,0xEC0C0111,0xF2042424,0xCA00098D,0xA2002426,0xFE306BE4,0xFA002945,0xD80015EB,0xD8003941,0xC00018FE,0x98002E12,0xA2006878,0x9C003FBB,0x84004933,0x6C00687B,0xF48BEC,0xEE004349,0xC6002804,0xC6004B2A,0xAE002717,0x920037A6,0x980072CF,0x960049C7,0x7E00509F,0x68006D47,0x1F08BEC, -0x7E0062AC,0x72006404,0x5C007ADF,0x52008BEC,0xFE786595,0xFE8C7DDC,0xF8A07F6D,0xFE3040E1,0xFE04237E,0xEE00192E,0xC8000FFB,0xB6002345,0xFE546487,0xFE043C07,0xB60031CB,0x7E00509F,0x15C8BEC,0xDC6878,0xFEA43B8D,0xFE701888,0xE6601145,0xFE743D82,0xFE2C0C8D,0xEA1400D9,0xF2042420,0xCA00098D,0xA2042422,0x3446878,0xFA002945,0xD80015EB,0xD8003941,0xC00018FE, -0x98002E12,0x27FC6878,0x9C003FBB,0x84004933,0x6C00687B,0x3446878,0xFA002945,0xD80015EB,0xD8003941,0xC00018FE,0x98002E12,0x27FC6878,0x9C003FBB,0x84004933,0x6C00687B,0x27FC6878,0x9C003FBB,0x84004933,0x6C00687B,0x6C00687B,0xFEA053D2,0xFECC6050,0xFECC5F74,0xFE543C9E,0xFE04237A,0xEE00192E,0xC8000FFB,0xB6002345,0xFE885438,0xFE2C3966,0xB6003152,0x84004933, -0x1D46878,0x401784,0x401784,0x401784,0x401784,0xFE0C0074,0xFE0C0074,0xFE0C0074,0x8E000004,0x8E000004,0x5E000005,0x94001142,0x94001142,0x94001142,0x74000631,0x74000631,0x5800030A,0x48001142,0x48001142,0x44000A69,0x30001142,0x601783,0x601783,0x601783,0x62000ACD,0x62000ACD,0x4C0005EB,0x4000132D,0x4000132D,0x3E000C3A,0x2E00122B,0xC41783, -0xC41783,0x3200106D,0x260014AE,0x20001783,0xFE200C8D,0xFE2C110D,0x401784,0xFA00078A,0xBC000679,0x8C000682,0x8C000559,0x6A0007B2,0xFE000D14,0xD00009C2,0x5C001166,0x3E000C3A,0x8C1783,0x601144,0x601144,0x601144,0x601144,0xFE0C0050,0xFE0C0050,0xFE0C0050,0x8C040001,0x8C040001,0x5E040001,0x901142,0x901142,0x901142,0x74000631,0x74000631, -0x5800030A,0x1241142,0x1241142,0x44000A69,0x30001142,0x901142,0x901142,0x901142,0x74000631,0x74000631,0x5800030A,0x1241142,0x1241142,0x44000A69,0x30001142,0x1241142,0x1241142,0x44000A69,0x30001142,0x30001142,0xFA340B48,0xFE4C0CA0,0x601144,0xFA00078A,0xBC000679,0x8C000682,0x8C000559,0x6A0007B2,0xFE0C0BE2,0xD0000919,0xD01142,0x44000A69, -0xD01142,0x1482420,0xFF0C12C8,0xFECC02FD,0xE6C00001,0x1E82420,0xFE640949,0xE63C0001,0x79F82420,0xCA000989,0xA2002422,0x1E82420,0xFE640949,0xE63C0001,0x79F82420,0xCA000989,0xA2002422,0x79F82420,0xCA000989,0xA2002422,0xA2002422,0x1E82420,0xFE640949,0xE63C0001,0x79F82420,0xCA000989,0xA2002422,0x79F82420,0xCA000989,0xA2002422,0xA2002422,0x79F82420, -0xCA000989,0xA2002422,0xA2002422,0xA2002422,0xFF142048,0x75C2420,0xF9402104,0xFED81A29,0xFE68133D,0xFC000928,0xD40004ED,0xC2000DFA,0xFF102000,0xFEC01919,0xE60003BA,0xA2002422,0x55FC2420,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4000000,0x4000000,0x4000000,0x4000000,0x4000000, -0x4000000,0x2000000,0x2000000,0x2000000,0x1,0x2000002,0x2000002,0x2000002,0x2000002,0x2000002,0x2000002,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x18000000,0x4,0x4,0xA000000,0x8000000,0x6000000,0x6000000,0x4000000,0x4000001,0x2000001,0x2000000,0x1, -0x2,}; -static const uint32_t g_etc1_to_bc7_m6_table231[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x140000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000, -0x1C0000,0x380000,0x380000,0x380000,0x8000001,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x1C0000,0x380000,0x380000,0x380000,0x8000001,0x380000,0x380000,0x380000,0x8000001,0x8000001,0x2140000,0x140000,0x140000,0x180000,0x180000,0x2180000,0x2180000,0x200000,0x180000,0x180000,0x280000,0x380000, -0x280000,0xD00000,0xD00000,0xD00000,0xD00000,0x1340000,0x1340000,0x1340000,0x1FF80000,0x1FF80000,0x66000001,0x1340000,0x1340000,0x1340000,0x1FF80000,0x1FF80000,0x66000001,0x1FF80000,0x1FF80000,0x66000001,0x66000001,0x1340000,0x1340000,0x1340000,0x1FF80000,0x1FF80000,0x66000001,0x1FF80000,0x1FF80000,0x66000001,0x66000001,0x1FF80000, -0x1FF80000,0x66000001,0x66000001,0x66000001,0x2F00000,0x6DC0000,0xD00000,0x3180000,0x15C0000,0x1B80000,0x1FC0000,0x33F40000,0x1040000,0x1340000,0x1B80000,0x66000001,0x1B80000,0x1E00000,0xD3FC0000,0xE9FC0000,0xEE000001,0xD3FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xD3FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xEE000001, -0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0xD3FC0000,0xE9FC0000,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0xE9FC0000,0xEE000001,0xEE000001,0xEE000001,0xEE000001,0xB7FC0000,0x17FC0000,0x17FC0000,0xDBFC0000,0xE7F80000,0xEDF40000,0xEE000001,0xEE000001,0xC9FC0000,0xE1FC0000,0xEFF00000,0xEE000001, -0xE3FC0000,0xB09144,0xFE805385,0xFE582588,0xEE4C19B9,0xFE5C4AD6,0xFE201109,0xF6140195,0xFC0C2454,0xD6000915,0xAA082456,0xFE3C6E48,0xFE08296D,0xE200142D,0xE80036E6,0xC60015E6,0xA2002BFB,0xAE006878,0xA6003DB5,0x90004763,0x7400687B,0x1049144,0xFA004419,0xD2002844,0xD2004B5A,0xBA00258F,0x9E0036E6,0xA2007431,0x9C0048BB,0x8A004FCF,0x6E006E1B,0x7FC9144, -0x840064EC,0x780065C4,0x66007DB4,0x58009144,0xFE786AC5,0xFAA48366,0xFEAC8499,0xFE40451B,0xFE04257E,0xFC0015D9,0xD2000D46,0xB6002035,0xFE5C697E,0xFE184056,0xBE002F7B,0x8A004FCF,0x1749144,0xEC6878,0xFEB03D85,0xFE7C1A74,0xEE701145,0xFE8C3F52,0xFE380EE1,0xF22400D9,0xFA142420,0xD6000915,0xAA142422,0x35C6878,0xFE08295D,0xE200142D,0xE80036E6,0xC60015E6, -0xA2002BFB,0x33FC6878,0xA6003DB5,0x90004763,0x7400687B,0x35C6878,0xFE08295D,0xE200142D,0xE80036E6,0xC60015E6,0xA2002BFB,0x33FC6878,0xA6003DB5,0x90004763,0x7400687B,0x33FC6878,0xA6003DB5,0x90004763,0x7400687B,0x7400687B,0xFEB45485,0xF8E06116,0xFAE4601D,0xFE6C3E89,0xFE102549,0xFC0015D9,0xD2000D46,0xB6002035,0xFE985529,0xFE403AFB,0xBE002EEB,0x90004763, -0x1F46878,0x4C19B8,0x4C19B8,0x4C19B8,0x4C19B8,0xFE180124,0xFE180124,0xFE180124,0x98080034,0x98080034,0x66080035,0xAC001142,0xAC001142,0xAC001142,0x80000521,0x80000521,0x620001FD,0x54001142,0x54001142,0x4A000989,0x38001142,0x7019B8,0x7019B8,0x7019B8,0x6E000AFD,0x6E000AFD,0x58000593,0x4C0013E5,0x4C0013E5,0x44000BEA,0x34001283,0xE419B8, -0xE419B8,0x38001155,0x2C0015E6,0x240019BB,0xFE200E1D,0xFA441304,0x4C19B8,0xFE08079A,0xD4000562,0xA2000562,0x96000448,0x6E0006AD,0xFE000E34,0xF2000912,0x6600116E,0x44000BEA,0xA019B8,0x701144,0x701144,0x701144,0x701144,0xFE240080,0xFE240080,0xFE240080,0x94140001,0x94140001,0x66140001,0xA81142,0xA81142,0xA81142,0x80000521,0x80000521, -0x620001FD,0x1581142,0x1581142,0x4A000989,0x38001142,0xA81142,0xA81142,0xA81142,0x80000521,0x80000521,0x620001FD,0x1581142,0x1581142,0x4A000989,0x38001142,0x1581142,0x1581142,0x4A000989,0x38001142,0x38001142,0xFE3C0B68,0xFA640CD1,0x701144,0xFE08078A,0xD4000562,0xA2000562,0x96000448,0x6E0006AD,0xFE140C14,0xF2000831,0xF01142,0x4A000989, -0xF01142,0x1582420,0xFF241408,0xFEE40425,0xEED00001,0x3FC2420,0xFE880AB5,0xEE4C0001,0x85F82420,0xD60008B1,0xAA002422,0x3FC2420,0xFE880AB5,0xEE4C0001,0x85F82420,0xD60008B1,0xAA002422,0x85F82420,0xD60008B1,0xAA002422,0xAA002422,0x3FC2420,0xFE880AB5,0xEE4C0001,0x85F82420,0xD60008B1,0xAA002422,0x85F82420,0xD60008B1,0xAA002422,0xAA002422,0x85F82420, -0xD60008B1,0xAA002422,0xAA002422,0xAA002422,0xFF342081,0xF6C2420,0xFF4C2114,0xFEEC1AC8,0xFE90147D,0xFE040910,0xDE000431,0xD0000D22,0xFF182032,0xFECC1A04,0xF2000301,0xAA002422,0x63FC2420,0x80034,0x80034,0x80034,0x80034,0x80034,0x80034,0x80034,0x80034,0x80034,0x80034,0x1C000000,0x1C000000,0x1C000000,0x1C000000,0x1C000000, -0x1C000000,0xE000000,0xE000000,0xE000000,0x8000001,0x20C0032,0x20C0032,0x20C0032,0x20C0032,0x20C0032,0x20C0032,0xC000011,0xC000011,0xC000011,0x800000A,0x180032,0x180032,0x180032,0x4000022,0x4000032,0x98000000,0x80034,0x80034,0x44000000,0x2E000000,0x24000000,0x24000000,0x18000000,0x3600000D,0x24000008,0x12000001,0xC000011, -0x140032,}; -static const uint32_t g_etc1_to_bc7_m6_table232[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x240001,0x380000,0x380000,0x380000,0x380000,0x380000, -0x380000,0x700000,0x700000,0x700000,0x12000000,0x380000,0x380000,0x380000,0x380000,0x380000,0x380000,0x700000,0x700000,0x700000,0x12000000,0x700000,0x700000,0x700000,0x12000000,0x12000000,0x280000,0x240001,0x240001,0x2C0000,0x300000,0x340000,0x340000,0x400000,0x2C0000,0x300000,0x500000,0x700000, -0x500000,0xE00001,0xE00001,0xE00001,0xE00001,0x1500000,0x1500000,0x1500000,0x2DF80000,0x2DF80000,0x70000000,0x1500000,0x1500000,0x1500000,0x2DF80000,0x2DF80000,0x70000000,0x2DF80000,0x2DF80000,0x70000000,0x70000000,0x1500000,0x1500000,0x1500000,0x2DF80000,0x2DF80000,0x70000000,0x2DF80000,0x2DF80000,0x70000000,0x70000000,0x2DF80000, -0x2DF80000,0x70000000,0x70000000,0x70000000,0x7040000,0xF00000,0xE00001,0x1340000,0x17C0000,0x1E00000,0x11FC0000,0x3FF40000,0x11C0000,0x1500000,0x1E00000,0x70000000,0x1E00000,0x1F00001,0xEFFC0000,0xF7F80000,0xF8000000,0xEFFC0000,0xF7F80000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xEFFC0000,0xF7F80000,0xF8000000,0xF7F80000,0xF8000000, -0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xEFFC0000,0xF7F80000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xF7F80000,0xF8000000,0xF8000000,0xF8000000,0xF8000000,0xE3FC0000,0xA7FC0000,0xA7FC0000,0xF1FC0000,0xF5FC0000,0xF9F00000,0xF8000000,0xF8000000,0xEBFC0000,0xF3FC0000,0xF9E40000,0xF8000000, -0xF5FC0000,0xC097BB,0xFE8C5AEA,0xFE642B8F,0xF8581C9A,0xFE6850F9,0xFE3815EA,0xFC200282,0xFE14251D,0xDE040922,0xB41424D5,0xFE4471AC,0xFE082B02,0xEE0012C6,0xF40034A9,0xD20012B1,0xAE002A0C,0xBC006878,0xB2003B2E,0x9600456C,0x7E006878,0x31897B9,0xFA004686,0xE200290A,0xE2004B75,0xC6002442,0xA8003621,0xAE00761C,0xA60047DF,0x90004F04,0x7A006EE8,0x11FC97B9, -0x900067C5,0x7E006825,0x6C008115,0x5E0097B9,0xFE8C716F,0xFEAC89AD,0xFEAC8B86,0xFE544AE1,0xFE1028CE,0xFC00135A,0xDE000A4D,0xCA001CD5,0xFE707042,0xFE244643,0xD6002C8C,0x90004F04,0x19497B9,0xFC687B,0xFEC43F8B,0xFE941CBB,0xF8841142,0xFE984159,0xFE5811F2,0xFC3800DA,0xFE2C2431,0xDE10090E,0xB4242421,0x1786878,0xFE082AF2,0xEE0012C6,0xF40034A9,0xD20012B1, -0xAE002A0C,0x41FC6878,0xB2003B2E,0x9600456C,0x7E006878,0x1786878,0xFE082AF2,0xEE0012C6,0xF40034A9,0xD20012B1,0xAE002A0C,0x41FC6878,0xB2003B2E,0x9600456C,0x7E006878,0x41FC6878,0xB2003B2E,0x9600456C,0x7E006878,0x7E006878,0xFED055D8,0xFEEC6131,0xFEEC6086,0xFE8040FD,0xFE242846,0xFC00135A,0xDE000A4D,0xCA001CD5,0xFEB456A6,0xFE5C3DAE,0xD6002BE3,0x9600456C, -0xFFC6878,0x581C9A,0x581C9A,0x581C9A,0x581C9A,0xFE240266,0xFE240266,0xFE240266,0xA21400B5,0xA21400B5,0x701400B5,0xC8001142,0xC8001142,0xC8001142,0x9200040D,0x9200040D,0x68000121,0x60001144,0x60001144,0x56000895,0x40001144,0x2801C9A,0x2801C9A,0x2801C9A,0x7A000B7D,0x7A000B7D,0x6200056D,0x580014D3,0x580014D3,0x50000BA2,0x400012FD,0x1081C9A, -0x1081C9A,0x440012AD,0x32001788,0x2A001C9D,0xFC38101A,0xFE4C1596,0x581C9A,0xFE100871,0xF2000448,0xC0000464,0xAA00031D,0x80000585,0xFE140FDB,0xFC000884,0x7C001182,0x50000BA2,0xB81C9A,0x841142,0x841142,0x841142,0x841142,0xFE3400C1,0xFE3400C1,0xFE3400C1,0x9E240001,0x9E240001,0x70240001,0xC41142,0xC41142,0xC41142,0x9200040D,0x9200040D, -0x68000121,0x18C1142,0x18C1142,0x56000895,0x40001144,0xC41142,0xC41142,0xC41142,0x9200040D,0x9200040D,0x68000121,0x18C1142,0x18C1142,0x56000895,0x40001144,0x18C1142,0x18C1142,0x56000895,0x40001144,0x40001144,0xFE580B95,0xFE6C0D0D,0x841142,0xFE1807E9,0xF2000448,0xC0000464,0xAA00031D,0x80000585,0xFE340C31,0xFC000784,0x1181142,0x56000895, -0x1181142,0x1682422,0xFF301572,0xFEFC05B9,0xF8E00001,0x1FFC2420,0xFEA00C69,0xF85C0000,0x91FC2420,0xDC0007D9,0xB4002420,0x1FFC2420,0xFEA00C69,0xF85C0000,0x91FC2420,0xDC0007D9,0xB4002420,0x91FC2420,0xDC0007D9,0xB4002420,0xB4002420,0x1FFC2420,0xFEA00C69,0xF85C0000,0x91FC2420,0xDC0007D9,0xB4002420,0x91FC2420,0xDC0007D9,0xB4002420,0xB4002420,0x91FC2420, -0xDC0007D9,0xB4002420,0xB4002420,0xB4002420,0xFD4C2102,0x9802420,0xFB642185,0xFF141BC1,0xFEA815C1,0xFE0409FA,0xE8000371,0xD8000C44,0xFF2C20D5,0xFEF01B2D,0xFE000248,0xB4002420,0x75FC2420,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x1400B5,0x38000000,0x38000000,0x38000000,0x38000000,0x38000000, -0x38000000,0x1C000000,0x1C000000,0x1C000000,0x12000000,0x1C00B5,0x1C00B5,0x1C00B5,0x1C00B5,0x1C00B5,0x1C00B5,0x18000044,0x18000044,0x18000044,0x12000024,0x3000B5,0x3000B5,0x3000B5,0xA000071,0x80000B5,0xFA040005,0x1400B5,0x1400B5,0x84000000,0x5C000000,0x46000000,0x46000000,0x2E000000,0x76000035,0x5600001A,0x22000004,0x18000044, -0x2400B5,}; -static const uint32_t g_etc1_to_bc7_m6_table233[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x340001,0x500000,0x500000,0x500000,0x500000,0x500000, -0x500000,0xA00000,0xA00000,0xA00000,0x1A000000,0x500000,0x500000,0x500000,0x500000,0x500000,0x500000,0xA00000,0xA00000,0xA00000,0x1A000000,0xA00000,0xA00000,0xA00000,0x1A000000,0x1A000000,0x4380000,0x340001,0x340001,0x63C0000,0x440000,0x480000,0x480000,0x580000,0x63C0000,0x440000,0x700000,0xA00000, -0x700000,0xF00001,0xF00001,0xF00001,0xF00001,0x1680000,0x1680000,0x1680000,0x39F80000,0x39F80000,0x78000000,0x1680000,0x1680000,0x1680000,0x39F80000,0x39F80000,0x78000000,0x39F80000,0x39F80000,0x78000000,0x78000000,0x1680000,0x1680000,0x1680000,0x39F80000,0x39F80000,0x78000000,0x39F80000,0x39F80000,0x78000000,0x78000000,0x39F80000, -0x39F80000,0x78000000,0x78000000,0x78000000,0x3180000,0x9000000,0xF00001,0x1480000,0x3940000,0x3FC0000,0x1FF80000,0x49F80000,0x1300000,0x1680000,0x3FC0000,0x78000000,0x3FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xC89B73,0xFE98601A,0xFE70308B,0xFE641F86,0xFE7454F9,0xFE3819DE,0xFE280401,0xFE20257D,0xE4100916,0xBA1C2481,0xFE507334,0xFE142CA6,0xFA0011D2,0xFA0031B5,0xDE000F8D,0xB4002774,0xC6006693,0xB80037EE,0x9C004258,0x86006694,0x12C9B71,0xFA0048EA,0xE20029B6,0xE8004A85,0xCC0022AE,0xAE003499,0xBA0075EC,0xB20045F3,0x9A004CE6,0x80006DCC,0x1BF89B71, -0x9600690D,0x8A0068A1,0x7200821D,0x64009B71,0xFE94756C,0xF8C08E33,0xFAC48FAF,0xFE544EB5,0xFE242B66,0xFC0011E2,0xEA0007C2,0xD0001968,0xFE7873EA,0xFE40496C,0xD6002964,0x9A004CE6,0x1AC9B71,0x10C6693,0xFED04023,0xFEAC1E33,0xFE941142,0xFEB0416D,0xFE6413AA,0xFE4400F5,0xFE402373,0xE41C08A6,0xBA342315,0x38C6693,0xFE202C26,0xFA0011D2,0xFA0031B5,0xDE000F8D, -0xB4002774,0x4BFC6693,0xB80037EE,0x9C004258,0x86006694,0x38C6693,0xFE202C26,0xFA0011D2,0xFA0031B5,0xDE000F8D,0xB4002774,0x4BFC6693,0xB80037EE,0x9C004258,0x86006694,0x4BFC6693,0xB80037EE,0x9C004258,0x86006694,0x86006694,0xFED05534,0xF900600B,0xFD085F33,0xFE9440FA,0xFE3829B2,0xFC0011E2,0xEA0007C2,0xD0001968,0xFEC455C3,0xFE843E6A,0xDE0028A6,0x9C004258, -0x1DF86693,0x641F86,0x641F86,0x641F86,0x641F86,0xFE280401,0xFE280401,0xFE280401,0xAC1C016D,0xAC1C016D,0x781C016D,0xE0001142,0xE0001142,0xE0001142,0xA200031D,0xA200031D,0x74000089,0x6C001144,0x6C001144,0x5C0007D9,0x48001144,0x901F85,0x901F85,0x901F85,0x86000C35,0x86000C35,0x680005B5,0x620015A4,0x620015A4,0x58000B8A,0x46001365,0x1241F85, -0x1241F85,0x4A001419,0x3E001918,0x30001F85,0xFE3C123E,0xF45818B1,0x641F86,0xFE180989,0xFC000384,0xC8000368,0xB800025D,0x8C0004A5,0xFE201212,0xFE0008CA,0x8600118A,0x58000B8A,0xD01F85,0x941142,0x941142,0x941142,0x941142,0xFE4400F5,0xFE4400F5,0xFE4400F5,0xA6340001,0xA6340001,0x78340001,0xDC1142,0xDC1142,0xDC1142,0xA200031D,0xA200031D, -0x74000089,0x1BC1142,0x1BC1142,0x5C0007D9,0x48001144,0xDC1142,0xDC1142,0xDC1142,0xA200031D,0xA200031D,0x74000089,0x1BC1142,0x1BC1142,0x5C0007D9,0x48001144,0x1BC1142,0x1BC1142,0x5C0007D9,0x48001144,0x48001144,0xFA6C0BE2,0xFC880D22,0x941142,0xFE340845,0xFC000384,0xC8000368,0xB800025D,0x8C0004A5,0xFA480C82,0xFE0407B4,0x1381142,0x5C0007D9, -0x1381142,0x1782312,0xFF441595,0xFF0806B9,0xFEF00001,0x35FC2312,0xFEB80D39,0xFE700000,0x9DF42312,0xE60006C4,0xBA002314,0x35FC2312,0xFEB80D39,0xFE700000,0x9DF42312,0xE60006C4,0xBA002314,0x9DF42312,0xE60006C4,0xBA002314,0xBA002314,0x35FC2312,0xFEB80D39,0xFE700000,0x9DF42312,0xE60006C4,0xBA002314,0x9DF42312,0xE60006C4,0xBA002314,0xBA002314,0x9DF42312, -0xE60006C4,0xBA002314,0xBA002314,0xBA002314,0xFF502032,0x1902312,0xFF6C2099,0xFF201B94,0xFED01619,0xFE180AF1,0xF20002A1,0xE0000B14,0xFD502000,0xFF081AAA,0xFE0001C4,0xBA002314,0x81FC2312,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x1C016D,0x50000000,0x50000000,0x50000000,0x50000000,0x50000000, -0x50000000,0x26000001,0x26000001,0x26000001,0x1A000000,0x28016D,0x28016D,0x28016D,0x28016D,0x28016D,0x28016D,0x22000082,0x22000082,0x22000082,0x18000044,0x4C016D,0x4C016D,0x4C016D,0x100000DD,0xC00016D,0xFE0C003D,0x1C016D,0x1C016D,0xBC000000,0x82000000,0x64000000,0x64000000,0x42000000,0xA0000074,0x7400003A,0x32000009,0x22000082, -0x34016D,}; -static const uint32_t g_etc1_to_bc7_m6_table234[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x440001,0x680000,0x680000,0x680000,0x680000,0x680000, -0x680000,0xD00000,0xD00000,0xD00000,0x22000000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0xD00000,0xD00000,0xD00000,0x22000000,0xD00000,0xD00000,0xD00000,0x22000000,0x22000000,0xC480000,0x440001,0x440001,0x500000,0x580000,0x25C0000,0x25C0000,0x740000,0x500000,0x580000,0x940000,0xD00000, -0x940000,0x1000001,0x1000001,0x1000001,0x1000001,0x1800000,0x1800000,0x1800000,0x45F80000,0x45F80000,0x80000000,0x1800000,0x1800000,0x1800000,0x45F80000,0x45F80000,0x80000000,0x45F80000,0x45F80000,0x80000000,0x80000000,0x1800000,0x1800000,0x1800000,0x45F80000,0x45F80000,0x80000000,0x45F80000,0x45F80000,0x80000000,0x80000000,0x45F80000, -0x45F80000,0x80000000,0x80000000,0x80000000,0x12C0000,0x1140000,0x1000001,0x35C0000,0x1B00000,0x13FC0000,0x2BFC0000,0x55F40000,0x1440000,0x1800000,0x13FC0000,0x80000000,0x13FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xD0985B,0xFEA46016,0xFE7C32E7,0xFE6C22C6,0xFE80534D,0xFE4C1AEE,0xFE300602,0xFE2C22E1,0xE8180846,0xBE242169,0xFE5C6E98,0xFE142B26,0xFC001148,0xFA002BC5,0xE2000B41,0xBA0021D8,0xD0005F33,0xBE0031CA,0xA6003B0D,0x8A005F34,0x1389859,0xFC004866,0xE80029FE,0xEE004581,0xD2001F56,0xB4002FCD,0xC0006FCC,0xB20040B3,0x9C004648,0x86006704,0x21F89859, -0x9C0065F9,0x8A0063E1,0x78007CE9,0x68009859,0xFEA072F9,0xFCC88B1B,0xFECC8CE7,0xFE6C4D3A,0xFE2829D6,0xFE040EE2,0xEE0004B9,0xD6001419,0xFE7871FA,0xFE4047CC,0xDE00246A,0x9C004648,0x1BC9859,0x1185F33,0xFEE83C13,0xFEB81D03,0xFEA41142,0xFEC43C4B,0xFE7C126A,0xFE5C013D,0xFE4C1F8B,0xE8300726,0xBE441F05,0x1A05F33,0xFE3829C6,0xFC001148,0xFA002BC5,0xE2000B41, -0xBA0021D8,0x55F85F33,0xBE0031CA,0xA6003B0D,0x8A005F34,0x1A05F33,0xFE3829C6,0xFC001148,0xFA002BC5,0xE2000B41,0xBA0021D8,0x55F85F33,0xBE0031CA,0xA6003B0D,0x8A005F34,0x55F85F33,0xBE0031CA,0xA6003B0D,0x8A005F34,0x8A005F34,0xFEE44F59,0xFF0C58D3,0xFF0C5843,0xFEB03CE2,0xFE4826EA,0xFE040EDE,0xEE0004B9,0xD6001419,0xFEDC4F89,0xFE8439AA,0xDE0023A6,0xA6003B0D, -0x27FC5F33,0x6C22C6,0x6C22C6,0x6C22C6,0x6C22C6,0xFE300602,0xFE300602,0xFE300602,0xB6240265,0xB6240265,0x80240265,0xF8001142,0xF8001142,0xF8001142,0xAE00025D,0xAE00025D,0x80000031,0x78001144,0x78001144,0x66000728,0x50001144,0xA422C5,0xA422C5,0xA422C5,0x92000D2D,0x92000D2D,0x7400063D,0x6E0016B4,0x6E0016B4,0x60000B84,0x4C0013E5,0x14C22C5, -0x14C22C5,0x500015CD,0x44001AD8,0x360022C5,0xFE4C14D5,0xFA641BA9,0x6C22C6,0xFE240B44,0xFE040388,0xE20002B1,0xCC00019A,0x960003E8,0xFC301481,0xFE000A0A,0x9600119B,0x60000B84,0xE822C5,0xA41142,0xA41142,0xA41142,0xA41142,0xFE5C013D,0xFE5C013D,0xFE5C013D,0xAE440001,0xAE440001,0x80440001,0xF41142,0xF41142,0xF41142,0xAE00025D,0xAE00025D, -0x80000031,0x1F01142,0x1F01142,0x66000728,0x50001144,0xF41142,0xF41142,0xF41142,0xAE00025D,0xAE00025D,0x80000031,0x1F01142,0x1F01142,0x66000728,0x50001144,0x1F01142,0x1F01142,0x66000728,0x50001144,0x50001144,0xFE740C02,0xFE8C0D6A,0xA41142,0xFE440894,0xFE040384,0xE20002B1,0xCC00019A,0x960003E8,0xFE500CB2,0xFE1807FD,0x15C1142,0x66000728, -0x15C1142,0x1801F02,0xFF501315,0xFF2005F1,0xFF000001,0x41FC1F02,0xFECC0BD5,0xFE880000,0xA1FC1F02,0xEC0004C8,0xBE001F04,0x41FC1F02,0xFECC0BD5,0xFE880000,0xA1FC1F02,0xEC0004C8,0xBE001F04,0xA1FC1F02,0xEC0004C8,0xBE001F04,0xBE001F04,0x41FC1F02,0xFECC0BD5,0xFE880000,0xA1FC1F02,0xEC0004C8,0xBE001F04,0xA1FC1F02,0xEC0004C8,0xBE001F04,0xBE001F04,0xA1FC1F02, -0xEC0004C8,0xBE001F04,0xBE001F04,0xBE001F04,0xF7681C99,0x5981F02,0xFF6C1D09,0xFF30184D,0xFEE81379,0xFE4809A1,0xF4000164,0xE0000894,0xFD581C22,0xFF1417A5,0xFE000124,0xBE001F04,0x89FC1F02,0x240265,0x240265,0x240265,0x240265,0x240265,0x240265,0x240265,0x240265,0x240265,0x240265,0x6A000000,0x6A000000,0x6A000000,0x6A000000,0x6A000000, -0x6A000000,0x32000001,0x32000001,0x32000001,0x22000000,0x340265,0x340265,0x340265,0x340265,0x340265,0x340265,0x280000DA,0x280000DA,0x280000DA,0x1E000074,0x640265,0x640265,0x640265,0x16000171,0x10000265,0xF21400C8,0x240265,0x240265,0xF6000000,0xAA000000,0x82000000,0x82000000,0x54000000,0xC40000C1,0x96000061,0x40000010,0x280000DA, -0x480265,}; -static const uint32_t g_etc1_to_bc7_m6_table235[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x540001,0x800000,0x800000,0x800000,0x800000,0x800000, -0x800000,0x1000000,0x1000000,0x1000000,0x2A000000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x1000000,0x1000000,0x1000000,0x2A000000,0x1000000,0x1000000,0x1000000,0x2A000000,0x2A000000,0x5C0000,0x540001,0x540001,0x640000,0x6C0000,0x740000,0x740000,0x900000,0x640000,0x6C0000,0xB40000,0x1000000, -0xB40000,0x1100001,0x1100001,0x1100001,0x1100001,0x1980000,0x1980000,0x1980000,0x51F80000,0x51F80000,0x88000000,0x1980000,0x1980000,0x1980000,0x51F80000,0x51F80000,0x88000000,0x51F80000,0x51F80000,0x88000000,0x88000000,0x1980000,0x1980000,0x1980000,0x51F80000,0x51F80000,0x88000000,0x51F80000,0x51F80000,0x88000000,0x88000000,0x51F80000, -0x51F80000,0x88000000,0x88000000,0x88000000,0x73C0000,0x1240000,0x1100001,0x1740000,0x1CC0000,0x21FC0000,0x39FC0000,0x5FF80000,0x1580000,0x1980000,0x21FC0000,0x88000000,0x21FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xD895C3,0xFEB0608A,0xFE8835A3,0xFE78265A,0xFE80521D,0xFE581C6A,0xFE440859,0xFE3820E5,0xEC2007F6,0xC22C1ED1,0xFE686AA4,0xFE202A26,0xFE0C116E,0xFE04269A,0xE80007B5,0xC0001CD4,0xD600582B,0xC4002C2E,0xAC003425,0x90005828,0x14495C1,0xFE08488A,0xEE002B26,0xF400410D,0xD8001CB6,0xB4002B8D,0xC6006A14,0xB8003BF7,0xA4004028,0x8C00609C,0x27F895C1, -0x9C006399,0x90005FA9,0x7E00782D,0x6C0095C1,0xFEA07179,0xFECC888F,0xFECC8AE7,0xFE6C4C2A,0xFE382902,0xFE040CD2,0xF4000288,0xD8000F71,0xFE906FEE,0xFE5046F2,0xE600202C,0xA4004028,0x1D095C1,0x120582B,0xFEF43833,0xFEC01C1A,0xFEB41142,0xFED03783,0xFE88113A,0xFE680195,0xFE641BE3,0xEA4005CA,0xC2541B35,0x1B05828,0xFE4C27C5,0xFE141142,0xFE08268D,0xE80007B5, -0xC0001CD4,0x5DF45828,0xC4002C2E,0xAC003425,0x90005828,0x1B05828,0xFE4C27C5,0xFE141142,0xFE08268D,0xE80007B5,0xC0001CD4,0x5DF45828,0xC4002C2E,0xAC003425,0x90005828,0x5DF45828,0xC4002C2E,0xAC003425,0x90005828,0x90005828,0xFEF8494A,0xFF0C5253,0xFF0C5243,0xFEB03872,0xFE682411,0xFE040CCE,0xF4000288,0xD8000F71,0xFEDC4979,0xFE9035DE,0xE6001F68,0xAC003425, -0x31FC5828,0x78265A,0x78265A,0x78265A,0x78265A,0xFE440859,0xFE440859,0xFE440859,0xC02C039D,0xC02C039D,0x882C039D,0xFE0C116E,0xFE0C116E,0xFE0C116E,0xBA0001BD,0xBA0001BD,0x88000004,0x84001144,0x84001144,0x72000668,0x58001144,0x2B0265A,0x2B0265A,0x2B0265A,0xA2000E36,0xA2000E36,0x7A00070D,0x740017D8,0x740017D8,0x68000B94,0x5200147D,0x168265A, -0x168265A,0x560017C9,0x4A001CC8,0x3A00265D,0xFE5817D5,0xFE6C1F01,0x78265A,0xFE340D49,0xFE14045E,0xEE0001F4,0xDA000112,0xAA00031D,0xFE341721,0xFE100BF2,0xA60011A8,0x68000B94,0xFC265A,0xB41142,0xB41142,0xB41142,0xB41142,0xFE680195,0xFE680195,0xFE680195,0xB6540001,0xB6540001,0x88540001,0x10C1142,0x10C1142,0x10C1142,0xBA0001BD,0xBA0001BD, -0x88000004,0xBF81142,0xBF81142,0x72000668,0x58001144,0x10C1142,0x10C1142,0x10C1142,0xBA0001BD,0xBA0001BD,0x88000004,0xBF81142,0xBF81142,0x72000668,0x58001144,0xBF81142,0xBF81142,0x72000668,0x58001144,0x58001144,0xFE900C31,0xFCA80D75,0xB41142,0xFE5C08C9,0xFE1803E8,0xEE0001F4,0xDA000112,0xAA00031D,0xFA700CD1,0xFE300869,0x17C1142,0x72000668, -0x17C1142,0x1881B32,0xFF5C10BD,0xFF2C052D,0xFF100001,0x4DFC1B32,0xFEE40A55,0xFEA00000,0xA7FC1B32,0xEC000328,0xC2001B34,0x4DFC1B32,0xFEE40A55,0xFEA00000,0xA7FC1B32,0xEC000328,0xC2001B34,0xA7FC1B32,0xEC000328,0xC2001B34,0xC2001B34,0x4DFC1B32,0xFEE40A55,0xFEA00000,0xA7FC1B32,0xEC000328,0xC2001B34,0xA7FC1B32,0xEC000328,0xC2001B34,0xC2001B34,0xA7FC1B32, -0xEC000328,0xC2001B34,0xC2001B34,0xC2001B34,0xFB7018F1,0x9A01B32,0xFB841962,0xFF401540,0xFEE81109,0xFE480871,0xF800009D,0xE4000665,0xFF5C1892,0xFF2014D2,0xFE1000E5,0xC2001B34,0x91FC1B32,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x2C039D,0x82000000,0x82000000,0x82000000,0x82000000,0x82000000, -0x82000000,0x3E000001,0x3E000001,0x3E000001,0x2A000000,0x40039D,0x40039D,0x40039D,0x40039D,0x40039D,0x40039D,0x34000152,0x34000152,0x34000152,0x280000AD,0x7C039D,0x7C039D,0x7C039D,0x1C00022D,0x1400039D,0xF61C0188,0x2C039D,0x2C039D,0xFE04001D,0xD2000000,0xA0000000,0xA0000000,0x68000000,0xF6000121,0xC2000099,0x50000019,0x34000152, -0x58039D,}; -static const uint32_t g_etc1_to_bc7_m6_table236[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x680000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000, -0x2980000,0x1380000,0x1380000,0x1380000,0x32000001,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x2980000,0x1380000,0x1380000,0x1380000,0x32000001,0x1380000,0x1380000,0x1380000,0x32000001,0x32000001,0xE6C0000,0x680000,0x680000,0x780000,0x2800000,0x8C0000,0x8C0000,0x2AC0000,0x780000,0x2800000,0xDC0000,0x1380000, -0xDC0000,0x1240000,0x1240000,0x1240000,0x1240000,0x3B00000,0x3B00000,0x3B00000,0x5DFC0000,0x5DFC0000,0x90000001,0x3B00000,0x3B00000,0x3B00000,0x5DFC0000,0x5DFC0000,0x90000001,0x5DFC0000,0x5DFC0000,0x90000001,0x90000001,0x3B00000,0x3B00000,0x3B00000,0x5DFC0000,0x5DFC0000,0x90000001,0x5DFC0000,0x5DFC0000,0x90000001,0x90000001,0x5DFC0000, -0x5DFC0000,0x90000001,0x90000001,0x90000001,0x1540000,0x1380000,0x1240000,0x18C0000,0x1EC0000,0x33FC0000,0x49F80000,0x6BF80000,0x36C0000,0x3B00000,0x33FC0000,0x90000001,0x33FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xE49371,0xFEB06174,0xFE943921,0xFE842AC8,0xFE8C5159,0xFE641E9A,0xFE500B99,0xFE401F71,0xEE300834,0xC8341C7D,0xFE7466F6,0xFE2C29B8,0xFE181234,0xFE0821B1,0xEE000485,0xC60017E2,0xE00050A2,0xCA002684,0xB2002CE1,0x960050A2,0x150936F,0xFE0849BC,0xEE002D78,0xFA003CBD,0xE2001A89,0xBA00277B,0xCC006426,0xC0003749,0xAA0039C2,0x920059D2,0x2DF8936F, -0xA60061D4,0x96005B93,0x8400735F,0x7000936F,0xFEB46FEE,0xFECC86CD,0xF6DC89B8,0xFE804B93,0xFE3C288E,0xFE040BB2,0xF80000EC,0xE0000ADE,0xFE986E7F,0xFE544677,0xF0001BFE,0xAA0039C2,0x1E0936F,0x12C50A5,0xFF00340D,0xFED81AE4,0xFEC41144,0xFEDC3275,0xFEA01012,0xFE8001F9,0xFE701821,0xEA580474,0xC8681735,0x1C050A2,0xFE642553,0xFE2C1144,0xFE0821A1,0xEE000485, -0xC60017E2,0x65F850A2,0xCA002684,0xB2002CE1,0x960050A2,0x1C050A2,0xFE642553,0xFE2C1144,0xFE0821A1,0xEE000485,0xC60017E2,0x65F850A2,0xCA002684,0xB2002CE1,0x960050A2,0x65F850A2,0xCA002684,0xB2002CE1,0x960050A2,0x960050A2,0xFEF84350,0xFB244B59,0xFD284B14,0xFEC033C8,0xFE7C2149,0xFE040BAE,0xF80000EC,0xE0000ADE,0xFEF843BD,0xFEA431C2,0xF0001B1D,0xB2002CE1, -0x3DF850A2,0x842AC8,0x842AC8,0x842AC8,0x842AC8,0xFE500B99,0xFE500B99,0xFE500B99,0xCC340548,0xCC340548,0x90340549,0xFE181234,0xFE181234,0xFE181234,0xCC000121,0xCC000121,0x92040009,0x92001142,0x92001142,0x7E0005AA,0x62001142,0xC42AC8,0xC42AC8,0xC42AC8,0xA8000FDA,0xA8000FDA,0x86000849,0x80001946,0x80001946,0x74000BC6,0x5E001523,0x18C2AC8, -0x18C2AC8,0x5C001A61,0x50001F2E,0x40002ACB,0xFE681BBA,0xF67C23A8,0x842AC8,0xFE441026,0xFE1805AA,0xFC000171,0xEA000088,0xB6000274,0xFE3C1B18,0xFE180E8E,0xB60011C3,0x74000BC6,0x1182AC8,0xC41144,0xC41144,0xC41144,0xC41144,0xFE8001F9,0xFE8001F9,0xFE8001F9,0xBE680001,0xBE680001,0x90680001,0x3241142,0x3241142,0x3241142,0xCC000121,0xCC000121, -0x900C0001,0x17FC1142,0x17FC1142,0x7E0005AA,0x62001142,0x3241142,0x3241142,0x3241142,0xCC000121,0xCC000121,0x900C0001,0x17FC1142,0x17FC1142,0x7E0005AA,0x62001142,0x17FC1142,0x17FC1142,0x7E0005AA,0x62001142,0x62001142,0xFEA00C82,0xF6BC0DC8,0xC41144,0xFE78094D,0xFE2C046A,0xFC000171,0xEA000088,0xB6000274,0xFE780D0D,0xFE4808B4,0x1A41142,0x7E0005AA, -0x1A41142,0x1901735,0xFF680E48,0xFF380464,0xFF240000,0x59FC1735,0xFEFC08C8,0xFEB80001,0xADFC1735,0xF20001B1,0xC8001735,0x59FC1735,0xFEFC08C8,0xFEB80001,0xADFC1735,0xF20001B1,0xC8001735,0xADFC1735,0xF20001B1,0xC8001735,0xC8001735,0x59FC1735,0xFEFC08C8,0xFEB80001,0xADFC1735,0xF20001B1,0xC8001735,0xADFC1735,0xF20001B1,0xC8001735,0xC8001735,0xADFC1735, -0xF20001B1,0xC8001735,0xC8001735,0xC8001735,0xFF781522,0x1AC1735,0xFF8C1589,0xFF401231,0xFEFC0E90,0xFE840734,0xFC000014,0xEC000454,0xFF701520,0xFF4011AD,0xFE3000C5,0xC8001735,0x99FC1735,0x340548,0x340548,0x340548,0x340548,0x340548,0x340548,0x340548,0x340548,0x340548,0x340548,0x9C000000,0x9C000000,0x9C000000,0x9C000000,0x9C000000, -0x9C000000,0x4C000000,0x4C000000,0x4C000000,0x32000001,0x4C0548,0x4C0548,0x4C0548,0x4C0548,0x4C0548,0x4C0548,0x3A0001F9,0x3A0001F9,0x3A0001F9,0x2E0000FA,0x980548,0x980548,0x980548,0x2000034D,0x1800054A,0xFA2402AD,0x340548,0x340548,0xFE100091,0xFE000000,0xC2000000,0xC2000000,0x7E000000,0xFC000200,0xE40000DD,0x60000024,0x3A0001F9, -0x6C0548,}; -static const uint32_t g_etc1_to_bc7_m6_table237[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x780000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000, -0x2B00000,0x1680000,0x1680000,0x1680000,0x3A000001,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x2B00000,0x1680000,0x1680000,0x1680000,0x3A000001,0x1680000,0x1680000,0x1680000,0x3A000001,0x3A000001,0x800000,0x780000,0x780000,0x8C0000,0x2940000,0xA40000,0xA40000,0xC80000,0x8C0000,0x2940000,0xFC0000,0x1680000, -0xFC0000,0x1340000,0x1340000,0x1340000,0x1340000,0x1C80000,0x1C80000,0x1C80000,0x69FC0000,0x69FC0000,0x98000001,0x1C80000,0x1C80000,0x1C80000,0x69FC0000,0x69FC0000,0x98000001,0x69FC0000,0x69FC0000,0x98000001,0x98000001,0x1C80000,0x1C80000,0x1C80000,0x69FC0000,0x69FC0000,0x98000001,0x69FC0000,0x69FC0000,0x98000001,0x98000001,0x69FC0000, -0x69FC0000,0x98000001,0x98000001,0x98000001,0x5640000,0x1480000,0x1340000,0x1A40000,0x7FC0000,0x41FC0000,0x55FC0000,0x77F40000,0x3800000,0x1C80000,0x41FC0000,0x98000001,0x41FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xEC91E9,0xFEC46279,0xFEA03CA5,0xFE902F14,0xFE985139,0xFE64210A,0xFE5C0EF9,0xFE4C1EBD,0xF23808E4,0xCC3C1AF5,0xFE806462,0xFE3829E8,0xFE241378,0xFE081E61,0xF000026D,0xCC00141E,0xE8004A4E,0xD0002208,0xB80026E5,0x9C004A4E,0x15C91E7,0xFE084BDC,0xF4003058,0xFA0039ED,0xE2001939,0xC000247F,0xD8005F3E,0xC60033B5,0xAE00348E,0x98005432,0x33F891E7, -0xA60060B4,0x9C005887,0x8A006F9B,0x740091E7,0xFEBC6F6D,0xF8E085F5,0xFAE48878,0xFE804B93,0xFE4C28D8,0xFE100BA9,0xFC000045,0xE40007A9,0xFE986E0F,0xFE5C46BB,0xF60018B4,0xAE00348E,0x1F091E7,0x1384A4D,0xFF0C3095,0xFEE419E8,0xFED41144,0xFEE82E49,0xFEAC0F1E,0xFE980269,0xFE881509,0xEE6C0364,0xCC7813ED,0x1D04A4D,0xFE70234B,0xFE441142,0xFE141E3D,0xF000026D, -0xCC00141E,0x6DF84A4D,0xD0002208,0xB80026E5,0x9C004A4E,0x1D04A4D,0xFE70234B,0xFE441142,0xFE141E3D,0xF000026D,0xCC00141E,0x6DF84A4D,0xD0002208,0xB80026E5,0x9C004A4E,0x6DF84A4D,0xD0002208,0xB80026E5,0x9C004A4E,0x9C004A4E,0xFF143E02,0xFF2C4531,0xFF2C4538,0xFED43009,0xFE901F05,0xFE240B1D,0xFC000045,0xE40007A9,0xFEF83E4D,0xFEC02DC4,0xF60017D3,0xB80026E5, -0x45FC4A4D,0x902F14,0x902F14,0x902F14,0x902F14,0xFE5C0EF9,0xFE5C0EF9,0xFE5C0EF9,0xD63C0708,0xD63C0708,0x983C0709,0xFE241378,0xFE241378,0xFE241378,0xD80000B9,0xD80000B9,0x9A080035,0x9E001142,0x9E001142,0x84000502,0x6A001142,0x2D02F13,0x2D02F13,0x2D02F13,0xB400119A,0xB400119A,0x8C0009B1,0x8C001AA6,0x8C001AA6,0x7A000C12,0x620015C2,0x1AC2F13, -0x1AC2F13,0x66001D13,0x56002186,0x46002F13,0xFE681F7A,0xFC8827B4,0x902F14,0xFE4C1319,0xFE2C078E,0xFE040199,0xFC000041,0xC00001D4,0xFE501E81,0xFE301181,0xC60011D4,0x7A000C12,0x12C2F13,0xD41144,0xD41144,0xD41144,0xD41144,0xFE980269,0xFE980269,0xFE980269,0xC6780001,0xC6780001,0x98780001,0x33C1142,0x33C1142,0x33C1142,0xD80000B9,0xD80000B9, -0x981C0001,0x23FC1142,0x23FC1142,0x84000502,0x6A001142,0x33C1142,0x33C1142,0x33C1142,0xD80000B9,0xD80000B9,0x981C0001,0x23FC1142,0x23FC1142,0x84000502,0x6A001142,0x23FC1142,0x23FC1142,0x84000502,0x6A001142,0x6A001142,0xFAB40CD1,0xFECC0DC8,0xD41144,0xFE880994,0xFE4804D9,0xFE0C0190,0xFC000041,0xC00001D4,0xFE940D2A,0xFE5C0901,0x1C81142,0x84000502, -0x1C81142,0x19813ED,0xFF740C44,0xFF4C03D9,0xFF340000,0x65FC13ED,0xFF080784,0xFED00000,0xB3FC13ED,0xF80000CD,0xCC0013ED,0x65FC13ED,0xFF080784,0xFED00000,0xB3FC13ED,0xF80000CD,0xCC0013ED,0xB3FC13ED,0xF80000CD,0xCC0013ED,0xCC0013ED,0x65FC13ED,0xFF080784,0xFED00000,0xB3FC13ED,0xF80000CD,0xCC0013ED,0xB3FC13ED,0xF80000CD,0xCC0013ED,0xCC0013ED,0xB3FC13ED, -0xF80000CD,0xCC0013ED,0xCC0013ED,0xCC0013ED,0xFF781232,0x1B413ED,0xFF8C1289,0xFF580FA1,0xFF100C84,0xFE980631,0xFE0C0000,0xF20002D0,0xFF701220,0xFF400F1D,0xFE5000A9,0xCC0013ED,0x9FFC13ED,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0x3C0708,0xB6000000,0xB6000000,0xB6000000,0xB6000000,0xB6000000, -0xB6000000,0x58000000,0x58000000,0x58000000,0x3A000001,0x580708,0x580708,0x580708,0x580708,0x580708,0x580708,0x460002A1,0x460002A1,0x460002A1,0x34000152,0xB00708,0xB00708,0xB00708,0x2600045D,0x1C00070A,0xFE2C03F5,0x3C0708,0x3C0708,0xFA180154,0xFC080029,0xE0000000,0xE0000000,0x92000000,0xFA080322,0xFE000140,0x70000031,0x460002A1, -0x7C0708,}; -static const uint32_t g_etc1_to_bc7_m6_table238[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0x880000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000, -0xC80000,0x1980000,0x1980000,0x1980000,0x42000001,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0xC80000,0x1980000,0x1980000,0x1980000,0x42000001,0x1980000,0x1980000,0x1980000,0x42000001,0x42000001,0x900000,0x880000,0x880000,0x49C0000,0x2A80000,0xB80000,0xB80000,0xE40000,0x49C0000,0x2A80000,0x1200000,0x1980000, -0x1200000,0x1440000,0x1440000,0x1440000,0x1440000,0x1E00000,0x1E00000,0x1E00000,0x75FC0000,0x75FC0000,0xA0000001,0x1E00000,0x1E00000,0x1E00000,0x75FC0000,0x75FC0000,0xA0000001,0x75FC0000,0x75FC0000,0xA0000001,0xA0000001,0x1E00000,0x1E00000,0x1E00000,0x75FC0000,0x75FC0000,0xA0000001,0x75FC0000,0x75FC0000,0xA0000001,0xA0000001,0x75FC0000, -0x75FC0000,0xA0000001,0xA0000001,0xA0000001,0x1780000,0x5580000,0x1440000,0x1B80000,0x1BFC0000,0x51FC0000,0x63FC0000,0x81F80000,0x3940000,0x1E00000,0x51FC0000,0xA0000001,0x51FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xF490E1,0xFEC46419,0xFEA04085,0xFE9833B4,0xFEA451A9,0xFE7023E2,0xFE5C12C9,0xFE581EA9,0xF6400A14,0xD04419ED,0xFE806262,0xFE402ADB,0xFE301544,0xFE141BF1,0xF60000F9,0xD00010E6,0xF000444D,0xD6001E14,0xBE002159,0xA000444E,0x16890DF,0xFE144EC8,0xFA003418,0xFA00381D,0xE80018CD,0xC6002223,0xE2005A92,0xCC0030B1,0xB4002FCA,0x98004EF2,0x39F890DF, -0xAC006018,0x9C005607,0x8A006C1B,0x780090DF,0xFEBC6F7D,0xFCE884ED,0xFEEC87B8,0xFE944C1E,0xFE50299A,0xFE180BFB,0xFE040069,0xEA0004E2,0xFEB46DCE,0xFE704795,0xF6001634,0xB4002FCA,0x3FC90DF,0x144444D,0xFF182D4D,0xFEF01904,0xFEE41144,0xFEF42A65,0xFEB80E5A,0xFEA402D5,0xFE941241,0xF07C0278,0xD08810E5,0x1E0444D,0xFE882153,0xFE5C1142,0xFE2C1B35,0xF60000F9, -0xD00010E6,0x75FC444D,0xD6001E14,0xBE002159,0xA000444E,0x1E0444D,0xFE882153,0xFE5C1142,0xFE2C1B35,0xF60000F9,0xD00010E6,0x75FC444D,0xD6001E14,0xBE002159,0xA000444E,0x75FC444D,0xD6001E14,0xBE002159,0xA000444E,0xA000444E,0xFF20392D,0xFF2C3FE1,0xF9404005,0xFEEC2C7A,0xFEA41CE9,0xFE380A7D,0xFE0C0050,0xEA0004E2,0xFF08395E,0xFEC82A3E,0xF6001553,0xBE002159, -0x51FC444D,0x9833B4,0x9833B4,0x9833B4,0x9833B4,0xFE5C12C9,0xFE5C12C9,0xFE5C12C9,0xE0440908,0xE0440908,0xA0440909,0xFE301544,0xFE301544,0xFE301544,0xE8000059,0xE8000059,0xA20C0089,0xAA001142,0xAA001142,0x9000046A,0x72001142,0xE433B3,0xE433B3,0xE433B3,0xC000139A,0xC000139A,0x98000B59,0x98001C26,0x98001C26,0x86000C7A,0x6E001672,0x1D033B3, -0x1D033B3,0x6C001FE3,0x5C00240E,0x4C0033B3,0xFE7423B8,0xFE8C2C28,0x9833B4,0xFE541675,0xFE2C09CE,0xFE0C0274,0xFE040069,0xCC00015A,0xFE5022C1,0xFE3014B1,0xD60011ED,0x86000C7A,0x14833B3,0xE41144,0xE41144,0xE41144,0xE41144,0xFEA402D5,0xFEA402D5,0xFEA402D5,0xCE880001,0xCE880001,0xA0880001,0x1541142,0x1541142,0x1541142,0xE8000059,0xE8000059, -0xA02C0001,0x2FFC1142,0x2FFC1142,0x9000046A,0x72001142,0x1541142,0x1541142,0x1541142,0xE8000059,0xE8000059,0xA02C0001,0x2FFC1142,0x2FFC1142,0x9000046A,0x72001142,0x2FFC1142,0x2FFC1142,0x9000046A,0x72001142,0x72001142,0xFEBC0CF9,0xF6DC0E1D,0xE41144,0xFE9809E5,0xFE5C0551,0xFE2001E2,0xFE0C0050,0xCC00015A,0xFAAC0D75,0xFE740975,0x1E81142,0x9000046A, -0x1E81142,0x1A010E5,0xFF800A68,0xFF58033D,0xFF440000,0x71FC10E5,0xFF200654,0xFEE80000,0xB9FC10E5,0xF800003D,0xD00010E5,0x71FC10E5,0xFF200654,0xFEE80000,0xB9FC10E5,0xF800003D,0xD00010E5,0xB9FC10E5,0xF800003D,0xD00010E5,0xD00010E5,0x71FC10E5,0xFF200654,0xFEE80000,0xB9FC10E5,0xF800003D,0xD00010E5,0xB9FC10E5,0xF800003D,0xD00010E5,0xD00010E5,0xB9FC10E5, -0xF800003D,0xD00010E5,0xD00010E5,0xD00010E5,0xFD900F79,0x1BC10E5,0xF79C0FD4,0xFF6C0D2A,0xFF280A82,0xFEC00544,0xFE340000,0xF2000190,0xF7880F79,0xFF4C0CE2,0xFE700090,0xD00010E5,0xA7FC10E5,0x440908,0x440908,0x440908,0x440908,0x440908,0x440908,0x440908,0x440908,0x440908,0x440908,0xCE000000,0xCE000000,0xCE000000,0xCE000000,0xCE000000, -0xCE000000,0x64000000,0x64000000,0x64000000,0x42000001,0x640908,0x640908,0x640908,0x640908,0x640908,0x640908,0x52000369,0x52000369,0x52000369,0x3A0001BA,0xCC0908,0xCC0908,0xCC0908,0x2C000595,0x2000090A,0xFE2C05A5,0x440908,0x440908,0xFE200244,0xFE0C009D,0xFE000000,0xFE000000,0xA6000000,0xFE100482,0xFE000200,0x7E000041,0x52000369, -0x900908,}; -static const uint32_t g_etc1_to_bc7_m6_table239[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0x980000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000, -0xE00000,0x1CC0000,0x1CC0000,0x1CC0000,0x4A000001,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0xE00000,0x1CC0000,0x1CC0000,0x1CC0000,0x4A000001,0x1CC0000,0x1CC0000,0x1CC0000,0x4A000001,0x4A000001,0x8A00000,0x980000,0x980000,0xB00000,0x2BC0000,0x2CC0000,0x2CC0000,0x1000000,0xB00000,0x2BC0000,0x1400000,0x1CC0000, -0x1400000,0x1540000,0x1540000,0x1540000,0x1540000,0x1F80000,0x1F80000,0x1F80000,0x81FC0000,0x81FC0000,0xA8000001,0x1F80000,0x1F80000,0x1F80000,0x81FC0000,0x81FC0000,0xA8000001,0x81FC0000,0x81FC0000,0xA8000001,0xA8000001,0x1F80000,0x1F80000,0x1F80000,0x81FC0000,0x81FC0000,0xA8000001,0x81FC0000,0x81FC0000,0xA8000001,0xA8000001,0x81FC0000, -0x81FC0000,0xA8000001,0xA8000001,0xA8000001,0x18C0000,0xD680000,0x1540000,0x3CC0000,0x2FFC0000,0x5FFC0000,0x71FC0000,0x8BFC0000,0x3A80000,0x1F80000,0x5FFC0000,0xA8000001,0x5FFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0xFC9059,0xFED0662D,0xFEAC44A9,0xFEA438A8,0xFEB052A9,0xFE7C2732,0xFE6816F9,0xFE581F29,0xFA480BC4,0xD44C1965,0xFE8C60F6,0xFE4C2C1F,0xFE3C1798,0xFE201A39,0xFA000035,0xD4080E36,0xF8003EA2,0xDC001AA8,0xC4001C3D,0xA6003EA2,0x1749057,0xFE20521C,0xFC0038AF,0xFA00374D,0xEE001919,0xCC002067,0xE2005652,0xD2002E3D,0xBA002B7E,0xA20049CB,0x3FF89057, -0xB2006024,0xA6005459,0x9000690F,0x7C009057,0xFED06FC2,0xFEEC8481,0xFEEC87D8,0xFE984D29,0xFE602AF8,0xFE240D01,0xFE100125,0xF00002D9,0xFEB46DDE,0xFE80487B,0xFE001462,0xBA002B7E,0xBFC9057,0x14C3EA5,0xFF242A35,0xFF081824,0xFEF41144,0xFF0026C9,0xFECC0DAC,0xFEBC0355,0xFEAC0FB9,0xF28C01B4,0xD4980E1D,0x1F03EA2,0xFEA01F7B,0xFE741142,0xFE381881,0xFA000035, -0xD4100E1E,0x7DF83EA2,0xDC001AA8,0xC4001C3D,0xA6003EA2,0x1F03EA2,0xFEA01F7B,0xFE741142,0xFE381881,0xFA000035,0xD4100E1E,0x7DF83EA2,0xDC001AA8,0xC4001C3D,0xA6003EA2,0x7DF83EA2,0xDC001AA8,0xC4001C3D,0xA6003EA2,0xA6003EA2,0xFF343494,0xFB443A79,0xFD483A9D,0xFEEC292A,0xFEA81AF3,0xFE480A18,0xFE280088,0xF00002D9,0xFF1834C1,0xFEDC273A,0xFE001362,0xC4001C3D, -0x5BFC3EA2,0xA438A8,0xA438A8,0xA438A8,0xA438A8,0xFE6816F9,0xFE6816F9,0xFE6816F9,0xEA4C0B48,0xEA4C0B48,0xA84C0B49,0xFE3C1798,0xFE3C1798,0xFE3C1798,0xFA000025,0xFA000025,0xAE100102,0xB6001142,0xB6001142,0x960003DA,0x7A001142,0xF438A8,0xF438A8,0xF438A8,0xCC0015DA,0xCC0015DA,0xA2000D3B,0xA2001D8D,0xA2001D8D,0x8C000CF6,0x7400172E,0x1F038A8, -0x1F038A8,0x720022FB,0x660026FB,0x500038AB,0xFE842831,0xF69C3169,0xA438A8,0xFE5C1A55,0xFE400CA2,0xFE1C03D8,0xFE100125,0xDA0000FA,0xFE64274E,0xFE44188A,0xE6001206,0x8C000CF6,0x15C38A8,0xF41144,0xF41144,0xF41144,0xF41144,0xFEBC0355,0xFEBC0355,0xFEBC0355,0xD6980001,0xD6980001,0xA8980001,0x16C1142,0x16C1142,0x16C1142,0xFA000025,0xFA000025, -0xA83C0001,0x3BFC1142,0x3BFC1142,0x960003DA,0x7A001142,0x16C1142,0x16C1142,0x16C1142,0xFA000025,0xFA000025,0xA83C0001,0x3BFC1142,0x3BFC1142,0x960003DA,0x7A001142,0x3BFC1142,0x3BFC1142,0x960003DA,0x7A001142,0x7A001142,0xFED80D22,0xFEEC0E1D,0xF41144,0xFEA40A68,0xFE7005D1,0xFE380249,0xFE280088,0xDA0000FA,0xFEB40D9D,0xFE9809D9,0x7FC1142,0x960003DA, -0x7FC1142,0x1A80E1D,0xFF8C08B4,0xFF6402B1,0xFF540000,0x7DFC0E1D,0xFF380544,0xFF000000,0xBFFC0E1D,0xFE000001,0xD4000E1D,0x7DFC0E1D,0xFF380544,0xFF000000,0xBFFC0E1D,0xFE000001,0xD4000E1D,0xBFFC0E1D,0xFE000001,0xD4000E1D,0xD4000E1D,0x7DFC0E1D,0xFF380544,0xFF000000,0xBFFC0E1D,0xFE000001,0xD4000E1D,0xBFFC0E1D,0xFE000001,0xD4000E1D,0xD4000E1D,0xBFFC0E1D, -0xFE000001,0xD4000E1D,0xD4000E1D,0xD4000E1D,0xFF940CD5,0x1C40E1D,0xFBA40D24,0xFF6C0AFA,0xFF3C08CA,0xFEC80451,0xFE5C0000,0xF60000B9,0xFB900CD1,0xFF640AD2,0xFE940079,0xD4000E1D,0xAFFC0E1D,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0x4C0B48,0xE6000000,0xE6000000,0xE6000000,0xE6000000,0xE6000000, -0xE6000000,0x70000000,0x70000000,0x70000000,0x4A000001,0x700B48,0x700B48,0x700B48,0x700B48,0x700B48,0x700B48,0x58000449,0x58000449,0x58000449,0x4600022A,0xE40B48,0xE40B48,0xE40B48,0x320006F5,0x24000B4A,0xF63C0784,0x4C0B48,0x4C0B48,0xFE2C039D,0xFE140164,0xFE080029,0xFE080029,0xBA000000,0xFE100652,0xFE000340,0x86000050,0x58000449, -0xA00B48,}; -static const uint32_t g_etc1_to_bc7_m6_table240[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xA80001,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000, -0xFC0000,0x3F80000,0x3F80000,0x3F80000,0x54000000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0x3F80000,0x3F80000,0x3F80000,0x54000000,0x3F80000,0x3F80000,0x3F80000,0x54000000,0x54000000,0x2B40000,0xA80001,0xA80001,0x2C40000,0xD40000,0xE80000,0xE80000,0x11C0000,0x2C40000,0xD40000,0x1680000,0x3F80000, -0x1680000,0x1640001,0x1640001,0x1640001,0x1640001,0x19FC0000,0x19FC0000,0x19FC0000,0x8FF80000,0x8FF80000,0xB2000000,0x19FC0000,0x19FC0000,0x19FC0000,0x8FF80000,0x8FF80000,0xB2000000,0x8FF80000,0x8FF80000,0xB2000000,0xB2000000,0x19FC0000,0x19FC0000,0x19FC0000,0x8FF80000,0x8FF80000,0xB2000000,0x8FF80000,0x8FF80000,0xB2000000,0xB2000000,0x8FF80000, -0x8FF80000,0xB2000000,0xB2000000,0xB2000000,0x1A00000,0x77C0000,0x1640001,0x1E80000,0x45FC0000,0x71FC0000,0x7FFC0000,0x99F40000,0x1C00000,0x19FC0000,0x71FC0000,0xB2000000,0x71FC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1049057,0xFEDC690F,0xFEB849CB,0xFEB03EA2,0xFEB05459,0xFE882B7E,0xFE741C3D,0xFE642067,0xFA540E36,0xD8541965,0xFE986024,0xFE582E3D,0xFE441AA8,0xFE201919,0xFE040035,0xDA080BC4,0xFE0438AF,0xE0001798,0xCA0016F9,0xAC0038A8,0x3809057,0xFE385652,0xFE0C3EA2,0xFE08374D,0xEE001A39,0xD2001F29,0xEE00521C,0xD8002C1F,0xC0002732,0xA80044A9,0x45FC9057, -0xB80060F6,0xA60052A9,0x9600662D,0x80009059,0xFED870CD,0xFEEC8535,0xF90088B3,0xFE984F45,0xFE682CFD,0xFE2C0EC7,0xFE1C02D9,0xF6000125,0xFEB46F22,0xFE804A3D,0xFE001354,0xC0002732,0x15FC9057,0x15838AB,0xFF3026FB,0xFF14172E,0xFF081142,0xFF1822FB,0xFEE40CF6,0xFED003DA,0xFEB80D3B,0xF6A00102,0xD8A80B49,0x7FC38A8,0xFEB81D8D,0xFE901142,0xFE5815DA,0xFE080025, -0xD8280B48,0x85FC38A8,0xE0001798,0xCA0016F9,0xAC0038A8,0x7FC38A8,0xFEB81D8D,0xFE901142,0xFE5815DA,0xFE080025,0xD8280B48,0x85FC38A8,0xE0001798,0xCA0016F9,0xAC0038A8,0x85FC38A8,0xE0001798,0xCA0016F9,0xAC0038A8,0xAC0038A8,0xFF342F72,0xFF4C34BB,0xFF4C3533,0xFF082595,0xFEC818C5,0xFE7009A1,0xFE3C00FA,0xF6000125,0xFF243009,0xFEE8241E,0xFE001254,0xCA0016F9, -0x65FC38A8,0xB03EA2,0xB03EA2,0xB03EA2,0xB03EA2,0xFE741C3D,0xFE741C3D,0xFE741C3D,0xF4540E1E,0xF4540E1E,0xB2540E1D,0xFE441AA8,0xFE441AA8,0xFE441AA8,0xFE040035,0xFE040035,0xB81801B4,0xC4001142,0xC4001142,0xA0000355,0x82001144,0x1043EA2,0x1043EA2,0x1043EA2,0xE2001881,0xE2001881,0xA8000FB9,0xAE001F7B,0xAE001F7B,0x98000DAC,0x7A001824,0x7FC3EA2, -0x7FC3EA2,0x7E0026C9,0x6C002A35,0x56003EA5,0xFE902DE5,0xFCA83721,0xB03EA2,0xFE701F65,0xFE441079,0xFE24061D,0xFE1C02D9,0xEA000088,0xFE782CA5,0xFE501D0A,0xF6001225,0x98000DAC,0x1743EA2,0x1081142,0x1081142,0x1081142,0x1081142,0xFED003DA,0xFED003DA,0xFED003DA,0xE0A80001,0xE0A80001,0xB2A80001,0x1881142,0x1881142,0x1881142,0xFE080025,0xFE080025, -0xB24C0001,0x49F81142,0x49F81142,0xA0000355,0x82001144,0x1881142,0x1881142,0x1881142,0xFE080025,0xFE080025,0xB24C0001,0x49F81142,0x49F81142,0xA0000355,0x82001144,0x49F81142,0x49F81142,0xA0000355,0x82001144,0x82001144,0xFAEC0D75,0xF9000E72,0x1081142,0xFEC40ABA,0xFE98065D,0xFE5802F2,0xFE3C00FA,0xEA000088,0xFED00DD0,0xFEA40A40,0x19FC1142,0xA0000355, -0x19FC1142,0x1B00B4A,0xFF9806F5,0xFF70022A,0xFF640001,0x8DFC0B48,0xFF4C0449,0xFF1C0000,0xC7FC0B48,0xFE2C0000,0xD8000B48,0x8DFC0B48,0xFF4C0449,0xFF1C0000,0xC7FC0B48,0xFE2C0000,0xD8000B48,0xC7FC0B48,0xFE2C0000,0xD8000B48,0xD8000B48,0x8DFC0B48,0xFF4C0449,0xFF1C0000,0xC7FC0B48,0xFE2C0000,0xD8000B48,0xC7FC0B48,0xFE2C0000,0xD8000B48,0xD8000B48,0xC7FC0B48, -0xFE2C0000,0xD8000B48,0xD8000B48,0xD8000B48,0xFF940A68,0xFCC0B48,0xFFAC0A6D,0xFF8408D1,0xFF500709,0xFEF00382,0xFE880000,0xFA000029,0xFF980A22,0xFF7008B4,0xFEB80064,0xD8000B48,0xB9FC0B48,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0x540E1D,0xFE000001,0xFE000001,0xFE000001,0xFE000001,0xFE000001, -0xFE000001,0x7E000000,0x7E000000,0x7E000000,0x54000000,0x7C0E1D,0x7C0E1D,0x7C0E1D,0x7C0E1D,0x7C0E1D,0x7C0E1D,0x62000544,0x62000544,0x62000544,0x4C0002B1,0xFC0E1D,0xFC0E1D,0xFC0E1D,0x380008B4,0x2A000E1D,0xFC4809D9,0x540E1D,0x540E1D,0xFE2C0568,0xFE200290,0xFE1000B9,0xFE1000B9,0xD0000000,0xFE20088A,0xFE1404E2,0x9E000065,0x62000544, -0xB00E1D,}; -static const uint32_t g_etc1_to_bc7_m6_table241[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0xB80001,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000, -0x1140000,0xFF80000,0xFF80000,0xFF80000,0x5C000000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0x1140000,0xFF80000,0xFF80000,0xFF80000,0x5C000000,0xFF80000,0xFF80000,0xFF80000,0x5C000000,0x5C000000,0xAC40000,0xB80001,0xB80001,0xD80000,0xE80000,0xFC0000,0xFC0000,0x1380000,0xD80000,0xE80000,0x18C0000,0xFF80000, -0x18C0000,0x1740001,0x1740001,0x1740001,0x1740001,0x31FC0000,0x31FC0000,0x31FC0000,0x9BF80000,0x9BF80000,0xBA000000,0x31FC0000,0x31FC0000,0x31FC0000,0x9BF80000,0x9BF80000,0xBA000000,0x9BF80000,0x9BF80000,0xBA000000,0xBA000000,0x31FC0000,0x31FC0000,0x31FC0000,0x9BF80000,0x9BF80000,0xBA000000,0x9BF80000,0x9BF80000,0xBA000000,0xBA000000,0x9BF80000, -0x9BF80000,0xBA000000,0xBA000000,0xBA000000,0x1B40000,0xF8C0000,0x1740001,0x1FC0000,0x59FC0000,0x7FFC0000,0x8DFC0000,0xA3F80000,0x1D40000,0x31FC0000,0x7FFC0000,0xBA000000,0x7FFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x10C90DF,0xFEE86C1B,0xFEC04EF2,0xFEBC444E,0xFEC45607,0xFE942FCA,0xFE802159,0xFE702223,0xFE5C10E6,0xDC5C19ED,0xFEA46018,0xFE6430B1,0xFE501E14,0xFE2C18CD,0xFE1000F9,0xDE100A14,0xFE083418,0xE6001544,0xCA0012C9,0xB20033B4,0x38C90DF,0xFE385A92,0xFE1C444D,0xFE08381D,0xF4001BF1,0xD2001EA9,0xF4004EC8,0xDE002ADB,0xC60023E2,0xAE004085,0x4BFC90DF, -0xBE006262,0xAC0051A9,0x9C006419,0x840090E1,0xFEE47241,0xFB048637,0xFD08897B,0xFEAC5155,0xFE742F9E,0xFE381111,0xFE2804E2,0xFC000069,0xFED07092,0xFE904C7B,0xFE001374,0xC60023E2,0x1DF890DF,0x16433B3,0xFF44240E,0xFF201672,0xFF181142,0xFF241FE3,0xFEF00C7A,0xFEDC046A,0xFECC0B59,0xF6B40089,0xDCB80909,0x15FC33B3,0xFECC1C26,0xFEA81142,0xFE70139A,0xFE2C0059, -0xDC3C0908,0x8DFC33B3,0xE6001544,0xCA0012C9,0xB20033B4,0x15FC33B3,0xFECC1C26,0xFEA81142,0xFE70139A,0xFE2C0059,0xDC3C0908,0x8DFC33B3,0xE6001544,0xCA0012C9,0xB20033B4,0x8DFC33B3,0xE6001544,0xCA0012C9,0xB20033B4,0xB20033B4,0xFF3C2BBB,0xF75C3071,0xF96030C6,0xFF142266,0xFEDC1721,0xFE7C0965,0xFE64015A,0xFC000069,0xFF342BED,0xFF042108,0xFE141223,0xCA0012C9, -0x6FFC33B3,0xBC444E,0xBC444E,0xBC444E,0xBC444E,0xFE802159,0xFE802159,0xFE802159,0xFE5C10E6,0xFE5C10E6,0xBA5C10E5,0xFE501E14,0xFE501E14,0xFE501E14,0xFE1000F9,0xFE1000F9,0xC01C0278,0xD0001142,0xD0001142,0xAC0002D5,0x8A001144,0x114444D,0x114444D,0x114444D,0xE8001B35,0xE8001B35,0xB4001241,0xBA002153,0xBA002153,0xA2000E5A,0x86001904,0xFF8444D, -0xFF8444D,0x84002A65,0x72002D4D,0x5C00444D,0xFEA03348,0xFEAC3CB9,0xBC444E,0xFE78242D,0xFE541448,0xFE3408B9,0xFE2804E2,0xF8000050,0xFE7831F5,0xFE5021DA,0xFE001274,0xA2000E5A,0x18C444D,0x1181142,0x1181142,0x1181142,0x1181142,0xFEDC046A,0xFEDC046A,0xFEDC046A,0xE8B80001,0xE8B80001,0xBAB80001,0x1A01142,0x1A01142,0x1A01142,0xFE2C0059,0xFE2C0059, -0xBA5C0001,0x55F81142,0x55F81142,0xAC0002D5,0x8A001144,0x1A01142,0x1A01142,0x1A01142,0xFE2C0059,0xFE2C0059,0xBA5C0001,0x55F81142,0x55F81142,0xAC0002D5,0x8A001144,0x55F81142,0x55F81142,0xAC0002D5,0x8A001144,0x8A001144,0xFEF40D9D,0xFF0C0E7A,0x1181142,0xFEDC0AFD,0xFEAC06D9,0xFE740361,0xFE64015A,0xF8000050,0xF8EC0E1D,0xFEC40AB2,0x27FC1142,0xAC0002D5, -0x27FC1142,0x1B8090A,0xFFA40595,0xFF8801BA,0xFF740001,0x99FC0908,0xFF580369,0xFF340000,0xCDFC0908,0xFE600000,0xDC000908,0x99FC0908,0xFF580369,0xFF340000,0xCDFC0908,0xFE600000,0xDC000908,0xCDFC0908,0xFE600000,0xDC000908,0xDC000908,0x99FC0908,0xFF580369,0xFF340000,0xCDFC0908,0xFE600000,0xDC000908,0xCDFC0908,0xFE600000,0xDC000908,0xDC000908,0xCDFC0908, -0xFE600000,0xDC000908,0xDC000908,0xDC000908,0xFBAC0841,0x1D80908,0xFFAC087D,0xFF94070A,0xFF680595,0xFF0402C2,0xFEB00000,0xFE000000,0xFF980832,0xFF8806D1,0xFEDC0051,0xDC000908,0xBFFC0908,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0x5C10E5,0xFE0C003D,0xFE0C003D,0xFE0C003D,0xFE0C003D,0xFE0C003D, -0xFE0C003D,0x8A000000,0x8A000000,0x8A000000,0x5C000000,0x8810E5,0x8810E5,0x8810E5,0x8810E5,0x8810E5,0x8810E5,0x6E000654,0x6E000654,0x6E000654,0x5200033D,0x11410E5,0x11410E5,0x11410E5,0x3E000A68,0x2E0010E5,0xFE4C0C35,0x5C10E5,0x5C10E5,0xFE3C0745,0xFE280401,0xFE180190,0xFE180190,0xE4000000,0xFE200AFA,0xFE1406B2,0xA6000074,0x6E000654, -0xC010E5,}; -static const uint32_t g_etc1_to_bc7_m6_table242[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0xC80001,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000, -0x12C0000,0x1BF80000,0x1BF80000,0x1BF80000,0x64000000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x12C0000,0x1BF80000,0x1BF80000,0x1BF80000,0x64000000,0x1BF80000,0x1BF80000,0x1BF80000,0x64000000,0x64000000,0xD80000,0xC80001,0xC80001,0x6E80000,0xFC0000,0x3100000,0x3100000,0x1540000,0x6E80000,0xFC0000,0x1AC0000,0x1BF80000, -0x1AC0000,0x1840001,0x1840001,0x1840001,0x1840001,0x49FC0000,0x49FC0000,0x49FC0000,0xA7F80000,0xA7F80000,0xC2000000,0x49FC0000,0x49FC0000,0x49FC0000,0xA7F80000,0xA7F80000,0xC2000000,0xA7F80000,0xA7F80000,0xC2000000,0xC2000000,0x49FC0000,0x49FC0000,0x49FC0000,0xA7F80000,0xA7F80000,0xC2000000,0xA7F80000,0xA7F80000,0xC2000000,0xC2000000,0xA7F80000, -0xA7F80000,0xC2000000,0xC2000000,0xC2000000,0x3C40000,0x1A00000,0x1840001,0x1FFC0000,0x6DFC0000,0x8FFC0000,0x9BFC0000,0xADFC0000,0x1E80000,0x49FC0000,0x8FFC0000,0xC2000000,0x8FFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x11491E7,0xFEE86F9B,0xFECC5432,0xFEC44A4E,0xFEC45887,0xFEA0348E,0xFE8C26E5,0xFE7C247F,0xFE64141E,0xE0641AF5,0xFEB060B4,0xFE7033B5,0xFE5C2208,0xFE381939,0xFE14026D,0xE21808E4,0xFE143058,0xEC001378,0xD0000EF9,0xB6002F14,0x39891E7,0xFE4C5F3E,0xFE2C4A4E,0xFE0839ED,0xFA001E61,0xD8001EBD,0xFA004BDC,0xE20029E8,0xCC00210A,0xAE003CA5,0x51FC91E7, -0xBE006462,0xB2005139,0x9C006279,0x880091E9,0xFEE47431,0xFF0C873F,0xFF0C8ACF,0xFEB45441,0xFE7C3299,0xFE48140A,0xFE3407A9,0xFE040045,0xFED4724F,0xFE984F5B,0xFE001494,0xCC00210A,0x23FC91E7,0x1702F13,0xFF502186,0xFF3815C2,0xFF281142,0xFF301D13,0xFF080C12,0xFEF40502,0xFEE409B1,0xFAC80035,0xE0C80709,0x29FC2F13,0xFEE41AA6,0xFEC01142,0xFE88119A,0xFE4000B9, -0xE0500708,0x97F82F13,0xEC001378,0xD0000EF9,0xB6002F14,0x29FC2F13,0xFEE41AA6,0xFEC01142,0xFE88119A,0xFE4000B9,0xE0500708,0x97F82F13,0xEC001378,0xD0000EF9,0xB6002F14,0x97F82F13,0xEC001378,0xD0000EF9,0xB6002F14,0xB6002F14,0xFF5027BA,0xFD682BE9,0xFF6C2C5A,0xFF30200A,0xFEE8158A,0xFEA4095B,0xFE7C01D4,0xFE040041,0xFF442838,0xFF041EA8,0xFE341206,0xD0000EF9, -0x7BFC2F13,0xC44A4E,0xC44A4E,0xC44A4E,0xC44A4E,0xFE8C26E5,0xFE8C26E5,0xFE8C26E5,0xFE64141E,0xFE64141E,0xC26413ED,0xFE5C2208,0xFE5C2208,0xFE5C2208,0xFE14026D,0xFE14026D,0xC8200364,0xDC001142,0xDC001142,0xB2000269,0x92001144,0x3244A4D,0x3244A4D,0x3244A4D,0xF4001E3D,0xF4001E3D,0xBA001509,0xC000234B,0xC000234B,0xA8000F1E,0x8C0019E8,0x17FC4A4D, -0x17FC4A4D,0x8A002E49,0x78003095,0x62004A4D,0xFEA03908,0xF8C0430A,0xC44A4E,0xFE802964,0xFE5818D5,0xFE3C0BE6,0xFE3407A9,0xFE040045,0xFE9437CD,0xFE5C2742,0xFE001394,0xA8000F1E,0x1A44A4D,0x1281142,0x1281142,0x1281142,0x1281142,0xFEF40502,0xFEF40502,0xFEF40502,0xF0C80001,0xF0C80001,0xC2C80001,0x1B81142,0x1B81142,0x1B81142,0xFE4000B9,0xFE4000B9, -0xC26C0001,0x61F81142,0x61F81142,0xB2000269,0x92001144,0x1B81142,0x1B81142,0x1B81142,0xFE4000B9,0xFE4000B9,0xC26C0001,0x61F81142,0x61F81142,0xB2000269,0x92001144,0x61F81142,0x61F81142,0xB2000269,0x92001144,0x92001144,0xFF100DC8,0xF9200EC9,0x1281142,0xFEDC0B8D,0xFEC0075D,0xFE7C0414,0xFE7C01D4,0xFE040041,0xFEF80E21,0xFEDC0AFD,0x37FC1142,0xB2000269, -0x37FC1142,0x1C0070A,0xFFB0045D,0xFF940152,0xFF840001,0xA5FC0708,0xFF7002A1,0xFF4C0000,0xD3FC0708,0xFE900000,0xE0000708,0xA5FC0708,0xFF7002A1,0xFF4C0000,0xD3FC0708,0xFE900000,0xE0000708,0xD3FC0708,0xFE900000,0xE0000708,0xE0000708,0xA5FC0708,0xFF7002A1,0xFF4C0000,0xD3FC0708,0xFE900000,0xE0000708,0xD3FC0708,0xFE900000,0xE0000708,0xE0000708,0xD3FC0708, -0xFE900000,0xE0000708,0xE0000708,0xE0000708,0xFFB40659,0x1E00708,0xF9C00692,0xFF94057A,0xFF7C045D,0xFF2C0232,0xFED80000,0xFE380000,0xFFAC065D,0xFF940550,0xFEFC0040,0xE0000708,0xC7FC0708,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0x6413ED,0xFE0C00CD,0xFE0C00CD,0xFE0C00CD,0xFE0C00CD,0xFE0C00CD, -0xFE0C00CD,0x96000000,0x96000000,0x96000000,0x64000000,0x9413ED,0x9413ED,0x9413ED,0x9413ED,0x9413ED,0x9413ED,0x7A000784,0x7A000784,0x7A000784,0x580003D9,0x12C13ED,0x12C13ED,0x12C13ED,0x44000C44,0x320013ED,0xFE4C0F05,0x6413ED,0x6413ED,0xFE3C0975,0xFE3405B4,0xFE1802D0,0xFE1802D0,0xF8000000,0xFC380D75,0xFE2008D1,0xB6000089,0x7A000784, -0xD413ED,}; -static const uint32_t g_etc1_to_bc7_m6_table243[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0xD80001,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000, -0x1440000,0x27F80000,0x27F80000,0x27F80000,0x6C000000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x1440000,0x27F80000,0x27F80000,0x27F80000,0x6C000000,0x27F80000,0x27F80000,0x27F80000,0x6C000000,0x6C000000,0xE80000,0xD80001,0xD80001,0x2FC0000,0x1100000,0x1280000,0x1280000,0x36C0000,0x2FC0000,0x1100000,0x1D00000,0x27F80000, -0x1D00000,0x1940001,0x1940001,0x1940001,0x1940001,0x63FC0000,0x63FC0000,0x63FC0000,0xB3F80000,0xB3F80000,0xCA000000,0x63FC0000,0x63FC0000,0x63FC0000,0xB3F80000,0xB3F80000,0xCA000000,0xB3F80000,0xB3F80000,0xCA000000,0xCA000000,0x63FC0000,0x63FC0000,0x63FC0000,0xB3F80000,0xB3F80000,0xCA000000,0xB3F80000,0xB3F80000,0xCA000000,0xCA000000,0xB3F80000, -0xB3F80000,0xCA000000,0xCA000000,0xCA000000,0x1D80000,0x1B00000,0x1940001,0x3DFC0000,0x81FC0000,0x9FF80000,0xA9F80000,0xB9F80000,0x1FC0000,0x63FC0000,0x9FF80000,0xCA000000,0x9FF80000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x11C936F,0xFEF4735F,0xFED859D2,0xFED050A2,0xFED05B93,0xFEA839C2,0xFE982CE1,0xFE88277B,0xFE7017E2,0xE46C1C7D,0xFEB061D4,0xFE7C3749,0xFE682684,0xFE381A89,0xFE200485,0xE6200834,0xFE142D78,0xF2001234,0xD6000B99,0xBC002AC8,0x3A4936F,0xFE646426,0xFE3C50A2,0xFE083CBD,0xFA0021B1,0xDE001F71,0xFA0049BC,0xE80029B8,0xCC001E9A,0xB4003921,0x57FC936F, -0xC40066F6,0xB8005159,0xA6006174,0x8C009371,0xFEF476C5,0xFF0C88FF,0xFF0C8D0F,0xFEC45747,0xFE883642,0xFE541781,0xFE3C0ADE,0xFE0C00EC,0xFED474DF,0xFE9852EB,0xFE101676,0xCC001E9A,0x2BFC936F,0x1782ACB,0xFF5C1F2E,0xFF401523,0xFF381142,0xFF441A61,0xFF140BC6,0xFF0005AA,0xFEF00849,0xFCD80009,0xE4D80549,0x37FC2AC8,0xFEFC1946,0xFED81142,0xFEA00FDA,0xFE640121, -0xE4640548,0x9DFC2AC8,0xF2001234,0xD6000B99,0xBC002AC8,0x37FC2AC8,0xFEFC1946,0xFED81142,0xFEA00FDA,0xFE640121,0xE4640548,0x9DFC2AC8,0xF2001234,0xD6000B99,0xBC002AC8,0x9DFC2AC8,0xF2001234,0xD6000B99,0xBC002AC8,0xBC002AC8,0xFF58247D,0xFF6C27E1,0xFF6C289A,0xFF301D7A,0xFEFC143A,0xFEB80925,0xFE900274,0xFE280088,0xFD5824CE,0xFF181C5E,0xFE5811EB,0xD6000B99, -0x83FC2AC8,0xD050A2,0xD050A2,0xD050A2,0xD050A2,0xFE982CE1,0xFE982CE1,0xFE982CE1,0xFE7017E2,0xFE7017E2,0xCA6C1735,0xFE682684,0xFE682684,0xFE682684,0xFE200485,0xFE200485,0xD2280474,0xE6001144,0xE6001144,0xBE0001F9,0x9A001144,0x13450A2,0x13450A2,0x13450A2,0xFA0021A1,0xFA0021A1,0xC6001821,0xCC002553,0xCC002553,0xAE001012,0x92001AE4,0x1FF850A2, -0x1FF850A2,0x90003275,0x7E00340D,0x660050A5,0xFEAC3F3D,0xFCC8492A,0xD050A2,0xFE902EFD,0xFE6C1DB1,0xFE3C0FE6,0xFE3C0ADE,0xFE0C00EC,0xFE943DAD,0xFE742C9D,0xFE101595,0xAE001012,0x1B850A2,0x1381142,0x1381142,0x1381142,0x1381142,0xFF0005AA,0xFF0005AA,0xFF0005AA,0xF8D80001,0xF8D80001,0xCAD80001,0x1D01142,0x1D01142,0x1D01142,0xFE640121,0xFE640121, -0xCA7C0001,0x6DF81142,0x6DF81142,0xBE0001F9,0x9A001144,0x1D01142,0x1D01142,0x1D01142,0xFE640121,0xFE640121,0xCA7C0001,0x6DF81142,0x6DF81142,0xBE0001F9,0x9A001144,0x6DF81142,0x6DF81142,0xBE0001F9,0x9A001144,0x9A001144,0xFF200E1D,0xFF2C0ED5,0x1381142,0xFEF80BD1,0xFED407E9,0xFEA804A0,0xFE900274,0xFE280088,0xFD100E72,0xFEE80B5A,0x45FC1142,0xBE0001F9, -0x45FC1142,0x1C8054A,0xFFB0034D,0xFFA000FA,0xFF940001,0xB1FC0548,0xFF7C01F9,0xFF640000,0xD9FC0548,0xFEC00000,0xE4000548,0xB1FC0548,0xFF7C01F9,0xFF640000,0xD9FC0548,0xFEC00000,0xE4000548,0xD9FC0548,0xFEC00000,0xE4000548,0xE4000548,0xB1FC0548,0xFF7C01F9,0xFF640000,0xD9FC0548,0xFEC00000,0xE4000548,0xD9FC0548,0xFEC00000,0xE4000548,0xE4000548,0xD9FC0548, -0xFEC00000,0xE4000548,0xE4000548,0xE4000548,0xFFB404D9,0x1E80548,0xFDC804E2,0xFFB00422,0xFF7C034D,0xFF480195,0xFEFC0000,0xFE740000,0xF5C004E2,0xFFA00401,0xFF200031,0xE4000548,0xCFFC0548,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0x6C1735,0xFE1801B1,0xFE1801B1,0xFE1801B1,0xFE1801B1,0xFE1801B1, -0xFE1801B1,0xA0000001,0xA0000001,0xA0000001,0x6C000000,0xA01735,0xA01735,0xA01735,0xA01735,0xA01735,0xA01735,0x800008C8,0x800008C8,0x800008C8,0x62000464,0x1441735,0x1441735,0x1441735,0x4A000E48,0x36001735,0xF8601200,0x6C1735,0x6C1735,0xFE4C0BE4,0xFE3407B4,0xFE240454,0xFE240454,0xFE040014,0xFE3C1031,0xFC300B48,0xC6000099,0x800008C8, -0xE41735,}; -static const uint32_t g_etc1_to_bc7_m6_table244[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0xEC0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000, -0x35C0000,0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x35C0000,0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0x33FC0000,0x33FC0000,0x33FC0000,0x74000001,0x74000001,0xFC0000,0xEC0000,0xEC0000,0x5100000,0x1280000,0x1400000,0x1400000,0x18C0000,0x5100000,0x1280000,0x1F40000,0x33FC0000, -0x1F40000,0x1A80000,0x1A80000,0x1A80000,0x1A80000,0x7DFC0000,0x7DFC0000,0x7DFC0000,0xBFFC0000,0xBFFC0000,0xD2000001,0x7DFC0000,0x7DFC0000,0x7DFC0000,0xBFFC0000,0xBFFC0000,0xD2000001,0xBFFC0000,0xBFFC0000,0xD2000001,0xD2000001,0x7DFC0000,0x7DFC0000,0x7DFC0000,0xBFFC0000,0xBFFC0000,0xD2000001,0xBFFC0000,0xBFFC0000,0xD2000001,0xD2000001,0xBFFC0000, -0xBFFC0000,0xD2000001,0xD2000001,0xD2000001,0x1EC0000,0x1C40000,0x1A80000,0x5FFC0000,0x97FC0000,0xAFFC0000,0xB7FC0000,0xC5F80000,0x2DFC0000,0x7DFC0000,0xAFFC0000,0xD2000001,0xAFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x12495C1,0xFF00782D,0xFEE4609C,0xFEDC5828,0xFEDC5FA9,0xFEB44028,0xFEA43425,0xFE942B8D,0xFE7C1CD4,0xE8741ED1,0xFEC46399,0xFE8C3BF7,0xFE742C2E,0xFE4C1CB6,0xFE2C07B5,0xEE2407F6,0xFE202B26,0xF800116E,0xDC000859,0xC200265A,0x3B095C1,0xFE706A14,0xFE4C582B,0xFE14410D,0xFC00269A,0xE20020E5,0xFA00488A,0xEE002A26,0xD2001C6A,0xBA0035A3,0x5DFC95C1, -0xCA006AA4,0xBE00521D,0xA600608A,0x920095C3,0xFF007A21,0xFF0C8C29,0xF9208FF4,0xFED45B79,0xFE903AF9,0xFE5C1BF9,0xFE4C0F71,0xFE140288,0xFEF07883,0xFEB0571E,0xFE141976,0xD2001C6A,0x33FC95C1,0x184265D,0xFF681CC8,0xFF58147D,0xFF481144,0xFF5017C9,0xFF2C0B94,0xFF180668,0xFF08070D,0xFEEC0004,0xE8EC039D,0x49FC265A,0xFF1417D8,0xFEF01144,0xFEB80E36,0xFE8801BD, -0xE87C039D,0xA7F8265A,0xF800116E,0xDC000859,0xC200265A,0x49FC265A,0xFF1417D8,0xFEF01144,0xFEB80E36,0xFE8801BD,0xE87C039D,0xA7F8265A,0xF800116E,0xDC000859,0xC200265A,0xA7F8265A,0xF800116E,0xDC000859,0xC200265A,0xC200265A,0xFF742111,0xF98023FD,0xFB842485,0xFF401AEA,0xFF1012F4,0xFEC80956,0xFEA8031D,0xFE480112,0xFF5C2106,0xFF401A06,0xFE7C11D2,0xDC000859, -0x8FFC265A,0xDC5828,0xDC5828,0xDC5828,0xDC5828,0xFEA43425,0xFEA43425,0xFEA43425,0xFE7C1CD4,0xFE7C1CD4,0xD2741B35,0xFE742C2E,0xFE742C2E,0xFE742C2E,0xFE2C07B5,0xFE2C07B5,0xDE2805CA,0xF4001142,0xF4001142,0xCA000195,0xA4001142,0x3445828,0x3445828,0x3445828,0xFA00268D,0xFA00268D,0xCC001BE3,0xD80027C5,0xD80027C5,0xBA00113A,0x9E001C1A,0x27FC5828, -0x27FC5828,0x96003783,0x84003833,0x6C00582B,0xFEBC4689,0xFECC50B4,0xDC5828,0xFE9835F1,0xFE6C2405,0xFE5414FE,0xFE4C0F71,0xFE140288,0xFEA04502,0xFE7433A5,0xFE141895,0xBA00113A,0x1D45828,0x1481144,0x1481144,0x1481144,0x1481144,0xFF180668,0xFF180668,0xFF180668,0xFEEC0004,0xFEEC0004,0xD2EC0001,0x3E81142,0x3E81142,0x3E81142,0xFE8801BD,0xFE8801BD, -0xD2900001,0x79FC1142,0x79FC1142,0xCA000195,0xA4001142,0x3E81142,0x3E81142,0x3E81142,0xFE8801BD,0xFE8801BD,0xD2900001,0x79FC1142,0x79FC1142,0xCA000195,0xA4001142,0x79FC1142,0x79FC1142,0xCA000195,0xA4001142,0xA4001142,0xFB340E74,0xFB440F20,0x1481144,0xFF180C35,0xFEF008A2,0xFEB80562,0xFEA8031D,0xFE480112,0xF9280EC9,0xFF040BEA,0x57FC1142,0xCA000195, -0x57FC1142,0x1D4039D,0xFFC4022D,0xFFAC00AD,0xFFA80000,0xBDFC039D,0xFF940152,0xFF7C0001,0xDFF8039D,0xFEF80000,0xE800039D,0xBDFC039D,0xFF940152,0xFF7C0001,0xDFF8039D,0xFEF80000,0xE800039D,0xDFF8039D,0xFEF80000,0xE800039D,0xE800039D,0xBDFC039D,0xFF940152,0xFF7C0001,0xDFF8039D,0xFEF80000,0xE800039D,0xDFF8039D,0xFEF80000,0xE800039D,0xE800039D,0xDFF8039D, -0xFEF80000,0xE800039D,0xE800039D,0xE800039D,0xFDCC0349,0x1F0039D,0xFFCC0355,0xFDBC02D4,0xFFA80242,0xFF5C0119,0xFF280000,0xFEB80000,0xF7CC0349,0xFFAC02C5,0xFF50001D,0xE800039D,0xD7FC039D,0x741B34,0x741B34,0x741B34,0x741B34,0x741B34,0x741B34,0x741B34,0x741B34,0x741B34,0x741B34,0xFE240328,0xFE240328,0xFE240328,0xFE240328,0xFE240328, -0xFE240328,0xAE000000,0xAE000000,0xAE000000,0x74000001,0xB01B32,0xB01B32,0xB01B32,0xB01B32,0xB01B32,0xB01B32,0x8C000A55,0x8C000A55,0x8C000A55,0x6800052D,0x1641B32,0x1641B32,0x1641B32,0x500010BD,0x3A001B32,0xFC681589,0x741B34,0x741B34,0xFE4C0F05,0xFE3C0A68,0xFE340665,0xFE340665,0xFE0C009D,0xFE3C13D0,0xFE340E29,0xD60000B9,0x8C000A55, -0xF81B32,}; -static const uint32_t g_etc1_to_bc7_m6_table245[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0xFC0000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000, -0x3740000,0x3FFC0000,0x3FFC0000,0x3FFC0000,0x7C000001,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3740000,0x3FFC0000,0x3FFC0000,0x3FFC0000,0x7C000001,0x3FFC0000,0x3FFC0000,0x3FFC0000,0x7C000001,0x7C000001,0x10C0000,0xFC0000,0xFC0000,0x1240000,0x13C0000,0x3540000,0x3540000,0x1A80000,0x1240000,0x13C0000,0xDFC0000,0x3FFC0000, -0xDFC0000,0x1B80000,0x1B80000,0x1B80000,0x1B80000,0x95FC0000,0x95FC0000,0x95FC0000,0xCBFC0000,0xCBFC0000,0xDA000001,0x95FC0000,0x95FC0000,0x95FC0000,0xCBFC0000,0xCBFC0000,0xDA000001,0xCBFC0000,0xCBFC0000,0xDA000001,0xDA000001,0x95FC0000,0x95FC0000,0x95FC0000,0xCBFC0000,0xCBFC0000,0xDA000001,0xCBFC0000,0xCBFC0000,0xDA000001,0xDA000001,0xCBFC0000, -0xCBFC0000,0xDA000001,0xDA000001,0xDA000001,0x9FC0000,0x3D40000,0x1B80000,0x7DFC0000,0xABFC0000,0xBFF80000,0xC5FC0000,0xD1F40000,0x55FC0000,0x95FC0000,0xBFF80000,0xDA000001,0xBFF80000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x12C9859,0xFF0C7CE9,0xFEF06704,0xFEE85F34,0xFEE863E1,0xFEC44648,0xFEB03B0D,0xFE942FCD,0xFE8821D8,0xEC7C2169,0xFEC465F9,0xFE9840B3,0xFE8031CA,0xFE581F56,0xFE380B41,0xF22C0846,0xFE2C29FE,0xFE041148,0xE6000602,0xC80022C6,0x3BC9859,0xFE7C6FCC,0xFE5C5F33,0xFE204581,0xFE082BC5,0xE80022E1,0xFE044866,0xEE002B26,0xD8001AEE,0xC00032E7,0x63FC9859, -0xD0006E98,0xBE00534D,0xAC006016,0x9600985B,0xFF007DA1,0xFB248F01,0xFD2892C4,0xFED45F89,0xFEA03FAE,0xFE6820C1,0xFE501419,0xFE2004B9,0xFEF87BA9,0xFEC45BAD,0xFE201CEC,0xD8001AEE,0x3BFC9859,0x19022C5,0xFF741AD8,0xFF6413E5,0xFF581144,0xFF5C15CD,0xFF380B84,0xFF300728,0xFF14063D,0xFEFC0031,0xECFC0265,0x59FC22C5,0xFF2016B4,0xFF081144,0xFED80D2D,0xFEA0025D, -0xEC900265,0xADFC22C5,0xFE081142,0xE6000602,0xC80022C6,0x59FC22C5,0xFF2016B4,0xFF081144,0xFED80D2D,0xFEA0025D,0xEC900265,0xADFC22C5,0xFE081142,0xE6000602,0xC80022C6,0xADFC22C5,0xFE081142,0xE6000602,0xC80022C6,0xC80022C6,0xFF781E0E,0xFF8C207D,0xFF8C211D,0xFF5C18D9,0xFF2411F8,0xFEEC0969,0xFED003E8,0xFE64019A,0xFD741E52,0xFF4817E4,0xFEA011BB,0xE6000602, -0x99FC22C5,0xE85F34,0xE85F34,0xE85F34,0xE85F34,0xFEB03B0D,0xFEB03B0D,0xFEB03B0D,0xFE8821D8,0xFE8821D8,0xDA7C1F05,0xFE8031CA,0xFE8031CA,0xFE8031CA,0xFE380B41,0xFE380B41,0xE62C0726,0xFE041148,0xFE041148,0xD000013D,0xAC001142,0x1545F33,0x1545F33,0x1545F33,0xFE082BC5,0xFE082BC5,0xD8001F8B,0xE20029C6,0xE20029C6,0xC000126A,0xA2001D03,0x2FFC5F33, -0x2FFC5F33,0x9C003C4B,0x8A003C13,0x72005F33,0xFECC4D68,0xF8E0580D,0xE85F34,0xFEAC3CD5,0xFE8029D5,0xFE5C1A05,0xFE501419,0xFE2004B9,0xFEB44BB9,0xFE903A4A,0xFE201C0B,0xC000126A,0x1E85F33,0x1581144,0x1581144,0x1581144,0x1581144,0xFF300728,0xFF300728,0xFF300728,0xFEFC0031,0xFEFC0031,0xDAFC0001,0x7FC1142,0x7FC1142,0x7FC1142,0xFEA0025D,0xFEA0025D, -0xDAA00001,0x85FC1142,0x85FC1142,0xD000013D,0xAC001142,0x7FC1142,0x7FC1142,0x7FC1142,0xFEA0025D,0xFEA0025D,0xDAA00001,0x85FC1142,0x85FC1142,0xD000013D,0xAC001142,0x85FC1142,0x85FC1142,0xD000013D,0xAC001142,0xAC001142,0xFF3C0EA4,0xFF4C0F40,0x1581144,0xFF240CB2,0xFF04093A,0xFEE40632,0xFED003E8,0xFE64019A,0xFF340ECD,0xFF180C3D,0x65FC1142,0xD000013D, -0x65FC1142,0x1DC0265,0xFFD00171,0xFFC00074,0xFFB80000,0xC9FC0265,0xFFAC00DA,0xFF940001,0xE5F80265,0xFF280000,0xEC000265,0xC9FC0265,0xFFAC00DA,0xFF940001,0xE5F80265,0xFF280000,0xEC000265,0xE5F80265,0xFF280000,0xEC000265,0xEC000265,0xC9FC0265,0xFFAC00DA,0xFF940001,0xE5F80265,0xFF280000,0xEC000265,0xE5F80265,0xFF280000,0xEC000265,0xEC000265,0xE5F80265, -0xFF280000,0xEC000265,0xEC000265,0xEC000265,0xFFD00225,0x1FC0265,0xF5D80244,0xFFC001D4,0xFFA80172,0xFF8400B4,0xFF500000,0xFEF40000,0xFBD40221,0xFFC001C4,0xFF700014,0xEC000265,0xDFF80265,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0x7C1F04,0xFE2404C8,0xFE2404C8,0xFE2404C8,0xFE2404C8,0xFE2404C8, -0xFE2404C8,0xBA000000,0xBA000000,0xBA000000,0x7C000001,0xBC1F02,0xBC1F02,0xBC1F02,0xBC1F02,0xBC1F02,0xBC1F02,0x98000BD5,0x98000BD5,0x98000BD5,0x6E0005F1,0x17C1F02,0x17C1F02,0x17C1F02,0x56001315,0x3E001F02,0xFE6C18FD,0x7C1F04,0x7C1F04,0xFE581220,0xFE500D24,0xFE3C0894,0xFE3C0894,0xFE140164,0xFC541735,0xFE341139,0xE60000CD,0x98000BD5, -0x10C1F02,}; -static const uint32_t g_etc1_to_bc7_m6_table246[] = { -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x10C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000, -0x38C0000,0x4BFC0000,0x4BFC0000,0x4BFC0000,0x84000001,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x38C0000,0x4BFC0000,0x4BFC0000,0x4BFC0000,0x84000001,0x4BFC0000,0x4BFC0000,0x4BFC0000,0x84000001,0x84000001,0x71C0000,0x10C0000,0x10C0000,0x1380000,0x1500000,0x16C0000,0x16C0000,0x3C00000,0x1380000,0x1500000,0x1DF80000,0x4BFC0000, -0x1DF80000,0x1C80000,0x1C80000,0x1C80000,0x1C80000,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xD7FC0000,0xD7FC0000,0xE2000001,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xD7FC0000,0xD7FC0000,0xE2000001,0xD7FC0000,0xD7FC0000,0xE2000001,0xE2000001,0xAFFC0000,0xAFFC0000,0xAFFC0000,0xD7FC0000,0xD7FC0000,0xE2000001,0xD7FC0000,0xD7FC0000,0xE2000001,0xE2000001,0xD7FC0000, -0xD7FC0000,0xE2000001,0xE2000001,0xE2000001,0x43FC0000,0xBE40000,0x1C80000,0x9BFC0000,0xBDFC0000,0xCDFC0000,0xD3F80000,0xDBF80000,0x7DFC0000,0xAFFC0000,0xCDFC0000,0xE2000001,0xCDFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1349B71,0xFF18821D,0xFEFC6DCC,0xFEF06694,0xFEE868A1,0xFEC84CE6,0xFEC44258,0xFEA03499,0xFE942774,0xF0842481,0xFED0690D,0xFE9845F3,0xFE8C37EE,0xFE6422AE,0xFE400F8D,0xF6340916,0xFE3829B6,0xFE0811D2,0xEA000401,0xCC001F86,0x1C89B71,0xFE8875EC,0xFE706693,0xFE2C4A85,0xFE0831B5,0xEE00257D,0xFE0848EA,0xF4002CA6,0xE20019DE,0xC600308B,0x69FC9B71, -0xD6007334,0xC40054F9,0xB200601A,0x9A009B73,0xFF0C818D,0xFF2C9219,0xFF2C962C,0xFED46499,0xFEA84503,0xFE7025F5,0xFE5C1968,0xFE2807C2,0xFEF87F79,0xFED06046,0xFE3020B2,0xE20019DE,0x41FC9B71,0x19C1F85,0xFF801918,0xFF701365,0xFF681144,0xFF681419,0xFF4C0B8A,0xFF4407D9,0xFF2C05B5,0xFF140089,0xF10C016D,0x6BFC1F85,0xFF3815A4,0xFF201144,0xFEF00C35,0xFEB8031D, -0xF0A4016D,0xB7F81F85,0xFE381142,0xEA000401,0xCC001F86,0x6BFC1F85,0xFF3815A4,0xFF201144,0xFEF00C35,0xFEB8031D,0xF0A4016D,0xB7F81F85,0xFE381142,0xEA000401,0xCC001F86,0xB7F81F85,0xFE381142,0xEA000401,0xCC001F86,0xCC001F86,0xFF801BA1,0xFF8C1D9D,0xF5981E64,0xFF5C1729,0xFF401123,0xFEFC0989,0xFEE404A5,0xFE8C025D,0xFF781B86,0xFF5C1652,0xFED011A5,0xEA000401, -0xA3FC1F85,0xF06694,0xF06694,0xF06694,0xF06694,0xFEC44258,0xFEC44258,0xFEC44258,0xFE942774,0xFE942774,0xE2842315,0xFE8C37EE,0xFE8C37EE,0xFE8C37EE,0xFE400F8D,0xFE400F8D,0xF03408A6,0xFE0811D2,0xFE0811D2,0xDC0000F5,0xB4001142,0x1686693,0x1686693,0x1686693,0xFE0831B5,0xFE0831B5,0xDE002373,0xEE002C26,0xEE002C26,0xCC0013AA,0xA8001E33,0x39F86693, -0x39F86693,0xA600416D,0x90004023,0x78006693,0xFECC54C8,0xFEEC5F3D,0xF06694,0xFEB443E1,0xFE943075,0xFE681FB0,0xFE5C1968,0xFE2807C2,0xFEB45309,0xFE98413E,0xFE301FEE,0xCC0013AA,0x3FC6693,0x1681144,0x1681144,0x1681144,0x1681144,0xFF4407D9,0xFF4407D9,0xFF4407D9,0xFF140089,0xFF140089,0xE30C0001,0x1FFC1142,0x1FFC1142,0x1FFC1142,0xFEB8031D,0xFEB8031D, -0xE2B00001,0x91FC1142,0x91FC1142,0xDC0000F5,0xB4001142,0x1FFC1142,0x1FFC1142,0x1FFC1142,0xFEB8031D,0xFEB8031D,0xE2B00001,0x91FC1142,0x91FC1142,0xDC0000F5,0xB4001142,0x91FC1142,0x91FC1142,0xDC0000F5,0xB4001142,0xB4001142,0xFF580EC9,0xFB640F79,0x1681144,0xFF440D22,0xFF1809DA,0xFEF406DA,0xFEE404A5,0xFE8C025D,0xFD4C0F20,0xFF240CC8,0x75FC1142,0xDC0000F5, -0x75FC1142,0x1E4016D,0xFFDC00DD,0xFFCC0044,0xFFC80000,0xD5FC016D,0xFFB80082,0xFFAC0001,0xEBF8016D,0xFF580000,0xF000016D,0xD5FC016D,0xFFB80082,0xFFAC0001,0xEBF8016D,0xFF580000,0xF000016D,0xEBF8016D,0xFF580000,0xF000016D,0xF000016D,0xD5FC016D,0xFFB80082,0xFFAC0001,0xEBF8016D,0xFF580000,0xF000016D,0xEBF8016D,0xFF580000,0xF000016D,0xF000016D,0xEBF8016D, -0xFF580000,0xF000016D,0xF000016D,0xF000016D,0xF9E00152,0x27FC016D,0xF9E00154,0xFFD40120,0xFFBC00DA,0xFF98006D,0xFF780000,0xFF300000,0xFFDC0139,0xFFCC010D,0xFF90000A,0xF000016D,0xE5FC016D,0x842314,0x842314,0x842314,0x842314,0x842314,0x842314,0x842314,0x842314,0x842314,0x842314,0xFE3006C4,0xFE3006C4,0xFE3006C4,0xFE3006C4,0xFE3006C4, -0xFE3006C4,0xC6000000,0xC6000000,0xC6000000,0x84000001,0x2C42312,0x2C42312,0x2C42312,0x2C42312,0x2C42312,0x2C42312,0xA2000D39,0xA2000D39,0xA2000D39,0x7A0006B9,0x1942312,0x1942312,0x1942312,0x5C001595,0x42002312,0xFE6C1CED,0x842314,0x842314,0xFE681589,0xFE501004,0xFE3C0B14,0xFE3C0B14,0xFE1802A1,0xFE581AC1,0xFE3C14B4,0xF60000EA,0xA2000D39, -0x11C2312,}; -static const uint32_t g_etc1_to_bc7_m6_table247[] = { -0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x100000,0x200000, -0x200000,0x200000,0x200000,0x4000001,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0xC0000,0x100000,0x180000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x11C0000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000, -0x3A40000,0x57FC0000,0x57FC0000,0x57FC0000,0x8C000001,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x3A40000,0x57FC0000,0x57FC0000,0x57FC0000,0x8C000001,0x57FC0000,0x57FC0000,0x57FC0000,0x8C000001,0x8C000001,0xF2C0000,0x11C0000,0x11C0000,0x5480000,0x1640000,0x3800000,0x3800000,0x1DC0000,0x5480000,0x1640000,0x2BFC0000,0x57FC0000, -0x2BFC0000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xE3FC0000,0xE3FC0000,0xEA000001,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xE3FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xE3FC0000,0xEA000001,0xEA000001,0xC7FC0000,0xC7FC0000,0xC7FC0000,0xE3FC0000,0xE3FC0000,0xEA000001,0xE3FC0000,0xE3FC0000,0xEA000001,0xEA000001,0xE3FC0000, -0xE3FC0000,0xEA000001,0xEA000001,0xEA000001,0x7BFC0000,0x1F80000,0x1D80000,0xB9FC0000,0xD1FC0000,0xDDF80000,0xDFFC0000,0xE5FC0000,0xA3FC0000,0xC7FC0000,0xDDF80000,0xEA000001,0xDDF80000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x14097B9,0xFF248115,0xFF086EE8,0xFF006878,0xFF006825,0xFEDC4F04,0xFED0456C,0xFEAC3621,0xFEA02A0C,0xF49424D5,0xFEDC67C5,0xFEB047DF,0xFE983B2E,0xFE702442,0xFE5812B1,0xFA3C0922,0xFE38290A,0xFE2012C6,0xEE040282,0xD20C1C9A,0x1DC97B9,0xFEA0761C,0xFE846878,0xFE384B75,0xFE1434A9,0xF400251D,0xFE084686,0xFA002B02,0xE20015EA,0xCC002B8F,0x73F897B9, -0xDC0071AC,0xCA0050F9,0xB8005AEA,0x9E0097BB,0xFF207F85,0xFF2C8F25,0xF73C935D,0xFEF064CD,0xFEB446BE,0xFE7C292B,0xFE681CD5,0xFE400A4D,0xFF107DEB,0xFED0602E,0xFE3C238C,0xE20015EA,0x4DFC97B9,0x1A41C9D,0xFF8C1788,0xFF7C12FD,0xFF781144,0xFF7412AD,0xFF5C0BA2,0xFF500895,0xFF38056D,0xFF2C0121,0xF51C00B5,0x7BFC1C9A,0xFF4C14D3,0xFF381144,0xFF080B7D,0xFED8040D, -0xF4B800B5,0xBFF81C9A,0xFE6C1142,0xEC000266,0xD2001C9A,0x7BFC1C9A,0xFF4C14D3,0xFF381144,0xFF080B7D,0xFED8040D,0xF4B800B5,0xBFF81C9A,0xFE6C1142,0xEC000266,0xD2001C9A,0xBFF81C9A,0xFE6C1142,0xEC000266,0xD2001C9A,0xD2001C9A,0xFF901929,0xF9A01B05,0xFBA41B98,0xFF781595,0xFF481062,0xFF200A13,0xFEFC0585,0xFEA8031D,0xFF88194D,0xFF6814FA,0xFEE41193,0xEC000266, -0xADFC1C9A,0x1006878,0x1006878,0x1006878,0x1006878,0xFED0456C,0xFED0456C,0xFED0456C,0xFEA02A0C,0xFEA02A0C,0xEA942421,0xFE983B2E,0xFE983B2E,0xFE983B2E,0xFE5812B1,0xFE5812B1,0xF640090E,0xFE2012C6,0xFE2012C6,0xE20400DA,0xBC0C1142,0x17C6878,0x17C6878,0x17C6878,0xFE1434A9,0xFE1434A9,0xE8002431,0xFA002AF2,0xFA002AF2,0xD20011F2,0xB4001CBB,0x43F86878, -0x43F86878,0xB2004159,0x9C003F8B,0x7E00687B,0xFEE85775,0xFEEC61A9,0x1006878,0xFEC446F4,0xFE943411,0xFE782328,0xFE681CD5,0xFE400A4D,0xFED055B3,0xFEB04469,0xFE3C22C8,0xD20011F2,0x11FC6878,0x1781144,0x1781144,0x1781144,0x1781144,0xFF500895,0xFF500895,0xFF500895,0xFF2C0121,0xFF2C0121,0xEB1C0001,0x37FC1142,0x37FC1142,0x37FC1142,0xFED8040D,0xFED8040D, -0xEAC00001,0x9DFC1142,0x9DFC1142,0xE40000C1,0xBC001142,0x37FC1142,0x37FC1142,0x37FC1142,0xFED8040D,0xFED8040D,0xEAC00001,0x9DFC1142,0x9DFC1142,0xE40000C1,0xBC001142,0x9DFC1142,0x9DFC1142,0xE40000C1,0xBC001142,0xBC001142,0xFB6C0F20,0xFF6C0FA1,0x1781144,0xFD580D75,0xFF2C0A82,0xFEFC07D5,0xFEFC0585,0xFEA8031D,0xFF500F68,0xFF480D24,0x83FC1142,0xE40000C1, -0x83FC1142,0x1EC00B5,0xFFE80071,0xFFD80024,0xFFD80000,0xE3FC00B5,0xFFCC0044,0xFFC40000,0xF1F800B5,0xFF880000,0xF40000B5,0xE3FC00B5,0xFFCC0044,0xFFC40000,0xF1F800B5,0xFF880000,0xF40000B5,0xF1F800B5,0xFF880000,0xF40000B5,0xF40000B5,0xE3FC00B5,0xFFCC0044,0xFFC40000,0xF1F800B5,0xFF880000,0xF40000B5,0xF1F800B5,0xFF880000,0xF40000B5,0xF40000B5,0xF1F800B5, -0xFF880000,0xF40000B5,0xF40000B5,0xF40000B5,0xFDE800A2,0x67FC00B5,0xFDE800A4,0xFBE40091,0xFFD0006A,0xFFC00034,0xFFA00000,0xFF6C0000,0xFBE800A2,0xFFD80088,0xFFB00005,0xF40000B5,0xEDFC00B5,0x942420,0x942420,0x942420,0x942420,0x942420,0x942420,0x942420,0x942420,0x942420,0x942420,0xFE4407D9,0xFE4407D9,0xFE4407D9,0xFE4407D9,0xFE4407D9, -0xFE4407D9,0xD00C0000,0xD00C0000,0xD00C0000,0x8C0C0001,0xDC2420,0xDC2420,0xDC2420,0xDC2420,0xDC2420,0xDC2420,0xAE000C69,0xAE000C69,0xAE000C69,0x800005B9,0x1BC2420,0x1BC2420,0x1BC2420,0x66001572,0x48002422,0xFC881E08,0x942420,0x942420,0xFE6816CD,0xFE641154,0xFE4C0C44,0xFE4C0C44,0xFE2C0371,0xFA6C1C20,0xFE5015C5,0xFE000095,0xAE000C69, -0x1382420,}; -static const uint32_t g_etc1_to_bc7_m6_table248[] = { -0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x2C0000,0x580000, -0x580000,0x580000,0x580000,0xE000000,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x1C0001,0x200000,0x200000,0x200000,0x2C0000,0x3C0000,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x12C0001,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000, -0x1C00000,0x65F80000,0x65F80000,0x65F80000,0x96000000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x1C00000,0x65F80000,0x65F80000,0x65F80000,0x96000000,0x65F80000,0x65F80000,0x65F80000,0x96000000,0x96000000,0x9400000,0x12C0001,0x12C0001,0x1600000,0x5780000,0x3980000,0x3980000,0x1FC0000,0x1600000,0x5780000,0x3DF80000,0x65F80000, -0x3DF80000,0x1E80001,0x1E80001,0x1E80001,0x1E80001,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xF1F80000,0xF1F80000,0xF4000000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xF1F80000,0xF1F80000,0xF4000000,0xF1F80000,0xF1F80000,0xF4000000,0xF4000000,0xE3FC0000,0xE3FC0000,0xE3FC0000,0xF1F80000,0xF1F80000,0xF4000000,0xF1F80000,0xF1F80000,0xF4000000,0xF4000000,0xF1F80000, -0xF1F80000,0xF4000000,0xF4000000,0xF4000000,0xBBFC0000,0x67FC0000,0x1E80001,0xDBFC0000,0xE7FC0000,0xEDFC0000,0xEFFC0000,0xF3F40000,0xD1FC0000,0xE3FC0000,0xEDFC0000,0xF4000000,0xEDFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x14C9144,0xFF307DB4,0xFF206E1B,0xFF10687B,0xFF0C65C4,0xFEE84FCF,0xFEDC4763,0xFEC036E6,0xFEB82BFB,0xF8A42456,0xFEF464EC,0xFEC448BB,0xFEB03DB5,0xFE88258F,0xFE7015E6,0xFE500915,0xFE582844,0xFE38142D,0xF4100195,0xD81C19B9,0x1EC9144,0xFEB87431,0xFEA06878,0xFE584B5A,0xFE2C36E6,0xF8042454,0xFE084419,0xFA00296D,0xEE001109,0xD2002588,0x7BFC9144, -0xE0006E48,0xD0004AD6,0xBE005385,0xA6009144,0xFF207B7A,0xFD488994,0xFD488D3C,0xFF0062DC,0xFECC477A,0xFE982BD6,0xFE902035,0xFE580D46,0xFF1079CE,0xFEDC5F8A,0xFE582697,0xEE001109,0x59FC9144,0x1B019BB,0xFFA415E6,0xFF941283,0xFF8C1142,0xFF8C1155,0xFF740BEA,0xFF680989,0xFF4C0593,0xFF3801FD,0xF92C0035,0x8DFC19B8,0xFF6413E5,0xFF541142,0xFF200AFD,0xFEFC0521, -0xFACC0034,0xC7FC19B8,0xFEA01142,0xF2000124,0xD80019B8,0x8DFC19B8,0xFF6413E5,0xFF541142,0xFF200AFD,0xFEFC0521,0xFACC0034,0xC7FC19B8,0xFEA01142,0xF2000124,0xD80019B8,0xC7FC19B8,0xFEA01142,0xF2000124,0xD80019B8,0xD80019B8,0xFFA016ED,0xFFAC1835,0xFFAC18E6,0xFF881403,0xFF5C0FD6,0xFF380A61,0xFF2006AD,0xFED00448,0xFF941715,0xFF841392,0xFF101175,0xF2000124, -0xB9FC19B8,0x110687B,0x110687B,0x110687B,0x110687B,0xFEDC4763,0xFEDC4763,0xFEDC4763,0xFEB82BFB,0xFEB82BFB,0xF4A42422,0xFEB03DB5,0xFEB03DB5,0xFEB03DB5,0xFE7015E6,0xFE7015E6,0xFE500915,0xFE38142D,0xFE38142D,0xEC1800D9,0xC41C1145,0x1986878,0x1986878,0x1986878,0xFE2C36E6,0xFE2C36E6,0xF4082420,0xFA00295D,0xFA00295D,0xE2000EE1,0xC0001A74,0x51F86878, -0x51F86878,0xB8003F52,0xA6003D85,0x88006878,0xFEF458B2,0xFF0C61E3,0x110687B,0xFED448E2,0xFEB0370B,0xFE9026C5,0xFE902035,0xFE580D46,0xFED85741,0xFEBC46B5,0xFE5825EE,0xE2000EE1,0x21FC6878,0x18C1142,0x18C1142,0x18C1142,0x18C1142,0xFF680989,0xFF680989,0xFF680989,0xFF3801FD,0xFF3801FD,0xF52C0001,0x53FC1142,0x53FC1142,0x53FC1142,0xFEFC0521,0xFEFC0521, -0xF4D00001,0xABF81142,0xABF81142,0xEC000080,0xC4001144,0x53FC1142,0x53FC1142,0x53FC1142,0xFEFC0521,0xFEFC0521,0xF4D00001,0xABF81142,0xABF81142,0xEC000080,0xC4001144,0xABF81142,0xABF81142,0xEC000080,0xC4001144,0xC4001144,0xFF740F52,0xFD880FD2,0x18C1142,0xFF5C0DE5,0xFF540B50,0xFF2808B1,0xFF2006AD,0xFED00448,0xFD740F79,0xFF5C0D81,0x95FC1142,0xEC000080, -0x95FC1142,0x1F40032,0xFDF00022,0xFFEC000A,0xFFE80001,0xF1FC0032,0xFFE40011,0xFFE00000,0xF9F80032,0xFFC00000,0xF8000034,0xF1FC0032,0xFFE40011,0xFFE00000,0xF9F80032,0xFFC00000,0xF8000034,0xF9F80032,0xFFC00000,0xF8000034,0xF8000034,0xF1FC0032,0xFFE40011,0xFFE00000,0xF9F80032,0xFFC00000,0xF8000034,0xF9F80032,0xFFC00000,0xF8000034,0xF8000034,0xF9F80032, -0xFFC00000,0xF8000034,0xF8000034,0xF8000034,0xFDF40029,0xB7FC0032,0xF3F40032,0xFFEC0022,0xFFE80019,0xFFDC000D,0xFFCC0000,0xFFB00000,0xFFF00029,0xFFEC0029,0xFFD40001,0xF8000034,0xF7FC0032,0xA42422,0xA42422,0xA42422,0xA42422,0xA42422,0xA42422,0xA42422,0xA42422,0xA42422,0xA42422,0xFE5008B1,0xFE5008B1,0xFE5008B1,0xFE5008B1,0xFE5008B1, -0xFE5008B1,0xD8200001,0xD8200001,0xD8200001,0x961C0001,0x2F42420,0x2F42420,0x2F42420,0x2F42420,0x2F42420,0x2F42420,0xBA000AB5,0xBA000AB5,0xBA000AB5,0x8C000425,0x1F42420,0x1F42420,0x1F42420,0x6C001408,0x52002420,0xFE8C1E6A,0xA42422,0xA42422,0xFE84174D,0xFE781212,0xFE5C0D22,0xFE5C0D22,0xFE400431,0xFE741C52,0xFE641699,0xFE1000D0,0xBA000AB5, -0x1602420,}; -static const uint32_t g_etc1_to_bc7_m6_table249[] = { -0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x440000,0x880000, -0x880000,0x880000,0x880000,0x16000000,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x2C0001,0x300000,0x300000,0x300000,0x440000,0x600000,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x13C0001,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000, -0x1D80000,0x71F80000,0x71F80000,0x71F80000,0x9E000000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x1D80000,0x71F80000,0x71F80000,0x71F80000,0x9E000000,0x71F80000,0x71F80000,0x71F80000,0x9E000000,0x9E000000,0x1540000,0x13C0001,0x13C0001,0x3700000,0x58C0000,0x1B00000,0x1B00000,0x13FC0000,0x3700000,0x58C0000,0x4BFC0000,0x71F80000, -0x4BFC0000,0x1F80001,0x1F80001,0x1F80001,0x1F80001,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFDF80000,0xFDF80000,0xFC000000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFDF80000,0xFDF80000,0xFC000000,0xFDF80000,0xFDF80000,0xFC000000,0xFC000000,0xFBFC0000,0xFBFC0000,0xFBFC0000,0xFDF80000,0xFDF80000,0xFC000000,0xFDF80000,0xFDF80000,0xFC000000,0xFC000000,0xFDF80000, -0xFDF80000,0xFC000000,0xFC000000,0xFC000000,0xF5FC0000,0xE7FC0000,0x1F80001,0xF9FC0000,0xFBFC0000,0xFDF80000,0xFDF80000,0xFDF80000,0xF7FC0000,0xFBFC0000,0xFDF80000,0xFC000000,0xFDF80000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1588BEC,0xFF447ADF,0xFF2C6D47,0xFF20687B,0xFF186404,0xFF00509F,0xFEF44933,0xFED837A6,0xFECC2E12,0xFCB42426,0xFF0062AC,0xFED049C7,0xFEC43FBB,0xFE942717,0xFE7C18FE,0xFE68098D,0xFE702804,0xFE4C15EB,0xF8240111,0xDE2C1785,0x3FC8BEC,0xFECC72CF,0xFEB86878,0xFE704B2A,0xFE4C3941,0xFC182424,0xFE204349,0xFE082945,0xF4000D79,0xD80020D8,0x85F88BEC, -0xE6006BE4,0xD60045F6,0xC4004D71,0xAC008BEC,0xFF3C7814,0xFF4C849C,0xFF4C888C,0xFF1861D6,0xFED8483B,0xFEAC2E3E,0xFE902345,0xFE6C0FFB,0xFF3476CA,0xFEF45E5F,0xFE7028DB,0xF4000D79,0x63FC8BEC,0x1BC1783,0xFFB014AE,0xFFA0122B,0xFF9C1142,0xFF98106D,0xFF800C3A,0xFF740A69,0xFF6405EB,0xFF4C030A,0xFD3C0005,0x9BFC1783,0xFF7C132D,0xFF6C1142,0xFF380ACD,0xFF140631, -0xFEE00004,0xCFF81783,0xFED41142,0xF8000074,0xDE001784,0x9BFC1783,0xFF7C132D,0xFF6C1142,0xFF380ACD,0xFF140631,0xFEE00004,0xCFF81783,0xFED41142,0xF8000074,0xDE001784,0xCFF81783,0xFED41142,0xF8000074,0xDE001784,0xDE001784,0xFFB41556,0xFFAC1685,0xF7BC1703,0xFF9812DD,0xFF700F7A,0xFF480B1E,0xFF2807B2,0xFEE40559,0xFFA41576,0xFF841292,0xFF301168,0xF8000074, -0xC1FC1783,0x120687B,0x120687B,0x120687B,0x120687B,0xFEF44933,0xFEF44933,0xFEF44933,0xFECC2E12,0xFECC2E12,0xFCB42422,0xFEC43FBB,0xFEC43FBB,0xFEC43FBB,0xFE7C18FE,0xFE7C18FE,0xFE68098D,0xFE4C15EB,0xFE4C15EB,0xF42800D9,0xCC2C1145,0x1B06878,0x1B06878,0x1B06878,0xFE4C3941,0xFE4C3941,0xFC182420,0xFE082945,0xFE082945,0xE8000C8D,0xC6001888,0x5DF46878, -0x5DF46878,0xC4003D82,0xAC003B8D,0x90006878,0xFF045983,0xF71C62B2,0x120687B,0xFEE84AEA,0xFEC4399B,0xFEAC29BA,0xFE902345,0xFE6C0FFB,0xFEF8582E,0xFED0482D,0xFE70284B,0xE8000C8D,0x31FC6878,0x19C1142,0x19C1142,0x19C1142,0x19C1142,0xFF740A69,0xFF740A69,0xFF740A69,0xFF4C030A,0xFF4C030A,0xFD3C0001,0x6BFC1142,0x6BFC1142,0x6BFC1142,0xFF140631,0xFF140631, -0xFCE00001,0xB7F81142,0xB7F81142,0xF8000050,0xCC001144,0x6BFC1142,0x6BFC1142,0x6BFC1142,0xFF140631,0xFF140631,0xFCE00001,0xB7F81142,0xB7F81142,0xF8000050,0xCC001144,0xB7F81142,0xB7F81142,0xF8000050,0xCC001144,0xCC001144,0xFF900F79,0xFF8C101A,0x19C1142,0xFF780E45,0xFF5C0C05,0xFF3809A1,0xFF2807B2,0xFEE40559,0xFF780FCD,0xFF680E10,0xA3FC1142,0xF8000050, -0xA3FC1142,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFF80001,0xFDFC0002,0xFFF80001,0xFFF80000,0xFFF80002,0xFFF00000,0xFC000004,0xFDFC0002,0xFFF80001,0xFFF80000,0xFFF80002,0xFFF00000,0xFC000004,0xFFF80002,0xFFF00000,0xFC000004,0xFC000004,0xFDFC0002,0xFFF80001,0xFFF80000,0xFFF80002,0xFFF00000,0xFC000004,0xFFF80002,0xFFF00000,0xFC000004,0xFC000004,0xFFF80002, -0xFFF00000,0xFC000004,0xFC000004,0xFC000004,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFF80001,0xFFF40001,0xFFF40000,0xFFEC0000,0xFDFC0002,0xFDFC0002,0xFFF40000,0xFC000004,0xFFF80002,0xB42422,0xB42422,0xB42422,0xB42422,0xB42422,0xB42422,0xB42422,0xB42422,0xB42422,0xB42422,0xFE680989,0xFE680989,0xFE680989,0xFE680989,0xFE680989, -0xFE680989,0xE0300001,0xE0300001,0xE0300001,0x9E2C0001,0x30C2420,0x30C2420,0x30C2420,0x30C2420,0x30C2420,0x30C2420,0xCC000949,0xCC000949,0xCC000949,0x980002FD,0xBFC2420,0xBFC2420,0xBFC2420,0x780012C8,0x5A002420,0xFEAC1E85,0xB42422,0xB42422,0xFE9017EA,0xFE8C12CA,0xFE780DFA,0xFE780DFA,0xFE5404ED,0xFE901C99,0xFE7816FA,0xFE200140,0xCC000949, -0x1802420,}; -static const uint32_t g_etc1_to_bc7_m6_table250[] = { -0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0x5C0000,0xB80000, -0xB80000,0xB80000,0xB80000,0x1E000000,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x3C0001,0x8400000,0x8400000,0x8400000,0x5C0000,0x800000,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x14C0001,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000, -0x1F00000,0x7DF80000,0x7DF80000,0x7DF80000,0xA6000000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x1F00000,0x7DF80000,0x7DF80000,0x7DF80000,0xA6000000,0x7DF80000,0x7DF80000,0x7DF80000,0xA6000000,0xA6000000,0x1640000,0x14C0001,0x14C0001,0x1840000,0x5A00000,0x3C40000,0x3C40000,0x27FC0000,0x1840000,0x5A00000,0x5BFC0000,0x7DF80000, -0x5BFC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1608334,0xFF4473EF,0xFF3867CB,0xFF2C6383,0xFF245F04,0xFF0C4D93,0xFF0046EB,0xFEE4366A,0xFED82DC2,0xFEC42422,0xFF0C5CE4,0xFEE8465F,0xFED03D53,0xFEAC2617,0xFE941956,0xFE740A69,0xFE7C2534,0xFE5814AB,0xFA3C009A,0xE03C142D,0x13FC8330,0xFEE46CB7,0xFEC86380,0xFE88483A,0xFE643831,0xFE2C2422,0xFE2C3F39,0xFE082639,0xF4000A2D,0xDE001B24,0x8BFC8330, -0xEC006584,0xDC003FEA,0xCA004541,0xB0008330,0xFF3C711C,0xFF4C7D04,0xF9608037,0xFF185C82,0xFEEC452B,0xFEBC2D3F,0xFEA82336,0xFE7410B2,0xFF346F66,0xFF00597C,0xFE7C2771,0xF4000A2D,0x6DFC8330,0x1C4142B,0xFFB411F3,0xFFAC0FDB,0xFFA40F22,0xFFA40E41,0xFF8C0ACE,0xFF800955,0xFF700543,0xFF6402EA,0xFF4C0001,0xA9FC142B,0xFF8810A9,0xFF7C0F20,0xFF4C09A2,0xFF2C05A5, -0xFEF80000,0xD5F8142B,0xFEF00F20,0xFE000010,0xE000142C,0xA9FC142B,0xFF8810A9,0xFF7C0F20,0xFF4C09A2,0xFF2C05A5,0xFEF80000,0xD5F8142B,0xFEF00F20,0xFE000010,0xE000142C,0xD5F8142B,0xFEF00F20,0xFE000010,0xE000142C,0xE000142C,0xFFB41242,0xF9C01343,0xF9C013BB,0xFF98106D,0xFF840D72,0xFF6409D1,0xFF500709,0xFEFC04FD,0xFFB41262,0xFF980FFE,0xFF440F44,0xFE000010, -0xC9FC142B,0x12C6383,0x12C6383,0x12C6383,0x12C6383,0xFF0046EB,0xFF0046EB,0xFF0046EB,0xFED82DC2,0xFED82DC2,0xFEC42422,0xFED03D53,0xFED03D53,0xFED03D53,0xFE941956,0xFE941956,0xFE740A69,0xFE5814AB,0xFE5814AB,0xF838007E,0xD23C0F21,0x1C06380,0x1C06380,0x1C06380,0xFE643831,0xFE643831,0xFE2C2422,0xFE082639,0xFE082639,0xEE0009C5,0xCC001478,0x65F86380, -0x65F86380,0xCA003962,0xB2003611,0x96006380,0xFF1055F5,0xFD285DF2,0x12C6383,0xFEF8483A,0xFED437FA,0xFEBC28FE,0xFEA82336,0xFE7410B2,0xFEF8548A,0xFEDC4611,0xFE7C26E1,0xEE0009C5,0x3DF86380,0x1A40F22,0x1A40F22,0x1A40F22,0x1A40F22,0xFF800955,0xFF800955,0xFF800955,0xFF6402EA,0xFF6402EA,0xFF4C0001,0x7BFC0F20,0x7BFC0F20,0x7BFC0F20,0xFF2C05A5,0xFF2C05A5, -0xFEF80000,0xBFF80F20,0xBFF80F20,0xFC00000D,0xD2000F20,0x7BFC0F20,0x7BFC0F20,0x7BFC0F20,0xFF2C05A5,0xFF2C05A5,0xFEF80000,0xBFF80F20,0xBFF80F20,0xFC00000D,0xD2000F20,0xBFF80F20,0xBFF80F20,0xFC00000D,0xD2000F20,0xD2000F20,0xFF900DB1,0xFBA40E1D,0x1A40F22,0xFF880C92,0xFF700AA5,0xFF5808CA,0xFF500709,0xFEFC04FD,0xFF940DC8,0xFF840C82,0xADFC0F20,0xFC00000D, -0xADFC0F20,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0xC42422,0xC42422,0xC42422,0xC42422,0xC42422,0xC42422,0xC42422,0xC42422,0xC42422,0xC42422,0xFE740A69,0xFE740A69,0xFE740A69,0xFE740A69,0xFE740A69, -0xFE740A69,0xE8400001,0xE8400001,0xE8400001,0xA63C0001,0x3242420,0x3242420,0x3242420,0x3242420,0x3242420,0x3242420,0xD80007F9,0xD80007F9,0xD80007F9,0xA20001F4,0x17FC2420,0x17FC2420,0x17FC2420,0x7E0011A4,0x62002420,0xFEAC1EF5,0xC42422,0xC42422,0xFEA01865,0xFE941379,0xFE880EBA,0xFE880EBA,0xFE6C05D2,0xFEA01D14,0xFE9417A4,0xFE3401BA,0xD80007F9, -0x1A42420,}; -static const uint32_t g_etc1_to_bc7_m6_table251[] = { -0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0x740000,0xE80000, -0xE80000,0xE80000,0xE80000,0x26000000,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x4C0001,0x540000,0x540000,0x540000,0x740000,0xA40000,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0x15C0001,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000, -0xDFC0000,0x89F80000,0x89F80000,0x89F80000,0xAE000000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0xDFC0000,0x89F80000,0x89F80000,0x89F80000,0xAE000000,0x89F80000,0x89F80000,0x89F80000,0xAE000000,0xAE000000,0x3740000,0x15C0001,0x15C0001,0x1980000,0x5B40000,0x1DC0000,0x1DC0000,0x3BFC0000,0x1980000,0x5B40000,0x69FC0000,0x89F80000, -0x69FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x16879B4,0xFF506BE7,0xFF406114,0xFF385D2B,0xFF305924,0xFF18496F,0xFF0C4373,0xFEF03492,0xFEE42CC6,0xFED42422,0xFF185634,0xFEF441BB,0xFEDC3993,0xFEB8246F,0xFEA018E6,0xFE8C0B51,0xFE9421B4,0xFE701283,0xFC4C003A,0xE44C10AD,0x1FFC79B0,0xFEF0656B,0xFED85D2B,0xFEA0448A,0xFE703629,0xFE442420,0xFE383A6D,0xFE0822E9,0xFA00077D,0xE2001579,0x91FC79B0, -0xF2005E40,0xE0003A48,0xD0003CE5,0xB40079B0,0xFF4C694B,0xFB647402,0xFD6876DF,0xFF2C56B2,0xFF004133,0xFED42B7A,0xFEBC21F6,0xFE84109D,0xFF3467C6,0xFF1053A2,0xFE94250F,0xFA00077D,0x75FC79B0,0x1C810AB,0xFFBC0EC6,0xFFB40D22,0xFFAC0C82,0xFFA40BD1,0xFF9808EE,0xFF8C07B5,0xFF7C0453,0xFF700262,0xFF5C0001,0xAFFC10AB,0xFF940DC1,0xFF880C80,0xFF5807F2,0xFF3804A9, -0xFF100000,0xD7FC10AB,0xFF080C80,0xFE140000,0xE40010AC,0xAFFC10AB,0xFF940DC1,0xFF880C80,0xFF5807F2,0xFF3804A9,0xFF100000,0xD7FC10AB,0xFF080C80,0xFE140000,0xE40010AC,0xD7FC10AB,0xFF080C80,0xFE140000,0xE40010AC,0xE40010AC,0xFFBC0F15,0xFBC40FDB,0xFDC81043,0xFFB00D9E,0xFF980B2E,0xFF6C0809,0xFF5005C9,0xFF20040D,0xFFB40F22,0xFF980D4E,0xFF540C99,0xFE140000, -0xCDFC10AB,0x1385D2B,0x1385D2B,0x1385D2B,0x1385D2B,0xFF0C4373,0xFF0C4373,0xFF0C4373,0xFEE42CC6,0xFEE42CC6,0xFED42422,0xFEDC3993,0xFEDC3993,0xFEDC3993,0xFEA018E6,0xFEA018E6,0xFE8C0B51,0xFE701283,0xFE701283,0xFA480032,0xD64C0C81,0x1D05D2B,0x1D05D2B,0x1D05D2B,0xFE703629,0xFE703629,0xFE442420,0xFE0822E9,0xFE0822E9,0xF4000759,0xD2001024,0x6DF85D2B, -0x6DF85D2B,0xD00034E6,0xB8002FC1,0x9C005D2C,0xFF205092,0xFF2C5816,0x1385D2B,0xFF004403,0xFEEC354B,0xFEBC276E,0xFEBC21F6,0xFE84109D,0xFF104F65,0xFEF441EE,0xFE942496,0xF4000759,0x45FC5D2B,0x1AC0C82,0x1AC0C82,0x1AC0C82,0x1AC0C82,0xFF8C07B5,0xFF8C07B5,0xFF8C07B5,0xFF700262,0xFF700262,0xFF5C0001,0x87FC0C80,0x87FC0C80,0x87FC0C80,0xFF3804A9,0xFF3804A9, -0xFF100000,0xC5F80C80,0xC5F80C80,0xFE140000,0xD6000C80,0x87FC0C80,0x87FC0C80,0x87FC0C80,0xFF3804A9,0xFF3804A9,0xFF100000,0xC5F80C80,0xC5F80C80,0xFE140000,0xD6000C80,0xC5F80C80,0xC5F80C80,0xFE140000,0xD6000C80,0xD6000C80,0xFFA00B50,0xFFAC0B95,0x1AC0C82,0xFF980A69,0xFF8408D1,0xFF640721,0xFF5005C9,0xFF20040D,0xFF940B68,0xFF840A52,0xB5FC0C80,0xFE140000, -0xB5FC0C80,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0xD42422,0xD42422,0xD42422,0xD42422,0xD42422,0xD42422,0xD42422,0xD42422,0xD42422,0xD42422,0xFE8C0B51,0xFE8C0B51,0xFE8C0B51,0xFE8C0B51,0xFE8C0B51, -0xFE8C0B51,0xF0500001,0xF0500001,0xF0500001,0xAE4C0001,0x33C2420,0x33C2420,0x33C2420,0x33C2420,0x33C2420,0x33C2420,0xE800069D,0xE800069D,0xE800069D,0xA8000124,0x23FC2420,0x23FC2420,0x23FC2420,0x8A001074,0x6A002420,0xFECC1F02,0xD42422,0xD42422,0xFEBC18F5,0xFEA81429,0xFE980F82,0xFE980F82,0xFE8006B2,0xFAB41D8D,0xFEA01829,0xFE50027D,0xE800069D, -0x1C82420,}; -static const uint32_t g_etc1_to_bc7_m6_table252[] = { -0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x28C0000,0x1200000, -0x1200000,0x1200000,0x1200000,0x2E000001,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0x600000,0xA640000,0xA640000,0xA640000,0x28C0000,0xCC0000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x1700000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000, -0x29FC0000,0x97F80000,0x97F80000,0x97F80000,0xB6000001,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x29FC0000,0x97F80000,0x97F80000,0x97F80000,0xB6000001,0x97F80000,0x97F80000,0x97F80000,0xB6000001,0xB6000001,0x1880000,0x1700000,0x1700000,0x1AC0000,0x3CC0000,0x1F40000,0x1F40000,0x51FC0000,0x1AC0000,0x3CC0000,0x7BFC0000,0x97F80000, -0x7BFC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1746F9A,0xFF5C636D,0xFF4C59E2,0xFF445671,0xFF4452B0,0xFF244509,0xFF183FC9,0xFF0832A0,0xFEFC2BCC,0xFEE82420,0xFF244F2A,0xFF003CE1,0xFEF43599,0xFECC22EC,0xFEB8187A,0xFEA40C6D,0xFEA01E26,0xFE88107D,0xFE5C0008,0xE6600D21,0x2BFC6F9A,0xFEFC5DB5,0xFEE85671,0xFEAC40A4,0xFE8833FB,0xFE602420,0xFE5835B7,0xFE142035,0xFA000585,0xE2000FFD,0x97FC6F9A, -0xF80056D6,0xE6003482,0xD0003409,0xB8006F9A,0xFF5860F6,0xFF6C6A48,0xFF6C6D09,0xFF2C503A,0xFF0C3CF6,0xFEDC2926,0xFECC20F9,0xFEA01085,0xFF505FB2,0xFF184DB4,0xFEB0221D,0xFA000585,0x7DF86F9A,0x1D00D22,0xFFC40B96,0xFFB80A52,0xFFB809D9,0xFFB00948,0xFFA40709,0xFF980614,0xFF880362,0xFF7C01DD,0xFF700000,0xB7FC0D21,0xFFA00AD2,0xFF9409D9,0xFF700633,0xFF5803BA, -0xFF2C0000,0xDDF40D21,0xFF2009D9,0xFE4C0000,0xE6000D21,0xB7FC0D21,0xFFA00AD2,0xFF9409D9,0xFF700633,0xFF5803BA,0xFF2C0000,0xDDF40D21,0xFF2009D9,0xFE4C0000,0xE6000D21,0xDDF40D21,0xFF2009D9,0xFE4C0000,0xE6000D21,0xE6000D21,0xFFBC0BF4,0xFFCC0C66,0xFFCC0CC6,0xFFB40AAE,0xFF9808C1,0xFF7C063E,0xFF680484,0xFF380334,0xFFC40C0E,0xFFA40A8D,0xFF6409F2,0xFE4C0000, -0xD3FC0D21,0x1445671,0x1445671,0x1445671,0x1445671,0xFF183FC9,0xFF183FC9,0xFF183FC9,0xFEFC2BCC,0xFEFC2BCC,0xFEE82420,0xFEF43599,0xFEF43599,0xFEF43599,0xFEB8187A,0xFEB8187A,0xFEA40C6D,0xFE88107D,0xFE88107D,0xFC600008,0xDA6009D9,0x1E05671,0x1E05671,0x1E05671,0xFE8833FB,0xFE8833FB,0xFE602420,0xFE142035,0xFE142035,0xFA000575,0xD8000BF6,0x75FC5671, -0x75FC5671,0xD6003080,0xBE002931,0xA2005672,0xFF2C4B21,0xF9405231,0x1445671,0xFF103F92,0xFEEC3269,0xFEDC25DD,0xFECC20F9,0xFEA01085,0xFF2049F1,0xFF003DFD,0xFEB021B9,0xFA000575,0x51FC5671,0x1B809D9,0x1B809D9,0x1B809D9,0x1B809D9,0xFF980614,0xFF980614,0xFF980614,0xFF7C01DD,0xFF7C01DD,0xFF700000,0x93FC09D9,0x93FC09D9,0x93FC09D9,0xFF5803BA,0xFF5803BA, -0xFF2C0000,0xCBF809D9,0xCBF809D9,0xFE4C0000,0xDA0009D9,0x93FC09D9,0x93FC09D9,0x93FC09D9,0xFF5803BA,0xFF5803BA,0xFF2C0000,0xCBF809D9,0xCBF809D9,0xFE4C0000,0xDA0009D9,0xCBF809D9,0xCBF809D9,0xFE4C0000,0xDA0009D9,0xDA0009D9,0xF9B00908,0xFFAC0928,0x1B809D9,0xFF980832,0xFF8406F4,0xFF740590,0xFF680484,0xFF380334,0xFFA80908,0xFF980808,0xBDF809D9,0xFE4C0000, -0xBDF809D9,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0xE82420,0xE82420,0xE82420,0xE82420,0xE82420,0xE82420,0xE82420,0xE82420,0xE82420,0xE82420,0xFEA40C6D,0xFEA40C6D,0xFEA40C6D,0xFEA40C6D,0xFEA40C6D, -0xFEA40C6D,0xFA600000,0xFA600000,0xFA600000,0xB6600001,0x1582420,0x1582420,0x1582420,0x1582420,0x1582420,0x1582420,0xFA000565,0xFA000565,0xFA000565,0xB4000082,0x31F82420,0x31F82420,0x31F82420,0x96000F3A,0x72002422,0xF8E01F81,0xE82420,0xE82420,0xFECC1974,0xFEB414F4,0xFEAC109D,0xFEAC109D,0xFE9407B4,0xFEBC1DC9,0xFEB418A0,0xFE60034D,0xFA000565, -0x1EC2420,}; -static const uint32_t g_etc1_to_bc7_m6_table253[] = { -0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x2A40000,0x1500000, -0x1500000,0x1500000,0x1500000,0x36000001,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x700000,0x780000,0x780000,0x780000,0x2A40000,0xEC0000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x1800000,0x41FC0000,0x41FC0000,0x41FC0000,0x41FC0000,0x41FC0000, -0x41FC0000,0xA1FC0000,0xA1FC0000,0xA1FC0000,0xBE000001,0x41FC0000,0x41FC0000,0x41FC0000,0x41FC0000,0x41FC0000,0x41FC0000,0xA1FC0000,0xA1FC0000,0xA1FC0000,0xBE000001,0xA1FC0000,0xA1FC0000,0xA1FC0000,0xBE000001,0xBE000001,0x5980000,0x1800000,0x1800000,0x7BC0000,0x3E00000,0x13FC0000,0x13FC0000,0x65FC0000,0x7BC0000,0x3E00000,0x89FC0000,0xA1FC0000, -0x89FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x17C672A,0xFF685C5D,0xFF5853E2,0xFF5050D1,0xFF444D70,0xFF30415D,0xFF243CB9,0xFF1430F0,0xFF082AE0,0xFEF82420,0xFF304956,0xFF0C38E9,0xFF00325D,0xFED821A0,0xFECC1848,0xFEB00D61,0xFEAC1B66,0xFE940EED,0xFE700004,0xE8700A59,0x37FC672A,0xFF145745,0xFEFC50D1,0xFEB83D84,0xFEA03223,0xFE782420,0xFE703187,0xFE2C1E1D,0xFC0004C5,0xE8000BE9,0x9DFC672A, -0xFC0050E5,0xE6003022,0xD6002CD1,0xBC00672A,0xFF645A02,0xFF6C6288,0xF578652A,0xFF444AE6,0xFF143961,0xFEF0276A,0xFEDC2036,0xFEB010A0,0xFF5058A2,0xFF304877,0xFEB41FE1,0xFC0004C5,0x83FC672A,0x1D40A56,0xFFC8092D,0xFFC00825,0xFFC007C1,0xFFBC074C,0xFFB0058D,0xFFA404C8,0xFF9402A6,0xFF880179,0xFF800000,0xC1FC0A56,0xFFAC0882,0xFFA007C1,0xFF7C04DB,0xFF6402EA, -0xFF400001,0xE1F80A56,0xFF3807C1,0xFE7C0000,0xE8000A59,0xC1FC0A56,0xFFAC0882,0xFFA007C1,0xFF7C04DB,0xFF6402EA,0xFF400001,0xE1F80A56,0xFF3807C1,0xFE7C0000,0xE8000A59,0xE1F80A56,0xFF3807C1,0xFE7C0000,0xE8000A59,0xE8000A59,0xFDCC0965,0xFFCC09C6,0xFFCC0A26,0xFFC00865,0xFFAC06E5,0xFF7C050E,0xFF7C0385,0xFF50028A,0xFFC4096E,0xFFB0085D,0xFF7407D1,0xFE7C0000, -0xD9FC0A56,0x15050D1,0x15050D1,0x15050D1,0x15050D1,0xFF243CB9,0xFF243CB9,0xFF243CB9,0xFF082AE0,0xFF082AE0,0xFEF82420,0xFF00325D,0xFF00325D,0xFF00325D,0xFECC1848,0xFECC1848,0xFEB00D61,0xFE940EED,0xFE940EED,0xFE700004,0xDE7007C1,0x1F450D1,0x1F450D1,0x1F450D1,0xFEA03223,0xFEA03223,0xFE782420,0xFE2C1E1D,0xFE2C1E1D,0xFC0004C1,0xDE0008E2,0x7FF850D1, -0x7FF850D1,0xDC002D24,0xC40023CD,0xA60050D2,0xFF3C469D,0xFF4C4CD1,0x15050D1,0xFF183C30,0xFF002FDD,0xFEE82482,0xFEDC2036,0xFEB010A0,0xFF344580,0xFF103A91,0xFEB41F7D,0xFC0004C1,0x5DF850D1,0x1C007C1,0x1C007C1,0x1C007C1,0x1C007C1,0xFFA404C8,0xFFA404C8,0xFFA404C8,0xFF880179,0xFF880179,0xFF800000,0x9FFC07C1,0x9FFC07C1,0x9FFC07C1,0xFF6402EA,0xFF6402EA, -0xFF400001,0xD1F807C1,0xD1F807C1,0xFE7C0000,0xDE0007C1,0x9FFC07C1,0x9FFC07C1,0x9FFC07C1,0xFF6402EA,0xFF6402EA,0xFF400001,0xD1F807C1,0xD1F807C1,0xFE7C0000,0xDE0007C1,0xD1F807C1,0xD1F807C1,0xFE7C0000,0xDE0007C1,0xDE0007C1,0xFDB80708,0xF7BC0745,0x1C007C1,0xFFA40681,0xFF980568,0xFF7C0465,0xFF7C0385,0xFF50028A,0xFDB0070A,0xFFA4065D,0xC3FC07C1,0xFE7C0000, -0xC3FC07C1,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0xF82420,0xF82420,0xF82420,0xF82420,0xF82420,0xF82420,0xF82420,0xF82420,0xF82420,0xF82420,0xFEB00D61,0xFEB00D61,0xFEB00D61,0xFEB00D61,0xFEB00D61, -0xFEB00D61,0xFE700004,0xFE700004,0xFE700004,0xBE700001,0x1702420,0x1702420,0x1702420,0x1702420,0x1702420,0x1702420,0xFA0004B5,0xFA0004B5,0xFA0004B5,0xBC00002D,0x3DF82420,0x3DF82420,0x3DF82420,0x9C000E2A,0x7A002422,0xFEEC1F85,0xF82420,0xF82420,0xFED81A11,0xFED015B1,0xFEC41174,0xFEC41174,0xFE9C08C8,0xFED81E0A,0xFED01962,0xFE74040D,0xFA0004B5, -0x9FC2420,}; -static const uint32_t g_etc1_to_bc7_m6_table254[] = { -0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x2BC0000,0x1800000, -0x1800000,0x1800000,0x1800000,0x3E000001,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x800000,0x880000,0x880000,0x880000,0x2BC0000,0x1100000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x1900000,0x59FC0000,0x59FC0000,0x59FC0000,0x59FC0000,0x59FC0000, -0x59FC0000,0xADFC0000,0xADFC0000,0xADFC0000,0xC6000001,0x59FC0000,0x59FC0000,0x59FC0000,0x59FC0000,0x59FC0000,0x59FC0000,0xADFC0000,0xADFC0000,0xADFC0000,0xC6000001,0xADFC0000,0xADFC0000,0xADFC0000,0xC6000001,0xC6000001,0xDA80000,0x1900000,0x1900000,0x1D00000,0x3F40000,0x31FC0000,0x31FC0000,0x79FC0000,0x1D00000,0x3F40000,0x99FC0000,0xADFC0000, -0x99FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x1845F3A,0xFF7455C5,0xFF644E42,0xFF584B89,0xFF504888,0xFF3C3DE9,0xFF3039D9,0xFF202F60,0xFF142A0C,0xFF082420,0xFF4443BD,0xFF183541,0xFF0C2F69,0xFEF02070,0xFED81820,0xFEC40E48,0xFEB81906,0xFEA00DB5,0xFE880034,0xEC8007E1,0x43FC5F3A,0xFF205129,0xFF084B89,0xFED83AA0,0xFEB8306B,0xFE902420,0xFE882DB7,0xFE381C71,0xFE0804BD,0xEA000892,0xA3FC5F3A, -0xFE084B86,0xEC002C5A,0xDC002651,0xC0005F3A,0xFF645372,0xF9805B72,0xF9805D5A,0xFF4445D6,0xFF20362E,0xFEFC25F8,0xFEE81F71,0xFEC010D5,0xFF58526E,0xFF3043C7,0xFEBC1E2D,0xFE0804BD,0x8BFC5F3A,0x1D807E2,0xFFD006F2,0xFFCC0635,0xFFC805E9,0xFFC40576,0xFFBC0441,0xFFB003A4,0xFFA00202,0xFFA00121,0xFF900000,0xC9FC07E1,0xFFB8067A,0xFFAC05E9,0xFF9403AB,0xFF7C0232, -0xFF580001,0xE5F807E1,0xFF5405E9,0xFEAC0000,0xEC0007E1,0xC9FC07E1,0xFFB8067A,0xFFAC05E9,0xFF9403AB,0xFF7C0232,0xFF580001,0xE5F807E1,0xFF5405E9,0xFEAC0000,0xEC0007E1,0xE5F807E1,0xFF5405E9,0xFEAC0000,0xEC0007E1,0xEC0007E1,0xFFD00715,0xF5D80798,0xF5D807BD,0xFFC4065E,0xFFAC0545,0xFFA003D8,0xFF8C02BA,0xFF6401E1,0xFFD0072E,0xFFC0063D,0xFF9005F6,0xFEAC0000, -0xDFF807E1,0x1584B89,0x1584B89,0x1584B89,0x1584B89,0xFF3039D9,0xFF3039D9,0xFF3039D9,0xFF142A0C,0xFF142A0C,0xFF082420,0xFF0C2F69,0xFF0C2F69,0xFF0C2F69,0xFED81820,0xFED81820,0xFEC40E48,0xFEA00DB5,0xFEA00DB5,0xFE880034,0xE28005E9,0x7FC4B86,0x7FC4B86,0x7FC4B86,0xFEB8306B,0xFEB8306B,0xFE902420,0xFE381C71,0xFE381C71,0xFE0804BD,0xE200064D,0x85FC4B86, -0x85FC4B86,0xE0002A76,0xCA001ED9,0xAC004B86,0xFF4C4244,0xFF4C4811,0x1584B89,0xFF2C38D6,0xFF142DA1,0xFEF8232A,0xFEE81F71,0xFEC010D5,0xFF344100,0xFF18376B,0xFEBC1DC9,0xFE0804BD,0x65FC4B86,0x1C805E9,0x1C805E9,0x1C805E9,0x1C805E9,0xFFB003A4,0xFFB003A4,0xFFB003A4,0xFFA00121,0xFFA00121,0xFF900000,0xABFC05E9,0xABFC05E9,0xABFC05E9,0xFF7C0232,0xFF7C0232, -0xFF580001,0xD7F805E9,0xD7F805E9,0xFEAC0000,0xE20005E9,0xABFC05E9,0xABFC05E9,0xABFC05E9,0xFF7C0232,0xFF7C0232,0xFF580001,0xD7F805E9,0xD7F805E9,0xFEAC0000,0xE20005E9,0xD7F805E9,0xD7F805E9,0xFEAC0000,0xE20005E9,0xE20005E9,0xFFBC0550,0xFBC4057D,0x1C805E9,0xFFB404EA,0xFFAC0424,0xFF940371,0xFF8C02BA,0xFF6401E1,0xFFB4055A,0xFFB004E4,0xCBFC05E9,0xFEAC0000, -0xCBFC05E9,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1082420,0x1082420,0x1082420,0x1082420,0x1082420,0x1082420,0x1082420,0x1082420,0x1082420,0x1082420,0xFEC40E48,0xFEC40E48,0xFEC40E48,0xFEC40E48,0xFEC40E48, -0xFEC40E48,0xFE880034,0xFE880034,0xFE880034,0xC6800001,0x1882420,0x1882420,0x1882420,0x1882420,0x1882420,0x1882420,0xFE0804BD,0xFE0804BD,0xFE0804BD,0xC6000002,0x49F82420,0x49F82420,0x49F82420,0xA6000D41,0x82002422,0xF9002000,0x1082420,0x1082420,0xFEE81A90,0xFEE41675,0xFED41248,0xFED41248,0xFEAC09CD,0xFAEC1E85,0xFED019E2,0xFE90052A,0xFE0804BD, -0x19FC2420,}; -static const uint32_t g_etc1_to_bc7_m6_table255[] = { -0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0xD40000,0x1B00000, -0x1B00000,0x1B00000,0x1B00000,0x46000001,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x900000,0x4980000,0x4980000,0x4980000,0xD40000,0x1300000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x1A00000,0x71FC0000,0x71FC0000,0x71FC0000,0x71FC0000,0x71FC0000, -0x71FC0000,0xB9FC0000,0xB9FC0000,0xB9FC0000,0xCE000001,0x71FC0000,0x71FC0000,0x71FC0000,0x71FC0000,0x71FC0000,0x71FC0000,0xB9FC0000,0xB9FC0000,0xB9FC0000,0xCE000001,0xB9FC0000,0xB9FC0000,0xB9FC0000,0xCE000001,0xCE000001,0x1BC0000,0x1A00000,0x1A00000,0x1E40000,0x1BFC0000,0x4FFC0000,0x4FFC0000,0x8DFC0000,0x1E40000,0x1BFC0000,0xA7FC0000,0xB9FC0000, -0xA7FC0000,0x1FC0001,0x1FC0001,0x1FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFBFC0001,0xF7FC0001,0x1FC0001,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0x1FC0001,0xFDFC0001,0xFFFC0000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000, -0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xFFFC0000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0001,0xF7FC0001,0xF7FC0001,0xFDFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0001,0xFDFC0001,0xFFF00000,0xFE000000, -0xFFFC0000,0x18C57CA,0xFF744F85,0xFF6C48F9,0xFF644691,0xFF5C43F0,0xFF443AAD,0xFF4436EC,0xFF2C2DF0,0xFF202950,0xFF182420,0xFF443E8D,0xFF2431E9,0xFF182CBD,0xFEFC1F6C,0xFEEC1816,0xFED00F64,0xFED81711,0xFEB80CAD,0xFE940094,0xEE9005C1,0x4FFC57CA,0xFF2C4B75,0xFF184691,0xFEF037C0,0xFECC2F04,0xFEA82420,0xFEA02A47,0xFE641B02,0xFE140585,0xEE0005E5,0xA9FC57CA, -0xFE284691,0xF2002962,0xDC002041,0xC40057CA,0xFF744D72,0xFD885442,0xFD88560A,0xFF5440F0,0xFF343326,0xFF1024C0,0xFEF81EEA,0xFED81141,0xFF704C95,0xFF503F25,0xFED81CB7,0xFE140585,0x93FC57CA,0x1E005C2,0xFFDC051E,0xFFD4048E,0xFFD00451,0xFFD00402,0xFFC40311,0xFFBC02A8,0xFFAC0176,0xFFAC00CD,0xFFA00000,0xCFFC05C1,0xFFC004C1,0xFFB80451,0xFFA002A3,0xFF88019A, -0xFF700001,0xE7FC05C1,0xFF6C0451,0xFEE00000,0xEE0005C1,0xCFFC05C1,0xFFC004C1,0xFFB80451,0xFFA002A3,0xFF88019A,0xFF700001,0xE7FC05C1,0xFF6C0451,0xFEE00000,0xEE0005C1,0xE7FC05C1,0xFF6C0451,0xFEE00000,0xEE0005C1,0xEE0005C1,0xFFD8052A,0xF7DC0584,0xF7DC05A5,0xFFD404BA,0xFFC003D1,0xFFA802C2,0xFFA001F9,0xFF7C0161,0xFFD0053E,0xFFC80479,0xFF98045A,0xFEE00000, -0xE1FC05C1,0x1644691,0x1644691,0x1644691,0x1644691,0xFF4436EC,0xFF4436EC,0xFF4436EC,0xFF202950,0xFF202950,0xFF182420,0xFF182CBD,0xFF182CBD,0xFF182CBD,0xFEEC1816,0xFEEC1816,0xFED00F64,0xFEB80CAD,0xFEB80CAD,0xFE940094,0xE6900451,0x15FC4691,0x15FC4691,0x15FC4691,0xFECC2F04,0xFECC2F04,0xFEA82420,0xFE641B02,0xFE641B02,0xFE140585,0xE6000461,0x8DFC4691, -0x8DFC4691,0xE6002822,0xD0001A55,0xB2004692,0xFF4C3E24,0xF96043A4,0x1644691,0xFF3C35A5,0xFF202BD5,0xFF08226D,0xFEF81EEA,0xFED81141,0xFF3C3D49,0xFF303446,0xFED81C66,0xFE140585,0x6FFC4691,0x1D00451,0x1D00451,0x1D00451,0x1D00451,0xFFBC02A8,0xFFBC02A8,0xFFBC02A8,0xFFAC00CD,0xFFAC00CD,0xFFA00000,0xB7FC0451,0xB7FC0451,0xB7FC0451,0xFF88019A,0xFF88019A, -0xFF700001,0xDDF40451,0xDDF40451,0xFEE00000,0xE6000451,0xB7FC0451,0xB7FC0451,0xB7FC0451,0xFF88019A,0xFF88019A,0xFF700001,0xDDF40451,0xDDF40451,0xFEE00000,0xE6000451,0xDDF40451,0xDDF40451,0xFEE00000,0xE6000451,0xE6000451,0xF9CC03F5,0xFFCC03F5,0x1D00451,0xFFC4039D,0xFFAC0304,0xFFA80271,0xFFA001F9,0xFF7C0161,0xFBC803F5,0xFBC0039D,0xD3FC0451,0xFEE00000, -0xD3FC0451,0x1FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFDFC0002,0xFFFC0001,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFE000000,0xFFFC0000,0xFFFC0000,0xFE000000,0xFE000000,0xFFFC0000, -0xFFFC0000,0xFE000000,0xFE000000,0xFE000000,0xFDFC0002,0xF7FC0002,0xF7FC0002,0xFDFC0002,0xFFFC0001,0xFFFC0000,0xFFFC0000,0xFFFC0000,0xFDFC0002,0xFDFC0002,0xFFFC0000,0xFE000000,0xFFFC0000,0x1182420,0x1182420,0x1182420,0x1182420,0x1182420,0x1182420,0x1182420,0x1182420,0x1182420,0x1182420,0xFED00F64,0xFED00F64,0xFED00F64,0xFED00F64,0xFED00F64, -0xFED00F64,0xFE940094,0xFE940094,0xFE940094,0xCE900001,0x1A02420,0x1A02420,0x1A02420,0x1A02420,0x1A02420,0x1A02420,0xFE140585,0xFE140585,0xFE140585,0xCE0C0001,0x55F82420,0x55F82420,0x55F82420,0xB2000C49,0x8A002422,0xFF0C2008,0x1182420,0x1182420,0xFF041B34,0xFEF81741,0xFEDC133D,0xFEDC133D,0xFEC00AE1,0xFEF41EAD,0xFEE41AAA,0xFE9C0631,0xFE140585, -0x27FC2420,}; -const uint32_t *g_etc1_to_bc7_m6_table[] = { -g_etc1_to_bc7_m6_table0, g_etc1_to_bc7_m6_table1, g_etc1_to_bc7_m6_table2, g_etc1_to_bc7_m6_table3, g_etc1_to_bc7_m6_table4, g_etc1_to_bc7_m6_table5, g_etc1_to_bc7_m6_table6, g_etc1_to_bc7_m6_table7, g_etc1_to_bc7_m6_table8, g_etc1_to_bc7_m6_table9, g_etc1_to_bc7_m6_table10, g_etc1_to_bc7_m6_table11, g_etc1_to_bc7_m6_table12, g_etc1_to_bc7_m6_table13, g_etc1_to_bc7_m6_table14, g_etc1_to_bc7_m6_table15, -g_etc1_to_bc7_m6_table16, g_etc1_to_bc7_m6_table17, g_etc1_to_bc7_m6_table18, g_etc1_to_bc7_m6_table19, g_etc1_to_bc7_m6_table20, g_etc1_to_bc7_m6_table21, g_etc1_to_bc7_m6_table22, g_etc1_to_bc7_m6_table23, g_etc1_to_bc7_m6_table24, g_etc1_to_bc7_m6_table25, g_etc1_to_bc7_m6_table26, g_etc1_to_bc7_m6_table27, g_etc1_to_bc7_m6_table28, g_etc1_to_bc7_m6_table29, g_etc1_to_bc7_m6_table30, g_etc1_to_bc7_m6_table31, -g_etc1_to_bc7_m6_table32, g_etc1_to_bc7_m6_table33, g_etc1_to_bc7_m6_table34, g_etc1_to_bc7_m6_table35, g_etc1_to_bc7_m6_table36, g_etc1_to_bc7_m6_table37, g_etc1_to_bc7_m6_table38, g_etc1_to_bc7_m6_table39, g_etc1_to_bc7_m6_table40, g_etc1_to_bc7_m6_table41, g_etc1_to_bc7_m6_table42, g_etc1_to_bc7_m6_table43, g_etc1_to_bc7_m6_table44, g_etc1_to_bc7_m6_table45, g_etc1_to_bc7_m6_table46, g_etc1_to_bc7_m6_table47, -g_etc1_to_bc7_m6_table48, g_etc1_to_bc7_m6_table49, g_etc1_to_bc7_m6_table50, g_etc1_to_bc7_m6_table51, g_etc1_to_bc7_m6_table52, g_etc1_to_bc7_m6_table53, g_etc1_to_bc7_m6_table54, g_etc1_to_bc7_m6_table55, g_etc1_to_bc7_m6_table56, g_etc1_to_bc7_m6_table57, g_etc1_to_bc7_m6_table58, g_etc1_to_bc7_m6_table59, g_etc1_to_bc7_m6_table60, g_etc1_to_bc7_m6_table61, g_etc1_to_bc7_m6_table62, g_etc1_to_bc7_m6_table63, -g_etc1_to_bc7_m6_table64, g_etc1_to_bc7_m6_table65, g_etc1_to_bc7_m6_table66, g_etc1_to_bc7_m6_table67, g_etc1_to_bc7_m6_table68, g_etc1_to_bc7_m6_table69, g_etc1_to_bc7_m6_table70, g_etc1_to_bc7_m6_table71, g_etc1_to_bc7_m6_table72, g_etc1_to_bc7_m6_table73, g_etc1_to_bc7_m6_table74, g_etc1_to_bc7_m6_table75, g_etc1_to_bc7_m6_table76, g_etc1_to_bc7_m6_table77, g_etc1_to_bc7_m6_table78, g_etc1_to_bc7_m6_table79, -g_etc1_to_bc7_m6_table80, g_etc1_to_bc7_m6_table81, g_etc1_to_bc7_m6_table82, g_etc1_to_bc7_m6_table83, g_etc1_to_bc7_m6_table84, g_etc1_to_bc7_m6_table85, g_etc1_to_bc7_m6_table86, g_etc1_to_bc7_m6_table87, g_etc1_to_bc7_m6_table88, g_etc1_to_bc7_m6_table89, g_etc1_to_bc7_m6_table90, g_etc1_to_bc7_m6_table91, g_etc1_to_bc7_m6_table92, g_etc1_to_bc7_m6_table93, g_etc1_to_bc7_m6_table94, g_etc1_to_bc7_m6_table95, -g_etc1_to_bc7_m6_table96, g_etc1_to_bc7_m6_table97, g_etc1_to_bc7_m6_table98, g_etc1_to_bc7_m6_table99, g_etc1_to_bc7_m6_table100, g_etc1_to_bc7_m6_table101, g_etc1_to_bc7_m6_table102, g_etc1_to_bc7_m6_table103, g_etc1_to_bc7_m6_table104, g_etc1_to_bc7_m6_table105, g_etc1_to_bc7_m6_table106, g_etc1_to_bc7_m6_table107, g_etc1_to_bc7_m6_table108, g_etc1_to_bc7_m6_table109, g_etc1_to_bc7_m6_table110, g_etc1_to_bc7_m6_table111, -g_etc1_to_bc7_m6_table112, g_etc1_to_bc7_m6_table113, g_etc1_to_bc7_m6_table114, g_etc1_to_bc7_m6_table115, g_etc1_to_bc7_m6_table116, g_etc1_to_bc7_m6_table117, g_etc1_to_bc7_m6_table118, g_etc1_to_bc7_m6_table119, g_etc1_to_bc7_m6_table120, g_etc1_to_bc7_m6_table121, g_etc1_to_bc7_m6_table122, g_etc1_to_bc7_m6_table123, g_etc1_to_bc7_m6_table124, g_etc1_to_bc7_m6_table125, g_etc1_to_bc7_m6_table126, g_etc1_to_bc7_m6_table127, -g_etc1_to_bc7_m6_table128, g_etc1_to_bc7_m6_table129, g_etc1_to_bc7_m6_table130, g_etc1_to_bc7_m6_table131, g_etc1_to_bc7_m6_table132, g_etc1_to_bc7_m6_table133, g_etc1_to_bc7_m6_table134, g_etc1_to_bc7_m6_table135, g_etc1_to_bc7_m6_table136, g_etc1_to_bc7_m6_table137, g_etc1_to_bc7_m6_table138, g_etc1_to_bc7_m6_table139, g_etc1_to_bc7_m6_table140, g_etc1_to_bc7_m6_table141, g_etc1_to_bc7_m6_table142, g_etc1_to_bc7_m6_table143, -g_etc1_to_bc7_m6_table144, g_etc1_to_bc7_m6_table145, g_etc1_to_bc7_m6_table146, g_etc1_to_bc7_m6_table147, g_etc1_to_bc7_m6_table148, g_etc1_to_bc7_m6_table149, g_etc1_to_bc7_m6_table150, g_etc1_to_bc7_m6_table151, g_etc1_to_bc7_m6_table152, g_etc1_to_bc7_m6_table153, g_etc1_to_bc7_m6_table154, g_etc1_to_bc7_m6_table155, g_etc1_to_bc7_m6_table156, g_etc1_to_bc7_m6_table157, g_etc1_to_bc7_m6_table158, g_etc1_to_bc7_m6_table159, -g_etc1_to_bc7_m6_table160, g_etc1_to_bc7_m6_table161, g_etc1_to_bc7_m6_table162, g_etc1_to_bc7_m6_table163, g_etc1_to_bc7_m6_table164, g_etc1_to_bc7_m6_table165, g_etc1_to_bc7_m6_table166, g_etc1_to_bc7_m6_table167, g_etc1_to_bc7_m6_table168, g_etc1_to_bc7_m6_table169, g_etc1_to_bc7_m6_table170, g_etc1_to_bc7_m6_table171, g_etc1_to_bc7_m6_table172, g_etc1_to_bc7_m6_table173, g_etc1_to_bc7_m6_table174, g_etc1_to_bc7_m6_table175, -g_etc1_to_bc7_m6_table176, g_etc1_to_bc7_m6_table177, g_etc1_to_bc7_m6_table178, g_etc1_to_bc7_m6_table179, g_etc1_to_bc7_m6_table180, g_etc1_to_bc7_m6_table181, g_etc1_to_bc7_m6_table182, g_etc1_to_bc7_m6_table183, g_etc1_to_bc7_m6_table184, g_etc1_to_bc7_m6_table185, g_etc1_to_bc7_m6_table186, g_etc1_to_bc7_m6_table187, g_etc1_to_bc7_m6_table188, g_etc1_to_bc7_m6_table189, g_etc1_to_bc7_m6_table190, g_etc1_to_bc7_m6_table191, -g_etc1_to_bc7_m6_table192, g_etc1_to_bc7_m6_table193, g_etc1_to_bc7_m6_table194, g_etc1_to_bc7_m6_table195, g_etc1_to_bc7_m6_table196, g_etc1_to_bc7_m6_table197, g_etc1_to_bc7_m6_table198, g_etc1_to_bc7_m6_table199, g_etc1_to_bc7_m6_table200, g_etc1_to_bc7_m6_table201, g_etc1_to_bc7_m6_table202, g_etc1_to_bc7_m6_table203, g_etc1_to_bc7_m6_table204, g_etc1_to_bc7_m6_table205, g_etc1_to_bc7_m6_table206, g_etc1_to_bc7_m6_table207, -g_etc1_to_bc7_m6_table208, g_etc1_to_bc7_m6_table209, g_etc1_to_bc7_m6_table210, g_etc1_to_bc7_m6_table211, g_etc1_to_bc7_m6_table212, g_etc1_to_bc7_m6_table213, g_etc1_to_bc7_m6_table214, g_etc1_to_bc7_m6_table215, g_etc1_to_bc7_m6_table216, g_etc1_to_bc7_m6_table217, g_etc1_to_bc7_m6_table218, g_etc1_to_bc7_m6_table219, g_etc1_to_bc7_m6_table220, g_etc1_to_bc7_m6_table221, g_etc1_to_bc7_m6_table222, g_etc1_to_bc7_m6_table223, -g_etc1_to_bc7_m6_table224, g_etc1_to_bc7_m6_table225, g_etc1_to_bc7_m6_table226, g_etc1_to_bc7_m6_table227, g_etc1_to_bc7_m6_table228, g_etc1_to_bc7_m6_table229, g_etc1_to_bc7_m6_table230, g_etc1_to_bc7_m6_table231, g_etc1_to_bc7_m6_table232, g_etc1_to_bc7_m6_table233, g_etc1_to_bc7_m6_table234, g_etc1_to_bc7_m6_table235, g_etc1_to_bc7_m6_table236, g_etc1_to_bc7_m6_table237, g_etc1_to_bc7_m6_table238, g_etc1_to_bc7_m6_table239, -g_etc1_to_bc7_m6_table240, g_etc1_to_bc7_m6_table241, g_etc1_to_bc7_m6_table242, g_etc1_to_bc7_m6_table243, g_etc1_to_bc7_m6_table244, g_etc1_to_bc7_m6_table245, g_etc1_to_bc7_m6_table246, g_etc1_to_bc7_m6_table247, g_etc1_to_bc7_m6_table248, g_etc1_to_bc7_m6_table249, g_etc1_to_bc7_m6_table250, g_etc1_to_bc7_m6_table251, g_etc1_to_bc7_m6_table252, g_etc1_to_bc7_m6_table253, g_etc1_to_bc7_m6_table254, g_etc1_to_bc7_m6_table255, -}; diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_5.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_5.inc index 3e7610ff53..8244550959 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_5.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_5.inc @@ -491,4 +491,4 @@ {17,31,10897},{16,31,12077},{13,31,6285},{13,31,6285},{8,31,68},{4,31,7686},{0,31,1341},{27,31,968},{27,31,968},{27,31,968},{25,31,325},{31,21,1513},{23,31,605},{23,31,605},{11,31,0},{31,26,1513},{11,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{0,31,0},{31,31,0},{0,31,0},{16,0,9248},{16,0,9248},{16,0,9248},{16,0,9248},{12,31,3626}, {12,31,3626},{12,31,3626},{8,31,68},{0,31,1341},{0,31,1341},{21,31,17476},{20,31,14998},{20,31,14098},{18,31,10672},{20,31,16018},{15,31,8154},{15,31,6218},{9,31,200},{10,31,11338},{0,31,1613},{28,31,1041},{27,31,801},{27,31,680},{26,31,232},{29,29,1473},{26,31,753},{24,31,442},{14,31,0},{31,28,1473},{14,31,0},{20,31,14098},{20,31,14098},{20,31,14098},{18,31,10672},{17,31,11453},{15,31,6218},{15,31,6218}, {9,31,200},{6,31,7270},{0,31,1613},{27,31,680},{27,31,680},{27,31,680},{26,31,232},{28,28,1105},{24,31,442},{24,31,442},{14,31,0},{28,28,1105},{14,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{31,31,0},{0,31,0},{31,31,0},{0,31,0},{17,0,9248},{17,0,9248},{17,0,9248},{17,0,9248},{13,31,3929},{13,31,3929},{13,31,3929},{9,31,200},{0,31,1613}, -{0,31,1613},
\ No newline at end of file +{0,31,1613}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_6.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_6.inc index 2441fbe859..fad45fe22d 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_6.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_dxt1_6.inc @@ -491,4 +491,4 @@ {34,63,10841},{34,63,12089},{26,63,6206},{26,63,6206},{17,63,74},{9,63,7678},{0,63,1341},{54,63,937},{54,63,937},{54,63,937},{51,63,305},{63,43,1513},{47,63,605},{47,63,605},{22,63,1},{62,53,1513},{22,63,1},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{0,63,0},{63,63,0},{0,63,0},{32,0,9256},{32,0,9256},{32,0,9256},{32,0,9256},{23,63,3650}, {23,63,3650},{23,63,3650},{17,63,74},{0,63,1341},{0,63,1341},{43,63,17392},{40,63,15021},{40,63,14060},{37,63,10673},{40,63,16013},{32,63,8261},{29,63,6166},{19,63,194},{20,63,11338},{1,63,1594},{57,63,1041},{56,63,822},{54,63,697},{52,63,234},{63,51,1473},{51,63,737},{49,63,442},{28,63,1},{63,57,1473},{28,63,1},{40,63,14060},{40,63,14060},{40,63,14060},{37,63,10673},{34,63,11401},{29,63,6166},{29,63,6166}, {19,63,194},{12,63,7270},{1,63,1594},{54,63,697},{54,63,697},{54,63,697},{52,63,234},{63,46,1105},{49,63,442},{49,63,442},{28,63,1},{63,54,1105},{28,63,1},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{63,63,0},{0,63,0},{63,63,0},{0,63,0},{34,0,9256},{34,0,9256},{34,0,9256},{34,0,9256},{26,63,3898},{26,63,3898},{26,63,3898},{19,63,194},{1,63,1594}, -{1,63,1594},
\ No newline at end of file +{1,63,1594}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc index 0bca0bbddc..fbaf988d78 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_45.inc @@ -478,4 +478,4 @@ {8,31,11312},{8,31,11249},{7,31,6499},{7,31,6499},{4,31,260},{3,31,10457},{0,31,2642},{13,31,925},{13,31,925},{13,31,925},{12,31,397},{15,22,1513},{11,31,794},{11,31,794},{7,31,4},{14,27,1513},{7,31,4},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{8,0,9376},{8,0,9376},{8,0,9376},{8,0,9376},{6,31,3074}, {6,31,3074},{6,31,3074},{4,31,260},{0,31,2642},{0,31,2642},{8,31,58848},{7,31,39683},{6,31,25130},{6,31,19007},{8,31,54849},{6,31,27132},{5,31,8569},{4,31,756},{4,31,51302},{0,31,5046},{13,31,1078},{13,31,806},{13,31,637},{12,31,365},{15,26,1473},{12,31,978},{12,31,617},{8,31,9},{14,29,1473},{8,31,9},{9,31,13604},{9,31,13604},{9,31,13604},{8,31,11184},{8,31,10433},{7,31,6339},{7,31,6339}, {5,31,424},{4,31,9713},{0,31,2930},{13,31,637},{13,31,637},{13,31,637},{12,31,365},{14,27,1105},{12,31,617},{12,31,617},{8,31,9},{13,29,1105},{8,31,9},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{15,31,0},{0,31,0},{15,31,0},{0,31,0},{8,0,9248},{8,0,9248},{8,0,9248},{8,0,9248},{6,31,3330},{6,31,3330},{6,31,3330},{5,31,424},{0,31,2930}, -{0,31,2930},
\ No newline at end of file +{0,31,2930}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc index 10c94153ad..3b9d7022e7 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc @@ -478,4 +478,4 @@ {4,7,11305},{4,7,11209},{3,7,6489},{3,7,6489},{2,7,272},{1,7,10377},{0,7,2642},{6,7,1040},{6,7,1040},{6,7,1040},{6,7,416},{7,6,1537},{6,7,929},{6,7,929},{3,7,9},{7,6,1513},{3,7,9},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{4,0,9280},{4,0,9280},{4,0,9280},{4,0,9280},{3,7,3125}, {3,7,3125},{3,7,3125},{2,7,272},{0,7,2642},{0,7,2642},{4,7,59414},{4,7,41414},{3,7,24952},{3,7,19100},{4,7,55014},{3,7,27085},{2,7,10021},{2,7,656},{1,7,52310},{0,7,5046},{7,7,1142},{7,7,1070},{7,7,1021},{6,7,416},{7,7,1538},{6,7,1025},{6,7,625},{4,7,4},{6,7,1529},{4,7,4},{5,7,13964},{5,7,13964},{5,7,13964},{4,7,11305},{4,7,10505},{3,7,6665},{3,7,6665}, {2,7,592},{2,7,9973},{0,7,2930},{7,7,1021},{7,7,1021},{7,7,1021},{6,7,416},{7,6,1105},{6,7,625},{6,7,625},{4,7,4},{6,7,1129},{4,7,4},{7,7,242},{7,7,170},{7,7,121},{7,7,49},{7,7,242},{7,7,98},{7,7,49},{0,7,0},{7,7,98},{0,7,0},{4,0,9280},{4,0,9280},{4,0,9280},{4,0,9280},{3,7,3301},{3,7,3301},{3,7,3301},{2,7,592},{0,7,2930}, -{0,7,2930},
\ No newline at end of file +{0,7,2930}, diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder_uastc.h b/thirdparty/basis_universal/transcoder/basisu_transcoder_uastc.h new file mode 100644 index 0000000000..d501a2af6e --- /dev/null +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder_uastc.h @@ -0,0 +1,297 @@ +// basisu_transcoder_uastc.h +#pragma once +#include "basisu_transcoder_internal.h" + +namespace basist +{ + struct color_quad_u8 + { + uint8_t m_c[4]; + }; + + const uint32_t TOTAL_UASTC_MODES = 19; + const uint32_t UASTC_MODE_INDEX_SOLID_COLOR = 8; + + const uint32_t TOTAL_ASTC_BC7_COMMON_PARTITIONS2 = 30; + const uint32_t TOTAL_ASTC_BC7_COMMON_PARTITIONS3 = 11; + const uint32_t TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS = 19; + + extern const uint8_t g_uastc_mode_weight_bits[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_weight_ranges[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_endpoint_ranges[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_subsets[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_planes[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_comps[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_has_etc1_bias[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_has_bc1_hint0[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_has_bc1_hint1[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_has_alpha[TOTAL_UASTC_MODES]; + extern const uint8_t g_uastc_mode_is_la[TOTAL_UASTC_MODES]; + + struct astc_bc7_common_partition2_desc + { + uint8_t m_bc7; + uint16_t m_astc; + bool m_invert; + }; + + extern const astc_bc7_common_partition2_desc g_astc_bc7_common_partitions2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2]; + + struct bc73_astc2_common_partition_desc + { + uint8_t m_bc73; + uint16_t m_astc2; + uint8_t k; // 0-5 - how to modify the BC7 3-subset pattern to match the ASTC pattern (LSB=invert) + }; + + extern const bc73_astc2_common_partition_desc g_bc7_3_astc2_common_partitions[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS]; + + struct astc_bc7_common_partition3_desc + { + uint8_t m_bc7; + uint16_t m_astc; + uint8_t m_astc_to_bc7_perm; // converts ASTC to BC7 partition using g_astc_bc7_partition_index_perm_tables[][] + }; + + extern const astc_bc7_common_partition3_desc g_astc_bc7_common_partitions3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3]; + + extern const uint8_t g_astc_bc7_patterns2[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][16]; + extern const uint8_t g_astc_bc7_patterns3[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][16]; + extern const uint8_t g_bc7_3_astc2_patterns2[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][16]; + + extern const uint8_t g_astc_bc7_pattern2_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS2][3]; + extern const uint8_t g_astc_bc7_pattern3_anchors[TOTAL_ASTC_BC7_COMMON_PARTITIONS3][3]; + extern const uint8_t g_bc7_3_astc2_patterns2_anchors[TOTAL_BC7_3_ASTC2_COMMON_PARTITIONS][3]; + + extern const uint32_t g_uastc_mode_huff_codes[TOTAL_UASTC_MODES + 1][2]; + + extern const uint8_t g_astc_to_bc7_partition_index_perm_tables[6][3]; + extern const uint8_t g_bc7_to_astc_partition_index_perm_tables[6][3]; // inverse of g_astc_to_bc7_partition_index_perm_tables + + extern const uint8_t* s_uastc_to_bc1_weights[6]; + + uint32_t bc7_convert_partition_index_3_to_2(uint32_t p, uint32_t k); + + inline uint32_t astc_interpolate(uint32_t l, uint32_t h, uint32_t w, bool srgb) + { + if (srgb) + { + l = (l << 8) | 0x80; + h = (h << 8) | 0x80; + } + else + { + l = (l << 8) | l; + h = (h << 8) | h; + } + + uint32_t k = (l * (64 - w) + h * w + 32) >> 6; + + return k >> 8; + } + + struct astc_block_desc + { + int m_weight_range; // weight BISE range + + int m_subsets; // number of ASTC partitions + int m_partition_seed; // partition pattern seed + int m_cem; // color endpoint mode used by all subsets + + int m_ccs; // color component selector (dual plane only) + bool m_dual_plane; // true if dual plane + + // Weight and endpoint BISE values. + // Note these values are NOT linear, they must be BISE encoded. See Table 97 and Table 107. + uint8_t m_endpoints[18]; // endpoint values, in RR GG BB etc. order + uint8_t m_weights[64]; // weight index values, raster order, in P0 P1, P0 P1, etc. or P0, P0, P0, P0, etc. order + }; + + const uint32_t BC7ENC_TOTAL_ASTC_RANGES = 21; + + // See tables 81, 93, 18.13.Endpoint Unquantization + const uint32_t TOTAL_ASTC_RANGES = 21; + extern const int g_astc_bise_range_table[TOTAL_ASTC_RANGES][3]; + + struct astc_quant_bin + { + uint8_t m_unquant; // unquantized value + uint8_t m_index; // sorted index + }; + + extern astc_quant_bin g_astc_unquant[BC7ENC_TOTAL_ASTC_RANGES][256]; // [ASTC encoded endpoint index] + + int astc_get_levels(int range); + bool astc_is_valid_endpoint_range(uint32_t range); + uint32_t unquant_astc_endpoint(uint32_t packed_bits, uint32_t packed_trits, uint32_t packed_quints, uint32_t range); + uint32_t unquant_astc_endpoint_val(uint32_t packed_val, uint32_t range); + + const uint8_t* get_anchor_indices(uint32_t subsets, uint32_t mode, uint32_t common_pattern, const uint8_t*& pPartition_pattern); + + // BC7 + const uint32_t BC7ENC_BLOCK_SIZE = 16; + + struct bc7_block + { + uint64_t m_qwords[2]; + }; + + struct bc7_optimization_results + { + uint32_t m_mode; + uint32_t m_partition; + uint8_t m_selectors[16]; + uint8_t m_alpha_selectors[16]; + color_quad_u8 m_low[3]; + color_quad_u8 m_high[3]; + uint32_t m_pbits[3][2]; + uint32_t m_index_selector; + uint32_t m_rotation; + }; + + extern const uint32_t g_bc7_weights1[2]; + extern const uint32_t g_bc7_weights2[4]; + extern const uint32_t g_bc7_weights3[8]; + extern const uint32_t g_bc7_weights4[16]; + extern const uint32_t g_astc_weights4[16]; + extern const uint32_t g_astc_weights5[32]; + extern const uint32_t g_astc_weights_3levels[3]; + extern const uint8_t g_bc7_partition1[16]; + extern const uint8_t g_bc7_partition2[64 * 16]; + extern const uint8_t g_bc7_partition3[64 * 16]; + extern const uint8_t g_bc7_table_anchor_index_second_subset[64]; + extern const uint8_t g_bc7_table_anchor_index_third_subset_1[64]; + extern const uint8_t g_bc7_table_anchor_index_third_subset_2[64]; + extern const uint8_t g_bc7_num_subsets[8]; + extern const uint8_t g_bc7_partition_bits[8]; + extern const uint8_t g_bc7_color_index_bitcount[8]; + extern const uint8_t g_bc7_mode_has_p_bits[8]; + extern const uint8_t g_bc7_mode_has_shared_p_bits[8]; + extern const uint8_t g_bc7_color_precision_table[8]; + extern const int8_t g_bc7_alpha_precision_table[8]; + extern const uint8_t g_bc7_alpha_index_bitcount[8]; + + inline bool get_bc7_mode_has_seperate_alpha_selectors(int mode) { return (mode == 4) || (mode == 5); } + inline int get_bc7_color_index_size(int mode, int index_selection_bit) { return g_bc7_color_index_bitcount[mode] + index_selection_bit; } + inline int get_bc7_alpha_index_size(int mode, int index_selection_bit) { return g_bc7_alpha_index_bitcount[mode] - index_selection_bit; } + + struct endpoint_err + { + uint16_t m_error; uint8_t m_lo; uint8_t m_hi; + }; + + extern endpoint_err g_bc7_mode_6_optimal_endpoints[256][2]; // [c][pbit] + const uint32_t BC7ENC_MODE_6_OPTIMAL_INDEX = 5; + + extern endpoint_err g_bc7_mode_5_optimal_endpoints[256]; // [c] + const uint32_t BC7ENC_MODE_5_OPTIMAL_INDEX = 1; + + // Packs a BC7 block from a high-level description. Handles all BC7 modes. + void encode_bc7_block(void* pBlock, const bc7_optimization_results* pResults); + + // Packs an ASTC block + // Constraints: Always 4x4, all subset CEM's must be equal, only tested with LDR CEM's. + bool pack_astc_block(uint32_t* pDst, const astc_block_desc* pBlock, uint32_t mode); + + void pack_astc_solid_block(void* pDst_block, const color32& color); + +#ifdef _DEBUG + int astc_compute_texel_partition(int seed, int x, int y, int z, int partitioncount, bool small_block); +#endif + + struct uastc_block + { + union + { + uint8_t m_bytes[16]; + uint32_t m_dwords[4]; + +#ifndef __EMSCRIPTEN__ + uint64_t m_qwords[2]; +#endif + }; + }; + + struct unpacked_uastc_block + { + astc_block_desc m_astc; + + uint32_t m_mode; + uint32_t m_common_pattern; + + color32 m_solid_color; + + bool m_bc1_hint0; + bool m_bc1_hint1; + + bool m_etc1_flip; + bool m_etc1_diff; + uint32_t m_etc1_inten0; + uint32_t m_etc1_inten1; + + uint32_t m_etc1_bias; + + uint32_t m_etc2_hints; + + uint32_t m_etc1_selector; + uint32_t m_etc1_r, m_etc1_g, m_etc1_b; + }; + + color32 apply_etc1_bias(const color32 &block_color, uint32_t bias, uint32_t limit, uint32_t subblock); + + struct decoder_etc_block; + struct eac_block; + + bool unpack_uastc(uint32_t mode, uint32_t common_pattern, const color32& solid_color, const astc_block_desc& astc, color32* pPixels, bool srgb); + bool unpack_uastc(const unpacked_uastc_block& unpacked_blk, color32* pPixels, bool srgb); + + bool unpack_uastc(const uastc_block& blk, color32* pPixels, bool srgb); + bool unpack_uastc(const uastc_block& blk, unpacked_uastc_block& unpacked, bool undo_blue_contract, bool read_hints = true); + + bool transcode_uastc_to_astc(const uastc_block& src_blk, void* pDst); + + bool transcode_uastc_to_bc7(const unpacked_uastc_block& unpacked_src_blk, bc7_optimization_results& dst_blk); + bool transcode_uastc_to_bc7(const uastc_block& src_blk, bc7_optimization_results& dst_blk); + bool transcode_uastc_to_bc7(const uastc_block& src_blk, void* pDst); + + void transcode_uastc_to_etc1(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst); + bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst); + bool transcode_uastc_to_etc1(const uastc_block& src_blk, void* pDst, uint32_t channel); + + void transcode_uastc_to_etc2_eac_a8(unpacked_uastc_block& unpacked_src_blk, color32 block_pixels[4][4], void* pDst); + bool transcode_uastc_to_etc2_rgba(const uastc_block& src_blk, void* pDst); + + // Packs 16 scalar values to BC4. Same PSNR as stb_dxt's BC4 encoder, around 13% faster. + void encode_bc4(void* pDst, const uint8_t* pPixels, uint32_t stride); + + void encode_bc1_solid_block(void* pDst, uint32_t fr, uint32_t fg, uint32_t fb); + + enum + { + cEncodeBC1HighQuality = 1, + cEncodeBC1HigherQuality = 2, + cEncodeBC1UseSelectors = 4, + }; + void encode_bc1(void* pDst, const uint8_t* pPixels, uint32_t flags); + + // Alternate PCA-free encoder, around 15% faster, same (or slightly higher) avg. PSNR + void encode_bc1_alt(void* pDst, const uint8_t* pPixels, uint32_t flags); + + void transcode_uastc_to_bc1_hint0(const unpacked_uastc_block& unpacked_src_blk, void* pDst); + void transcode_uastc_to_bc1_hint1(const unpacked_uastc_block& unpacked_src_blk, const color32 block_pixels[4][4], void* pDst, bool high_quality); + + bool transcode_uastc_to_bc1(const uastc_block& src_blk, void* pDst, bool high_quality); + bool transcode_uastc_to_bc3(const uastc_block& src_blk, void* pDst, bool high_quality); + bool transcode_uastc_to_bc4(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0); + bool transcode_uastc_to_bc5(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1); + + bool transcode_uastc_to_etc2_eac_r11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0); + bool transcode_uastc_to_etc2_eac_rg11(const uastc_block& src_blk, void* pDst, bool high_quality, uint32_t chan0, uint32_t chan1); + + bool transcode_uastc_to_pvrtc1_4_rgb(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality, bool from_alpha); + bool transcode_uastc_to_pvrtc1_4_rgba(const uastc_block* pSrc_blocks, void* pDst_blocks, uint32_t num_blocks_x, uint32_t num_blocks_y, bool high_quality); + + // uastc_init() MUST be called before using this module. + void uastc_init(); + +} // namespace basist diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_filter.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_filter.cpp deleted file mode 100644 index acddc0ff81..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_filter.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_filter.h" -#include "../sys/regression.h" -#include <map> - -namespace embree -{ - struct parallel_filter_regression_test : public RegressionTest - { - parallel_filter_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - auto pred = [&]( uint32_t v ) { return (v & 0x3) == 0; }; - - for (size_t N=10; N<1000000; N=size_t(2.1*N)) - { - size_t N0 = rand() % N; - - /* initialize array with random numbers */ - std::vector<uint32_t> src(N); - std::map<uint32_t,int> m; - for (size_t i=0; i<N; i++) src[i] = rand(); - - /* count elements up */ - for (size_t i=N0; i<N; i++) - if (pred(src[i])) - m[src[i]] = 0; - for (size_t i=N0; i<N; i++) - if (pred(src[i])) - m[src[i]]++; - - /* filter array */ - //size_t M = sequential_filter(src.data(),N0,N,pred); - size_t M = parallel_filter(src.data(),N0,N,size_t(1024),pred); - - /* check if filtered data is correct */ - for (size_t i=N0; i<M; i++) { - passed &= pred(src[i]); - m[src[i]]--; - } - for (size_t i=N0; i<M; i++) - passed &= (m[src[i]] == 0); - } - - return passed; - } - }; - - parallel_filter_regression_test parallel_filter_regression("parallel_filter_regression"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_for.cpp deleted file mode 100644 index ef070ebc4d..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_for.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_for.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_for_regression_test : public RegressionTest - { - parallel_for_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - const size_t M = 10; - for (size_t N=10; N<10000000; N=size_t(2.1*N)) - { - /* sequentially calculate sum of squares */ - size_t sum0 = 0; - for (size_t i=0; i<N; i++) { - sum0 += i*i; - } - - /* parallel calculation of sum of squares */ - for (size_t m=0; m<M; m++) - { - std::atomic<size_t> sum1(0); - parallel_for( size_t(0), size_t(N), size_t(1024), [&](const range<size_t>& r) - { - size_t s = 0; - for (size_t i=r.begin(); i<r.end(); i++) - s += i*i; - sum1 += s; - }); - passed = sum0 == sum1; - } - } - - return passed; - } - }; - - parallel_for_regression_test parallel_for_regression("parallel_for_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_for_for.cpp deleted file mode 100644 index 0337611b35..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_for_for.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_for_for_regression_test : public RegressionTest - { - parallel_for_for_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - /* create vector with random numbers */ - size_t sum0 = 0; - size_t K = 0; - const size_t M = 1000; - std::vector<std::vector<size_t>* > array2(M); - for (size_t i=0; i<M; i++) { - const size_t N = rand() % 1024; - K+=N; - array2[i] = new std::vector<size_t>(N); - for (size_t j=0; j<N; j++) - sum0 += (*array2[i])[j] = rand(); - } - - /* array to test global index */ - std::vector<atomic<size_t>> verify_k(K); - for (size_t i=0; i<K; i++) verify_k[i].store(0); - - /* add all numbers using parallel_for_for */ - std::atomic<size_t> sum1(0); - parallel_for_for( array2, size_t(1), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k) -> size_t - { - size_t s = 0; - for (size_t i=r.begin(); i<r.end(); i++) { - s += (*v)[i]; - verify_k[k++]++; - } - sum1 += s; - return sum1; - }); - passed &= (sum0 == sum1); - - /* check global index */ - for (size_t i=0; i<K; i++) - passed &= (verify_k[i] == 1); - - /* delete vectors again */ - for (size_t i=0; i<array2.size(); i++) - delete array2[i]; - - return passed; - } - }; - - parallel_for_for_regression_test parallel_for_for_regression("parallel_for_for_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for_prefix_sum.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_for_for_prefix_sum.cpp deleted file mode 100644 index 0169d8e481..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for_prefix_sum.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_for_for_prefix_sum.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_for_for_prefix_sum_regression_test : public RegressionTest - { - parallel_for_for_prefix_sum_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - /* create vector with random numbers */ - const size_t M = 10; - std::vector<atomic<size_t>> flattened; - typedef std::vector<std::vector<size_t>* > ArrayArray; - ArrayArray array2(M); - size_t K = 0; - for (size_t i=0; i<M; i++) { - const size_t N = rand() % 10; - K += N; - array2[i] = new std::vector<size_t>(N); - for (size_t j=0; j<N; j++) - (*array2[i])[j] = rand() % 10; - } - - /* array to test global index */ - std::vector<atomic<size_t>> verify_k(K); - for (size_t i=0; i<K; i++) verify_k[i].store(0); - - ParallelForForPrefixSumState<size_t> state(array2,size_t(1)); - - /* dry run only counts */ - size_t S = parallel_for_for_prefix_sum0( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, size_t i) -> size_t - { - size_t s = 0; - for (size_t i=r.begin(); i<r.end(); i++) { - s += (*v)[i]; - verify_k[k++]++; - } - return s; - }, [](size_t v0, size_t v1) { return v0+v1; }); - - /* create properly sized output array */ - flattened.resize(S); - for (auto& a : flattened) a.store(0); - - /* now we actually fill the flattened array */ - parallel_for_for_prefix_sum1( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, size_t i, const size_t base) -> size_t - { - size_t s = 0; - for (size_t i=r.begin(); i<r.end(); i++) { - for (size_t j=0; j<(*v)[i]; j++) { - flattened[base+s+j]++; - } - s += (*v)[i]; - verify_k[k++]++; - } - return s; - }, [](size_t v0, size_t v1) { return v0+v1; }); - - /* check global index */ - for (size_t i=0; i<K; i++) - passed &= (verify_k[i] == 2); - - /* check if each element was assigned exactly once */ - for (size_t i=0; i<flattened.size(); i++) - passed &= (flattened[i] == 1); - - /* delete arrays again */ - for (size_t i=0; i<array2.size(); i++) - delete array2[i]; - - return passed; - } - }; - - parallel_for_for_prefix_sum_regression_test parallel_for_for_prefix_sum_regression("parallel_for_for_prefix_sum_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_map.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_map.cpp deleted file mode 100644 index 09dc303f81..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_map.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_map.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_map_regression_test : public RegressionTest - { - parallel_map_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - /* create key/value vectors with random numbers */ - const size_t N = 10000; - std::vector<uint32_t> keys(N); - std::vector<uint32_t> vals(N); - for (size_t i=0; i<N; i++) keys[i] = 2*unsigned(i)*647382649; - for (size_t i=0; i<N; i++) std::swap(keys[i],keys[rand()%N]); - for (size_t i=0; i<N; i++) vals[i] = 2*rand(); - - /* create map */ - parallel_map<uint32_t,uint32_t> map; - map.init(keys,vals); - - /* check that all keys are properly mapped */ - for (size_t i=0; i<N; i++) { - const uint32_t* val = map.lookup(keys[i]); - passed &= val && (*val == vals[i]); - } - - /* check that these keys are not in the map */ - for (size_t i=0; i<N; i++) { - passed &= !map.lookup(keys[i]+1); - } - - return passed; - } - }; - - parallel_map_regression_test parallel_map_regression("parallel_map_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_partition.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_partition.cpp deleted file mode 100644 index eb20c4465d..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_partition.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_partition.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_partition_regression_test : public RegressionTest - { - parallel_partition_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - for (size_t i=0; i<100; i++) - { - /* create random permutation */ - size_t N = std::rand() % 1000000; - std::vector<unsigned> array(N); - for (unsigned i=0; i<N; i++) array[i] = i; - for (auto& v : array) std::swap(v,array[std::rand()%array.size()]); - size_t split = std::rand() % (N+1); - - /* perform parallel partitioning */ - size_t left_sum = 0, right_sum = 0; - size_t mid = parallel_partitioning(array.data(),0,array.size(),0,left_sum,right_sum, - [&] ( size_t i ) { return i < split; }, - [] ( size_t& sum, unsigned v) { sum += v; }, - [] ( size_t& sum, size_t v) { sum += v; }, - 128); - - /*serial_partitioning(array.data(),0,array.size(),left_sum,right_sum, - [&] ( size_t i ) { return i < split; }, - [] ( size_t& left_sum, int v) { left_sum += v; });*/ - - /* verify result */ - passed &= mid == split; - passed &= left_sum == split*(split-1)/2; - passed &= right_sum == N*(N-1)/2-left_sum; - for (size_t i=0; i<split; i++) passed &= array[i] < split; - for (size_t i=split; i<N; i++) passed &= array[i] >= split; - } - - return passed; - } - }; - - parallel_partition_regression_test parallel_partition_regression("parallel_partition_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_prefix_sum.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_prefix_sum.cpp deleted file mode 100644 index 685952c3dc..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_prefix_sum.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_prefix_sum.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_prefix_sum_regression_test : public RegressionTest - { - parallel_prefix_sum_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - const size_t M = 10; - - for (size_t N=10; N<10000000; N=size_t(2.1*N)) - { - /* initialize array with random numbers */ - uint32_t sum0 = 0; - std::vector<uint32_t> src(N); - for (size_t i=0; i<N; i++) { - sum0 += src[i] = rand(); - } - - /* calculate parallel prefix sum */ - std::vector<uint32_t> dst(N); - for (auto& v : dst) v = 0; - - for (size_t i=0; i<M; i++) { - uint32_t sum1 = parallel_prefix_sum(src,dst,N,0,std::plus<uint32_t>()); - passed &= (sum0 == sum1); - } - - /* check if prefix sum is correct */ - for (size_t i=0, sum=0; i<N; sum+=src[i++]) - passed &= ((uint32_t)sum == dst[i]); - } - - return passed; - } - }; - - parallel_prefix_sum_regression_test parallel_prefix_sum_regression("parallel_prefix_sum_regression"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.cpp deleted file mode 100644 index 331fe4288e..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_reduce.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_reduce_regression_test : public RegressionTest - { - parallel_reduce_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - const size_t M = 10; - for (size_t N=10; N<10000000; N=size_t(2.1*N)) - { - /* sequentially calculate sum of squares */ - size_t sum0 = 0; - for (size_t i=0; i<N; i++) { - sum0 += i*i; - } - - /* parallel calculation of sum of squares */ - for (size_t m=0; m<M; m++) - { - size_t sum1 = parallel_reduce( size_t(0), size_t(N), size_t(1024), size_t(0), [&](const range<size_t>& r) -> size_t - { - size_t s = 0; - for (size_t i=r.begin(); i<r.end(); i++) - s += i*i; - return s; - }, - [](const size_t v0, const size_t v1) { - return v0+v1; - }); - passed = sum0 == sum1; - } - } - return passed; - } - }; - - parallel_reduce_regression_test parallel_reduce_regression("parallel_reduce_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_set.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_set.cpp deleted file mode 100644 index 20b639c1c9..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_set.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_set.h" -#include "../sys/regression.h" - -namespace embree -{ - struct parallel_set_regression_test : public RegressionTest - { - parallel_set_regression_test(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - - /* create vector with random numbers */ - const size_t N = 10000; - std::vector<uint32_t> unsorted(N); - for (size_t i=0; i<N; i++) unsorted[i] = 2*rand(); - - /* created set from numbers */ - parallel_set<uint32_t> sorted; - sorted.init(unsorted); - - /* check that all elements are in the set */ - for (size_t i=0; i<N; i++) { - passed &= sorted.lookup(unsorted[i]); - } - - /* check that these elements are not in the set */ - for (size_t i=0; i<N; i++) { - passed &= !sorted.lookup(unsorted[i]+1); - } - - return passed; - } - }; - - parallel_set_regression_test parallel_set_regression("parallel_set_regression_test"); -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_sort.cpp b/thirdparty/embree-aarch64/common/algorithms/parallel_sort.cpp deleted file mode 100644 index 5e7ec79ac1..0000000000 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_sort.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#include "parallel_sort.h" -#include "../sys/regression.h" - -namespace embree -{ - template<typename Key> - struct RadixSortRegressionTest : public RegressionTest - { - RadixSortRegressionTest(const char* name) : RegressionTest(name) { - registerRegressionTest(this); - } - - bool run () - { - bool passed = true; - const size_t M = 10; - - for (size_t N=10; N<1000000; N=size_t(2.1*N)) - { - std::vector<Key> src(N); memset(src.data(),0,N*sizeof(Key)); - std::vector<Key> tmp(N); memset(tmp.data(),0,N*sizeof(Key)); - for (size_t i=0; i<N; i++) src[i] = uint64_t(rand())*uint64_t(rand()); - - /* calculate checksum */ - Key sum0 = 0; for (size_t i=0; i<N; i++) sum0 += src[i]; - - /* sort numbers */ - for (size_t i=0; i<M; i++) { - radix_sort<Key>(src.data(),tmp.data(),N); - } - - /* calculate checksum */ - Key sum1 = 0; for (size_t i=0; i<N; i++) sum1 += src[i]; - if (sum0 != sum1) passed = false; - - /* check if numbers are sorted */ - for (size_t i=1; i<N; i++) - passed &= src[i-1] <= src[i]; - } - - return passed; - } - }; - - RadixSortRegressionTest<uint32_t> test_u32("RadixSortRegressionTestU32"); - RadixSortRegressionTest<uint64_t> test_u64("RadixSortRegressionTestU64"); -} diff --git a/thirdparty/embree-aarch64/common/math/AVX2NEON.h b/thirdparty/embree-aarch64/common/math/AVX2NEON.h deleted file mode 100644 index e8698ac56d..0000000000 --- a/thirdparty/embree-aarch64/common/math/AVX2NEON.h +++ /dev/null @@ -1,986 +0,0 @@ -#pragma once - -#include "SSE2NEON.h" - - -#define AVX2NEON_ABI static inline __attribute__((always_inline)) - - -struct __m256d; - -struct __m256 { - __m128 lo,hi; - __m256() {} -}; - - - - -struct __m256i { - __m128i lo,hi; - explicit __m256i(const __m256 a) : lo(__m128i(a.lo)),hi(__m128i(a.hi)) {} - operator __m256() const {__m256 res; res.lo = __m128(lo);res.hi = __m128(hi); return res;} - __m256i() {} -}; - - - - -struct __m256d { - float64x2_t lo,hi; - __m256d() {} - __m256d(const __m256& a) : lo(float64x2_t(a.lo)),hi(float64x2_t(a.hi)) {} - __m256d(const __m256i& a) : lo(float64x2_t(a.lo)),hi(float64x2_t(a.hi)) {} -}; - -#define UNARY_AVX_OP(type,func,basic_func) AVX2NEON_ABI type func(const type& a) {type res;res.lo=basic_func(a.lo);res.hi=basic_func(a.hi);return res;} - - -#define BINARY_AVX_OP(type,func,basic_func) AVX2NEON_ABI type func(const type& a,const type& b) {type res;res.lo=basic_func(a.lo,b.lo);res.hi=basic_func(a.hi,b.hi);return res;} -#define BINARY_AVX_OP_CAST(type,func,basic_func,bdst,bsrc) AVX2NEON_ABI type func(const type& a,const type& b) {type res;res.lo=bdst(basic_func(bsrc(a.lo),bsrc(b.lo)));res.hi=bdst(basic_func(bsrc(a.hi),bsrc(b.hi)));return res;} - -#define TERNARY_AVX_OP(type,func,basic_func) AVX2NEON_ABI type func(const type& a,const type& b,const type& c) {type res;res.lo=basic_func(a.lo,b.lo,c.lo);res.hi=basic_func(a.hi,b.hi,c.hi);return res;} - - -#define CAST_SIMD_TYPE(to,name,from,basic_dst) AVX2NEON_ABI to name(const from& a) { to res; res.lo = basic_dst(a.lo); res.hi=basic_dst(a.hi); return res;} - - - -#define _mm_stream_load_si128 _mm_load_si128 -#define _mm256_stream_load_si256 _mm256_load_si256 - - -AVX2NEON_ABI -__m128 _mm_blend_ps (__m128 a, __m128 b, const int imm8) -{ - __m128 res; - for (int i=0;i<4;i++) - { - if (imm8 & (1<<i)) - { - res[i] = b[i]; - } - else{ - res[i] = a[i]; - } - } - - return res; -} - -AVX2NEON_ABI -__m128i _mm_blend_epi32 (__m128i a, __m128i b, const int imm8) -{ - __m128i res; - for (int i=0;i<4;i++) - { - if (imm8 & (1<<i)) - { - res[i] = b[i]; - } - else{ - res[i] = a[i]; - } - } - return res; -} - -AVX2NEON_ABI -__m128 _mm_cmpngt_ps (__m128 a, __m128 b) -{ - return __m128(vmvnq_s32(__m128i(_mm_cmpgt_ps(a,b)))); -} - - -AVX2NEON_ABI -__m128i _mm_loadl_epi64 (__m128i const* mem_addr) -{ - int64x2_t y; - y[0] = *(int64_t *)mem_addr; - y[1] = 0; - return __m128i(y); -} - -AVX2NEON_ABI -int _mm_movemask_popcnt(__m128 a) -{ - return __builtin_popcount(_mm_movemask_ps(a)); -} - -AVX2NEON_ABI -__m128 _mm_maskload_ps (float const * mem_addr, __m128i mask) -{ - __m128 res; - for (int i=0;i<4;i++) { - if (mask[i] & 0x80000000) res[i] = mem_addr[i]; else res[i] = 0; - } - return res; -} - -AVX2NEON_ABI -void _mm_maskstore_ps (float * mem_addr, __m128i mask, __m128 a) -{ - for (int i=0;i<4;i++) { - if (mask[i] & 0x80000000) mem_addr[i] = a[i]; - } -} - -AVX2NEON_ABI -void _mm_maskstore_epi32 (int * mem_addr, __m128i mask, __m128i a) -{ - for (int i=0;i<4;i++) { - if (mask[i] & 0x80000000) mem_addr[i] = a[i]; - } -} - -AVX2NEON_ABI -__m128 _mm_fnmsub_ps (__m128 a, __m128 b, __m128 c) -{ - return vnegq_f32(vfmaq_f32(c,a,b)); -} - -#define _mm_fnmsub_ss _mm_fnmsub_ps - -AVX2NEON_ABI -__m128 _mm_fnmadd_ps (__m128 a, __m128 b, __m128 c) -{ - return vfmsq_f32(c,a,b); -} - -#define _mm_fnmadd_ss _mm_fnmadd_ps - - -AVX2NEON_ABI -__m128 _mm_broadcast_ss (float const * mem_addr) -{ - return vdupq_n_f32(*mem_addr); -} - - -AVX2NEON_ABI -__m128 _mm_fmsub_ps (__m128 a, __m128 b, __m128 c) -{ - return vfmaq_f32(vnegq_f32(c),a,b); -} - -#define _mm_fmsub_ss _mm_fmsub_ps -#define _mm_fmadd_ps _mm_madd_ps -#define _mm_fmadd_ss _mm_madd_ps - - - -template<int code> -AVX2NEON_ABI float32x4_t dpps_neon(const float32x4_t& a,const float32x4_t& b) -{ - float v; - v = 0; - v += (code & 0x10) ? a[0]*b[0] : 0; - v += (code & 0x20) ? a[1]*b[1] : 0; - v += (code & 0x40) ? a[2]*b[2] : 0; - v += (code & 0x80) ? a[3]*b[3] : 0; - float32x4_t res; - res[0] = (code & 0x1) ? v : 0; - res[1] = (code & 0x2) ? v : 0; - res[2] = (code & 0x4) ? v : 0; - res[3] = (code & 0x8) ? v : 0; - return res; -} - -template<> -inline float32x4_t dpps_neon<0x7f>(const float32x4_t& a,const float32x4_t& b) -{ - float v; - float32x4_t m = _mm_mul_ps(a,b); - m[3] = 0; - v = vaddvq_f32(m); - return _mm_set1_ps(v); -} - -template<> -inline float32x4_t dpps_neon<0xff>(const float32x4_t& a,const float32x4_t& b) -{ - float v; - float32x4_t m = _mm_mul_ps(a,b); - v = vaddvq_f32(m); - return _mm_set1_ps(v); -} - -#define _mm_dp_ps(a,b,c) dpps_neon<c>((a),(b)) - - - -AVX2NEON_ABI -__m128 _mm_cmpnge_ps (__m128 a, __m128 b) -{ - return __m128(vmvnq_s32(__m128i(_mm_cmpge_ps(a,b)))); -} - - -AVX2NEON_ABI -__m128 _mm_permutevar_ps (__m128 a, __m128i b) -{ - __m128 x; - for (int i=0;i<4;i++) - { - x[i] = a[b[i&3]]; - } - return x; -} - -AVX2NEON_ABI -__m256i _mm256_setzero_si256() -{ - __m256i res; - res.lo = res.hi = vdupq_n_s32(0); - return res; -} - -AVX2NEON_ABI -__m256 _mm256_setzero_ps() -{ - __m256 res; - res.lo = res.hi = vdupq_n_f32(0.0f); - return res; -} - -AVX2NEON_ABI -__m256i _mm256_undefined_si256() -{ - return _mm256_setzero_si256(); -} - -AVX2NEON_ABI -__m256 _mm256_undefined_ps() -{ - return _mm256_setzero_ps(); -} - -CAST_SIMD_TYPE(__m256d,_mm256_castps_pd,__m256,float64x2_t) -CAST_SIMD_TYPE(__m256i,_mm256_castps_si256,__m256,__m128i) -CAST_SIMD_TYPE(__m256, _mm256_castsi256_ps, __m256i,__m128) -CAST_SIMD_TYPE(__m256, _mm256_castpd_ps ,__m256d,__m128) -CAST_SIMD_TYPE(__m256d, _mm256_castsi256_pd, __m256i,float64x2_t) -CAST_SIMD_TYPE(__m256i, _mm256_castpd_si256, __m256d,__m128i) - - - - -AVX2NEON_ABI -__m128 _mm256_castps256_ps128 (__m256 a) -{ - return a.lo; -} - -AVX2NEON_ABI -__m256i _mm256_castsi128_si256 (__m128i a) -{ - __m256i res; - res.lo = a ; - res.hi = vdupq_n_s32(0); - return res; -} - -AVX2NEON_ABI -__m128i _mm256_castsi256_si128 (__m256i a) -{ - return a.lo; -} - -AVX2NEON_ABI -__m256 _mm256_castps128_ps256 (__m128 a) -{ - __m256 res; - res.lo = a; - res.hi = vdupq_n_f32(0); - return res; -} - - -AVX2NEON_ABI -__m256 _mm256_broadcast_ss (float const * mem_addr) -{ - __m256 res; - res.lo = res.hi = vdupq_n_f32(*mem_addr); - return res; -} - - - -AVX2NEON_ABI -__m256i _mm256_set_epi32 (int e7, int e6, int e5, int e4, int e3, int e2, int e1, int e0) -{ - __m128i lo = {e0,e1,e2,e3}, hi = {e4,e5,e6,e7}; - __m256i res; - res.lo = lo; res.hi = hi; - return res; - -} - -AVX2NEON_ABI -__m256i _mm256_set1_epi32 (int a) -{ - __m256i res; - res.lo = res.hi = vdupq_n_s32(a); - return res; -} - - - - -AVX2NEON_ABI -int _mm256_movemask_ps(const __m256& v) -{ - return (_mm_movemask_ps(v.hi) << 4) | _mm_movemask_ps(v.lo); -} - -template<int imm8> -AVX2NEON_ABI -__m256 __mm256_permute_ps (const __m256& a) -{ - __m256 res; - res.lo = _mm_shuffle_ps(a.lo,a.lo,imm8); - res.hi = _mm_shuffle_ps(a.hi,a.hi,imm8); - return res; - -} - -#define _mm256_permute_ps(a,c) __mm256_permute_ps<c>(a) - - -template<int imm8> -AVX2NEON_ABI -__m256 __mm256_shuffle_ps (const __m256 a,const __m256& b) -{ - __m256 res; - res.lo = _mm_shuffle_ps(a.lo,b.lo,imm8); - res.hi = _mm_shuffle_ps(a.hi,b.hi,imm8); - return res; - -} - -#define _mm256_shuffle_ps(a,b,c) __mm256_shuffle_ps<c>(a,b) - -AVX2NEON_ABI -__m256i _mm256_set1_epi64x (long long a) -{ - __m256i res; - int64x2_t t = vdupq_n_s64(a); - res.lo = res.hi = __m128i(t); - return res; -} - - -AVX2NEON_ABI -__m256 _mm256_permute2f128_ps (__m256 a, __m256 b, int imm8) -{ - __m256 res; - __m128 tmp; - switch (imm8 & 0x7) - { - case 0: tmp = a.lo; break; - case 1: tmp = a.hi; break; - case 2: tmp = b.lo; break; - case 3: tmp = b.hi; break; - } - if (imm8 & 0x8) - tmp = _mm_setzero_ps(); - - - - res.lo = tmp; - imm8 >>= 4; - - switch (imm8 & 0x7) - { - case 0: tmp = a.lo; break; - case 1: tmp = a.hi; break; - case 2: tmp = b.lo; break; - case 3: tmp = b.hi; break; - } - if (imm8 & 0x8) - tmp = _mm_setzero_ps(); - - res.hi = tmp; - - return res; -} - -AVX2NEON_ABI -__m256 _mm256_moveldup_ps (__m256 a) -{ - __m256 res; - res.lo[0] = res.lo[1] = a.lo[0]; - res.lo[2] = res.lo[3] = a.lo[2]; - res.hi[0] = res.hi[1] = a.hi[0]; - res.hi[2] = res.hi[3] = a.hi[2]; - return res; - -} - -AVX2NEON_ABI -__m256 _mm256_movehdup_ps (__m256 a) -{ - __m256 res; - res.lo[0] = res.lo[1] = a.lo[1]; - res.lo[2] = res.lo[3] = a.lo[3]; - res.hi[0] = res.hi[1] = a.hi[1]; - res.hi[2] = res.hi[3] = a.hi[3]; - return res; -} - -AVX2NEON_ABI -__m256 _mm256_insertf128_ps (__m256 a, __m128 b, int imm8) -{ - __m256 res = a; - if (imm8 & 1) res.hi = b; - else res.lo = b; - return res; -} - - -AVX2NEON_ABI -__m128 _mm256_extractf128_ps (__m256 a, const int imm8) -{ - if (imm8 & 1) return a.hi; - return a.lo; -} - - -AVX2NEON_ABI -__m256d _mm256_movedup_pd (__m256d a) -{ - __m256d res; - res.hi = a.hi; - res.lo[0] = res.lo[1] = a.lo[0]; - return res; -} - -AVX2NEON_ABI -__m256i _mm256_abs_epi32(__m256i a) -{ - __m256i res; - res.lo = vabsq_s32(a.lo); - res.hi = vabsq_s32(a.hi); - return res; -} - -UNARY_AVX_OP(__m256,_mm256_sqrt_ps,_mm_sqrt_ps) -UNARY_AVX_OP(__m256,_mm256_rsqrt_ps,_mm_rsqrt_ps) -UNARY_AVX_OP(__m256,_mm256_rcp_ps,_mm_rcp_ps) -UNARY_AVX_OP(__m256,_mm256_floor_ps,vrndmq_f32) -UNARY_AVX_OP(__m256,_mm256_ceil_ps,vrndpq_f32) - - -BINARY_AVX_OP(__m256i,_mm256_add_epi32,_mm_add_epi32) -BINARY_AVX_OP(__m256i,_mm256_sub_epi32,_mm_sub_epi32) -BINARY_AVX_OP(__m256i,_mm256_mullo_epi32,_mm_mullo_epi32) - -BINARY_AVX_OP(__m256i,_mm256_min_epi32,_mm_min_epi32) -BINARY_AVX_OP(__m256i,_mm256_max_epi32,_mm_max_epi32) -BINARY_AVX_OP_CAST(__m256i,_mm256_min_epu32,vminq_u32,__m128i,uint32x4_t) -BINARY_AVX_OP_CAST(__m256i,_mm256_max_epu32,vmaxq_u32,__m128i,uint32x4_t) - -BINARY_AVX_OP(__m256,_mm256_min_ps,_mm_min_ps) -BINARY_AVX_OP(__m256,_mm256_max_ps,_mm_max_ps) - -BINARY_AVX_OP(__m256,_mm256_add_ps,_mm_add_ps) -BINARY_AVX_OP(__m256,_mm256_mul_ps,_mm_mul_ps) -BINARY_AVX_OP(__m256,_mm256_sub_ps,_mm_sub_ps) -BINARY_AVX_OP(__m256,_mm256_div_ps,_mm_div_ps) - -BINARY_AVX_OP(__m256,_mm256_and_ps,_mm_and_ps) -BINARY_AVX_OP(__m256,_mm256_andnot_ps,_mm_andnot_ps) -BINARY_AVX_OP(__m256,_mm256_or_ps,_mm_or_ps) -BINARY_AVX_OP(__m256,_mm256_xor_ps,_mm_xor_ps) - -BINARY_AVX_OP_CAST(__m256d,_mm256_and_pd,vandq_s64,float64x2_t,int64x2_t) -BINARY_AVX_OP_CAST(__m256d,_mm256_or_pd,vorrq_s64,float64x2_t,int64x2_t) -BINARY_AVX_OP_CAST(__m256d,_mm256_xor_pd,veorq_s64,float64x2_t,int64x2_t) - - - -BINARY_AVX_OP(__m256i,_mm256_and_si256,_mm_and_si128) -BINARY_AVX_OP(__m256i,_mm256_or_si256,_mm_or_si128) -BINARY_AVX_OP(__m256i,_mm256_xor_si256,_mm_xor_si128) - - -BINARY_AVX_OP(__m256,_mm256_unpackhi_ps,_mm_unpackhi_ps) -BINARY_AVX_OP(__m256,_mm256_unpacklo_ps,_mm_unpacklo_ps) -TERNARY_AVX_OP(__m256,_mm256_blendv_ps,_mm_blendv_ps) - - -TERNARY_AVX_OP(__m256,_mm256_fmadd_ps,_mm_fmadd_ps) -TERNARY_AVX_OP(__m256,_mm256_fnmadd_ps,_mm_fnmadd_ps) -TERNARY_AVX_OP(__m256,_mm256_fmsub_ps,_mm_fmsub_ps) -TERNARY_AVX_OP(__m256,_mm256_fnmsub_ps,_mm_fnmsub_ps) - - -BINARY_AVX_OP(__m256i,_mm256_unpackhi_epi32,_mm_unpackhi_epi32) -BINARY_AVX_OP(__m256i,_mm256_unpacklo_epi32,_mm_unpacklo_epi32) - - -BINARY_AVX_OP(__m256i,_mm256_cmpeq_epi32,_mm_cmpeq_epi32) -BINARY_AVX_OP(__m256i,_mm256_cmpgt_epi32,_mm_cmpgt_epi32) -BINARY_AVX_OP(__m256,_mm256_cmpeq_ps,_mm_cmpeq_ps) -BINARY_AVX_OP(__m256,_mm256_cmpneq_ps,_mm_cmpneq_ps) -BINARY_AVX_OP(__m256,_mm256_cmpnlt_ps,_mm_cmpnlt_ps) -BINARY_AVX_OP(__m256,_mm256_cmpngt_ps,_mm_cmpngt_ps) -BINARY_AVX_OP(__m256,_mm256_cmpge_ps,_mm_cmpge_ps) -BINARY_AVX_OP(__m256,_mm256_cmpnge_ps,_mm_cmpnge_ps) -BINARY_AVX_OP(__m256,_mm256_cmplt_ps,_mm_cmplt_ps) -BINARY_AVX_OP(__m256,_mm256_cmple_ps,_mm_cmple_ps) -BINARY_AVX_OP(__m256,_mm256_cmpgt_ps,_mm_cmpgt_ps) -BINARY_AVX_OP(__m256,_mm256_cmpnle_ps,_mm_cmpnle_ps) - - -AVX2NEON_ABI -__m256i _mm256_cvtps_epi32 (__m256 a) -{ - __m256i res; - res.lo = _mm_cvtps_epi32(a.lo); - res.hi = _mm_cvtps_epi32(a.hi); - return res; - -} - -AVX2NEON_ABI -__m256i _mm256_cvttps_epi32 (__m256 a) -{ - __m256i res; - res.lo = _mm_cvttps_epi32(a.lo); - res.hi = _mm_cvttps_epi32(a.hi); - return res; - -} - -AVX2NEON_ABI -__m256 _mm256_loadu_ps (float const * mem_addr) -{ - __m256 res; - res.lo = *(__m128 *)(mem_addr + 0); - res.hi = *(__m128 *)(mem_addr + 4); - return res; -} -#define _mm256_load_ps _mm256_loadu_ps - - -AVX2NEON_ABI -int _mm256_testz_ps (const __m256& a, const __m256& b) -{ - __m256 t = a; - if (&a != &b) - t = _mm256_and_ps(a,b); - - __m128i l = vshrq_n_s32(__m128i(t.lo),31); - __m128i h = vshrq_n_s32(__m128i(t.hi),31); - return vaddvq_s32(vaddq_s32(l,h)) == 0; -} - - -AVX2NEON_ABI -__m256i _mm256_set_epi64x (int64_t e3, int64_t e2, int64_t e1, int64_t e0) -{ - __m256i res; - int64x2_t t0 = {e0,e1}; - int64x2_t t1 = {e2,e3}; - res.lo = __m128i(t0); - res.hi = __m128i(t1); - return res; -} - -AVX2NEON_ABI -__m256d _mm256_setzero_pd () -{ - __m256d res; - res.lo = res.hi = vdupq_n_f64(0); - return res; -} - -AVX2NEON_ABI -int _mm256_movemask_pd (__m256d a) -{ - int res = 0; - uint64x2_t x; - x = uint64x2_t(a.lo); - res |= (x[0] >> 63) ? 1 : 0; - res |= (x[0] >> 63) ? 2 : 0; - x = uint64x2_t(a.hi); - res |= (x[0] >> 63) ? 4 : 0; - res |= (x[0] >> 63) ? 8 : 0; - return res; -} - -AVX2NEON_ABI -__m256i _mm256_cmpeq_epi64 (__m256i a, __m256i b) -{ - __m256i res; - res.lo = __m128i(vceqq_s64(int64x2_t(a.lo),int64x2_t(b.lo))); - res.hi = __m128i(vceqq_s64(int64x2_t(a.hi),int64x2_t(b.hi))); - return res; -} - -AVX2NEON_ABI -__m256i _mm256_cmpeq_pd (__m256d a, __m256d b) -{ - __m256i res; - res.lo = __m128i(vceqq_f64(a.lo,b.lo)); - res.hi = __m128i(vceqq_f64(a.hi,b.hi)); - return res; -} - - -AVX2NEON_ABI -int _mm256_testz_pd (const __m256d& a, const __m256d& b) -{ - __m256d t = a; - - if (&a != &b) - t = _mm256_and_pd(a,b); - - return _mm256_movemask_pd(t) == 0; -} - -AVX2NEON_ABI -__m256d _mm256_blendv_pd (__m256d a, __m256d b, __m256d mask) -{ - __m256d res; - uint64x2_t t = uint64x2_t(mask.lo); - res.lo[0] = (t[0] >> 63) ? b.lo[0] : a.lo[0]; - res.lo[1] = (t[1] >> 63) ? b.lo[1] : a.lo[1]; - t = uint64x2_t(mask.hi); - res.hi[0] = (t[0] >> 63) ? b.hi[0] : a.hi[0]; - res.hi[1] = (t[1] >> 63) ? b.hi[1] : a.hi[1]; - return res; -} - -template<int imm8> -__m256 __mm256_dp_ps (__m256 a, __m256 b) -{ - __m256 res; - res.lo = _mm_dp_ps(a.lo,b.lo,imm8); - res.hi = _mm_dp_ps(a.hi,b.hi,imm8); - return res; -} - -#define _mm256_dp_ps(a,b,c) __mm256_dp_ps<c>(a,b) - -AVX2NEON_ABI -double _mm256_permute4x64_pd_select(__m256d a, const int imm8) -{ - switch (imm8 & 3) { - case 0: - return a.lo[0]; - case 1: - return a.lo[1]; - case 2: - return a.hi[0]; - case 3: - return a.hi[1]; - } - __builtin_unreachable(); - return 0; -} - -AVX2NEON_ABI -__m256d _mm256_permute4x64_pd (__m256d a, const int imm8) -{ - __m256d res; - res.lo[0] = _mm256_permute4x64_pd_select(a,imm8 >> 0); - res.lo[1] = _mm256_permute4x64_pd_select(a,imm8 >> 2); - res.hi[0] = _mm256_permute4x64_pd_select(a,imm8 >> 4); - res.hi[1] = _mm256_permute4x64_pd_select(a,imm8 >> 6); - - return res; -} - -AVX2NEON_ABI -__m256i _mm256_insertf128_si256 (__m256i a, __m128i b, int imm8) -{ - return __m256i(_mm256_insertf128_ps((__m256)a,(__m128)b,imm8)); -} - - -AVX2NEON_ABI -__m256i _mm256_loadu_si256 (__m256i const * mem_addr) -{ - __m256i res; - res.lo = *(__m128i *)((int32_t *)mem_addr + 0); - res.hi = *(__m128i *)((int32_t *)mem_addr + 4); - return res; -} - -#define _mm256_load_si256 _mm256_loadu_si256 - -AVX2NEON_ABI -void _mm256_storeu_ps (float * mem_addr, __m256 a) -{ - *(__m128 *)(mem_addr + 0) = a.lo; - *(__m128 *)(mem_addr + 4) = a.hi; - -} - -#define _mm256_store_ps _mm256_storeu_ps -#define _mm256_stream_ps _mm256_storeu_ps - - -AVX2NEON_ABI -void _mm256_storeu_si256 (__m256i * mem_addr, __m256i a) -{ - *(__m128i *)((int *)mem_addr + 0) = a.lo; - *(__m128i *)((int *)mem_addr + 4) = a.hi; - -} - -#define _mm256_store_si256 _mm256_storeu_si256 - - - -AVX2NEON_ABI -__m256 _mm256_maskload_ps (float const * mem_addr, __m256i mask) -{ - __m256 res; - res.lo = _mm_maskload_ps(mem_addr,mask.lo); - res.hi = _mm_maskload_ps(mem_addr + 4,mask.hi); - return res; - -} - - -AVX2NEON_ABI -__m256i _mm256_cvtepu8_epi32 (__m128i a) -{ - __m256i res; - uint8x16_t x = uint8x16_t(a); - for (int i=0;i<4;i++) - { - res.lo[i] = x[i]; - res.hi[i] = x[i+4]; - } - return res; -} - - -AVX2NEON_ABI -__m256i _mm256_cvtepi8_epi32 (__m128i a) -{ - __m256i res; - int8x16_t x = int8x16_t(a); - for (int i=0;i<4;i++) - { - res.lo[i] = x[i]; - res.hi[i] = x[i+4]; - } - return res; -} - - -AVX2NEON_ABI -__m256i _mm256_cvtepu16_epi32 (__m128i a) -{ - __m256i res; - uint16x8_t x = uint16x8_t(a); - for (int i=0;i<4;i++) - { - res.lo[i] = x[i]; - res.hi[i] = x[i+4]; - } - return res; -} - -AVX2NEON_ABI -__m256i _mm256_cvtepi16_epi32 (__m128i a) -{ - __m256i res; - int16x8_t x = int16x8_t(a); - for (int i=0;i<4;i++) - { - res.lo[i] = x[i]; - res.hi[i] = x[i+4]; - } - return res; -} - - - -AVX2NEON_ABI -void _mm256_maskstore_epi32 (int* mem_addr, __m256i mask, __m256i a) -{ - _mm_maskstore_epi32(mem_addr,mask.lo,a.lo); - _mm_maskstore_epi32(mem_addr + 4,mask.hi,a.hi); -} - -AVX2NEON_ABI -__m256i _mm256_slli_epi32 (__m256i a, int imm8) -{ - __m256i res; - res.lo = _mm_slli_epi32(a.lo,imm8); - res.hi = _mm_slli_epi32(a.hi,imm8); - return res; -} - - -AVX2NEON_ABI -__m256i _mm256_srli_epi32 (__m256i a, int imm8) -{ - __m256i res; - res.lo = _mm_srli_epi32(a.lo,imm8); - res.hi = _mm_srli_epi32(a.hi,imm8); - return res; -} - -AVX2NEON_ABI -__m256i _mm256_srai_epi32 (__m256i a, int imm8) -{ - __m256i res; - res.lo = _mm_srai_epi32(a.lo,imm8); - res.hi = _mm_srai_epi32(a.hi,imm8); - return res; -} - - -AVX2NEON_ABI -__m256i _mm256_sllv_epi32 (__m256i a, __m256i count) -{ - __m256i res; - res.lo = vshlq_s32(a.lo,count.lo); - res.hi = vshlq_s32(a.hi,count.hi); - return res; - -} - - -AVX2NEON_ABI -__m256i _mm256_srav_epi32 (__m256i a, __m256i count) -{ - __m256i res; - res.lo = vshlq_s32(a.lo,vnegq_s32(count.lo)); - res.hi = vshlq_s32(a.hi,vnegq_s32(count.hi)); - return res; - -} - -AVX2NEON_ABI -__m256i _mm256_srlv_epi32 (__m256i a, __m256i count) -{ - __m256i res; - res.lo = __m128i(vshlq_u32(uint32x4_t(a.lo),vnegq_s32(count.lo))); - res.hi = __m128i(vshlq_u32(uint32x4_t(a.hi),vnegq_s32(count.hi))); - return res; - -} - - -AVX2NEON_ABI -__m256i _mm256_permute2f128_si256 (__m256i a, __m256i b, int imm8) -{ - return __m256i(_mm256_permute2f128_ps(__m256(a),__m256(b),imm8)); -} - - -AVX2NEON_ABI -__m128i _mm256_extractf128_si256 (__m256i a, const int imm8) -{ - if (imm8 & 1) return a.hi; - return a.lo; -} - -AVX2NEON_ABI -__m256 _mm256_set1_ps(float x) -{ - __m256 res; - res.lo = res.hi = vdupq_n_f32(x); - return res; -} - -AVX2NEON_ABI -__m256 _mm256_set_ps (float e7, float e6, float e5, float e4, float e3, float e2, float e1, float e0) -{ - __m256 res; - res.lo = _mm_set_ps(e3,e2,e1,e0); - res.hi = _mm_set_ps(e7,e6,e5,e4); - return res; -} - -AVX2NEON_ABI -__m256 _mm256_broadcast_ps (__m128 const * mem_addr) -{ - __m256 res; - res.lo = res.hi = *mem_addr; - return res; -} - -AVX2NEON_ABI -__m256 _mm256_cvtepi32_ps (__m256i a) -{ - __m256 res; - res.lo = _mm_cvtepi32_ps(a.lo); - res.hi = _mm_cvtepi32_ps(a.hi); - return res; -} -AVX2NEON_ABI -void _mm256_maskstore_ps (float * mem_addr, __m256i mask, __m256 a) -{ - for (int i=0;i<4;i++) { - if (mask.lo[i] & 0x80000000) mem_addr[i] = a.lo[i]; - if (mask.hi[i] & 0x80000000) mem_addr[i+4] = a.hi[i]; - } -} - -AVX2NEON_ABI -__m256d _mm256_andnot_pd (__m256d a, __m256d b) -{ - __m256d res; - res.lo = float64x2_t(_mm_andnot_ps(__m128(a.lo),__m128(b.lo))); - res.hi = float64x2_t(_mm_andnot_ps(__m128(a.hi),__m128(b.hi))); - return res; -} - -AVX2NEON_ABI -__m256 _mm256_blend_ps (__m256 a, __m256 b, const int imm8) -{ - __m256 res; - res.lo = _mm_blend_ps(a.lo,b.lo,imm8 & 0xf); - res.hi = _mm_blend_ps(a.hi,b.hi,imm8 >> 4); - return res; - -} - - -AVX2NEON_ABI -__m256i _mm256_blend_epi32 (__m256i a, __m256i b, const int imm8) -{ - __m256i res; - res.lo = _mm_blend_epi32(a.lo,b.lo,imm8 & 0xf); - res.hi = _mm_blend_epi32(a.hi,b.hi,imm8 >> 4); - return res; - -} - -AVX2NEON_ABI -__m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale) -{ - __m256i res; - for (int i=0;i<4;i++) - { - res.lo[i] = *(int *)((char *) base_addr + (vindex.lo[i]*scale)); - res.hi[i] = *(int *)((char *) base_addr + (vindex.hi[i]*scale)); - } - return res; -} - - -AVX2NEON_ABI -__m256i _mm256_mask_i32gather_epi32 (__m256i src, int const* base_addr, __m256i vindex, __m256i mask, const int scale) -{ - __m256i res = _mm256_setzero_si256(); - for (int i=0;i<4;i++) - { - if (mask.lo[i] >> 31) res.lo[i] = *(int *)((char *) base_addr + (vindex.lo[i]*scale)); - if (mask.hi[i] >> 31) res.hi[i] = *(int *)((char *) base_addr + (vindex.hi[i]*scale)); - } - - return res; - -} - - diff --git a/thirdparty/embree-aarch64/common/math/SSE2NEON.h b/thirdparty/embree-aarch64/common/math/SSE2NEON.h deleted file mode 100644 index 2013151d31..0000000000 --- a/thirdparty/embree-aarch64/common/math/SSE2NEON.h +++ /dev/null @@ -1,1753 +0,0 @@ -#ifndef SSE2NEON_H -#define SSE2NEON_H - -// This header file provides a simple API translation layer -// between SSE intrinsics to their corresponding ARM NEON versions -// -// This header file does not (yet) translate *all* of the SSE intrinsics. -// Since this is in support of a specific porting effort, I have only -// included the intrinsics I needed to get my port to work. -// -// Questions/Comments/Feedback send to: jratcliffscarab@gmail.com -// -// If you want to improve or add to this project, send me an -// email and I will probably approve your access to the depot. -// -// Project is located here: -// -// https://github.com/jratcliff63367/sse2neon -// -// Show your appreciation for open source by sending me a bitcoin tip to the following -// address. -// -// TipJar: 1PzgWDSyq4pmdAXRH8SPUtta4SWGrt4B1p : -// https://blockchain.info/address/1PzgWDSyq4pmdAXRH8SPUtta4SWGrt4B1p -// -// -// Contributors to this project are: -// -// John W. Ratcliff : jratcliffscarab@gmail.com -// Brandon Rowlett : browlett@nvidia.com -// Ken Fast : kfast@gdeb.com -// Eric van Beurden : evanbeurden@nvidia.com -// -// -// ********************************************************************************************************************* -// Release notes for January 20, 2017 version: -// -// The unit tests have been refactored. They no longer assert on an error, instead they return a pass/fail condition -// The unit-tests now test 10,000 random float and int values against each intrinsic. -// -// SSE2NEON now supports 95 SSE intrinsics. 39 of them have formal unit tests which have been implemented and -// fully tested on NEON/ARM. The remaining 56 still need unit tests implemented. -// -// A struct is now defined in this header file called 'SIMDVec' which can be used by applications which -// attempt to access the contents of an _m128 struct directly. It is important to note that accessing the __m128 -// struct directly is bad coding practice by Microsoft: @see: https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx -// -// However, some legacy source code may try to access the contents of an __m128 struct directly so the developer -// can use the SIMDVec as an alias for it. Any casting must be done manually by the developer, as you cannot -// cast or otherwise alias the base NEON data type for intrinsic operations. -// -// A bug was found with the _mm_shuffle_ps intrinsic. If the shuffle permutation was not one of the ones with -// a custom/unique implementation causing it to fall through to the default shuffle implementation it was failing -// to return the correct value. This is now fixed. -// -// A bug was found with the _mm_cvtps_epi32 intrinsic. This converts floating point values to integers. -// It was not honoring the correct rounding mode. In SSE the default rounding mode when converting from float to int -// is to use 'round to even' otherwise known as 'bankers rounding'. ARMv7 did not support this feature but ARMv8 does. -// As it stands today, this header file assumes ARMv8. If you are trying to target really old ARM devices, you may get -// a build error. -// -// Support for a number of new intrinsics was added, however, none of them yet have unit-tests to 100% confirm they are -// producing the correct results on NEON. These unit tests will be added as soon as possible. -// -// Here is the list of new instrinsics which have been added: -// -// _mm_cvtss_f32 : extracts the lower order floating point value from the parameter -// _mm_add_ss : adds the scalar single - precision floating point values of a and b -// _mm_div_ps : Divides the four single - precision, floating - point values of a and b. -// _mm_div_ss : Divides the scalar single - precision floating point value of a by b. -// _mm_sqrt_ss : Computes the approximation of the square root of the scalar single - precision floating point value of in. -// _mm_rsqrt_ps : Computes the approximations of the reciprocal square roots of the four single - precision floating point values of in. -// _mm_comilt_ss : Compares the lower single - precision floating point scalar values of a and b using a less than operation -// _mm_comigt_ss : Compares the lower single - precision floating point scalar values of a and b using a greater than operation. -// _mm_comile_ss : Compares the lower single - precision floating point scalar values of a and b using a less than or equal operation. -// _mm_comige_ss : Compares the lower single - precision floating point scalar values of a and b using a greater than or equal operation. -// _mm_comieq_ss : Compares the lower single - precision floating point scalar values of a and b using an equality operation. -// _mm_comineq_s : Compares the lower single - precision floating point scalar values of a and b using an inequality operation -// _mm_unpackhi_epi8 : Interleaves the upper 8 signed or unsigned 8 - bit integers in a with the upper 8 signed or unsigned 8 - bit integers in b. -// _mm_unpackhi_epi16: Interleaves the upper 4 signed or unsigned 16 - bit integers in a with the upper 4 signed or unsigned 16 - bit integers in b. -// -// ********************************************************************************************************************* -/* -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#pragma once - -#define GCC 1 -#define ENABLE_CPP_VERSION 0 - -// enable precise emulation of _mm_min_ps and _mm_max_ps? -// This would slow down the computation a bit, but gives consistent result with x86 SSE2. -// (e.g. would solve a hole or NaN pixel in the rendering result) -#define USE_PRECISE_MINMAX_IMPLEMENTATION (1) - -#if GCC -#define FORCE_INLINE inline __attribute__((always_inline)) -#define ALIGN_STRUCT(x) __attribute__((aligned(x))) -#else -#define FORCE_INLINE inline -#define ALIGN_STRUCT(x) __declspec(align(x)) -#endif - -#include <stdint.h> -#include "arm_neon.h" -#if defined(__aarch64__) -#include "constants.h" -#endif - - -#if !defined(__has_builtin) -#define __has_builtin(x) (0) -#endif - -/*******************************************************/ -/* MACRO for shuffle parameter for _mm_shuffle_ps(). */ -/* Argument fp3 is a digit[0123] that represents the fp*/ -/* from argument "b" of mm_shuffle_ps that will be */ -/* placed in fp3 of result. fp2 is the same for fp2 in */ -/* result. fp1 is a digit[0123] that represents the fp */ -/* from argument "a" of mm_shuffle_ps that will be */ -/* places in fp1 of result. fp0 is the same for fp0 of */ -/* result */ -/*******************************************************/ -#if defined(__aarch64__) -#define _MN_SHUFFLE(fp3,fp2,fp1,fp0) ( (uint8x16_t){ (((fp3)*4)+0), (((fp3)*4)+1), (((fp3)*4)+2), (((fp3)*4)+3), (((fp2)*4)+0), (((fp2)*4)+1), (((fp2)*4)+2), (((fp2)*4)+3), (((fp1)*4)+0), (((fp1)*4)+1), (((fp1)*4)+2), (((fp1)*4)+3), (((fp0)*4)+0), (((fp0)*4)+1), (((fp0)*4)+2), (((fp0)*4)+3) } ) -#define _MF_SHUFFLE(fp3,fp2,fp1,fp0) ( (uint8x16_t){ (((fp3)*4)+0), (((fp3)*4)+1), (((fp3)*4)+2), (((fp3)*4)+3), (((fp2)*4)+0), (((fp2)*4)+1), (((fp2)*4)+2), (((fp2)*4)+3), (((fp1)*4)+16+0), (((fp1)*4)+16+1), (((fp1)*4)+16+2), (((fp1)*4)+16+3), (((fp0)*4)+16+0), (((fp0)*4)+16+1), (((fp0)*4)+16+2), (((fp0)*4)+16+3) } ) -#endif - -#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) (((fp3) << 6) | ((fp2) << 4) | \ - ((fp1) << 2) | ((fp0))) - -typedef float32x4_t __m128; -typedef int32x4_t __m128i; - -// union intended to allow direct access to an __m128 variable using the names that the MSVC -// compiler provides. This union should really only be used when trying to access the members -// of the vector as integer values. GCC/clang allow native access to the float members through -// a simple array access operator (in C since 4.6, in C++ since 4.8). -// -// Ideally direct accesses to SIMD vectors should not be used since it can cause a performance -// hit. If it really is needed however, the original __m128 variable can be aliased with a -// pointer to this union and used to access individual components. The use of this union should -// be hidden behind a macro that is used throughout the codebase to access the members instead -// of always declaring this type of variable. -typedef union ALIGN_STRUCT(16) SIMDVec -{ - float m128_f32[4]; // as floats - do not to use this. Added for convenience. - int8_t m128_i8[16]; // as signed 8-bit integers. - int16_t m128_i16[8]; // as signed 16-bit integers. - int32_t m128_i32[4]; // as signed 32-bit integers. - int64_t m128_i64[2]; // as signed 64-bit integers. - uint8_t m128_u8[16]; // as unsigned 8-bit integers. - uint16_t m128_u16[8]; // as unsigned 16-bit integers. - uint32_t m128_u32[4]; // as unsigned 32-bit integers. - uint64_t m128_u64[2]; // as unsigned 64-bit integers. - double m128_f64[2]; // as signed double -} SIMDVec; - -// ****************************************** -// CPU stuff -// ****************************************** - -typedef SIMDVec __m128d; - -#include <stdlib.h> - -#ifndef _MM_MASK_MASK -#define _MM_MASK_MASK 0x1f80 -#define _MM_MASK_DIV_ZERO 0x200 -#define _MM_FLUSH_ZERO_ON 0x8000 -#define _MM_DENORMALS_ZERO_ON 0x40 -#define _MM_MASK_DENORM 0x100 -#endif -#define _MM_SET_EXCEPTION_MASK(x) -#define _MM_SET_FLUSH_ZERO_MODE(x) -#define _MM_SET_DENORMALS_ZERO_MODE(x) - -FORCE_INLINE void _mm_pause() -{ -} - -FORCE_INLINE void _mm_mfence() -{ - __sync_synchronize(); -} - -#define _MM_HINT_T0 3 -#define _MM_HINT_T1 2 -#define _MM_HINT_T2 1 -#define _MM_HINT_NTA 0 - -FORCE_INLINE void _mm_prefetch(const void* ptr, unsigned int level) -{ - __builtin_prefetch(ptr); - -} - -FORCE_INLINE void* _mm_malloc(int size, int align) -{ - void *ptr; - // align must be multiple of sizeof(void *) for posix_memalign. - if (align < sizeof(void *)) { - align = sizeof(void *); - } - - if ((align % sizeof(void *)) != 0) { - // fallback to malloc - ptr = malloc(size); - } else { - if (posix_memalign(&ptr, align, size)) { - return 0; - } - } - - return ptr; -} - -FORCE_INLINE void _mm_free(void* ptr) -{ - free(ptr); -} - -FORCE_INLINE int _mm_getcsr() -{ - return 0; -} - -FORCE_INLINE void _mm_setcsr(int val) -{ - return; -} - -// ****************************************** -// Set/get methods -// ****************************************** - -// extracts the lower order floating point value from the parameter : https://msdn.microsoft.com/en-us/library/bb514059%28v=vs.120%29.aspx?f=255&MSPPError=-2147217396 -#if defined(__aarch64__) -FORCE_INLINE float _mm_cvtss_f32(const __m128& x) -{ - return x[0]; -} -#else -FORCE_INLINE float _mm_cvtss_f32(__m128 a) -{ - return vgetq_lane_f32(a, 0); -} -#endif - -// Sets the 128-bit value to zero https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx -FORCE_INLINE __m128i _mm_setzero_si128() -{ - return vdupq_n_s32(0); -} - -// Clears the four single-precision, floating-point values. https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setzero_ps(void) -{ - return vdupq_n_f32(0); -} - -// Sets the four single-precision, floating-point values to w. https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set1_ps(float _w) -{ - return vdupq_n_f32(_w); -} - -// Sets the four single-precision, floating-point values to w. https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set_ps1(float _w) -{ - return vdupq_n_f32(_w); -} - -// Sets the four single-precision, floating-point values to the four inputs. https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx -#if defined(__aarch64__) -FORCE_INLINE __m128 _mm_set_ps(const float w, const float z, const float y, const float x) -{ - float32x4_t t = { x, y, z, w }; - return t; -} - -// Sets the four single-precision, floating-point values to the four inputs in reverse order. https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setr_ps(const float w, const float z , const float y , const float x ) -{ - float32x4_t t = { w, z, y, x }; - return t; -} -#else -FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) -{ - float __attribute__((aligned(16))) data[4] = { x, y, z, w }; - return vld1q_f32(data); -} - -// Sets the four single-precision, floating-point values to the four inputs in reverse order. https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setr_ps(float w, float z , float y , float x ) -{ - float __attribute__ ((aligned (16))) data[4] = { w, z, y, x }; - return vld1q_f32(data); -} -#endif - -// Sets the 4 signed 32-bit integer values to i. https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set1_epi32(int _i) -{ - return vdupq_n_s32(_i); -} - -//Set the first lane to of 4 signed single-position, floating-point number to w -#if defined(__aarch64__) -FORCE_INLINE __m128 _mm_set_ss(float _w) -{ - float32x4_t res = {_w, 0, 0, 0}; - return res; -} - -// Sets the 4 signed 32-bit integer values. https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) -{ - int32x4_t t = {i0,i1,i2,i3}; - return t; -} -#else -FORCE_INLINE __m128 _mm_set_ss(float _w) -{ - __m128 val = _mm_setzero_ps(); - return vsetq_lane_f32(_w, val, 0); -} - -// Sets the 4 signed 32-bit integer values. https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) -{ - int32_t __attribute__((aligned(16))) data[4] = { i0, i1, i2, i3 }; - return vld1q_s32(data); -} -#endif - -// Stores four single-precision, floating-point values. https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx -FORCE_INLINE void _mm_store_ps(float *p, __m128 a) -{ - vst1q_f32(p, a); -} - -// Stores four single-precision, floating-point values. https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx -FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) -{ - vst1q_f32(p, a); -} - -FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) -{ - vst1q_s32((int32_t*) p,a); -} - -// Stores four 32-bit integer values as (as a __m128i value) at the address p. https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx -FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a ) -{ - vst1q_s32((int32_t*) p,a); -} - -// Stores the lower single - precision, floating - point value. https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx -FORCE_INLINE void _mm_store_ss(float *p, __m128 a) -{ - vst1q_lane_f32(p, a, 0); -} - -// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx -FORCE_INLINE void _mm_storel_epi64(__m128i* a, __m128i b) -{ - *a = (__m128i)vsetq_lane_s64((int64_t)vget_low_s32(b), *(int64x2_t*)a, 0); -} - -// Loads a single single-precision, floating-point value, copying it into all four words https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx -FORCE_INLINE __m128 _mm_load1_ps(const float * p) -{ - return vld1q_dup_f32(p); -} - -// Loads four single-precision, floating-point values. https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx -FORCE_INLINE __m128 _mm_load_ps(const float * p) -{ - return vld1q_f32(p); -} - -// Loads four single-precision, floating-point values. https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_loadu_ps(const float * p) -{ - // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are equivalent for neon - return vld1q_f32(p); -} - -// Loads an single - precision, floating - point value into the low word and clears the upper three words. https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_load_ss(const float * p) -{ - __m128 result = vdupq_n_f32(0); - return vsetq_lane_f32(*p, result, 0); -} - -FORCE_INLINE __m128i _mm_loadu_si128(__m128i *p) -{ - return (__m128i)vld1q_s32((const int32_t*) p); -} - - -// ****************************************** -// Logic/Binary operations -// ****************************************** - -// Compares for inequality. https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) -{ - return (__m128)vmvnq_s32((__m128i)vceqq_f32(a, b)); -} - -// Computes the bitwise AND-NOT of the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx -FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) -{ - return (__m128)vbicq_s32((__m128i)b, (__m128i)a); // *NOTE* argument swap -} - -// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the 128-bit value in a. https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) -{ - return (__m128i)vbicq_s32(b, a); // *NOTE* argument swap -} - -// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in b. https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) -{ - return (__m128i)vandq_s32(a, b); -} - -// Computes the bitwise AND of the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) -{ - return (__m128)vandq_s32((__m128i)a, (__m128i)b); -} - -// Computes the bitwise OR of the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx -FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) -{ - return (__m128)vorrq_s32((__m128i)a, (__m128i)b); -} - -// Computes bitwise EXOR (exclusive-or) of the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx -FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) -{ - return (__m128)veorq_s32((__m128i)a, (__m128i)b); -} - -// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx -FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) -{ - return (__m128i)vorrq_s32(a, b); -} - -// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx -FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) -{ - return veorq_s32(a, b); -} - -// NEON does not provide this method -// Creates a 4-bit mask from the most significant bits of the four single-precision, floating-point values. https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx -FORCE_INLINE int _mm_movemask_ps(__m128 a) -{ -#if ENABLE_CPP_VERSION // I am not yet convinced that the NEON version is faster than the C version of this - uint32x4_t &ia = *(uint32x4_t *)&a; - return (ia[0] >> 31) | ((ia[1] >> 30) & 2) | ((ia[2] >> 29) & 4) | ((ia[3] >> 28) & 8); -#else - -#if defined(__aarch64__) - uint32x4_t t2 = vandq_u32(vreinterpretq_u32_f32(a), embree::movemask_mask); - return vaddvq_u32(t2); -#else - static const uint32x4_t movemask = { 1, 2, 4, 8 }; - static const uint32x4_t highbit = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; - uint32x4_t t0 = vreinterpretq_u32_f32(a); - uint32x4_t t1 = vtstq_u32(t0, highbit); - uint32x4_t t2 = vandq_u32(t1, movemask); - uint32x2_t t3 = vorr_u32(vget_low_u32(t2), vget_high_u32(t2)); - return vget_lane_u32(t3, 0) | vget_lane_u32(t3, 1); -#endif - -#endif -} - -#if defined(__aarch64__) -FORCE_INLINE int _mm_movemask_popcnt_ps(__m128 a) -{ - uint32x4_t t2 = vandq_u32(vreinterpretq_u32_f32(a), embree::movemask_mask); - t2 = vreinterpretq_u32_u8(vcntq_u8(vreinterpretq_u8_u32(t2))); - return vaddvq_u32(t2); - -} -#endif - -// Takes the upper 64 bits of a and places it in the low end of the result -// Takes the lower 64 bits of b and places it into the high end of the result. -FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b) -{ - return vcombine_f32(vget_high_f32(a), vget_low_f32(b)); -} - -// takes the lower two 32-bit values from a and swaps them and places in high end of result -// takes the higher two 32 bit values from b and swaps them and places in low end of result. -FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b) -{ - return vcombine_f32(vrev64_f32(vget_low_f32(a)), vrev64_f32(vget_high_f32(b))); -} - -// keeps the low 64 bits of b in the low and puts the high 64 bits of a in the high -FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b) -{ - return vcombine_f32(vget_low_f32(a), vget_high_f32(b)); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b) -{ - return vcombine_f32(vdup_n_f32(vgetq_lane_f32(a, 1)), vdup_n_f32(vgetq_lane_f32(b, 0))); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b) -{ - return vcombine_f32(vdup_n_f32(vgetq_lane_f32(a, 2)), vdup_n_f32(vgetq_lane_f32(b, 0))); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b) -{ - return vcombine_f32(vdup_n_f32(vgetq_lane_f32(a, 0)), vdup_n_f32(vgetq_lane_f32(b, 2))); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b) -{ - float32_t a0 = vgetq_lane_f32(a, 0); - float32_t a2 = vgetq_lane_f32(a, 2); - float32x2_t aVal = vdup_n_f32(a2); - aVal = vset_lane_f32(a0, aVal, 1); - return vcombine_f32(aVal, vget_high_f32(b)); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b) -{ - return vcombine_f32(vdup_n_f32(vgetq_lane_f32(a, 3)), vdup_n_f32(vgetq_lane_f32(b, 1))); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b) -{ - float32_t b0 = vgetq_lane_f32(b, 0); - float32_t b2 = vgetq_lane_f32(b, 2); - float32x2_t bVal = vdup_n_f32(b0); - bVal = vset_lane_f32(b2, bVal, 1); - return vcombine_f32(vget_low_f32(a), bVal); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b) -{ - float32_t b0 = vgetq_lane_f32(b, 0); - float32_t b2 = vgetq_lane_f32(b, 2); - float32x2_t bVal = vdup_n_f32(b0); - bVal = vset_lane_f32(b2, bVal, 1); - return vcombine_f32(vrev64_f32(vget_low_f32(a)), bVal); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) -{ - float32_t b0 = vgetq_lane_f32(b, 0); - float32_t b2 = vgetq_lane_f32(b, 2); - float32x2_t bVal = vdup_n_f32(b0); - bVal = vset_lane_f32(b2, bVal, 1); - return vcombine_f32(vget_high_f32(a), bVal); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b) -{ - float32x2_t a21 = vget_high_f32(vextq_f32(a, a, 3)); - float32x2_t b03 = vget_low_f32(vextq_f32(b, b, 3)); - return vcombine_f32(a21, b03); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b) -{ - float32x2_t a03 = vget_low_f32(vextq_f32(a, a, 3)); - float32x2_t b21 = vget_high_f32(vextq_f32(b, b, 3)); - return vcombine_f32(a03, b21); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b) -{ - float32x2_t a10 = vget_low_f32(a); - float32x2_t b10 = vget_low_f32(b); - return vcombine_f32(a10, b10); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b) -{ - float32x2_t a01 = vrev64_f32(vget_low_f32(a)); - float32x2_t b10 = vget_low_f32(b); - return vcombine_f32(a01, b10); -} - -FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b) -{ - float32x2_t a01 = vrev64_f32(vget_low_f32(a)); - float32x2_t b01 = vrev64_f32(vget_low_f32(b)); - return vcombine_f32(a01, b01); -} - -// NEON does not support a general purpose permute intrinsic -// Currently I am not sure whether the C implementation is faster or slower than the NEON version. -// Note, this has to be expanded as a template because the shuffle value must be an immediate value. -// The same is true on SSE as well. -// Selects four specific single-precision, floating-point values from a and b, based on the mask i. https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx -template <int i> -FORCE_INLINE __m128 _mm_shuffle_ps_default(const __m128& a, const __m128& b) -{ -#if ENABLE_CPP_VERSION // I am not convinced that the NEON version is faster than the C version yet. - __m128 ret; - ret[0] = a[i & 0x3]; - ret[1] = a[(i >> 2) & 0x3]; - ret[2] = b[(i >> 4) & 0x03]; - ret[3] = b[(i >> 6) & 0x03]; - return ret; -#else -# if __has_builtin(__builtin_shufflevector) - return __builtin_shufflevector( \ - a, b, (i) & (0x3), ((i) >> 2) & 0x3, - (((i) >> 4) & 0x3) + 4, (((i) >> 6) & 0x3) + 4); -# else - const int i0 = (i >> 0)&0x3; - const int i1 = (i >> 2)&0x3; - const int i2 = (i >> 4)&0x3; - const int i3 = (i >> 6)&0x3; - - if (&a == &b) - { - if (i0 == i1 && i0 == i2 && i0 == i3) - { - return (float32x4_t)vdupq_laneq_f32(a,i0); - } - static const uint8_t tbl[16] = { - (i0*4) + 0,(i0*4) + 1,(i0*4) + 2,(i0*4) + 3, - (i1*4) + 0,(i1*4) + 1,(i1*4) + 2,(i1*4) + 3, - (i2*4) + 0,(i2*4) + 1,(i2*4) + 2,(i2*4) + 3, - (i3*4) + 0,(i3*4) + 1,(i3*4) + 2,(i3*4) + 3 - }; - - return (float32x4_t)vqtbl1q_s8(int8x16_t(b),*(uint8x16_t *)tbl); - - } - else - { - - static const uint8_t tbl[16] = { - (i0*4) + 0,(i0*4) + 1,(i0*4) + 2,(i0*4) + 3, - (i1*4) + 0,(i1*4) + 1,(i1*4) + 2,(i1*4) + 3, - (i2*4) + 0 + 16,(i2*4) + 1 + 16,(i2*4) + 2 + 16,(i2*4) + 3 + 16, - (i3*4) + 0 + 16,(i3*4) + 1 + 16,(i3*4) + 2 + 16,(i3*4) + 3 + 16 - }; - - return float32x4_t(vqtbl2q_s8((int8x16x2_t){int8x16_t(a),int8x16_t(b)},*(uint8x16_t *)tbl)); - } -# endif //builtin(shufflevector) -#endif -} - -template <int i > -FORCE_INLINE __m128 _mm_shuffle_ps_function(const __m128& a, const __m128& b) -{ - switch (i) - { - case _MM_SHUFFLE(1, 0, 3, 2): - return _mm_shuffle_ps_1032(a, b); - break; - case _MM_SHUFFLE(2, 3, 0, 1): - return _mm_shuffle_ps_2301(a, b); - break; - case _MM_SHUFFLE(3, 2, 1, 0): - return _mm_shuffle_ps_3210(a, b); - break; - case _MM_SHUFFLE(0, 0, 1, 1): - return _mm_shuffle_ps_0011(a, b); - break; - case _MM_SHUFFLE(0, 0, 2, 2): - return _mm_shuffle_ps_0022(a, b); - break; - case _MM_SHUFFLE(2, 2, 0, 0): - return _mm_shuffle_ps_2200(a, b); - break; - case _MM_SHUFFLE(3, 2, 0, 2): - return _mm_shuffle_ps_3202(a, b); - break; - case _MM_SHUFFLE(1, 1, 3, 3): - return _mm_shuffle_ps_1133(a, b); - break; - case _MM_SHUFFLE(2, 0, 1, 0): - return _mm_shuffle_ps_2010(a, b); - break; - case _MM_SHUFFLE(2, 0, 0, 1): - return _mm_shuffle_ps_2001(a, b); - break; - case _MM_SHUFFLE(2, 0, 3, 2): - return _mm_shuffle_ps_2032(a, b); - break; - case _MM_SHUFFLE(0, 3, 2, 1): - return _mm_shuffle_ps_0321(a, b); - break; - case _MM_SHUFFLE(2, 1, 0, 3): - return _mm_shuffle_ps_2103(a, b); - break; - case _MM_SHUFFLE(1, 0, 1, 0): - return _mm_shuffle_ps_1010(a, b); - break; - case _MM_SHUFFLE(1, 0, 0, 1): - return _mm_shuffle_ps_1001(a, b); - break; - case _MM_SHUFFLE(0, 1, 0, 1): - return _mm_shuffle_ps_0101(a, b); - break; - } - return _mm_shuffle_ps_default<i>(a, b); -} - -# if __has_builtin(__builtin_shufflevector) -#define _mm_shuffle_ps(a,b,i) _mm_shuffle_ps_default<i>(a,b) -# else -#define _mm_shuffle_ps(a,b,i) _mm_shuffle_ps_function<i>(a,b) -#endif - -// Takes the upper 64 bits of a and places it in the low end of the result -// Takes the lower 64 bits of b and places it into the high end of the result. -FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a, __m128i b) -{ - return vcombine_s32(vget_high_s32(a), vget_low_s32(b)); -} - -// takes the lower two 32-bit values from a and swaps them and places in low end of result -// takes the higher two 32 bit values from b and swaps them and places in high end of result. -FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a, __m128i b) -{ - return vcombine_s32(vrev64_s32(vget_low_s32(a)), vrev64_s32(vget_high_s32(b))); -} - -// shift a right by 32 bits, and put the lower 32 bits of a into the upper 32 bits of b -// when a and b are the same, rotates the least significant 32 bits into the most signficant 32 bits, and shifts the rest down -FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a, __m128i b) -{ - return vextq_s32(a, b, 1); -} - -// shift a left by 32 bits, and put the upper 32 bits of b into the lower 32 bits of a -// when a and b are the same, rotates the most significant 32 bits into the least signficant 32 bits, and shifts the rest up -FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a, __m128i b) -{ - return vextq_s32(a, b, 3); -} - -// gets the lower 64 bits of a, and places it in the upper 64 bits -// gets the lower 64 bits of b and places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a, __m128i b) -{ - return vcombine_s32(vget_low_s32(a), vget_low_s32(a)); -} - -// gets the lower 64 bits of a, and places it in the upper 64 bits -// gets the lower 64 bits of b, swaps the 0 and 1 elements, and places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a, __m128i b) -{ - return vcombine_s32(vrev64_s32(vget_low_s32(a)), vget_low_s32(b)); -} - -// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the upper 64 bits -// gets the lower 64 bits of b, swaps the 0 and 1 elements, and places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a, __m128i b) -{ - return vcombine_s32(vrev64_s32(vget_low_s32(a)), vrev64_s32(vget_low_s32(b))); -} - -FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a, __m128i b) -{ - return vcombine_s32(vdup_n_s32(vgetq_lane_s32(a, 1)), vdup_n_s32(vgetq_lane_s32(b, 2))); -} - -FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a, __m128i b) -{ - return vcombine_s32(vdup_n_s32(vgetq_lane_s32(a, 2)), vrev64_s32(vget_low_s32(b))); -} - -FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a, __m128i b) -{ - return vcombine_s32(vget_high_s32(a), vdup_n_s32(vgetq_lane_s32(b, 3))); -} - -template <int i > -FORCE_INLINE __m128i _mm_shuffle_epi32_default(__m128i a, __m128i b) -{ -#if ENABLE_CPP_VERSION - __m128i ret; - ret[0] = a[i & 0x3]; - ret[1] = a[(i >> 2) & 0x3]; - ret[2] = b[(i >> 4) & 0x03]; - ret[3] = b[(i >> 6) & 0x03]; - return ret; -#else - __m128i ret = vmovq_n_s32(vgetq_lane_s32(a, i & 0x3)); - ret = vsetq_lane_s32(vgetq_lane_s32(a, (i >> 2) & 0x3), ret, 1); - ret = vsetq_lane_s32(vgetq_lane_s32(b, (i >> 4) & 0x3), ret, 2); - ret = vsetq_lane_s32(vgetq_lane_s32(b, (i >> 6) & 0x3), ret, 3); - return ret; -#endif -} - -template <int i > -FORCE_INLINE __m128i _mm_shuffle_epi32_function(__m128i a, __m128i b) -{ - switch (i) - { - case _MM_SHUFFLE(1, 0, 3, 2): return _mm_shuffle_epi_1032(a, b); break; - case _MM_SHUFFLE(2, 3, 0, 1): return _mm_shuffle_epi_2301(a, b); break; - case _MM_SHUFFLE(0, 3, 2, 1): return _mm_shuffle_epi_0321(a, b); break; - case _MM_SHUFFLE(2, 1, 0, 3): return _mm_shuffle_epi_2103(a, b); break; - case _MM_SHUFFLE(1, 0, 1, 0): return _mm_shuffle_epi_1010(a, b); break; - case _MM_SHUFFLE(1, 0, 0, 1): return _mm_shuffle_epi_1001(a, b); break; - case _MM_SHUFFLE(0, 1, 0, 1): return _mm_shuffle_epi_0101(a, b); break; - case _MM_SHUFFLE(2, 2, 1, 1): return _mm_shuffle_epi_2211(a, b); break; - case _MM_SHUFFLE(0, 1, 2, 2): return _mm_shuffle_epi_0122(a, b); break; - case _MM_SHUFFLE(3, 3, 3, 2): return _mm_shuffle_epi_3332(a, b); break; - default: return _mm_shuffle_epi32_default<i>(a, b); - } -} - -template <int i > -FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a) -{ - return vdupq_n_s32(vgetq_lane_s32(a, i)); -} - -template <int i> -FORCE_INLINE __m128i _mm_shuffle_epi32_single(__m128i a) -{ - switch (i) - { - case _MM_SHUFFLE(0, 0, 0, 0): return _mm_shuffle_epi32_splat<0>(a); break; - case _MM_SHUFFLE(1, 1, 1, 1): return _mm_shuffle_epi32_splat<1>(a); break; - case _MM_SHUFFLE(2, 2, 2, 2): return _mm_shuffle_epi32_splat<2>(a); break; - case _MM_SHUFFLE(3, 3, 3, 3): return _mm_shuffle_epi32_splat<3>(a); break; - default: return _mm_shuffle_epi32_function<i>(a, a); - } -} - -// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx -#define _mm_shuffle_epi32(a,i) _mm_shuffle_epi32_single<i>(a) - -template <int i> -FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a) -{ - int16x8_t ret = (int16x8_t)a; - int16x4_t highBits = vget_high_s16(ret); - ret = vsetq_lane_s16(vget_lane_s16(highBits, i & 0x3), ret, 4); - ret = vsetq_lane_s16(vget_lane_s16(highBits, (i >> 2) & 0x3), ret, 5); - ret = vsetq_lane_s16(vget_lane_s16(highBits, (i >> 4) & 0x3), ret, 6); - ret = vsetq_lane_s16(vget_lane_s16(highBits, (i >> 6) & 0x3), ret, 7); - return (__m128i)ret; -} - -// Shuffles the upper 4 signed or unsigned 16 - bit integers in a as specified by imm. https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx -#define _mm_shufflehi_epi16(a,i) _mm_shufflehi_epi16_function<i>(a) - -// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while shifting in zeros. : https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx -//#define _mm_slli_epi32(a, imm) (__m128i)vshlq_n_s32(a,imm) - -// Based on SIMDe -FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, const int imm8) -{ -#if defined(__aarch64__) - const int32x4_t s = vdupq_n_s32(imm8); - return vshlq_s32(a, s); -#else - int32_t __attribute__((aligned(16))) data[4]; - vst1q_s32(data, a); - const int s = (imm8 > 31) ? 0 : imm8; - data[0] = data[0] << s; - data[1] = data[1] << s; - data[2] = data[2] << s; - data[3] = data[3] << s; - - return vld1q_s32(data); -#endif -} - - -//Shifts the 4 signed or unsigned 32-bit integers in a right by count bits while shifting in zeros. https://msdn.microsoft.com/en-us/library/w486zcfa(v=vs.100).aspx -//#define _mm_srli_epi32( a, imm ) (__m128i)vshrq_n_u32((uint32x4_t)a, imm) - -// Based on SIMDe -FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, const int imm8) -{ -#if defined(__aarch64__) - const int shift = (imm8 > 31) ? 0 : imm8; // Unfortunately, we need to check for this case for embree. - const int32x4_t s = vdupq_n_s32(-shift); - return vreinterpretq_s32_u32(vshlq_u32(vreinterpretq_u32_s32(a), s)); -#else - int32_t __attribute__((aligned(16))) data[4]; - vst1q_s32(data, a); - - const int s = (imm8 > 31) ? 0 : imm8; - - data[0] = data[0] >> s; - data[1] = data[1] >> s; - data[2] = data[2] >> s; - data[3] = data[3] >> s; - - return vld1q_s32(data); -#endif -} - - -// Shifts the 4 signed 32 - bit integers in a right by count bits while shifting in the sign bit. https://msdn.microsoft.com/en-us/library/z1939387(v=vs.100).aspx -//#define _mm_srai_epi32( a, imm ) vshrq_n_s32(a, imm) - -// Based on SIMDe -FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, const int imm8) -{ -#if defined(__aarch64__) - const int32x4_t s = vdupq_n_s32(-imm8); - return vshlq_s32(a, s); -#else - int32_t __attribute__((aligned(16))) data[4]; - vst1q_s32(data, a); - const uint32_t m = (uint32_t) ((~0U) << (32 - imm8)); - - for (int i = 0; i < 4; i++) { - uint32_t is_neg = ((uint32_t) (((data[i]) >> 31))); - data[i] = (data[i] >> imm8) | (m * is_neg); - } - - return vld1q_s32(data); -#endif -} - -// Shifts the 128 - bit value in a right by imm bytes while shifting in zeros.imm must be an immediate. https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx -//#define _mm_srli_si128( a, imm ) (__m128i)vmaxq_s8((int8x16_t)a, vextq_s8((int8x16_t)a, vdupq_n_s8(0), imm)) -#define _mm_srli_si128( a, imm ) (__m128i)vextq_s8((int8x16_t)a, vdupq_n_s8(0), (imm)) - -// Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm must be an immediate. https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx -#define _mm_slli_si128( a, imm ) (__m128i)vextq_s8(vdupq_n_s8(0), (int8x16_t)a, 16 - (imm)) - -// NEON does not provide a version of this function, here is an article about some ways to repro the results. -// http://stackoverflow.com/questions/11870910/sse-mm-movemask-epi8-equivalent-method-for-arm-neon -// Creates a 16-bit mask from the most significant bits of the 16 signed or unsigned 8-bit integers in a and zero extends the upper bits. https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx -FORCE_INLINE int _mm_movemask_epi8(__m128i _a) -{ - uint8x16_t input = (uint8x16_t)_a; - const int8_t __attribute__((aligned(16))) xr[8] = { -7, -6, -5, -4, -3, -2, -1, 0 }; - uint8x8_t mask_and = vdup_n_u8(0x80); - int8x8_t mask_shift = vld1_s8(xr); - - uint8x8_t lo = vget_low_u8(input); - uint8x8_t hi = vget_high_u8(input); - - lo = vand_u8(lo, mask_and); - lo = vshl_u8(lo, mask_shift); - - hi = vand_u8(hi, mask_and); - hi = vshl_u8(hi, mask_shift); - - lo = vpadd_u8(lo, lo); - lo = vpadd_u8(lo, lo); - lo = vpadd_u8(lo, lo); - - hi = vpadd_u8(hi, hi); - hi = vpadd_u8(hi, hi); - hi = vpadd_u8(hi, hi); - - return ((hi[0] << 8) | (lo[0] & 0xFF)); -} - - -// ****************************************** -// Math operations -// ****************************************** - -// Subtracts the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) -{ - return vsubq_f32(a, b); -} - -FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) -{ - return vsubq_f32(a, b); -} - -// Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or unsigned 32-bit integers of a. https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx -FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) -{ - return vsubq_s32(a, b); -} - -// Adds the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx -FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) -{ - return vaddq_f32(a, b); -} - -// adds the scalar single-precision floating point values of a and b. https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx -FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) -{ - const float32_t b0 = vgetq_lane_f32(b, 0); - float32x4_t value = vdupq_n_f32(0); - - //the upper values in the result must be the remnants of <a>. - value = vsetq_lane_f32(b0, value, 0); - return vaddq_f32(a, value); -} - -// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or unsigned 32-bit integers in b. https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) -{ - return vaddq_s32(a, b); -} - -// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or unsigned 16-bit integers in b. https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) -{ - return (__m128i)vaddq_s16((int16x8_t)a, (int16x8_t)b); -} - -// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or unsigned 16-bit integers from b. https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) -{ - return (__m128i)vmulq_s16((int16x8_t)a, (int16x8_t)b); -} - -// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or unsigned 32-bit integers from b. https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mullo_epi32 (__m128i a, __m128i b) -{ - return (__m128i)vmulq_s32((int32x4_t)a,(int32x4_t)b); -} - -// Multiplies the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx -FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) -{ - return vmulq_f32(a, b); -} - -FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) -{ - return vmulq_f32(a, b); -} - -// Computes the approximations of reciprocals of the four single-precision, floating-point values of a. https://msdn.microsoft.com/en-us/library/vstudio/796k1tty(v=vs.100).aspx -FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) -{ -#if defined(BUILD_IOS) - return vdivq_f32(vdupq_n_f32(1.0f),in); - -#endif - // Get an initial estimate of 1/in. - float32x4_t reciprocal = vrecpeq_f32(in); - - // We only return estimated 1/in. - // Newton-Raphon iteration shold be done in the outside of _mm_rcp_ps(). - - // TODO(LTE): We could delete these ifdef? - reciprocal = vmulq_f32(vrecpsq_f32(in, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(in, reciprocal), reciprocal); - return reciprocal; - -} - -FORCE_INLINE __m128 _mm_rcp_ss(__m128 in) -{ - float32x4_t value; - float32x4_t result = in; - - value = _mm_rcp_ps(in); - return vsetq_lane_f32(vgetq_lane_f32(value, 0), result, 0); -} - -// Divides the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx -FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) -{ -#if defined(BUILD_IOS) - return vdivq_f32(a,b); -#else - float32x4_t reciprocal = _mm_rcp_ps(b); - - reciprocal = vmulq_f32(vrecpsq_f32(b, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(b, reciprocal), reciprocal); - - // Add one more round of newton-raphson since NEON's reciprocal estimation has less accuracy compared to SSE2's rcp. - reciprocal = vmulq_f32(vrecpsq_f32(b, reciprocal), reciprocal); - - // Another round for safety - reciprocal = vmulq_f32(vrecpsq_f32(b, reciprocal), reciprocal); - - - return vmulq_f32(a, reciprocal); -#endif -} - -// Divides the scalar single-precision floating point value of a by b. https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx -FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) -{ - float32x4_t value; - float32x4_t result = a; - value = _mm_div_ps(a, b); - return vsetq_lane_f32(vgetq_lane_f32(value, 0), result, 0); -} - -// Computes the approximations of the reciprocal square roots of the four single-precision floating point values of in. https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx -FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) -{ - - float32x4_t value = vrsqrteq_f32(in); - - // TODO: We must debug and ensure that rsqrt(0) and rsqrt(-0) yield proper values. - // Related code snippets can be found here: https://cpp.hotexamples.com/examples/-/-/vrsqrteq_f32/cpp-vrsqrteq_f32-function-examples.html - // If we adapt this function, we might be able to avoid special zero treatment in _mm_sqrt_ps - - value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(in, value), value)); - value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(in, value), value)); - - // one more round to get better precision - value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(in, value), value)); - - // another round for safety - value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(in, value), value)); - - return value; -} - -FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) -{ - float32x4_t result = in; - - __m128 value = _mm_rsqrt_ps(in); - - return vsetq_lane_f32(vgetq_lane_f32(value, 0), result, 0); -} - - -// Computes the approximations of square roots of the four single-precision, floating-point values of a. First computes reciprocal square roots and then reciprocals of the four values. https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) -{ -#if defined(BUILD_IOS) - return vsqrtq_f32(in); -#else - __m128 reciprocal = _mm_rsqrt_ps(in); - - // We must treat sqrt(in == 0) in a special way. At this point reciprocal contains gargabe due to vrsqrteq_f32(0) returning +inf. - // We assign 0 to reciprocal wherever required. - const float32x4_t vzero = vdupq_n_f32(0.0f); - const uint32x4_t mask = vceqq_f32(in, vzero); - reciprocal = vbslq_f32(mask, vzero, reciprocal); - - // sqrt(x) = x * (1 / sqrt(x)) - return vmulq_f32(in, reciprocal); -#endif -} - -// Computes the approximation of the square root of the scalar single-precision floating point value of in. https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) -{ - float32x4_t value; - float32x4_t result = in; - - value = _mm_sqrt_ps(in); - return vsetq_lane_f32(vgetq_lane_f32(value, 0), result, 0); -} - - -// Computes the maximums of the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx -FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) -{ -#if USE_PRECISE_MINMAX_IMPLEMENTATION - return vbslq_f32(vcltq_f32(b,a),a,b); -#else - // Faster, but would give inconsitent rendering(e.g. holes, NaN pixels) - return vmaxq_f32(a, b); -#endif -} - -// Computes the minima of the four single-precision, floating-point values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) -{ -#if USE_PRECISE_MINMAX_IMPLEMENTATION - return vbslq_f32(vcltq_f32(a,b),a,b); -#else - // Faster, but would give inconsitent rendering(e.g. holes, NaN pixels) - return vminq_f32(a, b); -#endif -} - -// Computes the maximum of the two lower scalar single-precision floating point values of a and b. https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) -{ - float32x4_t value; - float32x4_t result = a; - - value = _mm_max_ps(a, b); - return vsetq_lane_f32(vgetq_lane_f32(value, 0), result, 0); -} - -// Computes the minimum of the two lower scalar single-precision floating point values of a and b. https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx -FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) -{ - float32x4_t value; - float32x4_t result = a; - - - value = _mm_min_ps(a, b); - return vsetq_lane_f32(vgetq_lane_f32(value, 0), result, 0); -} - -// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 signed 16-bit integers from b. https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx -FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) -{ - return (__m128i)vminq_s16((int16x8_t)a, (int16x8_t)b); -} - -// epi versions of min/max -// Computes the pariwise maximums of the four signed 32-bit integer values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx -FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b ) -{ - return vmaxq_s32(a,b); -} - -// Computes the pariwise minima of the four signed 32-bit integer values of a and b. https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx -FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b ) -{ - return vminq_s32(a,b); -} - -// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit integers from b. https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) -{ - int16x8_t ret = vqdmulhq_s16((int16x8_t)a, (int16x8_t)b); - ret = vshrq_n_s16(ret, 1); - return (__m128i)ret; -} - -// Computes pairwise add of each argument as single-precision, floating-point values a and b. -//https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx -FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b ) -{ -#if defined(__aarch64__) - return vpaddq_f32(a,b); -#else -// This does not work, no vpaddq... -// return (__m128) vpaddq_f32(a,b); - // - // get two f32x2_t values from a - // do vpadd - // put result in low half of f32x4 result - // - // get two f32x2_t values from b - // do vpadd - // put result in high half of f32x4 result - // - // combine - return vcombine_f32( vpadd_f32( vget_low_f32(a), vget_high_f32(a) ), vpadd_f32( vget_low_f32(b), vget_high_f32(b) ) ); -#endif -} - -// ****************************************** -// Compare operations -// ****************************************** - -// Compares for less than https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) -{ - return (__m128)vcltq_f32(a, b); -} - -FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) -{ - return (__m128) vmvnq_s32((__m128i)_mm_cmplt_ps(a,b)); -} - -// Compares for greater than. https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) -{ - return (__m128)vcgtq_f32(a, b); -} - -FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) -{ - return (__m128) _mm_cmpgt_ps(a,b); -} - - -// Compares for greater than or equal. https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) -{ - return (__m128)vcgeq_f32(a, b); -} - -// Compares for less than or equal. https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) -{ - return (__m128)vcleq_f32(a, b); -} - -// Compares for equality. https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) -{ - return (__m128)vceqq_f32(a, b); -} - -// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers in b for less than. https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) -{ - return (__m128i)vcltq_s32(a, b); -} - -FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) -{ - return (__m128i) vceqq_s32(a,b); -} - -// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers in b for greater than. https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) -{ - return (__m128i)vcgtq_s32(a, b); -} - -// Compares the four 32-bit floats in a and b to check if any values are NaN. Ordered compare between each value returns true for "orderable" and false for "not orderable" (NaN). https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx -// see also: -// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean -// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics -FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b ) -{ - // Note: NEON does not have ordered compare builtin - // Need to compare a eq a and b eq b to check for NaN - // Do AND of results to get final - return (__m128) vreinterpretq_f32_u32( vandq_u32( vceqq_f32(a,a), vceqq_f32(b,b) ) ); -} - -// Compares the lower single-precision floating point scalar values of a and b using a less than operation. : https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx -FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) -{ - uint32x4_t value; - - value = vcltq_f32(a, b); - return vgetq_lane_u32(value, 0); -} - -// Compares the lower single-precision floating point scalar values of a and b using a greater than operation. : https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx -FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) -{ - uint32x4_t value; - - value = vcgtq_f32(a, b); - return vgetq_lane_u32(value, 0); -} - -// Compares the lower single-precision floating point scalar values of a and b using a less than or equal operation. : https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx -FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) -{ - uint32x4_t value; - - value = vcleq_f32(a, b); - return vgetq_lane_u32(value, 0); -} - -// Compares the lower single-precision floating point scalar values of a and b using a greater than or equal operation. : https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx -FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) -{ - uint32x4_t value; - - value = vcgeq_f32(a, b); - return vgetq_lane_u32(value, 0); -} - -// Compares the lower single-precision floating point scalar values of a and b using an equality operation. : https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx -FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) -{ - uint32x4_t value; - - value = vceqq_f32(a, b); - return vgetq_lane_u32(value, 0); -} - -// Compares the lower single-precision floating point scalar values of a and b using an inequality operation. : https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx -FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) -{ - uint32x4_t value; - - value = vceqq_f32(a, b); - return !vgetq_lane_u32(value, 0); -} - -// according to the documentation, these intrinsics behave the same as the non-'u' versions. We'll just alias them here. -#define _mm_ucomilt_ss _mm_comilt_ss -#define _mm_ucomile_ss _mm_comile_ss -#define _mm_ucomigt_ss _mm_comigt_ss -#define _mm_ucomige_ss _mm_comige_ss -#define _mm_ucomieq_ss _mm_comieq_ss -#define _mm_ucomineq_ss _mm_comineq_ss - -// ****************************************** -// Conversions -// ****************************************** - -// Converts the four single-precision, floating-point values of a to signed 32-bit integer values using truncate. https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) -{ - return vcvtq_s32_f32(a); -} - -// Converts the four signed 32-bit integer values of a to single-precision, floating-point values https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) -{ - return vcvtq_f32_s32(a); -} - -// Converts the four single-precision, floating-point values of a to signed 32-bit integer values. https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx -// *NOTE*. The default rounding mode on SSE is 'round to even', which ArmV7 does not support! -// It is supported on ARMv8 however. -FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) -{ -#if 1 - return vcvtnq_s32_f32(a); -#else - __m128 half = vdupq_n_f32(0.5f); - const __m128 sign = vcvtq_f32_u32((vshrq_n_u32(vreinterpretq_u32_f32(a), 31))); - const __m128 aPlusHalf = vaddq_f32(a, half); - const __m128 aRound = vsubq_f32(aPlusHalf, sign); - return vcvtq_s32_f32(aRound); -#endif -} - -// Moves the least significant 32 bits of a to a 32-bit integer. https://msdn.microsoft.com/en-us/library/5z7a9642%28v=vs.90%29.aspx -FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) -{ - return vgetq_lane_s32(a, 0); -} - -// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, zero extending the upper bits. https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) -{ - __m128i result = vdupq_n_s32(0); - return vsetq_lane_s32(a, result, 0); -} - - -// Applies a type cast to reinterpret four 32-bit floating point values passed in as a 128-bit parameter as packed 32-bit integers. https://msdn.microsoft.com/en-us/library/bb514099.aspx -FORCE_INLINE __m128i _mm_castps_si128(__m128 a) -{ -#if defined(__aarch64__) - return (__m128i)a; -#else - return *(const __m128i *)&a; -#endif -} - -// Applies a type cast to reinterpret four 32-bit integers passed in as a 128-bit parameter as packed 32-bit floating point values. https://msdn.microsoft.com/en-us/library/bb514029.aspx -FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) -{ -#if defined(__aarch64__) - return (__m128)a; -#else - return *(const __m128 *)&a; -#endif -} - -// Loads 128-bit value. : https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx -FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) -{ - return vld1q_s32((int32_t *)p); -} - -FORCE_INLINE __m128d _mm_castps_pd(const __m128 a) -{ - return *(const __m128d *)&a; -} - -FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) -{ - return *(const __m128d *)&a; -} -// ****************************************** -// Miscellaneous Operations -// ****************************************** - -// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and saturates. https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) -{ - return (__m128i)vcombine_s8(vqmovn_s16((int16x8_t)a), vqmovn_s16((int16x8_t)b)); -} - -// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned integers and saturates. https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx -FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) -{ - return (__m128i)vcombine_u8(vqmovun_s16((int16x8_t)a), vqmovun_s16((int16x8_t)b)); -} - -// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers and saturates. https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) -{ - return (__m128i)vcombine_s16(vqmovn_s32(a), vqmovn_s32(b)); -} - -// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower 8 signed or unsigned 8-bit integers in b. https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) -{ - int8x8_t a1 = (int8x8_t)vget_low_s16((int16x8_t)a); - int8x8_t b1 = (int8x8_t)vget_low_s16((int16x8_t)b); - - int8x8x2_t result = vzip_s8(a1, b1); - - return (__m128i)vcombine_s8(result.val[0], result.val[1]); -} - -// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the lower 4 signed or unsigned 16-bit integers in b. https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) -{ - int16x4_t a1 = vget_low_s16((int16x8_t)a); - int16x4_t b1 = vget_low_s16((int16x8_t)b); - - int16x4x2_t result = vzip_s16(a1, b1); - - return (__m128i)vcombine_s16(result.val[0], result.val[1]); -} - -// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the lower 2 signed or unsigned 32 - bit integers in b. https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) -{ - int32x2_t a1 = vget_low_s32(a); - int32x2_t b1 = vget_low_s32(b); - - int32x2x2_t result = vzip_s32(a1, b1); - - return vcombine_s32(result.val[0], result.val[1]); -} - -// Selects and interleaves the lower two single-precision, floating-point values from a and b. https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) -{ - float32x2x2_t result = vzip_f32(vget_low_f32(a), vget_low_f32(b)); - return vcombine_f32(result.val[0], result.val[1]); -} - -// Selects and interleaves the upper two single-precision, floating-point values from a and b. https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) -{ - float32x2x2_t result = vzip_f32(vget_high_f32(a), vget_high_f32(b)); - return vcombine_f32(result.val[0], result.val[1]); -} - -// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper 8 signed or unsigned 8-bit integers in b. https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) -{ - int8x8_t a1 = (int8x8_t)vget_high_s16((int16x8_t)a); - int8x8_t b1 = (int8x8_t)vget_high_s16((int16x8_t)b); - - int8x8x2_t result = vzip_s8(a1, b1); - - return (__m128i)vcombine_s8(result.val[0], result.val[1]); -} - -// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the upper 4 signed or unsigned 16-bit integers in b. https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) -{ - int16x4_t a1 = vget_high_s16((int16x8_t)a); - int16x4_t b1 = vget_high_s16((int16x8_t)b); - - int16x4x2_t result = vzip_s16(a1, b1); - - return (__m128i)vcombine_s16(result.val[0], result.val[1]); -} - -// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the upper 2 signed or unsigned 32-bit integers in b. https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) -{ - int32x2_t a1 = vget_high_s32(a); - int32x2_t b1 = vget_high_s32(b); - - int32x2x2_t result = vzip_s32(a1, b1); - - return vcombine_s32(result.val[0], result.val[1]); -} - -// Extracts the selected signed or unsigned 16-bit integer from a and zero extends. https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx -#define _mm_extract_epi16( a, imm ) vgetq_lane_s16((int16x8_t)a, imm) - -// ****************************************** -// Streaming Extensions -// ****************************************** - -// Guarantees that every preceding store is globally visible before any subsequent store. https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx -FORCE_INLINE void _mm_sfence(void) -{ - __sync_synchronize(); -} - -// Stores the data in a to the address p without polluting the caches. If the cache line containing address p is already in the cache, the cache will be updated.Address p must be 16 - byte aligned. https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx -FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) -{ - *p = a; -} - -// Cache line containing p is flushed and invalidated from all caches in the coherency domain. : https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx -FORCE_INLINE void _mm_clflush(void const*p) -{ - // no corollary for Neon? -} - -FORCE_INLINE __m128i _mm_set_epi64x(int64_t a, int64_t b) -{ - // Stick to the flipped behavior of x86. - int64_t __attribute__((aligned(16))) data[2] = { b, a }; - return (__m128i)vld1q_s64(data); -} - -FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) -{ - return (__m128i)vmovq_n_s64(_i); -} - -#if defined(__aarch64__) -FORCE_INLINE __m128 _mm_blendv_ps(__m128 a, __m128 b, __m128 c) -{ - int32x4_t mask = vshrq_n_s32(__m128i(c),31); - return vbslq_f32( uint32x4_t(mask), b, a); -} - -FORCE_INLINE __m128i _mm_load4epu8_epi32(__m128i *ptr) -{ - uint8x8_t t0 = vld1_u8((uint8_t*)ptr); - uint16x8_t t1 = vmovl_u8(t0); - uint32x4_t t2 = vmovl_u16(vget_low_u16(t1)); - return vreinterpretq_s32_u32(t2); -} - -FORCE_INLINE __m128i _mm_load4epu16_epi32(__m128i *ptr) -{ - uint16x8_t t0 = vld1q_u16((uint16_t*)ptr); - uint32x4_t t1 = vmovl_u16(vget_low_u16(t0)); - return vreinterpretq_s32_u32(t1); -} - -FORCE_INLINE __m128i _mm_load4epi8_f32(__m128i *ptr) -{ - int8x8_t t0 = vld1_s8((int8_t*)ptr); - int16x8_t t1 = vmovl_s8(t0); - int32x4_t t2 = vmovl_s16(vget_low_s16(t1)); - float32x4_t t3 = vcvtq_f32_s32(t2); - return vreinterpretq_s32_f32(t3); -} - -FORCE_INLINE __m128i _mm_load4epu8_f32(__m128i *ptr) -{ - uint8x8_t t0 = vld1_u8((uint8_t*)ptr); - uint16x8_t t1 = vmovl_u8(t0); - uint32x4_t t2 = vmovl_u16(vget_low_u16(t1)); - return vreinterpretq_s32_u32(t2); -} - -FORCE_INLINE __m128i _mm_load4epi16_f32(__m128i *ptr) -{ - int16x8_t t0 = vld1q_s16((int16_t*)ptr); - int32x4_t t1 = vmovl_s16(vget_low_s16(t0)); - float32x4_t t2 = vcvtq_f32_s32(t1); - return vreinterpretq_s32_f32(t2); -} - -FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) -{ - return (__m128i)vcombine_u8(vqmovun_s16((int16x8_t)a), vqmovun_s16((int16x8_t)b)); -} - -FORCE_INLINE __m128i _mm_stream_load_si128(__m128i* ptr) -{ - // No non-temporal load on a single register on ARM. - return vreinterpretq_s32_u8(vld1q_u8((uint8_t*)ptr)); -} - -FORCE_INLINE void _mm_stream_ps(float* ptr, __m128i a) -{ - // No non-temporal store on a single register on ARM. - vst1q_f32((float*)ptr, vreinterpretq_f32_s32(a)); -} - -FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) -{ - return vreinterpretq_s32_u32(vminq_u32(vreinterpretq_u32_s32(a), vreinterpretq_u32_s32(b))); -} - -FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) -{ - return vreinterpretq_s32_u32(vmaxq_u32(vreinterpretq_u32_s32(a), vreinterpretq_u32_s32(b))); -} - -FORCE_INLINE __m128 _mm_abs_ps(__m128 a) -{ - return vabsq_f32(a); -} - -FORCE_INLINE __m128 _mm_madd_ps(__m128 a, __m128 b, __m128 c) -{ - return vmlaq_f32(c, a, b); -} - -FORCE_INLINE __m128 _mm_msub_ps(__m128 a, __m128 b, __m128 c) -{ - return vmlsq_f32(c, a, b); -} - -FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) -{ - return vabsq_s32(a); -} -#endif //defined(__aarch64__) - -// Count the number of bits set to 1 in unsigned 32-bit integer a, and -// return that count in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 -FORCE_INLINE int _mm_popcnt_u32(unsigned int a) -{ - return (int)vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t)a))); -} - -// Count the number of bits set to 1 in unsigned 64-bit integer a, and -// return that count in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 -FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) -{ - return (int64_t)vaddlv_u8(vcnt_u8(vcreate_u8(a))); -} - -#endif diff --git a/thirdparty/embree-aarch64/common/math/constants.cpp b/thirdparty/embree-aarch64/common/math/constants.cpp deleted file mode 100644 index eeff131664..0000000000 --- a/thirdparty/embree-aarch64/common/math/constants.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#if defined(__aarch64__) -#include <arm_neon.h> -#endif - -#include "constants.h" - -namespace embree -{ - TrueTy True; - FalseTy False; - ZeroTy zero; - OneTy one; - NegInfTy neg_inf; - PosInfTy inf; - PosInfTy pos_inf; - NaNTy nan; - UlpTy ulp; - PiTy pi; - OneOverPiTy one_over_pi; - TwoPiTy two_pi; - OneOverTwoPiTy one_over_two_pi; - FourPiTy four_pi; - OneOverFourPiTy one_over_four_pi; - StepTy step; - ReverseStepTy reverse_step; - EmptyTy empty; - UndefinedTy undefined; - -#if defined(__aarch64__) -const uint32x4_t movemask_mask = { 1, 2, 4, 8 }; -const uint32x4_t vzero = { 0, 0, 0, 0 }; -const uint32x4_t v0x80000000 = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; -const uint32x4_t v0x7fffffff = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }; -const uint32x4_t v000F = { 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF }; -const uint32x4_t v00F0 = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000 }; -const uint32x4_t v00FF = { 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; -const uint32x4_t v0F00 = { 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000 }; -const uint32x4_t v0F0F = { 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }; -const uint32x4_t v0FF0 = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; -const uint32x4_t v0FFF = { 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; -const uint32x4_t vF000 = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }; -const uint32x4_t vF00F = { 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF }; -const uint32x4_t vF0F0 = { 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000 }; -const uint32x4_t vF0FF = { 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF }; -const uint32x4_t vFF00 = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 }; -const uint32x4_t vFF0F = { 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF }; -const uint32x4_t vFFF0 = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }; -const uint32x4_t vFFFF = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; -const uint8x16_t v0022 = {0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11}; -const uint8x16_t v1133 = {4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15}; -const uint8x16_t v0101 = {0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7}; -const float32x4_t vOne = { 1.0f, 1.0f, 1.0f, 1.0f }; -const float32x4_t vmOne = { -1.0f, -1.0f, -1.0f, -1.0f }; -const float32x4_t vInf = { INFINITY, INFINITY, INFINITY, INFINITY }; -const float32x4_t vmInf = { -INFINITY, -INFINITY, -INFINITY, -INFINITY }; -#endif - -} diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulergcd.h b/thirdparty/embree-aarch64/common/tasking/taskschedulergcd.h deleted file mode 100644 index d31f8bb478..0000000000 --- a/thirdparty/embree-aarch64/common/tasking/taskschedulergcd.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../sys/platform.h" -#include "../sys/alloc.h" -#include "../sys/barrier.h" -#include "../sys/thread.h" -#include "../sys/mutex.h" -#include "../sys/condition.h" -#include "../sys/ref.h" - -#include <dispatch/dispatch.h> - -namespace embree -{ - struct TaskScheduler - { - /*! initializes the task scheduler */ - static void create(size_t numThreads, bool set_affinity, bool start_threads); - - /*! destroys the task scheduler again */ - static void destroy() {} - - /* returns the ID of the current thread */ - static __forceinline size_t threadID() - { - return threadIndex(); - } - - /* returns the index (0..threadCount-1) of the current thread */ - static __forceinline size_t threadIndex() - { - currentThreadIndex = (currentThreadIndex + 1) % GCDNumThreads; - return currentThreadIndex; - } - - /* returns the total number of threads */ - static __forceinline size_t threadCount() - { - return GCDNumThreads; - } - - private: - static size_t GCDNumThreads; - static size_t currentThreadIndex; - - }; - -}; - diff --git a/thirdparty/embree-aarch64/kernels/builders/primrefgen.h b/thirdparty/embree-aarch64/kernels/builders/primrefgen.h deleted file mode 100644 index 9919c945c3..0000000000 --- a/thirdparty/embree-aarch64/kernels/builders/primrefgen.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "../common/scene.h" -#include "../common/primref.h" -#include "../common/primref_mb.h" -#include "priminfo.h" -#include "bvh_builder_morton.h" - -namespace embree -{ - namespace isa - { - PrimInfo createPrimRefArray(Geometry* geometry, unsigned int geomID, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor); - - PrimInfo createPrimRefArray(Scene* scene, Geometry::GTypeMask types, bool mblur, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor); - - PrimInfo createPrimRefArrayMBlur(Scene* scene, Geometry::GTypeMask types, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor, size_t itime = 0); - - PrimInfoMB createPrimRefArrayMSMBlur(Scene* scene, Geometry::GTypeMask types, mvector<PrimRefMB>& prims, BuildProgressMonitor& progressMonitor, BBox1f t0t1 = BBox1f(0.0f,1.0f)); - - template<typename Mesh> - size_t createMortonCodeArray(Mesh* mesh, mvector<BVHBuilderMorton::BuildPrim>& morton, BuildProgressMonitor& progressMonitor); - } -} - diff --git a/thirdparty/embree-aarch64/kernels/common/instance_stack.h b/thirdparty/embree-aarch64/kernels/common/instance_stack.h deleted file mode 100644 index d7e3637f7b..0000000000 --- a/thirdparty/embree-aarch64/kernels/common/instance_stack.h +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "rtcore.h" - -namespace embree { -namespace instance_id_stack { - -static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0, - "RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0."); - -/******************************************************************************* - * Instance ID stack manipulation. - * This is used from the instance intersector. - ******************************************************************************/ - -/* - * Push an instance to the stack. - */ -RTC_FORCEINLINE bool push(RTCIntersectContext* context, - unsigned instanceId) -{ -#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1 - const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT; - /* We assert here because instances are silently dropped when the stack is full. - This might be quite hard to find in production. */ - assert(spaceAvailable); - if (likely(spaceAvailable)) - context->instID[context->instStackSize++] = instanceId; - return spaceAvailable; -#else - const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID); - assert(spaceAvailable); - if (likely(spaceAvailable)) - context->instID[0] = instanceId; - return spaceAvailable; -#endif -} - - -/* - * Pop the last instance pushed to the stack. - * Do not call on an empty stack. - */ -RTC_FORCEINLINE void pop(RTCIntersectContext* context) -{ - assert(context); -#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1 - assert(context->instStackSize > 0); - context->instID[--context->instStackSize] = RTC_INVALID_GEOMETRY_ID; -#else - assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID); - context->instID[0] = RTC_INVALID_GEOMETRY_ID; -#endif -} - -/******************************************************************************* - * Optimized instance id stack copy. - * The copy() function at the bottom of this block will either copy full - * stacks or copy only until the last valid element has been copied, depending - * on RTC_MAX_INSTANCE_LEVEL_COUNT. - ******************************************************************************/ - -/* - * Plain array assignment. This works for scalar->scalar, - * scalar->vector, and vector->vector. - */ -template <class Src, class Tgt> -RTC_FORCEINLINE void level_copy(unsigned level, Src* src, Tgt* tgt) -{ - tgt[level] = src[level]; -} - -/* - * Masked SIMD vector->vector store. - */ -template <int K> -RTC_FORCEINLINE void level_copy(unsigned level, const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask) -{ - vuint<K>::storeu(mask, tgt + level, src[level]); -} - -/* - * Masked scalar->SIMD vector store. - */ -template <int K> -RTC_FORCEINLINE void level_copy(unsigned level, const unsigned* src, vuint<K>* tgt, const vbool<K>& mask) -{ - vuint<K>::store(mask, tgt + level, src[level]); -} - -/* - * Indexed assign from vector to scalar. - */ -template <int K> -RTC_FORCEINLINE void level_copy(unsigned level, const vuint<K>* src, unsigned* tgt, const size_t& idx) -{ - tgt[level] = src[level][idx]; -} - -/* - * Indexed assign from scalar to vector. - */ -template <int K> -RTC_FORCEINLINE void level_copy(unsigned level, const unsigned* src, vuint<K>* tgt, const size_t& idx) -{ - tgt[level][idx] = src[level]; -} - -/* - * Indexed assign from vector to vector. - */ -template <int K> -RTC_FORCEINLINE void level_copy(unsigned level, const vuint<K>* src, vuint<K>* tgt, const size_t& i, const size_t& j) -{ - tgt[level][j] = src[level][i]; -} - -/* - * Check if the given stack level is valid. - * These are only used for large max stack sizes. - */ -RTC_FORCEINLINE bool level_valid(unsigned level, const unsigned* stack) -{ - return stack[level] != RTC_INVALID_GEOMETRY_ID; -} -RTC_FORCEINLINE bool level_valid(unsigned level, const unsigned* stack, const size_t& /*i*/) -{ - return stack[level] != RTC_INVALID_GEOMETRY_ID; -} -template <int K> -RTC_FORCEINLINE bool level_valid(unsigned level, const unsigned* stack, const vbool<K>& /*mask*/) -{ - return stack[level] != RTC_INVALID_GEOMETRY_ID; -} - -template <int K> -RTC_FORCEINLINE bool level_valid(unsigned level, const vuint<K>* stack) -{ - return any(stack[level] != RTC_INVALID_GEOMETRY_ID); -} -template <int K> -RTC_FORCEINLINE bool level_valid(unsigned level, const vuint<K>* stack, const vbool<K>& mask) -{ - return any(mask & (stack[level] != RTC_INVALID_GEOMETRY_ID)); -} - -template <int K> -RTC_FORCEINLINE bool level_valid(unsigned level, const vuint<K>* stack, const size_t& i) -{ - return stack[level][i] != RTC_INVALID_GEOMETRY_ID; -} -template <int K> -RTC_FORCEINLINE bool level_valid(unsigned level, const vuint<K>* stack, const size_t& i, const size_t& /*j*/) -{ - return stack[level][i] != RTC_INVALID_GEOMETRY_ID; -} - -/* - * Copy an instance ID stack. - * - * This function automatically selects a LevelFunctor from the above Assign - * structs. - */ -template <class Src, class Tgt, class... Args> -RTC_FORCEINLINE void copy(Src src, Tgt tgt, Args&&... args) -{ -#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) - /* - * Avoid all loops for only one level. - */ - level_copy(0, src, tgt, std::forward<Args>(args)...); - -#elif (RTC_MAX_INSTANCE_LEVEL_COUNT <= 4) - /* - * It is faster to avoid the valid test for low level counts. - * Just copy the whole stack. - */ - for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) - level_copy(l, src, tgt, std::forward<Args>(args)...); - -#else - /* - * For general stack sizes, it pays off to test for validity. - */ - bool valid = true; - for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT && valid; ++l) - { - level_copy(l, src, tgt, std::forward<Args>(args)...); - valid = level_valid(l, src, std::forward<Args>(args)...); - } -#endif -} - -} // namespace instance_id_stack -} // namespace embree - diff --git a/thirdparty/embree-aarch64/kernels/common/scene_curves.h b/thirdparty/embree-aarch64/kernels/common/scene_curves.h deleted file mode 100644 index 2649ab0e3e..0000000000 --- a/thirdparty/embree-aarch64/kernels/common/scene_curves.h +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "default.h" -#include "geometry.h" -#include "buffer.h" - -namespace embree -{ - /*! represents an array of bicubic bezier curves */ - struct CurveGeometry : public Geometry - { - /*! type of this geometry */ - static const Geometry::GTypeMask geom_type = Geometry::MTY_CURVE4; - - public: - - /*! bezier curve construction */ - CurveGeometry (Device* device, Geometry::GType gtype); - - public: - void setMask(unsigned mask); - void setNumTimeSteps (unsigned int numTimeSteps); - void setVertexAttributeCount (unsigned int N); - void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num); - void* getBuffer(RTCBufferType type, unsigned int slot); - void updateBuffer(RTCBufferType type, unsigned int slot); - void commit(); - bool verify(); - void setTessellationRate(float N); - void setMaxRadiusScale(float s); - void addElementsToCount (GeometryCounts & counts) const; - - public: - - /*! returns the number of vertices */ - __forceinline size_t numVertices() const { - return vertices[0].size(); - } - - /*! returns the i'th curve */ - __forceinline const unsigned int& curve(size_t i) const { - return curves[i]; - } - - /*! returns i'th vertex of the first time step */ - __forceinline Vec3ff vertex(size_t i) const { - return vertices0[i]; - } - - /*! returns i'th normal of the first time step */ - __forceinline Vec3fa normal(size_t i) const { - return normals0[i]; - } - - /*! returns i'th tangent of the first time step */ - __forceinline Vec3ff tangent(size_t i) const { - return tangents0[i]; - } - - /*! returns i'th normal derivative of the first time step */ - __forceinline Vec3fa dnormal(size_t i) const { - return dnormals0[i]; - } - - /*! returns i'th radius of the first time step */ - __forceinline float radius(size_t i) const { - return vertices0[i].w; - } - - /*! returns i'th vertex of itime'th timestep */ - __forceinline Vec3ff vertex(size_t i, size_t itime) const { - return vertices[itime][i]; - } - - /*! returns i'th normal of itime'th timestep */ - __forceinline Vec3fa normal(size_t i, size_t itime) const { - return normals[itime][i]; - } - - /*! returns i'th tangent of itime'th timestep */ - __forceinline Vec3ff tangent(size_t i, size_t itime) const { - return tangents[itime][i]; - } - - /*! returns i'th normal derivative of itime'th timestep */ - __forceinline Vec3fa dnormal(size_t i, size_t itime) const { - return dnormals[itime][i]; - } - - /*! returns i'th radius of itime'th timestep */ - __forceinline float radius(size_t i, size_t itime) const { - return vertices[itime][i].w; - } - - /*! gathers the curve starting with i'th vertex */ - __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, size_t i) const - { - p0 = vertex(i+0); - p1 = vertex(i+1); - p2 = vertex(i+2); - p3 = vertex(i+3); - } - - /*! gathers the curve starting with i'th vertex of itime'th timestep */ - __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, size_t i, size_t itime) const - { - p0 = vertex(i+0,itime); - p1 = vertex(i+1,itime); - p2 = vertex(i+2,itime); - p3 = vertex(i+3,itime); - } - - /*! gathers the curve starting with i'th vertex */ - __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3, size_t i) const - { - p0 = vertex(i+0); - p1 = vertex(i+1); - p2 = vertex(i+2); - p3 = vertex(i+3); - n0 = normal(i+0); - n1 = normal(i+1); - n2 = normal(i+2); - n3 = normal(i+3); - } - - /*! gathers the curve starting with i'th vertex of itime'th timestep */ - __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3, size_t i, size_t itime) const - { - p0 = vertex(i+0,itime); - p1 = vertex(i+1,itime); - p2 = vertex(i+2,itime); - p3 = vertex(i+3,itime); - n0 = normal(i+0,itime); - n1 = normal(i+1,itime); - n2 = normal(i+2,itime); - n3 = normal(i+3,itime); - } - - /*! prefetches the curve starting with i'th vertex of itime'th timestep */ - __forceinline void prefetchL1_vertices(size_t i) const - { - prefetchL1(vertices0.getPtr(i)+0); - prefetchL1(vertices0.getPtr(i)+64); - } - - /*! prefetches the curve starting with i'th vertex of itime'th timestep */ - __forceinline void prefetchL2_vertices(size_t i) const - { - prefetchL2(vertices0.getPtr(i)+0); - prefetchL2(vertices0.getPtr(i)+64); - } - - /*! loads curve vertices for specified time */ - __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, size_t i, float time) const - { - float ftime; - const size_t itime = timeSegment(time, ftime); - - const float t0 = 1.0f - ftime; - const float t1 = ftime; - Vec3ff a0,a1,a2,a3; - gather(a0,a1,a2,a3,i,itime); - Vec3ff b0,b1,b2,b3; - gather(b0,b1,b2,b3,i,itime+1); - p0 = madd(Vec3ff(t0),a0,t1*b0); - p1 = madd(Vec3ff(t0),a1,t1*b1); - p2 = madd(Vec3ff(t0),a2,t1*b2); - p3 = madd(Vec3ff(t0),a3,t1*b3); - } - - /*! loads curve vertices for specified time */ - __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3, size_t i, float time) const - { - float ftime; - const size_t itime = timeSegment(time, ftime); - - const float t0 = 1.0f - ftime; - const float t1 = ftime; - Vec3ff a0,a1,a2,a3; Vec3fa an0,an1,an2,an3; - gather(a0,a1,a2,a3,an0,an1,an2,an3,i,itime); - Vec3ff b0,b1,b2,b3; Vec3fa bn0,bn1,bn2,bn3; - gather(b0,b1,b2,b3,bn0,bn1,bn2,bn3,i,itime+1); - p0 = madd(Vec3ff(t0),a0,t1*b0); - p1 = madd(Vec3ff(t0),a1,t1*b1); - p2 = madd(Vec3ff(t0),a2,t1*b2); - p3 = madd(Vec3ff(t0),a3,t1*b3); - n0 = madd(Vec3ff(t0),an0,t1*bn0); - n1 = madd(Vec3ff(t0),an1,t1*bn1); - n2 = madd(Vec3ff(t0),an2,t1*bn2); - n3 = madd(Vec3ff(t0),an3,t1*bn3); - } - - template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> - __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const size_t itime) const - { - Vec3ff v0,v1,v2,v3; Vec3fa n0,n1,n2,n3; - unsigned int vertexID = curve(primID); - gather(v0,v1,v2,v3,n0,n1,n2,n3,vertexID,itime); - SourceCurve3ff ccurve(v0,v1,v2,v3); - SourceCurve3fa ncurve(n0,n1,n2,n3); - ccurve = enlargeRadiusToMinWidth(context,this,ray_org,ccurve); - return TensorLinearCubicBezierSurface3fa::fromCenterAndNormalCurve(ccurve,ncurve); - } - - template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> - __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const float time) const - { - float ftime; - const size_t itime = timeSegment(time, ftime); - const TensorLinearCubicBezierSurface3fa curve0 = getNormalOrientedCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context,ray_org,primID,itime+0); - const TensorLinearCubicBezierSurface3fa curve1 = getNormalOrientedCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context,ray_org,primID,itime+1); - return clerp(curve0,curve1,ftime); - } - - /*! gathers the hermite curve starting with i'th vertex */ - __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3ff& p1, Vec3ff& t1, size_t i) const - { - p0 = vertex (i+0); - p1 = vertex (i+1); - t0 = tangent(i+0); - t1 = tangent(i+1); - } - - /*! gathers the hermite curve starting with i'th vertex of itime'th timestep */ - __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3ff& p1, Vec3ff& t1, size_t i, size_t itime) const - { - p0 = vertex (i+0,itime); - p1 = vertex (i+1,itime); - t0 = tangent(i+0,itime); - t1 = tangent(i+1,itime); - } - - /*! loads curve vertices for specified time */ - __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3ff& p1, Vec3ff& t1, size_t i, float time) const - { - float ftime; - const size_t itime = timeSegment(time, ftime); - const float f0 = 1.0f - ftime, f1 = ftime; - Vec3ff ap0,at0,ap1,at1; - gather_hermite(ap0,at0,ap1,at1,i,itime); - Vec3ff bp0,bt0,bp1,bt1; - gather_hermite(bp0,bt0,bp1,bt1,i,itime+1); - p0 = madd(Vec3ff(f0),ap0,f1*bp0); - t0 = madd(Vec3ff(f0),at0,f1*bt0); - p1 = madd(Vec3ff(f0),ap1,f1*bp1); - t1 = madd(Vec3ff(f0),at1,f1*bt1); - } - - /*! gathers the hermite curve starting with i'th vertex */ - __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3fa& n0, Vec3fa& dn0, Vec3ff& p1, Vec3ff& t1, Vec3fa& n1, Vec3fa& dn1, size_t i) const - { - p0 = vertex (i+0); - p1 = vertex (i+1); - t0 = tangent(i+0); - t1 = tangent(i+1); - n0 = normal(i+0); - n1 = normal(i+1); - dn0 = dnormal(i+0); - dn1 = dnormal(i+1); - } - - /*! gathers the hermite curve starting with i'th vertex of itime'th timestep */ - __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3fa& n0, Vec3fa& dn0, Vec3ff& p1, Vec3ff& t1, Vec3fa& n1, Vec3fa& dn1, size_t i, size_t itime) const - { - p0 = vertex (i+0,itime); - p1 = vertex (i+1,itime); - t0 = tangent(i+0,itime); - t1 = tangent(i+1,itime); - n0 = normal(i+0,itime); - n1 = normal(i+1,itime); - dn0 = dnormal(i+0,itime); - dn1 = dnormal(i+1,itime); - } - - /*! loads curve vertices for specified time */ - __forceinline void gather_hermite(Vec3ff& p0, Vec3fa& t0, Vec3fa& n0, Vec3fa& dn0, Vec3ff& p1, Vec3fa& t1, Vec3fa& n1, Vec3fa& dn1, size_t i, float time) const - { - float ftime; - const size_t itime = timeSegment(time, ftime); - const float f0 = 1.0f - ftime, f1 = ftime; - Vec3ff ap0,at0,ap1,at1; Vec3fa an0,adn0,an1,adn1; - gather_hermite(ap0,at0,an0,adn0,ap1,at1,an1,adn1,i,itime); - Vec3ff bp0,bt0,bp1,bt1; Vec3fa bn0,bdn0,bn1,bdn1; - gather_hermite(bp0,bt0,bn0,bdn0,bp1,bt1,bn1,bdn1,i,itime+1); - p0 = madd(Vec3ff(f0),ap0,f1*bp0); - t0 = madd(Vec3ff(f0),at0,f1*bt0); - n0 = madd(Vec3ff(f0),an0,f1*bn0); - dn0= madd(Vec3ff(f0),adn0,f1*bdn0); - p1 = madd(Vec3ff(f0),ap1,f1*bp1); - t1 = madd(Vec3ff(f0),at1,f1*bt1); - n1 = madd(Vec3ff(f0),an1,f1*bn1); - dn1= madd(Vec3ff(f0),adn1,f1*bdn1); - } - - template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> - __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedHermiteCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const size_t itime) const - { - Vec3ff v0,t0,v1,t1; Vec3fa n0,dn0,n1,dn1; - unsigned int vertexID = curve(primID); - gather_hermite(v0,t0,n0,dn0,v1,t1,n1,dn1,vertexID,itime); - - SourceCurve3ff ccurve(v0,t0,v1,t1); - SourceCurve3fa ncurve(n0,dn0,n1,dn1); - ccurve = enlargeRadiusToMinWidth(context,this,ray_org,ccurve); - return TensorLinearCubicBezierSurface3fa::fromCenterAndNormalCurve(ccurve,ncurve); - } - - template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> - __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedHermiteCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const float time) const - { - float ftime; - const size_t itime = timeSegment(time, ftime); - const TensorLinearCubicBezierSurface3fa curve0 = getNormalOrientedHermiteCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,itime+0); - const TensorLinearCubicBezierSurface3fa curve1 = getNormalOrientedHermiteCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,itime+1); - return clerp(curve0,curve1,ftime); - } - - private: - void resizeBuffers(unsigned int numSteps); - - public: - BufferView<unsigned int> curves; //!< array of curve indices - BufferView<Vec3ff> vertices0; //!< fast access to first vertex buffer - BufferView<Vec3fa> normals0; //!< fast access to first normal buffer - BufferView<Vec3ff> tangents0; //!< fast access to first tangent buffer - BufferView<Vec3fa> dnormals0; //!< fast access to first normal derivative buffer - vector<BufferView<Vec3ff>> vertices; //!< vertex array for each timestep - vector<BufferView<Vec3fa>> normals; //!< normal array for each timestep - vector<BufferView<Vec3ff>> tangents; //!< tangent array for each timestep - vector<BufferView<Vec3fa>> dnormals; //!< normal derivative array for each timestep - BufferView<char> flags; //!< start, end flag per segment - vector<BufferView<char>> vertexAttribs; //!< user buffers - int tessellationRate; //!< tessellation rate for flat curve - float maxRadiusScale = 1.0; //!< maximal min-width scaling of curve radii - }; - - DECLARE_ISA_FUNCTION(CurveGeometry*, createCurves, Device* COMMA Geometry::GType); -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_bezier_curve.h b/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_bezier_curve.h deleted file mode 100644 index 69cf612275..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_bezier_curve.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 Light Transport Entertainment Inc. -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "curve_intersector_virtual.h" - -namespace embree -{ - namespace isa - { - void AddVirtualCurveBezierCurveInterector4i(VirtualCurveIntersector &prim); - void AddVirtualCurveBezierCurveInterector4v(VirtualCurveIntersector &prim); - void AddVirtualCurveBezierCurveInterector4iMB(VirtualCurveIntersector &prim); -#if defined(__AVX__) - void AddVirtualCurveBezierCurveInterector8i(VirtualCurveIntersector &prim); - void AddVirtualCurveBezierCurveInterector8v(VirtualCurveIntersector &prim); - void AddVirtualCurveBezierCurveInterector8iMB(VirtualCurveIntersector &prim); -#endif - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_bspline_curve.h b/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_bspline_curve.h deleted file mode 100644 index d37e41098e..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_bspline_curve.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 Light Transport Entertainment Inc. -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "curve_intersector_virtual.h" - -namespace embree -{ - namespace isa - { - void AddVirtualCurveBSplineCurveInterector4i(VirtualCurveIntersector &prim); - void AddVirtualCurveBSplineCurveInterector4v(VirtualCurveIntersector &prim); - void AddVirtualCurveBSplineCurveInterector4iMB(VirtualCurveIntersector &prim); -#if defined(__AVX__) - void AddVirtualCurveBSplineCurveInterector8i(VirtualCurveIntersector &prim); - void AddVirtualCurveBSplineCurveInterector8v(VirtualCurveIntersector &prim); - void AddVirtualCurveBSplineCurveInterector8iMB(VirtualCurveIntersector &prim); -#endif - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_catmullrom_curve.h b/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_catmullrom_curve.h deleted file mode 100644 index a133a11d63..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_catmullrom_curve.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 Light Transport Entertainment Inc. -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "curve_intersector_virtual.h" - -namespace embree -{ - namespace isa - { - void AddVirtualCurveCatmullRomCurveInterector4i(VirtualCurveIntersector &prim); - void AddVirtualCurveCatmullRomCurveInterector4v(VirtualCurveIntersector &prim); - void AddVirtualCurveCatmullRomCurveInterector4iMB(VirtualCurveIntersector &prim); -#if defined(__AVX__) - void AddVirtualCurveCatmullRomCurveInterector8i(VirtualCurveIntersector &prim); - void AddVirtualCurveCatmullRomCurveInterector8v(VirtualCurveIntersector &prim); - void AddVirtualCurveCatmullRomCurveInterector8iMB(VirtualCurveIntersector &prim); -#endif - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_hermite_curve.h b/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_hermite_curve.h deleted file mode 100644 index 9aec35da45..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_hermite_curve.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 Light Transport Entertainment Inc. -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "curve_intersector_virtual.h" - -namespace embree -{ - namespace isa - { - void AddVirtualCurveHermiteCurveInterector4i(VirtualCurveIntersector &prim); - void AddVirtualCurveHermiteCurveInterector4v(VirtualCurveIntersector &prim); - void AddVirtualCurveHermiteCurveInterector4iMB(VirtualCurveIntersector &prim); -#if defined(__AVX__) - void AddVirtualCurveHermiteCurveInterector8i(VirtualCurveIntersector &prim); - void AddVirtualCurveHermiteCurveInterector8v(VirtualCurveIntersector &prim); - void AddVirtualCurveHermiteCurveInterector8iMB(VirtualCurveIntersector &prim); -#endif - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_linear_curve.h b/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_linear_curve.h deleted file mode 100644 index dd37d194f5..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_linear_curve.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 Light Transport Entertainment Inc. -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "curve_intersector_virtual.h" - -namespace embree -{ - namespace isa - { - void AddVirtualCurveLinearCurveInterector4i(VirtualCurveIntersector &prim); - void AddVirtualCurveLinearCurveInterector4v(VirtualCurveIntersector &prim); - void AddVirtualCurveLinearCurveInterector4iMB(VirtualCurveIntersector &prim); -#if defined(__AVX__) - void AddVirtualCurveLinearCurveInterector8i(VirtualCurveIntersector &prim); - void AddVirtualCurveLinearCurveInterector8v(VirtualCurveIntersector &prim); - void AddVirtualCurveLinearCurveInterector8iMB(VirtualCurveIntersector &prim); -#endif - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_point.h b/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_point.h deleted file mode 100644 index fe5ceed840..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual_point.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 Light Transport Entertainment Inc. -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "curve_intersector_virtual.h" - -namespace embree -{ - namespace isa - { - void AddVirtualCurvePointInterector4i(VirtualCurveIntersector &prim); - void AddVirtualCurvePointInterector4v(VirtualCurveIntersector &prim); - void AddVirtualCurvePointInterector4iMB(VirtualCurveIntersector &prim); - -#if defined (__AVX__) - void AddVirtualCurvePointInterector8i(VirtualCurveIntersector &prim); - void AddVirtualCurvePointInterector8v(VirtualCurveIntersector &prim); - void AddVirtualCurvePointInterector8iMB(VirtualCurveIntersector &prim); -#endif - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector_moeller.h b/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector_moeller.h deleted file mode 100644 index f65b4abf61..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector_moeller.h +++ /dev/null @@ -1,493 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "subgrid.h" -#include "quad_intersector_moeller.h" - -namespace embree -{ - namespace isa - { - - /* ----------------------------- */ - /* -- single ray intersectors -- */ - /* ----------------------------- */ - - template<int M> - __forceinline void interpolateUV(MoellerTrumboreHitM<M> &hit,const GridMesh::Grid &g, const SubGrid& subgrid) - { - /* correct U,V interpolation across the entire grid */ - const vint<M> sx((int)subgrid.x()); - const vint<M> sy((int)subgrid.y()); - const vint<M> sxM(sx + vint<M>(0,1,1,0)); - const vint<M> syM(sy + vint<M>(0,0,1,1)); - const float inv_resX = rcp((float)((int)g.resX-1)); - const float inv_resY = rcp((float)((int)g.resY-1)); - hit.U = (hit.U + (vfloat<M>)sxM * hit.absDen) * inv_resX; - hit.V = (hit.V + (vfloat<M>)syM * hit.absDen) * inv_resY; - } - - template<int M, bool filter> - struct SubGridQuadMIntersector1MoellerTrumbore; - - template<int M, bool filter> - struct SubGridQuadMIntersector1MoellerTrumbore - { - __forceinline SubGridQuadMIntersector1MoellerTrumbore() {} - - __forceinline SubGridQuadMIntersector1MoellerTrumbore(const Ray& ray, const void* ptr) {} - - __forceinline void intersect(RayHit& ray, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - MoellerTrumboreHitM<M> hit; - MoellerTrumboreIntersector1<M> intersector(ray,nullptr); - Intersect1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); - - /* intersect first triangle */ - if (intersector.intersect(ray,v0,v1,v3,hit)) - { - interpolateUV<M>(hit,g,subgrid); - epilog(hit.valid,hit); - } - - /* intersect second triangle */ - if (intersector.intersect(ray,v2,v3,v1,hit)) - { - hit.U = hit.absDen - hit.U; - hit.V = hit.absDen - hit.V; - interpolateUV<M>(hit,g,subgrid); - epilog(hit.valid,hit); - } - } - - __forceinline bool occluded(Ray& ray, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - MoellerTrumboreHitM<M> hit; - MoellerTrumboreIntersector1<M> intersector(ray,nullptr); - Occluded1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); - - /* intersect first triangle */ - if (intersector.intersect(ray,v0,v1,v3,hit)) - { - interpolateUV<M>(hit,g,subgrid); - if (epilog(hit.valid,hit)) - return true; - } - - /* intersect second triangle */ - if (intersector.intersect(ray,v2,v3,v1,hit)) - { - hit.U = hit.absDen - hit.U; - hit.V = hit.absDen - hit.V; - interpolateUV<M>(hit,g,subgrid); - if (epilog(hit.valid,hit)) - return true; - } - return false; - } - }; - -#if defined (__AVX__) - - /*! Intersects 4 quads with 1 ray using AVX */ - template<bool filter> - struct SubGridQuadMIntersector1MoellerTrumbore<4,filter> - { - __forceinline SubGridQuadMIntersector1MoellerTrumbore() {} - - __forceinline SubGridQuadMIntersector1MoellerTrumbore(const Ray& ray, const void* ptr) {} - - template<typename Epilog> - __forceinline bool intersect(Ray& ray, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid& subgrid, const Epilog& epilog) const - { - const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); - const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); -#else - const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); - const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); -#endif - MoellerTrumboreHitM<8> hit; - MoellerTrumboreIntersector1<8> intersector(ray,nullptr); - const vbool8 flags(0,0,0,0,1,1,1,1); - if (unlikely(intersector.intersect(ray,vtx0,vtx1,vtx2,hit))) - { - vfloat8 U = hit.U, V = hit.V, absDen = hit.absDen; - -#if !defined(EMBREE_BACKFACE_CULLING) - hit.U = select(flags,absDen-V,U); - hit.V = select(flags,absDen-U,V); - hit.vNg *= select(flags,vfloat8(-1.0f),vfloat8(1.0f)); -#else - hit.U = select(flags,absDen-U,U); - hit.V = select(flags,absDen-V,V); -#endif - /* correct U,V interpolation across the entire grid */ - const vint8 sx((int)subgrid.x()); - const vint8 sy((int)subgrid.y()); - const vint8 sx8(sx + vint8(0,1,1,0,0,1,1,0)); - const vint8 sy8(sy + vint8(0,0,1,1,0,0,1,1)); - const float inv_resX = rcp((float)((int)g.resX-1)); - const float inv_resY = rcp((float)((int)g.resY-1)); - hit.U = (hit.U + (vfloat8)sx8 * absDen) * inv_resX; - hit.V = (hit.V + (vfloat8)sy8 * absDen) * inv_resY; - - if (unlikely(epilog(hit.valid,hit))) - return true; - } - return false; - } - - __forceinline bool intersect(RayHit& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - return intersect(ray,v0,v1,v2,v3,g,subgrid,Intersect1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); - } - - __forceinline bool occluded(Ray& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - return intersect(ray,v0,v1,v2,v3,g,subgrid,Occluded1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); - } - }; - -#endif - - // ============================================================================================================================ - // ============================================================================================================================ - // ============================================================================================================================ - - - /* ----------------------------- */ - /* -- ray packet intersectors -- */ - /* ----------------------------- */ - - template<int K> - struct SubGridQuadHitK - { - __forceinline SubGridQuadHitK(const vfloat<K>& U, - const vfloat<K>& V, - const vfloat<K>& T, - const vfloat<K>& absDen, - const Vec3vf<K>& Ng, - const vbool<K>& flags, - const GridMesh::Grid &g, - const SubGrid& subgrid, - const unsigned int i) - : U(U), V(V), T(T), absDen(absDen), flags(flags), tri_Ng(Ng), g(g), subgrid(subgrid), i(i) {} - - __forceinline std::tuple<vfloat<K>,vfloat<K>,vfloat<K>,Vec3vf<K>> operator() () const - { - const vfloat<K> rcpAbsDen = rcp(absDen); - const vfloat<K> t = T * rcpAbsDen; - const vfloat<K> u0 = min(U * rcpAbsDen,1.0f); - const vfloat<K> v0 = min(V * rcpAbsDen,1.0f); - const vfloat<K> u1 = vfloat<K>(1.0f) - u0; - const vfloat<K> v1 = vfloat<K>(1.0f) - v0; - const vfloat<K> uu = select(flags,u1,u0); - const vfloat<K> vv = select(flags,v1,v0); - const unsigned int sx = subgrid.x() + (unsigned int)(i % 2); - const unsigned int sy = subgrid.y() + (unsigned int)(i >>1); - const float inv_resX = rcp((float)(int)(g.resX-1)); - const float inv_resY = rcp((float)(int)(g.resY-1)); - const vfloat<K> u = (uu + (float)(int)sx) * inv_resX; - const vfloat<K> v = (vv + (float)(int)sy) * inv_resY; - const Vec3vf<K> Ng(tri_Ng.x,tri_Ng.y,tri_Ng.z); - return std::make_tuple(u,v,t,Ng); - } - - private: - const vfloat<K> U; - const vfloat<K> V; - const vfloat<K> T; - const vfloat<K> absDen; - const vbool<K> flags; - const Vec3vf<K> tri_Ng; - - const GridMesh::Grid &g; - const SubGrid& subgrid; - const size_t i; - }; - - template<int M, int K, bool filter> - struct SubGridQuadMIntersectorKMoellerTrumboreBase - { - __forceinline SubGridQuadMIntersectorKMoellerTrumboreBase(const vbool<K>& valid, const RayK<K>& ray) {} - - template<typename Epilog> - __forceinline vbool<K> intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& tri_v0, - const Vec3vf<K>& tri_e1, - const Vec3vf<K>& tri_e2, - const Vec3vf<K>& tri_Ng, - const vbool<K>& flags, - const GridMesh::Grid &g, - const SubGrid &subgrid, - const unsigned int i, - const Epilog& epilog) const - { - /* calculate denominator */ - vbool<K> valid = valid0; - const Vec3vf<K> C = tri_v0 - ray.org; - const Vec3vf<K> R = cross(C,ray.dir); - const vfloat<K> den = dot(tri_Ng,ray.dir); - const vfloat<K> absDen = abs(den); - const vfloat<K> sgnDen = signmsk(den); - - /* test against edge p2 p0 */ - const vfloat<K> U = dot(R,tri_e2) ^ sgnDen; - valid &= U >= 0.0f; - if (likely(none(valid))) return false; - - /* test against edge p0 p1 */ - const vfloat<K> V = dot(R,tri_e1) ^ sgnDen; - valid &= V >= 0.0f; - if (likely(none(valid))) return false; - - /* test against edge p1 p2 */ - const vfloat<K> W = absDen-U-V; - valid &= W >= 0.0f; - if (likely(none(valid))) return false; - - /* perform depth test */ - const vfloat<K> T = dot(tri_Ng,C) ^ sgnDen; - valid &= (absDen*ray.tnear() < T) & (T <= absDen*ray.tfar); - if (unlikely(none(valid))) return false; - - /* perform backface culling */ -#if defined(EMBREE_BACKFACE_CULLING) - valid &= den < vfloat<K>(zero); - if (unlikely(none(valid))) return false; -#else - valid &= den != vfloat<K>(zero); - if (unlikely(none(valid))) return false; -#endif - - /* calculate hit information */ - SubGridQuadHitK<K> hit(U,V,T,absDen,tri_Ng,flags,g,subgrid,i); - return epilog(valid,hit); - } - - template<typename Epilog> - __forceinline vbool<K> intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& tri_v0, - const Vec3vf<K>& tri_v1, - const Vec3vf<K>& tri_v2, - const vbool<K>& flags, - const GridMesh::Grid &g, - const SubGrid &subgrid, - const unsigned int i, - const Epilog& epilog) const - { - const Vec3vf<K> e1 = tri_v0-tri_v1; - const Vec3vf<K> e2 = tri_v2-tri_v0; - const Vec3vf<K> Ng = cross(e2,e1); - return intersectK(valid0,ray,tri_v0,e1,e2,Ng,flags,g,subgrid,i,epilog); - } - - template<typename Epilog> - __forceinline bool intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& v0, - const Vec3vf<K>& v1, - const Vec3vf<K>& v2, - const Vec3vf<K>& v3, - const GridMesh::Grid &g, - const SubGrid &subgrid, - const unsigned int i, - const Epilog& epilog) const - { - intersectK(valid0,ray,v0,v1,v3,vbool<K>(false),g,subgrid,i,epilog); - if (none(valid0)) return true; - intersectK(valid0,ray,v2,v3,v1,vbool<K>(true ),g,subgrid,i,epilog); - return none(valid0); - } - - static __forceinline bool intersect1(RayK<K>& ray, - size_t k, - const Vec3vf<M>& tri_v0, - const Vec3vf<M>& tri_e1, - const Vec3vf<M>& tri_e2, - const Vec3vf<M>& tri_Ng, - MoellerTrumboreHitM<M> &hit) - { - /* calculate denominator */ - const Vec3vf<M> O = broadcast<vfloat<M>>(ray.org,k); - const Vec3vf<M> D = broadcast<vfloat<M>>(ray.dir,k); - const Vec3vf<M> C = Vec3vf<M>(tri_v0) - O; - const Vec3vf<M> R = cross(C,D); - const vfloat<M> den = dot(Vec3vf<M>(tri_Ng),D); - const vfloat<M> absDen = abs(den); - const vfloat<M> sgnDen = signmsk(den); - - /* perform edge tests */ - const vfloat<M> U = dot(R,Vec3vf<M>(tri_e2)) ^ sgnDen; - const vfloat<M> V = dot(R,Vec3vf<M>(tri_e1)) ^ sgnDen; - - /* perform backface culling */ -#if defined(EMBREE_BACKFACE_CULLING) - vbool<M> valid = (den < vfloat<M>(zero)) & (U >= 0.0f) & (V >= 0.0f) & (U+V<=absDen); -#else - vbool<M> valid = (den != vfloat<M>(zero)) & (U >= 0.0f) & (V >= 0.0f) & (U+V<=absDen); -#endif - if (likely(none(valid))) return false; - - /* perform depth test */ - const vfloat<M> T = dot(Vec3vf<M>(tri_Ng),C) ^ sgnDen; - valid &= (absDen*vfloat<M>(ray.tnear()[k]) < T) & (T <= absDen*vfloat<M>(ray.tfar[k])); - if (likely(none(valid))) return false; - - /* calculate hit information */ - new (&hit) MoellerTrumboreHitM<M>(valid,U,V,T,absDen,tri_Ng); - return true; - } - - static __forceinline bool intersect1(RayK<K>& ray, - size_t k, - const Vec3vf<M>& v0, - const Vec3vf<M>& v1, - const Vec3vf<M>& v2, - MoellerTrumboreHitM<M> &hit) - { - const Vec3vf<M> e1 = v0-v1; - const Vec3vf<M> e2 = v2-v0; - const Vec3vf<M> Ng = cross(e2,e1); - return intersect1(ray,k,v0,e1,e2,Ng,hit); - } - - }; - - template<int M, int K, bool filter> - struct SubGridQuadMIntersectorKMoellerTrumbore : public SubGridQuadMIntersectorKMoellerTrumboreBase<M,K,filter> - { - __forceinline SubGridQuadMIntersectorKMoellerTrumbore(const vbool<K>& valid, const RayK<K>& ray) - : SubGridQuadMIntersectorKMoellerTrumboreBase<M,K,filter>(valid,ray) {} - - __forceinline void intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const - { - Intersect1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); - - MoellerTrumboreHitM<4> hit; - if (SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter>::intersect1(ray,k,v0,v1,v3,hit)) - { - interpolateUV<M>(hit,g,subgrid); - epilog(hit.valid,hit); - } - - if (SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter>::intersect1(ray,k,v2,v3,v1,hit)) - { - hit.U = hit.absDen - hit.U; - hit.V = hit.absDen - hit.V; - interpolateUV<M>(hit,g,subgrid); - epilog(hit.valid,hit); - } - - } - - __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const - { - Occluded1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); - - MoellerTrumboreHitM<4> hit; - if (SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter>::intersect1(ray,k,v0,v1,v3,hit)) - { - interpolateUV<M>(hit,g,subgrid); - if (epilog(hit.valid,hit)) return true; - } - - if (SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter>::intersect1(ray,k,v2,v3,v1,hit)) - { - hit.U = hit.absDen - hit.U; - hit.V = hit.absDen - hit.V; - interpolateUV<M>(hit,g,subgrid); - if (epilog(hit.valid,hit)) return true; - } - return false; - } - }; - - -#if defined (__AVX__) - - /*! Intersects 4 quads with 1 ray using AVX */ - template<int K, bool filter> - struct SubGridQuadMIntersectorKMoellerTrumbore<4,K,filter> : public SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter> - { - __forceinline SubGridQuadMIntersectorKMoellerTrumbore(const vbool<K>& valid, const RayK<K>& ray) - : SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter>(valid,ray) {} - - template<typename Epilog> - __forceinline bool intersect1(RayK<K>& ray, size_t k,const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const GridMesh::Grid &g, const SubGrid &subgrid, const Epilog& epilog) const - { - const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); - const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); -#else - const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); - const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); -#endif - const vbool8 flags(0,0,0,0,1,1,1,1); - - MoellerTrumboreHitM<8> hit; - if (SubGridQuadMIntersectorKMoellerTrumboreBase<8,K,filter>::intersect1(ray,k,vtx0,vtx1,vtx2,hit)) - { - vfloat8 U = hit.U, V = hit.V, absDen = hit.absDen; -#if !defined(EMBREE_BACKFACE_CULLING) - hit.U = select(flags,absDen-V,U); - hit.V = select(flags,absDen-U,V); - hit.vNg *= select(flags,vfloat8(-1.0f),vfloat8(1.0f)); -#else - hit.U = select(flags,absDen-U,U); - hit.V = select(flags,absDen-V,V); -#endif - - /* correct U,V interpolation across the entire grid */ - const vint8 sx((int)subgrid.x()); - const vint8 sy((int)subgrid.y()); - const vint8 sx8(sx + vint8(0,1,1,0,0,1,1,0)); - const vint8 sy8(sy + vint8(0,0,1,1,0,0,1,1)); - const float inv_resX = rcp((float)((int)g.resX-1)); - const float inv_resY = rcp((float)((int)g.resY-1)); - hit.U = (hit.U + (vfloat8)sx8 * absDen) * inv_resX; - hit.V = (hit.V + (vfloat8)sy8 * absDen) * inv_resY; - if (unlikely(epilog(hit.valid,hit))) - return true; - - } - return false; - } - - __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const - { - return intersect1(ray,k,v0,v1,v2,v3,g,subgrid,Intersect1KEpilogMU<8,K,filter>(ray,k,context,subgrid.geomID(),subgrid.primID())); - } - - __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const - { - return intersect1(ray,k,v0,v1,v2,v3,g,subgrid,Occluded1KEpilogMU<8,K,filter>(ray,k,context,subgrid.geomID(),subgrid.primID())); - } - }; - -#endif - - - - } -} diff --git a/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector_pluecker.h b/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector_pluecker.h deleted file mode 100644 index 1cd88aa799..0000000000 --- a/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector_pluecker.h +++ /dev/null @@ -1,508 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "subgrid.h" -#include "quad_intersector_moeller.h" -#include "quad_intersector_pluecker.h" - -namespace embree -{ - namespace isa - { - - template<int M> - struct SubGridQuadHitPlueckerM - { - __forceinline SubGridQuadHitPlueckerM() {} - - __forceinline SubGridQuadHitPlueckerM(const vbool<M>& valid, - const vfloat<M>& U, - const vfloat<M>& V, - const vfloat<M>& UVW, - const vfloat<M>& t, - const Vec3vf<M>& Ng, - const vbool<M>& flags) : valid(valid), vt(t) - { - const vbool<M> invalid = abs(UVW) < min_rcp_input; - const vfloat<M> rcpUVW = select(invalid,vfloat<M>(0.0f),rcp(UVW)); - const vfloat<M> u = min(U * rcpUVW,1.0f); - const vfloat<M> v = min(V * rcpUVW,1.0f); - const vfloat<M> u1 = vfloat<M>(1.0f) - u; - const vfloat<M> v1 = vfloat<M>(1.0f) - v; -#if !defined(__AVX__) || defined(EMBREE_BACKFACE_CULLING) - vu = select(flags,u1,u); - vv = select(flags,v1,v); - vNg = Vec3vf<M>(Ng.x,Ng.y,Ng.z); -#else - const vfloat<M> flip = select(flags,vfloat<M>(-1.0f),vfloat<M>(1.0f)); - vv = select(flags,u1,v); - vu = select(flags,v1,u); - vNg = Vec3vf<M>(flip*Ng.x,flip*Ng.y,flip*Ng.z); -#endif - } - - __forceinline void finalize() - { - } - - __forceinline Vec2f uv(const size_t i) - { - const float u = vu[i]; - const float v = vv[i]; - return Vec2f(u,v); - } - - __forceinline float t(const size_t i) { return vt[i]; } - __forceinline Vec3fa Ng(const size_t i) { return Vec3fa(vNg.x[i],vNg.y[i],vNg.z[i]); } - - public: - vbool<M> valid; - vfloat<M> vu; - vfloat<M> vv; - vfloat<M> vt; - Vec3vf<M> vNg; - }; - - template<int M> - __forceinline void interpolateUV(SubGridQuadHitPlueckerM<M> &hit,const GridMesh::Grid &g, const SubGrid& subgrid, const vint<M> &stepX, const vint<M> &stepY) - { - /* correct U,V interpolation across the entire grid */ - const vint<M> sx((int)subgrid.x()); - const vint<M> sy((int)subgrid.y()); - const vint<M> sxM(sx + stepX); - const vint<M> syM(sy + stepY); - const float inv_resX = rcp((float)((int)g.resX-1)); - const float inv_resY = rcp((float)((int)g.resY-1)); - hit.vu = (hit.vu + vfloat<M>(sxM)) * inv_resX; - hit.vv = (hit.vv + vfloat<M>(syM)) * inv_resY; - } - - template<int M> - __forceinline static bool intersectPluecker(Ray& ray, - const Vec3vf<M>& tri_v0, - const Vec3vf<M>& tri_v1, - const Vec3vf<M>& tri_v2, - const vbool<M>& flags, - SubGridQuadHitPlueckerM<M> &hit) - { - /* calculate vertices relative to ray origin */ - const Vec3vf<M> O = Vec3vf<M>((Vec3fa)ray.org); - const Vec3vf<M> D = Vec3vf<M>((Vec3fa)ray.dir); - const Vec3vf<M> v0 = tri_v0-O; - const Vec3vf<M> v1 = tri_v1-O; - const Vec3vf<M> v2 = tri_v2-O; - - /* calculate triangle edges */ - const Vec3vf<M> e0 = v2-v0; - const Vec3vf<M> e1 = v0-v1; - const Vec3vf<M> e2 = v1-v2; - - /* perform edge tests */ - const vfloat<M> U = dot(cross(e0,v2+v0),D); - const vfloat<M> V = dot(cross(e1,v0+v1),D); - const vfloat<M> W = dot(cross(e2,v1+v2),D); - const vfloat<M> UVW = U+V+W; - const vfloat<M> eps = float(ulp)*abs(UVW); -#if defined(EMBREE_BACKFACE_CULLING) - vbool<M> valid = max(U,V,W) <= eps; -#else - vbool<M> valid = (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); -#endif - if (unlikely(none(valid))) return false; - - /* calculate geometry normal and denominator */ - const Vec3vf<M> Ng = stable_triangle_normal(e0,e1,e2); - const vfloat<M> den = twice(dot(Ng,D)); - - /* perform depth test */ - const vfloat<M> T = twice(dot(v0,Ng)); - const vfloat<M> t = rcp(den)*T; - valid &= vfloat<M>(ray.tnear()) <= t & t <= vfloat<M>(ray.tfar); - valid &= den != vfloat<M>(zero); - if (unlikely(none(valid))) return false; - - /* update hit information */ - new (&hit) SubGridQuadHitPlueckerM<M>(valid,U,V,UVW,t,Ng,flags); - return true; - } - - template<int M, bool filter> - struct SubGridQuadMIntersector1Pluecker; - - template<int M, bool filter> - struct SubGridQuadMIntersector1Pluecker - { - __forceinline SubGridQuadMIntersector1Pluecker() {} - - __forceinline SubGridQuadMIntersector1Pluecker(const Ray& ray, const void* ptr) {} - - __forceinline void intersect(RayHit& ray, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - SubGridQuadHitPlueckerM<M> hit; - Intersect1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); - - /* intersect first triangle */ - if (intersectPluecker(ray,v0,v1,v3,vbool<M>(false),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - epilog(hit.valid,hit); - } - - /* intersect second triangle */ - if (intersectPluecker(ray,v2,v3,v1,vbool<M>(true),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - epilog(hit.valid,hit); - } - } - - __forceinline bool occluded(Ray& ray, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - SubGridQuadHitPlueckerM<M> hit; - Occluded1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); - - /* intersect first triangle */ - if (intersectPluecker(ray,v0,v1,v3,vbool<M>(false),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - if (epilog(hit.valid,hit)) - return true; - } - - /* intersect second triangle */ - if (intersectPluecker(ray,v2,v3,v1,vbool<M>(true),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - if (epilog(hit.valid,hit)) - return true; - } - - return false; - } - }; - -#if defined (__AVX__) - - /*! Intersects 4 quads with 1 ray using AVX */ - template<bool filter> - struct SubGridQuadMIntersector1Pluecker<4,filter> - { - __forceinline SubGridQuadMIntersector1Pluecker() {} - - __forceinline SubGridQuadMIntersector1Pluecker(const Ray& ray, const void* ptr) {} - - template<typename Epilog> - __forceinline bool intersect(Ray& ray, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid& subgrid, const Epilog& epilog) const - { - const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); - const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); -#else - const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); - const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); -#endif - SubGridQuadHitPlueckerM<8> hit; - const vbool8 flags(0,0,0,0,1,1,1,1); - if (unlikely(intersectPluecker(ray,vtx0,vtx1,vtx2,flags,hit))) - { - /* correct U,V interpolation across the entire grid */ - interpolateUV<8>(hit,g,subgrid,vint<8>(0,1,1,0,0,1,1,0),vint<8>(0,0,1,1,0,0,1,1)); - if (unlikely(epilog(hit.valid,hit))) - return true; - } - return false; - } - - __forceinline bool intersect(RayHit& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - return intersect(ray,v0,v1,v2,v3,g,subgrid,Intersect1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); - } - - __forceinline bool occluded(Ray& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const GridMesh::Grid &g, const SubGrid& subgrid) const - { - return intersect(ray,v0,v1,v2,v3,g,subgrid,Occluded1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); - } - }; - -#endif - - - /* ----------------------------- */ - /* -- ray packet intersectors -- */ - /* ----------------------------- */ - - template<int K> - struct SubGridQuadHitPlueckerK - { - __forceinline SubGridQuadHitPlueckerK(const vfloat<K>& U, - const vfloat<K>& V, - const vfloat<K>& UVW, - const vfloat<K>& t, - const Vec3vf<K>& Ng, - const vbool<K>& flags, - const GridMesh::Grid &g, - const SubGrid& subgrid, - const unsigned int i) - : U(U), V(V), UVW(UVW), t(t), flags(flags), tri_Ng(Ng), g(g), subgrid(subgrid), i(i) {} - - __forceinline std::tuple<vfloat<K>,vfloat<K>,vfloat<K>,Vec3vf<K>> operator() () const - { - const vbool<K> invalid = abs(UVW) < min_rcp_input; - const vfloat<K> rcpUVW = select(invalid,vfloat<K>(0.0f),rcp(UVW)); - const vfloat<K> u0 = min(U * rcpUVW,1.0f); - const vfloat<K> v0 = min(V * rcpUVW,1.0f); - const vfloat<K> u1 = vfloat<K>(1.0f) - u0; - const vfloat<K> v1 = vfloat<K>(1.0f) - v0; - const vfloat<K> uu = select(flags,u1,u0); - const vfloat<K> vv = select(flags,v1,v0); - const unsigned int sx = subgrid.x() + (unsigned int)(i % 2); - const unsigned int sy = subgrid.y() + (unsigned int)(i >>1); - const float inv_resX = rcp((float)(int)(g.resX-1)); - const float inv_resY = rcp((float)(int)(g.resY-1)); - const vfloat<K> u = (uu + (float)(int)sx) * inv_resX; - const vfloat<K> v = (vv + (float)(int)sy) * inv_resY; - const Vec3vf<K> Ng(tri_Ng.x,tri_Ng.y,tri_Ng.z); - return std::make_tuple(u,v,t,Ng); - } - - private: - const vfloat<K> U; - const vfloat<K> V; - const vfloat<K> UVW; - const vfloat<K> t; - const vfloat<K> absDen; - const vbool<K> flags; - const Vec3vf<K> tri_Ng; - - const GridMesh::Grid &g; - const SubGrid& subgrid; - const size_t i; - }; - - - template<int M, int K, bool filter> - struct SubGridQuadMIntersectorKPlueckerBase - { - __forceinline SubGridQuadMIntersectorKPlueckerBase(const vbool<K>& valid, const RayK<K>& ray) {} - - template<typename Epilog> - __forceinline vbool<K> intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& tri_v0, - const Vec3vf<K>& tri_v1, - const Vec3vf<K>& tri_v2, - const Vec3vf<K>& tri_Ng, - const vbool<K>& flags, - const GridMesh::Grid &g, - const SubGrid &subgrid, - const unsigned int i, - const Epilog& epilog) const - { - /* calculate denominator */ - /* calculate vertices relative to ray origin */ - vbool<K> valid = valid0; - const Vec3vf<K> O = ray.org; - const Vec3vf<K> D = ray.dir; - const Vec3vf<K> v0 = tri_v0-O; - const Vec3vf<K> v1 = tri_v1-O; - const Vec3vf<K> v2 = tri_v2-O; - - /* calculate triangle edges */ - const Vec3vf<K> e0 = v2-v0; - const Vec3vf<K> e1 = v0-v1; - const Vec3vf<K> e2 = v1-v2; - - /* perform edge tests */ - const vfloat<K> U = dot(Vec3vf<K>(cross(e0,v2+v0)),D); - const vfloat<K> V = dot(Vec3vf<K>(cross(e1,v0+v1)),D); - const vfloat<K> W = dot(Vec3vf<K>(cross(e2,v1+v2)),D); - const vfloat<K> UVW = U+V+W; - const vfloat<K> eps = float(ulp)*abs(UVW); -#if defined(EMBREE_BACKFACE_CULLING) - valid &= max(U,V,W) <= eps; -#else - valid &= (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); -#endif - if (unlikely(none(valid))) return false; - - /* calculate geometry normal and denominator */ - const Vec3vf<K> Ng = stable_triangle_normal(e0,e1,e2); - const vfloat<K> den = twice(dot(Vec3vf<K>(Ng),D)); - - /* perform depth test */ - const vfloat<K> T = twice(dot(v0,Vec3vf<K>(Ng))); - const vfloat<K> t = rcp(den)*T; - valid &= ray.tnear() <= t & t <= ray.tfar; - valid &= den != vfloat<K>(zero); - if (unlikely(none(valid))) return false; - - /* calculate hit information */ - SubGridQuadHitPlueckerK<K> hit(U,V,UVW,t,tri_Ng,flags,g,subgrid,i); - return epilog(valid,hit); - } - - template<typename Epilog> - __forceinline vbool<K> intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& v0, - const Vec3vf<K>& v1, - const Vec3vf<K>& v2, - const vbool<K>& flags, - const GridMesh::Grid &g, - const SubGrid &subgrid, - const unsigned int i, - const Epilog& epilog) const - { - const Vec3vf<K> e1 = v0-v1; - const Vec3vf<K> e2 = v2-v0; - const Vec3vf<K> Ng = cross(e2,e1); - return intersectK(valid0,ray,v0,v1,v2,Ng,flags,g,subgrid,i,epilog); - } - - template<typename Epilog> - __forceinline bool intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& v0, - const Vec3vf<K>& v1, - const Vec3vf<K>& v2, - const Vec3vf<K>& v3, - const GridMesh::Grid &g, - const SubGrid &subgrid, - const unsigned int i, - const Epilog& epilog) const - { - intersectK(valid0,ray,v0,v1,v3,vbool<K>(false),g,subgrid,i,epilog); - if (none(valid0)) return true; - intersectK(valid0,ray,v2,v3,v1,vbool<K>(true ),g,subgrid,i,epilog); - return none(valid0); - } - - static __forceinline bool intersect1(RayK<K>& ray, - size_t k, - const Vec3vf<M>& tri_v0, - const Vec3vf<M>& tri_v1, - const Vec3vf<M>& tri_v2, - const Vec3vf<M>& tri_Ng, - const vbool<M>& flags, - SubGridQuadHitPlueckerM<M> &hit) - { - /* calculate vertices relative to ray origin */ - const Vec3vf<M> O = broadcast<vfloat<M>>(ray.org,k); - const Vec3vf<M> D = broadcast<vfloat<M>>(ray.dir,k); - const Vec3vf<M> v0 = tri_v0-O; - const Vec3vf<M> v1 = tri_v1-O; - const Vec3vf<M> v2 = tri_v2-O; - - /* calculate triangle edges */ - const Vec3vf<M> e0 = v2-v0; - const Vec3vf<M> e1 = v0-v1; - const Vec3vf<M> e2 = v1-v2; - - /* perform edge tests */ - const vfloat<M> U = dot(cross(e0,v2+v0),D); - const vfloat<M> V = dot(cross(e1,v0+v1),D); - const vfloat<M> W = dot(cross(e2,v1+v2),D); - const vfloat<M> UVW = U+V+W; - const vfloat<M> eps = float(ulp)*abs(UVW); -#if defined(EMBREE_BACKFACE_CULLING) - vbool<M> valid = max(U,V,W) <= eps ; -#else - vbool<M> valid = (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); -#endif - if (unlikely(none(valid))) return false; - - /* calculate geometry normal and denominator */ - const Vec3vf<M> Ng = stable_triangle_normal(e0,e1,e2); - const vfloat<M> den = twice(dot(Ng,D)); - - /* perform depth test */ - const vfloat<M> T = twice(dot(v0,Ng)); - const vfloat<M> t = rcp(den)*T; - valid &= vfloat<M>(ray.tnear()[k]) <= t & t <= vfloat<M>(ray.tfar[k]); - if (unlikely(none(valid))) return false; - - /* avoid division by 0 */ - valid &= den != vfloat<M>(zero); - if (unlikely(none(valid))) return false; - - /* update hit information */ - new (&hit) SubGridQuadHitPlueckerM<M>(valid,U,V,UVW,t,tri_Ng,flags); - return true; - } - - static __forceinline bool intersect1(RayK<K>& ray, - size_t k, - const Vec3vf<M>& v0, - const Vec3vf<M>& v1, - const Vec3vf<M>& v2, - const vbool<M>& flags, - SubGridQuadHitPlueckerM<M> &hit) - { - const Vec3vf<M> e1 = v0-v1; - const Vec3vf<M> e2 = v2-v0; - const Vec3vf<M> Ng = cross(e2,e1); // FIXME: optimize!!! - return intersect1(ray,k,v0,v1,v2,Ng,flags,hit); - } - - }; - - template<int M, int K, bool filter> - struct SubGridQuadMIntersectorKPluecker : public SubGridQuadMIntersectorKPlueckerBase<M,K,filter> - { - __forceinline SubGridQuadMIntersectorKPluecker(const vbool<K>& valid, const RayK<K>& ray) - : SubGridQuadMIntersectorKPlueckerBase<M,K,filter>(valid,ray) {} - - __forceinline void intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const - { - Intersect1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); - - SubGridQuadHitPlueckerM<4> hit; - if (SubGridQuadMIntersectorKPlueckerBase<4,K,filter>::intersect1(ray,k,v0,v1,v3,vboolf4(false),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - epilog(hit.valid,hit); - } - - if (SubGridQuadMIntersectorKPlueckerBase<4,K,filter>::intersect1(ray,k,v2,v3,v1,vboolf4(true),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - epilog(hit.valid,hit); - } - - } - - __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const - { - Occluded1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); - - SubGridQuadHitPlueckerM<4> hit; - if (SubGridQuadMIntersectorKPlueckerBase<4,K,filter>::intersect1(ray,k,v0,v1,v3,vboolf4(false),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - if (epilog(hit.valid,hit)) return true; - } - - if (SubGridQuadMIntersectorKPlueckerBase<4,K,filter>::intersect1(ray,k,v2,v3,v1,vboolf4(true),hit)) - { - interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); - if (epilog(hit.valid,hit)) return true; - } - return false; - } - }; - - } -} diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_any_of.h b/thirdparty/embree/common/algorithms/parallel_any_of.h index 01f1f80f6c..a64e4a1889 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_any_of.h +++ b/thirdparty/embree/common/algorithms/parallel_any_of.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_filter.h b/thirdparty/embree/common/algorithms/parallel_filter.h index 5823fc631f..090ef164c2 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_filter.h +++ b/thirdparty/embree/common/algorithms/parallel_filter.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for.h b/thirdparty/embree/common/algorithms/parallel_for.h index 51d296fb16..645681ac63 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_for.h +++ b/thirdparty/embree/common/algorithms/parallel_for.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -8,12 +8,6 @@ #include "../math/math.h" #include "../math/range.h" -#if defined(TASKING_GCD) && defined(BUILD_IOS) -#include <dispatch/dispatch.h> -#include <algorithm> -#include <type_traits> -#endif - namespace embree { /* parallel_for without range */ @@ -29,28 +23,10 @@ namespace embree if (!TaskScheduler::wait()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- } -#elif defined(TASKING_GCD) && defined(BUILD_IOS) - - const size_t baselineNumBlocks = (TaskScheduler::threadCount() > 1)? TaskScheduler::threadCount() : 1; - const size_t length = N; - const size_t blockSize = (length + baselineNumBlocks-1) / baselineNumBlocks; - const size_t numBlocks = (length + blockSize-1) / blockSize; - - dispatch_apply(numBlocks, DISPATCH_APPLY_AUTO, ^(size_t currentBlock) { - - const size_t start = (currentBlock * blockSize); - const size_t blockLength = std::min(length - start, blockSize); - const size_t end = start + blockLength; - - for(size_t i=start; i < end; i++) - { - func(i); - } - }); - + #elif defined(TASKING_TBB) #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; @@ -60,7 +36,7 @@ namespace embree if (context.is_group_execution_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { @@ -69,7 +45,7 @@ namespace embree if (tbb::task::self().is_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #endif @@ -92,28 +68,9 @@ namespace embree if (!TaskScheduler::wait()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- -#elif defined(TASKING_GCD) && defined(BUILD_IOS) - - const size_t baselineNumBlocks = (TaskScheduler::threadCount() > 1)? 4*TaskScheduler::threadCount() : 1; - const size_t length = last - first; - const size_t blockSizeByThreads = (length + baselineNumBlocks-1) / baselineNumBlocks; - size_t blockSize = std::max<size_t>(minStepSize,blockSizeByThreads); - blockSize += blockSize % 4; - - const size_t numBlocks = (length + blockSize-1) / blockSize; - - dispatch_apply(numBlocks, DISPATCH_APPLY_AUTO, ^(size_t currentBlock) { - - const size_t start = first + (currentBlock * blockSize); - const size_t end = std::min<size_t>(last, start + blockSize); - - func( embree::range<Index>(start,end) ); - }); - - #elif defined(TASKING_TBB) #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; @@ -123,7 +80,7 @@ namespace embree if (context.is_group_execution_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #else tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) { @@ -132,7 +89,7 @@ namespace embree if (tbb::task::self().is_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #endif @@ -167,7 +124,7 @@ namespace embree if (context.is_group_execution_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { @@ -176,7 +133,7 @@ namespace embree if (tbb::task::self().is_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #endif } @@ -192,10 +149,10 @@ namespace embree func(i); },ap,context); if (context.is_group_execution_cancelled()) - // -- GODOT start -- - // throw std::runtime_error("task cancelled"); - abort(); - // -- GODOT end -- + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); + abort(); + // -- GODOT end -- #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); @@ -203,7 +160,7 @@ namespace embree if (tbb::task::self().is_cancelled()) // -- GODOT start -- // throw std::runtime_error("task cancelled"); - abort(); + abort(); // -- GODOT end -- #endif } diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for.h b/thirdparty/embree/common/algorithms/parallel_for_for.h index 852b8a0900..92c37a4a38 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for.h +++ b/thirdparty/embree/common/algorithms/parallel_for_for.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for_prefix_sum.h b/thirdparty/embree/common/algorithms/parallel_for_for_prefix_sum.h index d2671d8a6a..b15b44a991 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_for_for_prefix_sum.h +++ b/thirdparty/embree/common/algorithms/parallel_for_for_prefix_sum.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_map.h b/thirdparty/embree/common/algorithms/parallel_map.h index 02e1a8f8d0..15c098fe20 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_map.h +++ b/thirdparty/embree/common/algorithms/parallel_map.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_partition.h b/thirdparty/embree/common/algorithms/parallel_partition.h index 3b3ad7c854..a1cbdc8e04 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_partition.h +++ b/thirdparty/embree/common/algorithms/parallel_partition.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_prefix_sum.h b/thirdparty/embree/common/algorithms/parallel_prefix_sum.h index 117c7a79b0..208bb4e480 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_prefix_sum.h +++ b/thirdparty/embree/common/algorithms/parallel_prefix_sum.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.h b/thirdparty/embree/common/algorithms/parallel_reduce.h index 0daf94e50e..8271372ea4 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.h +++ b/thirdparty/embree/common/algorithms/parallel_reduce.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,7 +43,7 @@ namespace embree template<typename Index, typename Value, typename Func, typename Reduction> __forceinline Value parallel_reduce( const Index first, const Index last, const Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction ) { -#if defined(TASKING_INTERNAL) || (defined(TASKING_GCD) && defined(BUILD_IOS)) +#if defined(TASKING_INTERNAL) /* fast path for small number of iterations */ Index taskCount = (last-first+minStepSize-1)/minStepSize; diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_set.h b/thirdparty/embree/common/algorithms/parallel_set.h index 640beba7ec..7eae577457 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_set.h +++ b/thirdparty/embree/common/algorithms/parallel_set.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_sort.h b/thirdparty/embree/common/algorithms/parallel_sort.h index a758227c1b..30e56c2bfc 100644 --- a/thirdparty/embree-aarch64/common/algorithms/parallel_sort.h +++ b/thirdparty/embree/common/algorithms/parallel_sort.h @@ -1,13 +1,10 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../simd/simd.h" #include "parallel_for.h" -#if defined(TASKING_GCD) && defined(BUILD_IOS) -#include "../sys/alloc.h" -#endif #include <algorithm> namespace embree @@ -323,7 +320,7 @@ namespace embree #pragma nounroll #endif for (size_t i=startID; i<endID; i++) { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) const size_t index = ((size_t)(Key)src[i] >> (size_t)shift) & (size_t)mask; #else const Key index = ((Key)src[i] >> shift) & mask; @@ -385,7 +382,7 @@ namespace embree #endif for (size_t i=startID; i<endID; i++) { const Ty elt = src[i]; -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) const size_t index = ((size_t)(Key)src[i] >> (size_t)shift) & (size_t)mask; #else const size_t index = ((Key)src[i] >> shift) & mask; diff --git a/thirdparty/embree-aarch64/common/lexers/parsestream.h b/thirdparty/embree/common/lexers/parsestream.h index db46dc114f..f65a52cb47 100644 --- a/thirdparty/embree-aarch64/common/lexers/parsestream.h +++ b/thirdparty/embree/common/lexers/parsestream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/lexers/stream.h b/thirdparty/embree/common/lexers/stream.h index 3f75677e68..a40c15f8eb 100644 --- a/thirdparty/embree-aarch64/common/lexers/stream.h +++ b/thirdparty/embree/common/lexers/stream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/lexers/streamfilters.h b/thirdparty/embree/common/lexers/streamfilters.h index 25580a77b8..3592b77b03 100644 --- a/thirdparty/embree-aarch64/common/lexers/streamfilters.h +++ b/thirdparty/embree/common/lexers/streamfilters.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/lexers/stringstream.cpp b/thirdparty/embree/common/lexers/stringstream.cpp index 98dc80ad59..a037869506 100644 --- a/thirdparty/embree-aarch64/common/lexers/stringstream.cpp +++ b/thirdparty/embree/common/lexers/stringstream.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "stringstream.h" diff --git a/thirdparty/embree-aarch64/common/lexers/stringstream.h b/thirdparty/embree/common/lexers/stringstream.h index e6dbd4aecc..6d9c27e3cd 100644 --- a/thirdparty/embree-aarch64/common/lexers/stringstream.h +++ b/thirdparty/embree/common/lexers/stringstream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/lexers/tokenstream.cpp b/thirdparty/embree/common/lexers/tokenstream.cpp index d05be65862..6ed6f2045a 100644 --- a/thirdparty/embree-aarch64/common/lexers/tokenstream.cpp +++ b/thirdparty/embree/common/lexers/tokenstream.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "tokenstream.h" diff --git a/thirdparty/embree-aarch64/common/lexers/tokenstream.h b/thirdparty/embree/common/lexers/tokenstream.h index 72a7b4f2f3..6e49dd0b39 100644 --- a/thirdparty/embree-aarch64/common/lexers/tokenstream.h +++ b/thirdparty/embree/common/lexers/tokenstream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/affinespace.h b/thirdparty/embree/common/math/affinespace.h index 32452fbe72..9d4a0f0846 100644 --- a/thirdparty/embree-aarch64/common/math/affinespace.h +++ b/thirdparty/embree/common/math/affinespace.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/bbox.h b/thirdparty/embree/common/math/bbox.h index 29bb13912b..bc43155358 100644 --- a/thirdparty/embree-aarch64/common/math/bbox.h +++ b/thirdparty/embree/common/math/bbox.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -77,7 +77,7 @@ namespace embree return lower > upper; } -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined(__SSE__) template<> __forceinline bool BBox<Vec3fa>::empty() const { return !all(le_mask(lower,upper)); } @@ -228,11 +228,11 @@ namespace embree /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// -#if defined (__SSE__) || defined(__ARM_NEON) +#if defined __SSE__ #include "../simd/sse.h" #endif -#if defined (__AVX__) +#if defined __AVX__ #include "../simd/avx.h" #endif diff --git a/thirdparty/embree-aarch64/common/math/col3.h b/thirdparty/embree/common/math/col3.h index f52015fb88..3f50c04393 100644 --- a/thirdparty/embree-aarch64/common/math/col3.h +++ b/thirdparty/embree/common/math/col3.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -42,6 +42,6 @@ namespace embree } /*! default template instantiations */ - typedef Col3<uint8_t > Col3uc; + typedef Col3<unsigned char> Col3uc; typedef Col3<float > Col3f; } diff --git a/thirdparty/embree-aarch64/common/math/col4.h b/thirdparty/embree/common/math/col4.h index 90df293f8e..788508516b 100644 --- a/thirdparty/embree-aarch64/common/math/col4.h +++ b/thirdparty/embree/common/math/col4.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -42,6 +42,6 @@ namespace embree } /*! default template instantiations */ - typedef Col4<uint8_t > Col4uc; + typedef Col4<unsigned char> Col4uc; typedef Col4<float > Col4f; } diff --git a/thirdparty/embree-aarch64/common/math/color.h b/thirdparty/embree/common/math/color.h index c3083e4fc0..529584ea16 100644 --- a/thirdparty/embree-aarch64/common/math/color.h +++ b/thirdparty/embree/common/math/color.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -52,17 +52,17 @@ namespace embree __forceinline void set(Col3uc& d) const { vfloat4 s = clamp(vfloat4(m128))*255.0f; - d.r = (uint8_t)(s[0]); - d.g = (uint8_t)(s[1]); - d.b = (uint8_t)(s[2]); + d.r = (unsigned char)(s[0]); + d.g = (unsigned char)(s[1]); + d.b = (unsigned char)(s[2]); } __forceinline void set(Col4uc& d) const { vfloat4 s = clamp(vfloat4(m128))*255.0f; - d.r = (uint8_t)(s[0]); - d.g = (uint8_t)(s[1]); - d.b = (uint8_t)(s[2]); - d.a = (uint8_t)(s[3]); + d.r = (unsigned char)(s[0]); + d.g = (unsigned char)(s[1]); + d.b = (unsigned char)(s[2]); + d.a = (unsigned char)(s[3]); } //////////////////////////////////////////////////////////////////////////////// @@ -114,16 +114,16 @@ namespace embree __forceinline void set(Col3uc& d) const { vfloat4 s = clamp(vfloat4(m128))*255.0f; - d.r = (uint8_t)(s[0]); - d.g = (uint8_t)(s[1]); - d.b = (uint8_t)(s[2]); + d.r = (unsigned char)(s[0]); + d.g = (unsigned char)(s[1]); + d.b = (unsigned char)(s[2]); } __forceinline void set(Col4uc& d) const { vfloat4 s = clamp(vfloat4(m128))*255.0f; - d.r = (uint8_t)(s[0]); - d.g = (uint8_t)(s[1]); - d.b = (uint8_t)(s[2]); + d.r = (unsigned char)(s[0]); + d.g = (unsigned char)(s[1]); + d.b = (unsigned char)(s[2]); d.a = 255; } @@ -152,37 +152,21 @@ namespace embree } __forceinline const Color rcp ( const Color& a ) { -#if defined(__aarch64__) && defined(BUILD_IOS) - __m128 reciprocal = _mm_rcp_ps(a.m128); - reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); - return (const Color)reciprocal; -#else #if defined(__AVX512VL__) const Color r = _mm_rcp14_ps(a.m128); #else const Color r = _mm_rcp_ps(a.m128); #endif return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a)); -#endif //defined(__aarch64__) && defined(BUILD_IOS) } __forceinline const Color rsqrt( const Color& a ) { -#if defined(__aarch64__) && defined(BUILD_IOS) - __m128 r = _mm_rsqrt_ps(a.m128); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); - return r; -#else - #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); - -#endif //defined(__aarch64__) && defined(BUILD_IOS) } __forceinline const Color sqrt ( const Color& a ) { return _mm_sqrt_ps(a.m128); } diff --git a/thirdparty/embree/common/math/constants.cpp b/thirdparty/embree/common/math/constants.cpp new file mode 100644 index 0000000000..03919ae20c --- /dev/null +++ b/thirdparty/embree/common/math/constants.cpp @@ -0,0 +1,27 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "constants.h" + +namespace embree +{ + TrueTy True; + FalseTy False; + ZeroTy zero; + OneTy one; + NegInfTy neg_inf; + PosInfTy inf; + PosInfTy pos_inf; + NaNTy nan; + UlpTy ulp; + PiTy pi; + OneOverPiTy one_over_pi; + TwoPiTy two_pi; + OneOverTwoPiTy one_over_two_pi; + FourPiTy four_pi; + OneOverFourPiTy one_over_four_pi; + StepTy step; + ReverseStepTy reverse_step; + EmptyTy empty; + UndefinedTy undefined; +} diff --git a/thirdparty/embree-aarch64/common/math/constants.h b/thirdparty/embree/common/math/constants.h index e80abec80f..578473a8ab 100644 --- a/thirdparty/embree-aarch64/common/math/constants.h +++ b/thirdparty/embree/common/math/constants.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -12,19 +12,6 @@ #include <cfloat> #include <climits> -// Math constants may not be defined in libcxx + mingw + strict C++ standard -#if defined(__MINGW32__) - -// TODO(LTE): use constexpr -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#ifndef M_1_PI -#define M_1_PI 0.31830988618379067154 -#endif - -#endif // __MINGW32__ - namespace embree { static MAYBE_UNUSED const float one_over_255 = 1.0f/255.0f; @@ -57,8 +44,8 @@ namespace embree __forceinline operator unsigned int ( ) const { return 0; } __forceinline operator short ( ) const { return 0; } __forceinline operator unsigned short ( ) const { return 0; } - __forceinline operator int8_t ( ) const { return 0; } - __forceinline operator uint8_t ( ) const { return 0; } + __forceinline operator char ( ) const { return 0; } + __forceinline operator unsigned char ( ) const { return 0; } }; extern MAYBE_UNUSED ZeroTy zero; @@ -75,8 +62,8 @@ namespace embree __forceinline operator unsigned int ( ) const { return 1; } __forceinline operator short ( ) const { return 1; } __forceinline operator unsigned short ( ) const { return 1; } - __forceinline operator int8_t ( ) const { return 1; } - __forceinline operator uint8_t ( ) const { return 1; } + __forceinline operator char ( ) const { return 1; } + __forceinline operator unsigned char ( ) const { return 1; } }; extern MAYBE_UNUSED OneTy one; @@ -93,8 +80,8 @@ namespace embree __forceinline operator unsigned int ( ) const { return std::numeric_limits<unsigned int>::min(); } __forceinline operator short ( ) const { return std::numeric_limits<short>::min(); } __forceinline operator unsigned short ( ) const { return std::numeric_limits<unsigned short>::min(); } - __forceinline operator int8_t ( ) const { return std::numeric_limits<int8_t>::min(); } - __forceinline operator uint8_t ( ) const { return std::numeric_limits<uint8_t>::min(); } + __forceinline operator char ( ) const { return std::numeric_limits<char>::min(); } + __forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::min(); } }; @@ -112,8 +99,8 @@ namespace embree __forceinline operator unsigned int ( ) const { return std::numeric_limits<unsigned int>::max(); } __forceinline operator short ( ) const { return std::numeric_limits<short>::max(); } __forceinline operator unsigned short ( ) const { return std::numeric_limits<unsigned short>::max(); } - __forceinline operator int8_t ( ) const { return std::numeric_limits<int8_t>::max(); } - __forceinline operator uint8_t ( ) const { return std::numeric_limits<uint8_t>::max(); } + __forceinline operator char ( ) const { return std::numeric_limits<char>::max(); } + __forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::max(); } }; extern MAYBE_UNUSED PosInfTy inf; @@ -207,33 +194,4 @@ namespace embree }; extern MAYBE_UNUSED UndefinedTy undefined; - -#if defined(__aarch64__) - extern const uint32x4_t movemask_mask; - extern const uint32x4_t vzero; - extern const uint32x4_t v0x80000000; - extern const uint32x4_t v0x7fffffff; - extern const uint32x4_t v000F; - extern const uint32x4_t v00F0; - extern const uint32x4_t v00FF; - extern const uint32x4_t v0F00; - extern const uint32x4_t v0F0F; - extern const uint32x4_t v0FF0; - extern const uint32x4_t v0FFF; - extern const uint32x4_t vF000; - extern const uint32x4_t vF00F; - extern const uint32x4_t vF0F0; - extern const uint32x4_t vF0FF; - extern const uint32x4_t vFF00; - extern const uint32x4_t vFF0F; - extern const uint32x4_t vFFF0; - extern const uint32x4_t vFFFF; - extern const uint8x16_t v0022; - extern const uint8x16_t v1133; - extern const uint8x16_t v0101; - extern const float32x4_t vOne; - extern const float32x4_t vmOne; - extern const float32x4_t vInf; - extern const float32x4_t vmInf; -#endif } diff --git a/thirdparty/embree-aarch64/common/math/interval.h b/thirdparty/embree/common/math/interval.h index f06478e881..310add2129 100644 --- a/thirdparty/embree-aarch64/common/math/interval.h +++ b/thirdparty/embree/common/math/interval.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/lbbox.h b/thirdparty/embree/common/math/lbbox.h index 95df4a918d..2b397a05c8 100644 --- a/thirdparty/embree-aarch64/common/math/lbbox.h +++ b/thirdparty/embree/common/math/lbbox.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/linearspace2.h b/thirdparty/embree/common/math/linearspace2.h index b9a382962c..184ee695fb 100644 --- a/thirdparty/embree-aarch64/common/math/linearspace2.h +++ b/thirdparty/embree/common/math/linearspace2.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/linearspace3.h b/thirdparty/embree/common/math/linearspace3.h index 12b5bb776b..9eaa2cc2bb 100644 --- a/thirdparty/embree-aarch64/common/math/linearspace3.h +++ b/thirdparty/embree/common/math/linearspace3.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/math.h b/thirdparty/embree/common/math/math.h index 6d54abd44d..4bc54c1a6a 100644 --- a/thirdparty/embree-aarch64/common/math/math.h +++ b/thirdparty/embree/common/math/math.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -9,18 +9,15 @@ #include <cmath> #if defined(__ARM_NEON) -#include "SSE2NEON.h" -#if defined(NEON_AVX2_EMULATION) -#include "AVX2NEON.h" -#endif +#include "../simd/arm/emulation.h" #else #include <emmintrin.h> #include <xmmintrin.h> #include <immintrin.h> #endif -#if defined(__WIN32__) && !defined(__MINGW32__) -#if (__MSV_VER <= 1700) +#if defined(__WIN32__) +#if defined(_MSC_VER) && (_MSC_VER <= 1700) namespace std { __forceinline bool isinf ( const float x ) { return _finite(x) == 0; } @@ -47,7 +44,7 @@ namespace embree __forceinline int toInt (const float& a) { return int(a); } __forceinline float toFloat(const int& a) { return float(a); } -#if defined(__WIN32__) && !defined(__MINGW32__) +#if defined(__WIN32__) __forceinline bool finite ( const float x ) { return _finite(x) != 0; } #endif @@ -56,16 +53,6 @@ namespace embree __forceinline float rcp ( const float x ) { -#if defined(__aarch64__) - // Move scalar to vector register and do rcp. - __m128 a; - a[0] = x; - float32x4_t reciprocal = vrecpeq_f32(a); - reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); - return reciprocal[0]; -#else - const __m128 a = _mm_set_ss(x); #if defined(__AVX512VL__) @@ -79,74 +66,33 @@ namespace embree #else return _mm_cvtss_f32(_mm_mul_ss(r,_mm_sub_ss(_mm_set_ss(2.0f), _mm_mul_ss(r, a)))); #endif - -#endif //defined(__aarch64__) } __forceinline float signmsk ( const float x ) { -#if defined(__aarch64__) - // FP and Neon shares same vector register in arm64 - __m128 a; - __m128i b; - a[0] = x; - b[0] = 0x80000000; - a = _mm_and_ps(a, vreinterpretq_f32_s32(b)); - return a[0]; -#else return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(0x80000000)))); -#endif } __forceinline float xorf( const float x, const float y ) { -#if defined(__aarch64__) - // FP and Neon shares same vector register in arm64 - __m128 a; - __m128 b; - a[0] = x; - b[0] = y; - a = _mm_xor_ps(a, b); - return a[0]; -#else return _mm_cvtss_f32(_mm_xor_ps(_mm_set_ss(x),_mm_set_ss(y))); -#endif } __forceinline float andf( const float x, const unsigned y ) { -#if defined(__aarch64__) - // FP and Neon shares same vector register in arm64 - __m128 a; - __m128i b; - a[0] = x; - b[0] = y; - a = _mm_and_ps(a, vreinterpretq_f32_s32(b)); - return a[0]; -#else return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(y)))); -#endif } __forceinline float rsqrt( const float x ) { -#if defined(__aarch64__) - // FP and Neon shares same vector register in arm64 - __m128 a; - a[0] = x; - __m128 value = _mm_rsqrt_ps(a); - value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(a, value), value)); - value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(a, value), value)); - return value[0]; -#else - const __m128 a = _mm_set_ss(x); #if defined(__AVX512VL__) - const __m128 r = _mm_rsqrt14_ss(_mm_set_ss(0.0f),a); + __m128 r = _mm_rsqrt14_ss(_mm_set_ss(0.0f),a); #else - const __m128 r = _mm_rsqrt_ss(a); + __m128 r = _mm_rsqrt_ss(a); #endif - const __m128 c = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), - _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); - return _mm_cvtss_f32(c); + r = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); +#if defined(__ARM_NEON) + r = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); #endif + return _mm_cvtss_f32(r); } -#if defined(__WIN32__) && (__MSC_VER <= 1700) && !defined(__MINGW32__) +#if defined(__WIN32__) && defined(_MSC_VER) && (_MSC_VER <= 1700) __forceinline float nextafter(float x, float y) { if ((x<y) == (x>0)) return x*(1.1f+float(ulp)); else return x*(0.9f-float(ulp)); } __forceinline double nextafter(double x, double y) { return _nextafter(x, y); } __forceinline int roundf(float f) { return (int)(f + 0.5f); } @@ -200,17 +146,7 @@ namespace embree __forceinline double floor( const double x ) { return ::floor (x); } __forceinline double ceil ( const double x ) { return ::ceil (x); } -#if defined(__aarch64__) - __forceinline float mini(float a, float b) { - // FP and Neon shares same vector register in arm64 - __m128 x; - __m128 y; - x[0] = a; - y[0] = b; - x = _mm_min_ps(x, y); - return x[0]; - } -#elif defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline float mini(float a, float b) { const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); @@ -219,17 +155,7 @@ namespace embree } #endif -#if defined(__aarch64__) - __forceinline float maxi(float a, float b) { - // FP and Neon shares same vector register in arm64 - __m128 x; - __m128 y; - x[0] = a; - y[0] = b; - x = _mm_max_ps(x, y); - return x[0]; - } -#elif defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline float maxi(float a, float b) { const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); @@ -246,7 +172,7 @@ namespace embree __forceinline int64_t min(int64_t a, int64_t b) { return a<b ? a:b; } __forceinline float min(float a, float b) { return a<b ? a:b; } __forceinline double min(double a, double b) { return a<b ? a:b; } -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) __forceinline size_t min(size_t a, size_t b) { return a<b ? a:b; } #endif @@ -263,7 +189,7 @@ namespace embree __forceinline int64_t max(int64_t a, int64_t b) { return a<b ? b:a; } __forceinline float max(float a, float b) { return a<b ? b:a; } __forceinline double max(double a, double b) { return a<b ? b:a; } -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) __forceinline size_t max(size_t a, size_t b) { return a<b ? b:a; } #endif @@ -305,16 +231,6 @@ namespace embree __forceinline float msub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float nmadd ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmadd_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float nmsub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } -#elif defined (__aarch64__) && defined(__clang__) -#pragma clang fp contract(fast) - - -__forceinline float madd ( const float a, const float b, const float c) { return a*b + c; } -__forceinline float msub ( const float a, const float b, const float c) { return a*b - c; } -__forceinline float nmadd ( const float a, const float b, const float c) { return c - a*b; } -__forceinline float nmsub ( const float a, const float b, const float c) { return -(c + a*b); } - -#pragma clang fp contract(on) #else __forceinline float madd ( const float a, const float b, const float c) { return a*b+c; } __forceinline float msub ( const float a, const float b, const float c) { return a*b-c; } @@ -363,15 +279,17 @@ __forceinline float nmsub ( const float a, const float b, const float c) { retur /*! exchange */ template<typename T> __forceinline void xchg ( T& a, T& b ) { const T tmp = a; a = b; b = tmp; } - - template<typename T> __forceinline T prod_diff(const T& a,const T& b,const T& c,const T& d) { -#if 1//!defined(__aarch64__) - return msub(a,b,c*d); -#else - return nmadd(c,d,a*b); -#endif - } - + /* load/store */ + template<typename Ty> struct mem; + + template<> struct mem<float> { + static __forceinline float load (bool mask, const void* ptr) { return mask ? *(float*)ptr : 0.0f; } + static __forceinline float loadu(bool mask, const void* ptr) { return mask ? *(float*)ptr : 0.0f; } + + static __forceinline void store (bool mask, void* ptr, const float v) { if (mask) *(float*)ptr = v; } + static __forceinline void storeu(bool mask, void* ptr, const float v) { if (mask) *(float*)ptr = v; } + }; + /*! bit reverse operation */ template<class T> __forceinline T bitReverse(const T& vin) @@ -389,7 +307,7 @@ __forceinline float nmsub ( const float a, const float b, const float c) { retur template<class T> __forceinline T bitInterleave(const T& xin, const T& yin, const T& zin) { - T x = xin, y = yin, z = zin; + T x = xin, y = yin, z = zin; x = (x | (x << 16)) & 0x030000FF; x = (x | (x << 8)) & 0x0300F00F; x = (x | (x << 4)) & 0x030C30C3; @@ -408,7 +326,7 @@ __forceinline float nmsub ( const float a, const float b, const float c) { retur return x | (y << 1) | (z << 2); } -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) template<> __forceinline unsigned int bitInterleave(const unsigned int &xi, const unsigned int& yi, const unsigned int& zi) diff --git a/thirdparty/embree-aarch64/common/math/obbox.h b/thirdparty/embree/common/math/obbox.h index 032b56904e..2fe8bbf071 100644 --- a/thirdparty/embree-aarch64/common/math/obbox.h +++ b/thirdparty/embree/common/math/obbox.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/quaternion.h b/thirdparty/embree/common/math/quaternion.h index 20c69bc62f..080800efcd 100644 --- a/thirdparty/embree-aarch64/common/math/quaternion.h +++ b/thirdparty/embree/common/math/quaternion.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/range.h b/thirdparty/embree/common/math/range.h index 762d9cd9ea..909fadb995 100644 --- a/thirdparty/embree-aarch64/common/math/range.h +++ b/thirdparty/embree/common/math/range.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/transcendental.h b/thirdparty/embree/common/math/transcendental.h index 6855d82b53..fd16c26e81 100644 --- a/thirdparty/embree-aarch64/common/math/transcendental.h +++ b/thirdparty/embree/common/math/transcendental.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -418,7 +418,7 @@ __forceinline void __rangeReduceLog(const T &input, } template <typename T> struct ExponentType { }; -template <int N> struct ExponentType<vfloat<N>> { typedef vint<N> Ty; }; +template <int N> struct ExponentType<vfloat_impl<N>> { typedef vint<N> Ty; }; template <> struct ExponentType<float> { typedef int Ty; }; template <typename T> diff --git a/thirdparty/embree-aarch64/common/math/vec2.h b/thirdparty/embree/common/math/vec2.h index a619459e9c..d62aef51f3 100644 --- a/thirdparty/embree-aarch64/common/math/vec2.h +++ b/thirdparty/embree/common/math/vec2.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -205,11 +205,11 @@ namespace embree #include "vec2fa.h" -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined __SSE__ #include "../simd/sse.h" #endif -#if defined(__AVX__) +#if defined __AVX__ #include "../simd/avx.h" #endif @@ -221,7 +221,7 @@ namespace embree { template<> __forceinline Vec2<float>::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined(__SSE__) template<> __forceinline Vec2<vfloat4>::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} #endif diff --git a/thirdparty/embree-aarch64/common/math/vec2fa.h b/thirdparty/embree/common/math/vec2fa.h index 451ecd556c..a51fb68fd0 100644 --- a/thirdparty/embree-aarch64/common/math/vec2fa.h +++ b/thirdparty/embree/common/math/vec2fa.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -97,12 +97,6 @@ namespace embree __forceinline Vec2fa rcp ( const Vec2fa& a ) { -#if defined(__aarch64__) - __m128 reciprocal = _mm_rcp_ps(a.m128); - reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); - return (const Vec2fa)reciprocal; -#else #if defined(__AVX512VL__) const Vec2fa r = _mm_rcp14_ps(a.m128); #else @@ -117,7 +111,6 @@ namespace embree #endif return res; -#endif //defined(__aarch64__) } __forceinline Vec2fa sqrt ( const Vec2fa& a ) { return _mm_sqrt_ps(a.m128); } @@ -125,21 +118,12 @@ namespace embree __forceinline Vec2fa rsqrt( const Vec2fa& a ) { -#if defined(__aarch64__) - __m128 r = _mm_rsqrt_ps(a.m128); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); - return r; -#else - #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); - -#endif } __forceinline Vec2fa zero_fix(const Vec2fa& a) { @@ -172,7 +156,7 @@ namespace embree __forceinline Vec2fa min( const Vec2fa& a, const Vec2fa& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec2fa max( const Vec2fa& a, const Vec2fa& b ) { return _mm_max_ps(a.m128,b.m128); } -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec2fa mini(const Vec2fa& a, const Vec2fa& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); @@ -181,7 +165,7 @@ namespace embree } #endif -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec2fa maxi(const Vec2fa& a, const Vec2fa& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); @@ -292,9 +276,9 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) -__forceinline Vec2fa floor(const Vec2fa& a) { return vrndmq_f32(a); } -__forceinline Vec2fa ceil (const Vec2fa& a) { return vrndpq_f32(a); } -//__forceinline Vec2fa trunc(const Vec2fa& a) { return vrndq_f32(a); } + //__forceinline Vec2fa trunc(const Vec2fa& a) { return vrndq_f32(a); } + __forceinline Vec2fa floor(const Vec2fa& a) { return vrndmq_f32(a); } + __forceinline Vec2fa ceil (const Vec2fa& a) { return vrndpq_f32(a); } #elif defined (__SSE4_1__) //__forceinline Vec2fa trunc( const Vec2fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); } __forceinline Vec2fa floor( const Vec2fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); } diff --git a/thirdparty/embree-aarch64/common/math/vec3.h b/thirdparty/embree/common/math/vec3.h index 1870321715..ce94eff327 100644 --- a/thirdparty/embree-aarch64/common/math/vec3.h +++ b/thirdparty/embree/common/math/vec3.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -206,7 +206,8 @@ namespace embree template<typename T> __forceinline T rcp_length( const Vec3<T>& a ) { return rsqrt(sqr(a)); } template<typename T> __forceinline Vec3<T> normalize( const Vec3<T>& a ) { return a*rsqrt(sqr(a)); } template<typename T> __forceinline T distance ( const Vec3<T>& a, const Vec3<T>& b ) { return length(a-b); } - template<typename T> __forceinline Vec3<T> cross ( const Vec3<T>& a, const Vec3<T>& b ) { return Vec3<T>(prod_diff(a.y,b.z,a.z,b.y), prod_diff(a.z,b.x,a.x,b.z), prod_diff(a.x,b.y,a.y,b.x)); } + template<typename T> __forceinline Vec3<T> cross ( const Vec3<T>& a, const Vec3<T>& b ) { return Vec3<T>(msub(a.y,b.z,a.z*b.y), msub(a.z,b.x,a.x*b.z), msub(a.x,b.y,a.y*b.x)); } + template<typename T> __forceinline Vec3<T> stable_triangle_normal( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c ) { const T ab_x = a.z*b.y, ab_y = a.x*b.z, ab_z = a.y*b.x; @@ -265,11 +266,11 @@ namespace embree /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined __SSE__ #include "../simd/sse.h" #endif -#if defined(__AVX__) +#if defined __AVX__ #include "../simd/avx.h" #endif @@ -290,18 +291,14 @@ namespace embree template<> __forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } -#elif defined(__SSE__) || defined(__ARM_NEON) +#elif defined(__SSE__) template<> __forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) { const vfloat4 v = vfloat4(a.m128); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v); } #endif -#if defined(__SSE__) || defined(__ARM_NEON) - __forceinline Vec3<vfloat4> broadcast4f(const Vec3<vfloat4>& a, const size_t k) { - return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k])); - } - +#if defined(__SSE__) template<> __forceinline Vec3<vfloat4> broadcast<vfloat4,vfloat4>(const Vec3<vfloat4>& a, const size_t k) { return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k])); @@ -318,15 +315,6 @@ namespace embree __forceinline Vec3<vfloat8>::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } - __forceinline Vec3<vfloat4> broadcast4f(const Vec3<vfloat8>& a, const size_t k) { - return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k])); - } - __forceinline Vec3<vfloat8> broadcast8f(const Vec3<vfloat4>& a, const size_t k) { - return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k])); - } - __forceinline Vec3<vfloat8> broadcast8f(const Vec3<vfloat8>& a, const size_t k) { - return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k])); - } template<> __forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat4>(const Vec3<vfloat4>& a, const size_t k) { diff --git a/thirdparty/embree-aarch64/common/math/vec3ba.h b/thirdparty/embree/common/math/vec3ba.h index 90f31739c2..a021b522dc 100644 --- a/thirdparty/embree-aarch64/common/math/vec3ba.h +++ b/thirdparty/embree/common/math/vec3ba.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/math/vec3fa.h b/thirdparty/embree/common/math/vec3fa.h index 6163cfb596..586039741d 100644 --- a/thirdparty/embree-aarch64/common/math/vec3fa.h +++ b/thirdparty/embree/common/math/vec3fa.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -55,13 +55,7 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// static __forceinline Vec3fa load( const void* const a ) { -#if defined(__aarch64__) - __m128 t = _mm_load_ps((float*)a); - t[3] = 0.0f; - return Vec3fa(t); -#else return Vec3fa(_mm_and_ps(_mm_load_ps((float*)a),_mm_castsi128_ps(_mm_set_epi32(0, -1, -1, -1)))); -#endif } static __forceinline Vec3fa loadu( const void* const a ) { @@ -95,42 +89,19 @@ namespace embree __forceinline Vec3fa operator +( const Vec3fa& a ) { return a; } __forceinline Vec3fa operator -( const Vec3fa& a ) { -#if defined(__aarch64__) - return vnegq_f32(a.m128); -#else const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); - return _mm_xor_ps(a.m128, mask); -#endif } __forceinline Vec3fa abs ( const Vec3fa& a ) { -#if defined(__aarch64__) - return _mm_abs_ps(a.m128); -#else const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)); return _mm_and_ps(a.m128, mask); -#endif } __forceinline Vec3fa sign ( const Vec3fa& a ) { -#if defined(__aarch64__) - Vec3fa r = blendv_ps(vOne, vmOne, _mm_cmplt_ps (a.m128,vdupq_n_f32(0.0f))); - return r; -#else return blendv_ps(Vec3fa(one).m128, (-Vec3fa(one)).m128, _mm_cmplt_ps (a.m128,Vec3fa(zero).m128)); -#endif } __forceinline Vec3fa rcp ( const Vec3fa& a ) { -#if defined(__aarch64__) && defined(BUILD_IOS) - return vdivq_f32(vdupq_n_f32(1.0f),a.m128); -#elif defined(__aarch64__) - __m128 reciprocal = _mm_rcp_ps(a.m128); - reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal); - return (const Vec3fa)reciprocal; -#else - #if defined(__AVX512VL__) const Vec3fa r = _mm_rcp14_ps(a.m128); #else @@ -145,7 +116,6 @@ namespace embree #endif return res; -#endif //defined(__aarch64__) } __forceinline Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); } @@ -153,20 +123,12 @@ namespace embree __forceinline Vec3fa rsqrt( const Vec3fa& a ) { -#if defined(__aarch64__) - __m128 r = _mm_rsqrt_ps(a.m128); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); - return r; -#else - #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a.m128, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); -#endif } __forceinline Vec3fa zero_fix(const Vec3fa& a) { @@ -199,7 +161,7 @@ namespace embree __forceinline Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); } -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec3fa mini(const Vec3fa& a, const Vec3fa& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -208,7 +170,7 @@ namespace embree } #endif -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec3fa maxi(const Vec3fa& a, const Vec3fa& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -231,29 +193,10 @@ namespace embree __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fnmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fnmsub_ps(a.m128,b.m128,c.m128); } #else - -#if defined(__aarch64__) - __forceinline Vec3fa madd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { - return _mm_madd_ps(a.m128, b.m128, c.m128); //a*b+c; - } - __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { - return _mm_msub_ps(a.m128, b.m128, c.m128); //-a*b+c; - } - __forceinline Vec3fa nmsub( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { - Vec3fa t = _mm_madd_ps(a.m128, b.m128, c.m128); - return -t; - } - __forceinline Vec3fa msub( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { - return _mm_madd_ps(a.m128,b.m128,vnegq_f32(c.m128)); //a*b-c - } - -#else __forceinline Vec3fa madd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b+c; } + __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b-c; } __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b+c;} __forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b-c; } - __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b-c; } -#endif - #endif __forceinline Vec3fa madd ( const float a, const Vec3fa& b, const Vec3fa& c) { return madd(Vec3fa(a),b,c); } @@ -275,37 +218,18 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// -#if defined(__aarch64__) && defined(BUILD_IOS) - __forceinline float reduce_add(const Vec3fa& v) { - float32x4_t t = v.m128; - t[3] = 0.0f; - return vaddvq_f32(t); - } - - __forceinline float reduce_mul(const Vec3fa& v) { return v.x*v.y*v.z; } - __forceinline float reduce_min(const Vec3fa& v) { - float32x4_t t = v.m128; - t[3] = t[2]; - return vminvq_f32(t); - } - __forceinline float reduce_max(const Vec3fa& v) { - float32x4_t t = v.m128; - t[3] = t[2]; - return vmaxvq_f32(t); - } -#else - __forceinline float reduce_add(const Vec3fa& v) { + + __forceinline float reduce_add(const Vec3fa& v) { const vfloat4 a(v.m128); const vfloat4 b = shuffle<1>(a); const vfloat4 c = shuffle<2>(a); - return _mm_cvtss_f32(a+b+c); + return _mm_cvtss_f32(a+b+c); } __forceinline float reduce_mul(const Vec3fa& v) { return v.x*v.y*v.z; } __forceinline float reduce_min(const Vec3fa& v) { return min(v.x,v.y,v.z); } __forceinline float reduce_max(const Vec3fa& v) { return max(v.x,v.y,v.z); } -#endif - + //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// @@ -317,13 +241,8 @@ namespace embree __forceinline Vec3ba neq_mask(const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpneq_ps(a.m128, b.m128); } __forceinline Vec3ba lt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmplt_ps (a.m128, b.m128); } __forceinline Vec3ba le_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmple_ps (a.m128, b.m128); } - #if defined(__aarch64__) - __forceinline Vec3ba gt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpgt_ps (a.m128, b.m128); } - __forceinline Vec3ba ge_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpge_ps (a.m128, b.m128); } -#else - __forceinline Vec3ba gt_mask(const Vec3fa& a, const Vec3fa& b) { return _mm_cmpnle_ps(a.m128, b.m128); } - __forceinline Vec3ba ge_mask(const Vec3fa& a, const Vec3fa& b) { return _mm_cmpnlt_ps(a.m128, b.m128); } -#endif + __forceinline Vec3ba gt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpnle_ps(a.m128, b.m128); } + __forceinline Vec3ba ge_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpnlt_ps(a.m128, b.m128); } __forceinline bool isvalid ( const Vec3fa& v ) { return all(gt_mask(v,Vec3fa(-FLT_LARGE)) & lt_mask(v,Vec3fa(+FLT_LARGE))); @@ -361,7 +280,7 @@ namespace embree vfloat4 b0 = shuffle<1,2,0,3>(vfloat4(b.m128)); vfloat4 a1 = shuffle<1,2,0,3>(vfloat4(a.m128)); vfloat4 b1 = vfloat4(b.m128); - return Vec3fa(shuffle<1,2,0,3>(prod_diff(a0,b0,a1,b1))); + return Vec3fa(shuffle<1,2,0,3>(msub(a0,b0,a1*b1))); } __forceinline float sqr_length ( const Vec3fa& a ) { return dot(a,a); } @@ -416,11 +335,7 @@ namespace embree /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// -#if defined(__aarch64__) - __forceinline Vec3fa floor(const Vec3fa& a) { return vrndmq_f32(a.m128); } - __forceinline Vec3fa ceil (const Vec3fa& a) { return vrndpq_f32(a.m128); } - __forceinline Vec3fa trunc(const Vec3fa& a) { return vrndq_f32(a.m128); } -#elif defined (__SSE4_1__) +#if defined (__SSE4_1__) __forceinline Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEAREST_INT); } __forceinline Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEG_INF ); } __forceinline Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_POS_INF ); } @@ -478,10 +393,8 @@ namespace embree __forceinline Vec3fx( const Vec3fa& other, const int a1) { m128 = other.m128; a = a1; } __forceinline Vec3fx( const Vec3fa& other, const unsigned a1) { m128 = other.m128; u = a1; } - __forceinline Vec3fx( const Vec3fa& other, const float w1) { -#if defined (__aarch64__) - m128 = other.m128; m128[3] = w1; -#elif defined (__SSE4_1__) + __forceinline Vec3fx( const Vec3fa& other, const float w1) { +#if defined (__SSE4_1__) m128 = _mm_insert_ps(other.m128, _mm_set_ss(w1),3 << 4); #else const vint4 mask(-1,-1,-1,0); @@ -613,7 +526,7 @@ namespace embree __forceinline Vec3fx min( const Vec3fx& a, const Vec3fx& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec3fx max( const Vec3fx& a, const Vec3fx& b ) { return _mm_max_ps(a.m128,b.m128); } -#if defined(__SSE4_1__) || defined(__aarch64__) +#if defined(__SSE4_1__) __forceinline Vec3fx mini(const Vec3fx& a, const Vec3fx& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -622,7 +535,7 @@ namespace embree } #endif -#if defined(__SSE4_1__) || defined(__aarch64__) +#if defined(__SSE4_1__) __forceinline Vec3fx maxi(const Vec3fx& a, const Vec3fx& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); @@ -671,11 +584,11 @@ namespace embree /// Reductions //////////////////////////////////////////////////////////////////////////////// - __forceinline float reduce_add(const Vec3fx& v) { + __forceinline float reduce_add(const Vec3fx& v) { const vfloat4 a(v.m128); const vfloat4 b = shuffle<1>(a); const vfloat4 c = shuffle<2>(a); - return _mm_cvtss_f32(a+b+c); + return _mm_cvtss_f32(a+b+c); } __forceinline float reduce_mul(const Vec3fx& v) { return v.x*v.y*v.z; } @@ -787,7 +700,11 @@ namespace embree /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// -#if defined (__SSE4_1__) && !defined(__aarch64__) +#if defined(__aarch64__) + __forceinline Vec3fx trunc(const Vec3fx& a) { return vrndq_f32(a.m128); } + __forceinline Vec3fx floor(const Vec3fx& a) { return vrndmq_f32(a.m128); } + __forceinline Vec3fx ceil (const Vec3fx& a) { return vrndpq_f32(a.m128); } +#elif defined (__SSE4_1__) __forceinline Vec3fx trunc( const Vec3fx& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEAREST_INT); } __forceinline Vec3fx floor( const Vec3fx& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEG_INF ); } __forceinline Vec3fx ceil ( const Vec3fx& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_POS_INF ); } diff --git a/thirdparty/embree-aarch64/common/math/vec3ia.h b/thirdparty/embree/common/math/vec3ia.h index 737f67fd72..694804c40d 100644 --- a/thirdparty/embree-aarch64/common/math/vec3ia.h +++ b/thirdparty/embree/common/math/vec3ia.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -65,9 +65,7 @@ namespace embree __forceinline Vec3ia operator +( const Vec3ia& a ) { return a; } __forceinline Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); } -#if (defined(__aarch64__)) - __forceinline Vec3ia abs ( const Vec3ia& a ) { return vabsq_s32(a.m128); } -#elif defined(__SSSE3__) +#if defined(__SSSE3__) __forceinline Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); } #endif @@ -83,7 +81,7 @@ namespace embree __forceinline Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); } __forceinline Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; } -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); } __forceinline Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); } __forceinline Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; } @@ -101,14 +99,12 @@ namespace embree __forceinline Vec3ia operator ^( const Vec3ia& a, const int b ) { return a ^ Vec3ia(b); } __forceinline Vec3ia operator ^( const int a, const Vec3ia& b ) { return Vec3ia(a) ^ b; } -#if !defined(__ARM_NEON) __forceinline Vec3ia operator <<( const Vec3ia& a, const int n ) { return _mm_slli_epi32(a.m128, n); } __forceinline Vec3ia operator >>( const Vec3ia& a, const int n ) { return _mm_srai_epi32(a.m128, n); } __forceinline Vec3ia sll ( const Vec3ia& a, const int b ) { return _mm_slli_epi32(a.m128, b); } __forceinline Vec3ia sra ( const Vec3ia& a, const int b ) { return _mm_srai_epi32(a.m128, b); } __forceinline Vec3ia srl ( const Vec3ia& a, const int b ) { return _mm_srli_epi32(a.m128, b); } -#endif //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators @@ -120,7 +116,7 @@ namespace embree __forceinline Vec3ia& operator -=( Vec3ia& a, const Vec3ia& b ) { return a = a - b; } __forceinline Vec3ia& operator -=( Vec3ia& a, const int& b ) { return a = a - b; } -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec3ia& operator *=( Vec3ia& a, const Vec3ia& b ) { return a = a * b; } __forceinline Vec3ia& operator *=( Vec3ia& a, const int& b ) { return a = a * b; } #endif @@ -131,38 +127,18 @@ namespace embree __forceinline Vec3ia& operator |=( Vec3ia& a, const Vec3ia& b ) { return a = a | b; } __forceinline Vec3ia& operator |=( Vec3ia& a, const int& b ) { return a = a | b; } -#if !defined(__ARM_NEON) __forceinline Vec3ia& operator <<=( Vec3ia& a, const int& b ) { return a = a << b; } __forceinline Vec3ia& operator >>=( Vec3ia& a, const int& b ) { return a = a >> b; } -#endif //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// -#if defined(__aarch64__) - __forceinline int reduce_add(const Vec3ia& v) { - int32x4_t t = v.m128; - t[3] = 0; - return vaddvq_s32(t); - - } - __forceinline int reduce_mul(const Vec3ia& v) { return v.x*v.y*v.z; } - __forceinline int reduce_min(const Vec3ia& v) { - int32x4_t t = (__m128i)blendv_ps((__m128)v0x7fffffff, (__m128)v.m128, (__m128)vFFF0); - return vminvq_s32(t); - - } - __forceinline int reduce_max(const Vec3ia& v) { - int32x4_t t = (__m128i)blendv_ps((__m128)v0x80000000, (__m128)v.m128, (__m128)vFFF0); - return vmaxvq_s32(t); - - } -#else + __forceinline int reduce_add(const Vec3ia& v) { return v.x+v.y+v.z; } __forceinline int reduce_mul(const Vec3ia& v) { return v.x*v.y*v.z; } __forceinline int reduce_min(const Vec3ia& v) { return min(v.x,v.y,v.z); } __forceinline int reduce_max(const Vec3ia& v) { return max(v.x,v.y,v.z); } -#endif + //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// @@ -185,14 +161,14 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) { -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); #else return _mm_or_si128(_mm_and_si128(_mm_castps_si128(m), t), _mm_andnot_si128(_mm_castps_si128(m), f)); #endif } -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); } __forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); } #else diff --git a/thirdparty/embree-aarch64/common/math/vec4.h b/thirdparty/embree/common/math/vec4.h index d16542f507..0ed107928a 100644 --- a/thirdparty/embree-aarch64/common/math/vec4.h +++ b/thirdparty/embree/common/math/vec4.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -192,7 +192,7 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// typedef Vec4<bool > Vec4b; - typedef Vec4<uint8_t > Vec4uc; + typedef Vec4<unsigned char> Vec4uc; typedef Vec4<int > Vec4i; typedef Vec4<float > Vec4f; } @@ -205,7 +205,7 @@ namespace embree /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined __SSE__ #include "../simd/sse.h" #endif @@ -225,31 +225,16 @@ namespace embree template<> __forceinline Vec4<vfloat4>::Vec4( const Vec3fx& a ) { x = a.x; y = a.y; z = a.z; w = a.w; } -#elif defined(__SSE__) || defined(__ARM_NEON) +#elif defined(__SSE__) template<> __forceinline Vec4<vfloat4>::Vec4( const Vec3fx& a ) { const vfloat4 v = vfloat4(a.m128); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v); w = shuffle<3,3,3,3>(v); } #endif -#if defined(__SSE__) || defined(__ARM_NEON) - __forceinline Vec4<vfloat4> broadcast4f( const Vec4<vfloat4>& a, const size_t k ) { - return Vec4<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]), vfloat4::broadcast(&a.w[k])); - } -#endif - #if defined(__AVX__) template<> __forceinline Vec4<vfloat8>::Vec4( const Vec3fx& a ) { x = a.x; y = a.y; z = a.z; w = a.w; } - __forceinline Vec4<vfloat4> broadcast4f( const Vec4<vfloat8>& a, const size_t k ) { - return Vec4<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]), vfloat4::broadcast(&a.w[k])); - } - __forceinline Vec4<vfloat8> broadcast8f( const Vec4<vfloat4>& a, const size_t k ) { - return Vec4<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]), vfloat8::broadcast(&a.w[k])); - } - __forceinline Vec4<vfloat8> broadcast8f( const Vec4<vfloat8>& a, const size_t k ) { - return Vec4<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]), vfloat8::broadcast(&a.w[k])); - } #endif #if defined(__AVX512F__) diff --git a/thirdparty/embree/common/simd/arm/emulation.h b/thirdparty/embree/common/simd/arm/emulation.h new file mode 100644 index 0000000000..1c3875fb27 --- /dev/null +++ b/thirdparty/embree/common/simd/arm/emulation.h @@ -0,0 +1,50 @@ +// Copyright 2009-2020 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +/* Make precision match SSE, at the cost of some performance */ +#if !defined(__aarch64__) +# define SSE2NEON_PRECISE_DIV 1 +# define SSE2NEON_PRECISE_SQRT 1 +#endif + +#include "sse2neon.h" + +__forceinline __m128 _mm_fmsub_ps(__m128 a, __m128 b, __m128 c) { + __m128 neg_c = vreinterpretq_m128_f32(vnegq_f32(vreinterpretq_f32_m128(c))); + return _mm_fmadd_ps(a, b, neg_c); +} + +__forceinline __m128 _mm_fnmadd_ps(__m128 a, __m128 b, __m128 c) { +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vfmsq_f32(vreinterpretq_f32_m128(c), + vreinterpretq_f32_m128(b), + vreinterpretq_f32_m128(a))); +#else + return _mm_sub_ps(c, _mm_mul_ps(a, b)); +#endif +} + +__forceinline __m128 _mm_fnmsub_ps(__m128 a, __m128 b, __m128 c) { + return vreinterpretq_m128_f32(vnegq_f32(vreinterpretq_f32_m128(_mm_fmadd_ps(a,b,c)))); +} + + +/* Dummy defines for floating point control */ +#define _MM_MASK_MASK 0x1f80 +#define _MM_MASK_DIV_ZERO 0x200 +#define _MM_FLUSH_ZERO_ON 0x8000 +#define _MM_MASK_DENORM 0x100 +#define _MM_SET_EXCEPTION_MASK(x) +#define _MM_SET_FLUSH_ZERO_MODE(x) + +__forceinline int _mm_getcsr() +{ + return 0; +} + +__forceinline void _mm_mfence() +{ + __sync_synchronize(); +} diff --git a/thirdparty/embree/common/simd/arm/sse2neon.h b/thirdparty/embree/common/simd/arm/sse2neon.h new file mode 100644 index 0000000000..7eb25cf2c5 --- /dev/null +++ b/thirdparty/embree/common/simd/arm/sse2neon.h @@ -0,0 +1,6996 @@ +#ifndef SSE2NEON_H +#define SSE2NEON_H + +// This header file provides a simple API translation layer +// between SSE intrinsics to their corresponding Arm/Aarch64 NEON versions +// +// This header file does not yet translate all of the SSE intrinsics. +// +// Contributors to this work are: +// John W. Ratcliff <jratcliffscarab@gmail.com> +// Brandon Rowlett <browlett@nvidia.com> +// Ken Fast <kfast@gdeb.com> +// Eric van Beurden <evanbeurden@nvidia.com> +// Alexander Potylitsin <apotylitsin@nvidia.com> +// Hasindu Gamaarachchi <hasindu2008@gmail.com> +// Jim Huang <jserv@biilabs.io> +// Mark Cheng <marktwtn@biilabs.io> +// Malcolm James MacLeod <malcolm@gulden.com> +// Devin Hussey (easyaspi314) <husseydevin@gmail.com> +// Sebastian Pop <spop@amazon.com> +// Developer Ecosystem Engineering <DeveloperEcosystemEngineering@apple.com> +// Danila Kutenin <danilak@google.com> +// François Turban (JishinMaster) <francois.turban@gmail.com> +// Pei-Hsuan Hung <afcidk@gmail.com> +// Yang-Hao Yuan <yanghau@biilabs.io> +// Syoyo Fujita <syoyo@lighttransport.com> +// Brecht Van Lommel <brecht@blender.org> + +/* + * sse2neon is freely redistributable under the MIT License. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Tunable configurations */ + +/* Enable precise implementation of math operations + * This would slow down the computation a bit, but gives consistent result with + * x86 SSE2. (e.g. would solve a hole or NaN pixel in the rendering result) + */ +/* _mm_min_ps and _mm_max_ps */ +#ifndef SSE2NEON_PRECISE_MINMAX +#define SSE2NEON_PRECISE_MINMAX (0) +#endif +/* _mm_rcp_ps and _mm_div_ps */ +#ifndef SSE2NEON_PRECISE_DIV +#define SSE2NEON_PRECISE_DIV (0) +#endif +/* _mm_sqrt_ps and _mm_rsqrt_ps */ +#ifndef SSE2NEON_PRECISE_SQRT +#define SSE2NEON_PRECISE_SQRT (0) +#endif +#ifndef SSE2NEON_PRECISE_RSQRT +#define SSE2NEON_PRECISE_RSQRT (0) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#pragma push_macro("FORCE_INLINE") +#pragma push_macro("ALIGN_STRUCT") +#define FORCE_INLINE static inline __attribute__((always_inline)) +#define ALIGN_STRUCT(x) __attribute__((aligned(x))) +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#else +#error "Macro name collisions may happen with unsupported compiler." +#ifdef FORCE_INLINE +#undef FORCE_INLINE +#endif +#define FORCE_INLINE static inline +#ifndef ALIGN_STRUCT +#define ALIGN_STRUCT(x) __declspec(align(x)) +#endif +#endif +#ifndef likely +#define likely(x) (x) +#endif +#ifndef unlikely +#define unlikely(x) (x) +#endif + +#include <stdint.h> +#include <stdlib.h> + +/* Architecture-specific build options */ +/* FIXME: #pragma GCC push_options is only available on GCC */ +#if defined(__GNUC__) +#if defined(__arm__) && __ARM_ARCH == 7 +/* According to ARM C Language Extensions Architecture specification, + * __ARM_NEON is defined to a value indicating the Advanced SIMD (NEON) + * architecture supported. + */ +#if !defined(__ARM_NEON) || !defined(__ARM_NEON__) +#error "You must enable NEON instructions (e.g. -mfpu=neon) to use SSE2NEON." +#endif +#if !defined(__clang__) +#pragma GCC push_options +#pragma GCC target("fpu=neon") +#endif +#elif defined(__aarch64__) +#if !defined(__clang__) +#pragma GCC push_options +#pragma GCC target("+simd") +#endif +#else +#error "Unsupported target. Must be either ARMv7-A+NEON or ARMv8-A." +#endif +#endif + +#include <arm_neon.h> + +/* Rounding functions require either Aarch64 instructions or libm failback */ +#if !defined(__aarch64__) +#include <math.h> +#endif + +/* "__has_builtin" can be used to query support for built-in functions + * provided by gcc/clang and other compilers that support it. + */ +#ifndef __has_builtin /* GCC prior to 10 or non-clang compilers */ +/* Compatibility with gcc <= 9 */ +#if __GNUC__ <= 9 +#define __has_builtin(x) HAS##x +#define HAS__builtin_popcount 1 +#define HAS__builtin_popcountll 1 +#else +#define __has_builtin(x) 0 +#endif +#endif + +/** + * MACRO for shuffle parameter for _mm_shuffle_ps(). + * Argument fp3 is a digit[0123] that represents the fp from argument "b" + * of mm_shuffle_ps that will be placed in fp3 of result. fp2 is the same + * for fp2 in result. fp1 is a digit[0123] that represents the fp from + * argument "a" of mm_shuffle_ps that will be places in fp1 of result. + * fp0 is the same for fp0 of result. + */ +#define _MM_SHUFFLE(fp3, fp2, fp1, fp0) \ + (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | ((fp0))) + +/* Rounding mode macros. */ +#define _MM_FROUND_TO_NEAREST_INT 0x00 +#define _MM_FROUND_TO_NEG_INF 0x01 +#define _MM_FROUND_TO_POS_INF 0x02 +#define _MM_FROUND_TO_ZERO 0x03 +#define _MM_FROUND_CUR_DIRECTION 0x04 +#define _MM_FROUND_NO_EXC 0x08 +#define _MM_ROUND_NEAREST 0x0000 +#define _MM_ROUND_DOWN 0x2000 +#define _MM_ROUND_UP 0x4000 +#define _MM_ROUND_TOWARD_ZERO 0x6000 + +/* indicate immediate constant argument in a given range */ +#define __constrange(a, b) const + +/* A few intrinsics accept traditional data types like ints or floats, but + * most operate on data types that are specific to SSE. + * If a vector type ends in d, it contains doubles, and if it does not have + * a suffix, it contains floats. An integer vector type can contain any type + * of integer, from chars to shorts to unsigned long longs. + */ +typedef int64x1_t __m64; +typedef float32x4_t __m128; /* 128-bit vector containing 4 floats */ +// On ARM 32-bit architecture, the float64x2_t is not supported. +// The data type __m128d should be represented in a different way for related +// intrinsic conversion. +#if defined(__aarch64__) +typedef float64x2_t __m128d; /* 128-bit vector containing 2 doubles */ +#else +typedef float32x4_t __m128d; +#endif +typedef int64x2_t __m128i; /* 128-bit vector containing integers */ + +/* type-safe casting between types */ + +#define vreinterpretq_m128_f16(x) vreinterpretq_f32_f16(x) +#define vreinterpretq_m128_f32(x) (x) +#define vreinterpretq_m128_f64(x) vreinterpretq_f32_f64(x) + +#define vreinterpretq_m128_u8(x) vreinterpretq_f32_u8(x) +#define vreinterpretq_m128_u16(x) vreinterpretq_f32_u16(x) +#define vreinterpretq_m128_u32(x) vreinterpretq_f32_u32(x) +#define vreinterpretq_m128_u64(x) vreinterpretq_f32_u64(x) + +#define vreinterpretq_m128_s8(x) vreinterpretq_f32_s8(x) +#define vreinterpretq_m128_s16(x) vreinterpretq_f32_s16(x) +#define vreinterpretq_m128_s32(x) vreinterpretq_f32_s32(x) +#define vreinterpretq_m128_s64(x) vreinterpretq_f32_s64(x) + +#define vreinterpretq_f16_m128(x) vreinterpretq_f16_f32(x) +#define vreinterpretq_f32_m128(x) (x) +#define vreinterpretq_f64_m128(x) vreinterpretq_f64_f32(x) + +#define vreinterpretq_u8_m128(x) vreinterpretq_u8_f32(x) +#define vreinterpretq_u16_m128(x) vreinterpretq_u16_f32(x) +#define vreinterpretq_u32_m128(x) vreinterpretq_u32_f32(x) +#define vreinterpretq_u64_m128(x) vreinterpretq_u64_f32(x) + +#define vreinterpretq_s8_m128(x) vreinterpretq_s8_f32(x) +#define vreinterpretq_s16_m128(x) vreinterpretq_s16_f32(x) +#define vreinterpretq_s32_m128(x) vreinterpretq_s32_f32(x) +#define vreinterpretq_s64_m128(x) vreinterpretq_s64_f32(x) + +#define vreinterpretq_m128i_s8(x) vreinterpretq_s64_s8(x) +#define vreinterpretq_m128i_s16(x) vreinterpretq_s64_s16(x) +#define vreinterpretq_m128i_s32(x) vreinterpretq_s64_s32(x) +#define vreinterpretq_m128i_s64(x) (x) + +#define vreinterpretq_m128i_u8(x) vreinterpretq_s64_u8(x) +#define vreinterpretq_m128i_u16(x) vreinterpretq_s64_u16(x) +#define vreinterpretq_m128i_u32(x) vreinterpretq_s64_u32(x) +#define vreinterpretq_m128i_u64(x) vreinterpretq_s64_u64(x) + +#define vreinterpretq_f32_m128i(x) vreinterpretq_f32_s64(x) +#define vreinterpretq_f64_m128i(x) vreinterpretq_f64_s64(x) + +#define vreinterpretq_s8_m128i(x) vreinterpretq_s8_s64(x) +#define vreinterpretq_s16_m128i(x) vreinterpretq_s16_s64(x) +#define vreinterpretq_s32_m128i(x) vreinterpretq_s32_s64(x) +#define vreinterpretq_s64_m128i(x) (x) + +#define vreinterpretq_u8_m128i(x) vreinterpretq_u8_s64(x) +#define vreinterpretq_u16_m128i(x) vreinterpretq_u16_s64(x) +#define vreinterpretq_u32_m128i(x) vreinterpretq_u32_s64(x) +#define vreinterpretq_u64_m128i(x) vreinterpretq_u64_s64(x) + +#define vreinterpret_m64_s8(x) vreinterpret_s64_s8(x) +#define vreinterpret_m64_s16(x) vreinterpret_s64_s16(x) +#define vreinterpret_m64_s32(x) vreinterpret_s64_s32(x) +#define vreinterpret_m64_s64(x) (x) + +#define vreinterpret_m64_u8(x) vreinterpret_s64_u8(x) +#define vreinterpret_m64_u16(x) vreinterpret_s64_u16(x) +#define vreinterpret_m64_u32(x) vreinterpret_s64_u32(x) +#define vreinterpret_m64_u64(x) vreinterpret_s64_u64(x) + +#define vreinterpret_m64_f16(x) vreinterpret_s64_f16(x) +#define vreinterpret_m64_f32(x) vreinterpret_s64_f32(x) +#define vreinterpret_m64_f64(x) vreinterpret_s64_f64(x) + +#define vreinterpret_u8_m64(x) vreinterpret_u8_s64(x) +#define vreinterpret_u16_m64(x) vreinterpret_u16_s64(x) +#define vreinterpret_u32_m64(x) vreinterpret_u32_s64(x) +#define vreinterpret_u64_m64(x) vreinterpret_u64_s64(x) + +#define vreinterpret_s8_m64(x) vreinterpret_s8_s64(x) +#define vreinterpret_s16_m64(x) vreinterpret_s16_s64(x) +#define vreinterpret_s32_m64(x) vreinterpret_s32_s64(x) +#define vreinterpret_s64_m64(x) (x) + +#define vreinterpret_f32_m64(x) vreinterpret_f32_s64(x) + +#if defined(__aarch64__) +#define vreinterpretq_m128d_s32(x) vreinterpretq_f64_s32(x) +#define vreinterpretq_m128d_s64(x) vreinterpretq_f64_s64(x) + +#define vreinterpretq_m128d_u64(x) vreinterpretq_f64_u64(x) + +#define vreinterpretq_m128d_f32(x) vreinterpretq_f64_f32(x) +#define vreinterpretq_m128d_f64(x) (x) + +#define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f64(x) + +#define vreinterpretq_u64_m128d(x) vreinterpretq_u64_f64(x) + +#define vreinterpretq_f64_m128d(x) (x) +#define vreinterpretq_f32_m128d(x) vreinterpretq_f32_f64(x) +#else +#define vreinterpretq_m128d_s32(x) vreinterpretq_f32_s32(x) +#define vreinterpretq_m128d_s64(x) vreinterpretq_f32_s64(x) + +#define vreinterpretq_m128d_u32(x) vreinterpretq_f32_u32(x) +#define vreinterpretq_m128d_u64(x) vreinterpretq_f32_u64(x) + +#define vreinterpretq_m128d_f32(x) (x) + +#define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f32(x) + +#define vreinterpretq_u32_m128d(x) vreinterpretq_u32_f32(x) +#define vreinterpretq_u64_m128d(x) vreinterpretq_u64_f32(x) + +#define vreinterpretq_f32_m128d(x) (x) +#endif + +// A struct is defined in this header file called 'SIMDVec' which can be used +// by applications which attempt to access the contents of an _m128 struct +// directly. It is important to note that accessing the __m128 struct directly +// is bad coding practice by Microsoft: @see: +// https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx +// +// However, some legacy source code may try to access the contents of an __m128 +// struct directly so the developer can use the SIMDVec as an alias for it. Any +// casting must be done manually by the developer, as you cannot cast or +// otherwise alias the base NEON data type for intrinsic operations. +// +// union intended to allow direct access to an __m128 variable using the names +// that the MSVC compiler provides. This union should really only be used when +// trying to access the members of the vector as integer values. GCC/clang +// allow native access to the float members through a simple array access +// operator (in C since 4.6, in C++ since 4.8). +// +// Ideally direct accesses to SIMD vectors should not be used since it can cause +// a performance hit. If it really is needed however, the original __m128 +// variable can be aliased with a pointer to this union and used to access +// individual components. The use of this union should be hidden behind a macro +// that is used throughout the codebase to access the members instead of always +// declaring this type of variable. +typedef union ALIGN_STRUCT(16) SIMDVec { + float m128_f32[4]; // as floats - DON'T USE. Added for convenience. + int8_t m128_i8[16]; // as signed 8-bit integers. + int16_t m128_i16[8]; // as signed 16-bit integers. + int32_t m128_i32[4]; // as signed 32-bit integers. + int64_t m128_i64[2]; // as signed 64-bit integers. + uint8_t m128_u8[16]; // as unsigned 8-bit integers. + uint16_t m128_u16[8]; // as unsigned 16-bit integers. + uint32_t m128_u32[4]; // as unsigned 32-bit integers. + uint64_t m128_u64[2]; // as unsigned 64-bit integers. +} SIMDVec; + +// casting using SIMDVec +#define vreinterpretq_nth_u64_m128i(x, n) (((SIMDVec *) &x)->m128_u64[n]) +#define vreinterpretq_nth_u32_m128i(x, n) (((SIMDVec *) &x)->m128_u32[n]) +#define vreinterpretq_nth_u8_m128i(x, n) (((SIMDVec *) &x)->m128_u8[n]) + +/* Backwards compatibility for compilers with lack of specific type support */ + +// Older gcc does not define vld1q_u8_x4 type +#if defined(__GNUC__) && !defined(__clang__) && \ + ((__GNUC__ == 10 && (__GNUC_MINOR__ <= 1)) || \ + (__GNUC__ == 9 && (__GNUC_MINOR__ <= 3)) || \ + (__GNUC__ == 8 && (__GNUC_MINOR__ <= 4)) || __GNUC__ <= 7) +FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) +{ + uint8x16x4_t ret; + ret.val[0] = vld1q_u8(p + 0); + ret.val[1] = vld1q_u8(p + 16); + ret.val[2] = vld1q_u8(p + 32); + ret.val[3] = vld1q_u8(p + 48); + return ret; +} +#else +// Wraps vld1q_u8_x4 +FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) +{ + return vld1q_u8_x4(p); +} +#endif + +/* Function Naming Conventions + * The naming convention of SSE intrinsics is straightforward. A generic SSE + * intrinsic function is given as follows: + * _mm_<name>_<data_type> + * + * The parts of this format are given as follows: + * 1. <name> describes the operation performed by the intrinsic + * 2. <data_type> identifies the data type of the function's primary arguments + * + * This last part, <data_type>, is a little complicated. It identifies the + * content of the input values, and can be set to any of the following values: + * + ps - vectors contain floats (ps stands for packed single-precision) + * + pd - vectors cantain doubles (pd stands for packed double-precision) + * + epi8/epi16/epi32/epi64 - vectors contain 8-bit/16-bit/32-bit/64-bit + * signed integers + * + epu8/epu16/epu32/epu64 - vectors contain 8-bit/16-bit/32-bit/64-bit + * unsigned integers + * + si128 - unspecified 128-bit vector or 256-bit vector + * + m128/m128i/m128d - identifies input vector types when they are different + * than the type of the returned vector + * + * For example, _mm_setzero_ps. The _mm implies that the function returns + * a 128-bit vector. The _ps at the end implies that the argument vectors + * contain floats. + * + * A complete example: Byte Shuffle - pshufb (_mm_shuffle_epi8) + * // Set packed 16-bit integers. 128 bits, 8 short, per 16 bits + * __m128i v_in = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); + * // Set packed 8-bit integers + * // 128 bits, 16 chars, per 8 bits + * __m128i v_perm = _mm_setr_epi8(1, 0, 2, 3, 8, 9, 10, 11, + * 4, 5, 12, 13, 6, 7, 14, 15); + * // Shuffle packed 8-bit integers + * __m128i v_out = _mm_shuffle_epi8(v_in, v_perm); // pshufb + * + * Data (Number, Binary, Byte Index): + +------+------+-------------+------+------+-------------+ + | 1 | 2 | 3 | 4 | Number + +------+------+------+------+------+------+------+------+ + | 0000 | 0001 | 0000 | 0010 | 0000 | 0011 | 0000 | 0100 | Binary + +------+------+------+------+------+------+------+------+ + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Index + +------+------+------+------+------+------+------+------+ + + +------+------+------+------+------+------+------+------+ + | 5 | 6 | 7 | 8 | Number + +------+------+------+------+------+------+------+------+ + | 0000 | 0101 | 0000 | 0110 | 0000 | 0111 | 0000 | 1000 | Binary + +------+------+------+------+------+------+------+------+ + | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Index + +------+------+------+------+------+------+------+------+ + * Index (Byte Index): + +------+------+------+------+------+------+------+------+ + | 1 | 0 | 2 | 3 | 8 | 9 | 10 | 11 | + +------+------+------+------+------+------+------+------+ + + +------+------+------+------+------+------+------+------+ + | 4 | 5 | 12 | 13 | 6 | 7 | 14 | 15 | + +------+------+------+------+------+------+------+------+ + * Result: + +------+------+------+------+------+------+------+------+ + | 1 | 0 | 2 | 3 | 8 | 9 | 10 | 11 | Index + +------+------+------+------+------+------+------+------+ + | 0001 | 0000 | 0000 | 0010 | 0000 | 0101 | 0000 | 0110 | Binary + +------+------+------+------+------+------+------+------+ + | 256 | 2 | 5 | 6 | Number + +------+------+------+------+------+------+------+------+ + + +------+------+------+------+------+------+------+------+ + | 4 | 5 | 12 | 13 | 6 | 7 | 14 | 15 | Index + +------+------+------+------+------+------+------+------+ + | 0000 | 0011 | 0000 | 0111 | 0000 | 0100 | 0000 | 1000 | Binary + +------+------+------+------+------+------+------+------+ + | 3 | 7 | 4 | 8 | Number + +------+------+------+------+------+------+-------------+ + */ + +/* Set/get methods */ + +/* Constants for use with _mm_prefetch. */ +enum _mm_hint { + _MM_HINT_NTA = 0, /* load data to L1 and L2 cache, mark it as NTA */ + _MM_HINT_T0 = 1, /* load data to L1 and L2 cache */ + _MM_HINT_T1 = 2, /* load data to L2 cache only */ + _MM_HINT_T2 = 3, /* load data to L2 cache only, mark it as NTA */ + _MM_HINT_ENTA = 4, /* exclusive version of _MM_HINT_NTA */ + _MM_HINT_ET0 = 5, /* exclusive version of _MM_HINT_T0 */ + _MM_HINT_ET1 = 6, /* exclusive version of _MM_HINT_T1 */ + _MM_HINT_ET2 = 7 /* exclusive version of _MM_HINT_T2 */ +}; + +// Loads one cache line of data from address p to a location closer to the +// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx +FORCE_INLINE void _mm_prefetch(const void *p, int i) +{ + (void) i; + __builtin_prefetch(p); +} + +// Pause the processor. This is typically used in spin-wait loops and depending +// on the x86 processor typical values are in the 40-100 cycle range. The +// 'yield' instruction isn't a good fit beacuse it's effectively a nop on most +// Arm cores. Experience with several databases has shown has shown an 'isb' is +// a reasonable approximation. +FORCE_INLINE void _mm_pause() +{ + __asm__ __volatile__("isb\n"); +} + +// Copy the lower single-precision (32-bit) floating-point element of a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32 +FORCE_INLINE float _mm_cvtss_f32(__m128 a) +{ + return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); +} + +// Convert the lower single-precision (32-bit) floating-point element in b to a +// double-precision (64-bit) floating-point element, store the result in the +// lower element of dst, and copy the upper element from a to the upper element +// of dst. +// +// dst[63:0] := Convert_FP32_To_FP64(b[31:0]) +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_sd +FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b) +{ + double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0)); +#else + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &d, vreinterpretq_s64_m128d(a), 0)); +#endif +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32 +#define _mm_cvtss_si32(a) _mm_cvt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64 +FORCE_INLINE int _mm_cvtss_si64(__m128 a) +{ +#if defined(__aarch64__) + return vgetq_lane_s64( + vreinterpretq_s64_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a))), 0); +#else + float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t diff = data - floor(data); + if (diff > 0.5) + return (int64_t) ceil(data); + if (unlikely(diff == 0.5)) { + int64_t f = (int64_t) floor(data); + int64_t c = (int64_t) ceil(data); + return c & 1 ? f : c; + } + return (int64_t) floor(data); +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi +FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a) +{ + return vreinterpret_m64_s32( + vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si +FORCE_INLINE int _mm_cvtt_ss2si(__m128 a) +{ + return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0); +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32 +#define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32 +#define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64 +FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) +{ + return vgetq_lane_s64( + vmovl_s32(vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))), 0); +} + +// Sets the 128-bit value to zero +// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx +FORCE_INLINE __m128i _mm_setzero_si128(void) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(0)); +} + +// Clears the four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setzero_ps(void) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(0)); +} + +// Return vector of type __m128d with all elements set to zero. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd +FORCE_INLINE __m128d _mm_setzero_pd(void) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(0)); +#else + return vreinterpretq_m128d_f32(vdupq_n_f32(0)); +#endif +} + +// Sets the four single-precision, floating-point values to w. +// +// r0 := r1 := r2 := r3 := w +// +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set1_ps(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Sets the four single-precision, floating-point values to w. +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps1(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Sets the four single-precision, floating-point values to the four inputs. +// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) +{ + float ALIGN_STRUCT(16) data[4] = {x, y, z, w}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Copy single-precision (32-bit) floating-point element a to the lower element +// of dst, and zero the upper 3 elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss +FORCE_INLINE __m128 _mm_set_ss(float a) +{ + float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the four single-precision, floating-point values to the four inputs in +// reverse order. +// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) +{ + float ALIGN_STRUCT(16) data[4] = {w, z, y, x}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the 8 signed 16-bit integer values in reverse order. +// +// Return Value +// r0 := w0 +// r1 := w1 +// ... +// r7 := w7 +FORCE_INLINE __m128i _mm_setr_epi16(short w0, + short w1, + short w2, + short w3, + short w4, + short w5, + short w6, + short w7) +{ + int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; + return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); +} + +// Sets the 4 signed 32-bit integer values in reverse order +// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) +{ + int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Set packed 64-bit integers in dst with the supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64 +FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0) +{ + return vreinterpretq_m128i_s64(vcombine_s64(e1, e0)); +} + +// Sets the 16 signed 8-bit integer values to b. +// +// r0 := b +// r1 := b +// ... +// r15 := b +// +// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi8(signed char w) +{ + return vreinterpretq_m128i_s8(vdupq_n_s8(w)); +} + +// Broadcast double-precision (64-bit) floating-point value a to all elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_pd +FORCE_INLINE __m128d _mm_set1_pd(double d) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(d)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d)); +#endif +} + +// Sets the 8 signed 16-bit integer values to w. +// +// r0 := w +// r1 := w +// ... +// r7 := w +// +// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set1_epi16(short w) +{ + return vreinterpretq_m128i_s16(vdupq_n_s16(w)); +} + +// Sets the 16 signed 8-bit integer values. +// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi8(signed char b15, + signed char b14, + signed char b13, + signed char b12, + signed char b11, + signed char b10, + signed char b9, + signed char b8, + signed char b7, + signed char b6, + signed char b5, + signed char b4, + signed char b3, + signed char b2, + signed char b1, + signed char b0) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Sets the 8 signed 16-bit integer values. +// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi16(short i7, + short i6, + short i5, + short i4, + short i3, + short i2, + short i1, + short i0) +{ + int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; + return vreinterpretq_m128i_s16(vld1q_s16(data)); +} + +// Sets the 16 signed 8-bit integer values in reverse order. +// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, + signed char b1, + signed char b2, + signed char b3, + signed char b4, + signed char b5, + signed char b6, + signed char b7, + signed char b8, + signed char b9, + signed char b10, + signed char b11, + signed char b12, + signed char b13, + signed char b14, + signed char b15) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Sets the 4 signed 32-bit integer values to i. +// +// r0 := i +// r1 := i +// r2 := i +// r3 := I +// +// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi32(int _i) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) +FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x +FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); +} + +// Sets the 4 signed 32-bit integer values. +// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) +{ + int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) +{ + return vreinterpretq_m128i_s64( + vcombine_s64(vcreate_s64(i2), vcreate_s64(i1))); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) +{ + return _mm_set_epi64x((int64_t) i1, (int64_t) i2); +} + +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd +FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) +{ + double ALIGN_STRUCT(16) data[2] = {e0, e1}; +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); +#else + return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); +#endif +} + +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_pd +FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0) +{ + return _mm_set_pd(e0, e1); +} + +// Copy double-precision (64-bit) floating-point element a to the lower element +// of dst, and zero the upper element. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_sd +FORCE_INLINE __m128d _mm_set_sd(double a) +{ + return _mm_set_pd(0, a); +} + +// Broadcast double-precision (64-bit) floating-point value a to all elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd1 +#define _mm_set_pd1 _mm_set1_pd + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx +FORCE_INLINE void _mm_store_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Store the lower single-precision (32-bit) floating-point element from a into +// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[31:0] +// MEM[mem_addr+63:mem_addr+32] := a[31:0] +// MEM[mem_addr+95:mem_addr+64] := a[31:0] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_ps1 +FORCE_INLINE void _mm_store_ps1(float *p, __m128 a) +{ + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + vst1q_f32(p, vdupq_n_f32(a0)); +} + +// Store the lower single-precision (32-bit) floating-point element from a into +// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[31:0] +// MEM[mem_addr+63:mem_addr+32] := a[31:0] +// MEM[mem_addr+95:mem_addr+64] := a[31:0] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps +#define _mm_store1_ps _mm_store_ps1 + +// Store 4 single-precision (32-bit) floating-point elements from a into memory +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[127:96] +// MEM[mem_addr+63:mem_addr+32] := a[95:64] +// MEM[mem_addr+95:mem_addr+64] := a[63:32] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps +FORCE_INLINE void _mm_storer_ps(float *p, __m128 a) +{ + float32x4_t tmp = vrev64q_f32(vreinterpretq_f32_m128(a)); + float32x4_t rev = vextq_f32(tmp, tmp, 2); + vst1q_f32(p, rev); +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores the lower single - precision, floating - point value. +// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx +FORCE_INLINE void _mm_store_ss(float *p, __m128 a) +{ + vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); +} + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr must be aligned on a 16-byte boundary +// or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd +FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); +#else + vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); +#endif +} + +// Store the upper double-precision (64-bit) floating-point element from a into +// memory. +// +// MEM[mem_addr+63:mem_addr] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeh_pd +FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a))); +#endif +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// memory. +// +// MEM[mem_addr+63:mem_addr] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storel_pd +FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a))); +#endif +} + +// Store 2 double-precision (64-bit) floating-point elements from a into memory +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// MEM[mem_addr+63:mem_addr] := a[127:64] +// MEM[mem_addr+127:mem_addr+64] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_pd +FORCE_INLINE void _mm_storer_pd(double *mem_addr, __m128d a) +{ + float32x4_t f = vreinterpretq_f32_m128d(a); + _mm_store_pd(mem_addr, vreinterpretq_m128d_f32(vextq_f32(f, f, 2))); +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd1 +FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a)); + vst1q_f64((float64_t *) mem_addr, + vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low))); +#else + float32x2_t a_low = vget_low_f32(vreinterpretq_f32_m128d(a)); + vst1q_f32((float32_t *) mem_addr, + vreinterpretq_f32_m128d(vcombine_f32(a_low, a_low))); +#endif +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=9,526,5601&text=_mm_store1_pd +#define _mm_store1_pd _mm_store_pd1 + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr does not need to be aligned on any +// particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd +FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a) +{ + _mm_store_pd(mem_addr, a); +} + +// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. +// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx +FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) +{ + uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a)); + uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b)); + *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi)); +} + +// Stores the lower two single-precision floating point values of a to the +// address p. +// +// *p0 := a0 +// *p1 := a1 +// +// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx +FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) +{ + *p = vreinterpret_m64_f32(vget_low_f32(a)); +} + +// Stores the upper two single-precision, floating-point values of a to the +// address p. +// +// *p0 := a2 +// *p1 := a3 +// +// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx +FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a) +{ + *p = vreinterpret_m64_f32(vget_high_f32(a)); +} + +// Loads a single single-precision, floating-point value, copying it into all +// four words +// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load1_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_dup_f32(p)); +} + +// Load a single-precision (32-bit) floating-point element from memory into all +// elements of dst. +// +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[63:32] := MEM[mem_addr+31:mem_addr] +// dst[95:64] := MEM[mem_addr+31:mem_addr] +// dst[127:96] := MEM[mem_addr+31:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1 +#define _mm_load_ps1 _mm_load1_ps + +// Sets the lower two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the upper two values are passed +// through from a. +// +// Return Value +// r0 := *p0 +// r1 := *p1 +// r2 := a2 +// r3 := a3 +// +// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx +FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); +} + +// Load 4 single-precision (32-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[31:0] := MEM[mem_addr+127:mem_addr+96] +// dst[63:32] := MEM[mem_addr+95:mem_addr+64] +// dst[95:64] := MEM[mem_addr+63:mem_addr+32] +// dst[127:96] := MEM[mem_addr+31:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps +FORCE_INLINE __m128 _mm_loadr_ps(const float *p) +{ + float32x4_t v = vrev64q_f32(vld1q_f32(p)); + return vreinterpretq_m128_f32(vextq_f32(v, v, 2)); +} + +// Sets the upper two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the lower two values are passed +// through from a. +// +// r0 := a0 +// r1 := a1 +// r2 := *p0 +// r3 := *p1 +// +// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx +FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_loadu_ps(const float *p) +{ + // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are + // equivalent for neon + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Load unaligned 16-bit integer from memory into the first element of dst. +// +// dst[15:0] := MEM[mem_addr+15:mem_addr] +// dst[MAX:16] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16 +FORCE_INLINE __m128i _mm_loadu_si16(const void *p) +{ + return vreinterpretq_m128i_s16( + vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0)); +} + +// Load unaligned 64-bit integer from memory into the first element of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[MAX:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64 +FORCE_INLINE __m128i _mm_loadu_si64(const void *p) +{ + return vreinterpretq_m128i_s64( + vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0))); +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// lower of dst, and zero the upper element. mem_addr does not need to be +// aligned on any particular boundary. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd +FORCE_INLINE __m128d _mm_load_sd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); +#endif +} + +// Loads two double-precision from 16-byte aligned memory, floating-point +// values. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd +FORCE_INLINE __m128d _mm_load_pd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64(p)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); +#endif +} + +// Loads two double-precision from unaligned memory, floating-point values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd +FORCE_INLINE __m128d _mm_loadu_pd(const double *p) +{ + return _mm_load_pd(p); +} + +// Loads an single - precision, floating - point value into the low word and +// clears the upper three words. +// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_load_ss(const float *p) +{ + return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); +} + +// Load 64-bit integer from memory into the first element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_epi64 +FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) +{ + /* Load the lower 64 bits of the value pointed to by p into the + * lower 64 bits of the result, zeroing the upper 64 bits of the result. + */ + return vreinterpretq_m128i_s32( + vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// lower element of dst, and copy the upper element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd +FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); +#else + return vreinterpretq_m128d_f32( + vcombine_f32(vld1_f32((const float *) p), + vget_high_f32(vreinterpretq_f32_m128d(a)))); +#endif +} + +// Load 2 double-precision (64-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[63:0] := MEM[mem_addr+127:mem_addr+64] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd +FORCE_INLINE __m128d _mm_loadr_pd(const double *p) +{ +#if defined(__aarch64__) + float64x2_t v = vld1q_f64(p); + return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); +#else + int64x2_t v = vld1q_s64((const int64_t *) p); + return vreinterpretq_m128d_s64(vextq_s64(v, v, 1)); +#endif +} + +// Sets the low word to the single-precision, floating-point value of b +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100) +FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0), + vreinterpretq_f32_m128(a), 0)); +} + +// Move the lower double-precision (64-bit) floating-point element from b to the +// lower element of dst, and copy the upper element from a to the upper element +// of dst. +// +// dst[63:0] := b[63:0] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd +FORCE_INLINE __m128d _mm_move_sd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_f32( + vcombine_f32(vget_low_f32(vreinterpretq_f32_m128d(b)), + vget_high_f32(vreinterpretq_f32_m128d(a)))); +} + +// Copy the lower 64-bit integer in a to the lower element of dst, and zero the +// upper element. +// +// dst[63:0] := a[63:0] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64 +FORCE_INLINE __m128i _mm_move_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1)); +} + +// Return vector of type __m128 with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps +FORCE_INLINE __m128 _mm_undefined_ps(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + __m128 a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} + +/* Logic/Binary operations */ + +// Computes the bitwise AND-NOT of the four single-precision, floating-point +// values of a and b. +// +// r0 := ~a0 & b0 +// r1 := ~a1 & b1 +// r2 := ~a2 & b2 +// r3 := ~a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx +FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vbicq_s32(vreinterpretq_s32_m128(b), + vreinterpretq_s32_m128(a))); // *NOTE* argument swap +} + +// Compute the bitwise NOT of packed double-precision (64-bit) floating-point +// elements in a and then AND with b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd +FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b) +{ + // *NOTE* argument swap + return vreinterpretq_m128d_s64( + vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a))); +} + +// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the +// 128-bit value in a. +// +// r := (~a) & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vbicq_s32(vreinterpretq_s32_m128i(b), + vreinterpretq_s32_m128i(a))); // *NOTE* argument swap +} + +// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in +// b. +// +// r := a & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the bitwise AND of the four single-precision, floating-point values +// of a and b. +// +// r0 := a0 & b0 +// r1 := a1 & b1 +// r2 := a2 & b2 +// r3 := a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Compute the bitwise AND of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] AND b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd +FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Computes the bitwise OR of the four single-precision, floating-point values +// of a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx +FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Computes bitwise EXOR (exclusive-or) of the four single-precision, +// floating-point values of a and b. +// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Compute the bitwise XOR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] XOR b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd +FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Compute the bitwise OR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_or_pd +FORCE_INLINE __m128d _mm_or_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + vorrq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. +// +// r := a | b +// +// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx +FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in +// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx +FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Duplicate the low double-precision (64-bit) floating-point element from a, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movedup_pd +FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) +{ +#if (__aarch64__) + return vreinterpretq_m128d_f64( + vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0)); +#else + return vreinterpretq_m128d_u64( + vdupq_n_u64(vgetq_lane_u64(vreinterpretq_u64_m128d(a), 0))); +#endif +} + +// Duplicate odd-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps +FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) +{ +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3)); +#else + float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3); + float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif +} + +// Duplicate even-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps +FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) +{ +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2)); +#else + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2); + float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif +} + +// Moves the upper two values of B into the lower two values of A. +// +// r3 := a3 +// r2 := a2 +// r1 := b3 +// r0 := b2 +FORCE_INLINE __m128 _mm_movehl_ps(__m128 __A, __m128 __B) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(b32, a32)); +} + +// Moves the lower two values of B into the upper two values of A. +// +// r3 := b1 +// r2 := b0 +// r1 := a1 +// r0 := a0 +FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32 +FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); +} + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16 +FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) +{ + return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); +} + +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8 +FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) +{ + return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); +} + +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 1 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32 +FORCE_INLINE __m64 _mm_abs_pi32(__m64 a) +{ + return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a))); +} + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16 +FORCE_INLINE __m64 _mm_abs_pi16(__m64 a) +{ + return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a))); +} + +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8 +FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) +{ + return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a))); +} + +// Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift +// the result right by imm8 bytes, and store the low 16 bytes in dst. +// +// tmp[255:0] := ((a[127:0] << 128)[255:0] OR b[127:0]) >> (imm8*8) +// dst[127:0] := tmp[127:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_epi8 +#define _mm_alignr_epi8(a, b, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm) >= 32)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + uint8x16_t tmp_low, tmp_high; \ + if (imm >= 16) { \ + const int idx = imm - 16; \ + tmp_low = vreinterpretq_u8_m128i(a); \ + tmp_high = vdupq_n_u8(0); \ + ret = \ + vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \ + } else { \ + const int idx = imm; \ + tmp_low = vreinterpretq_u8_m128i(b); \ + tmp_high = vreinterpretq_u8_m128i(a); \ + ret = \ + vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \ + } \ + } \ + ret; \ + }) + +// Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift +// the result right by imm8 bytes, and store the low 8 bytes in dst. +// +// tmp[127:0] := ((a[63:0] << 64)[127:0] OR b[63:0]) >> (imm8*8) +// dst[63:0] := tmp[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_pi8 +#define _mm_alignr_pi8(a, b, imm) \ + __extension__({ \ + __m64 ret; \ + if (unlikely((imm) >= 16)) { \ + ret = vreinterpret_m64_s8(vdup_n_s8(0)); \ + } else { \ + uint8x8_t tmp_low, tmp_high; \ + if (imm >= 8) { \ + const int idx = imm - 8; \ + tmp_low = vreinterpret_u8_m64(a); \ + tmp_high = vdup_n_u8(0); \ + ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ + } else { \ + const int idx = imm; \ + tmp_low = vreinterpret_u8_m64(b); \ + tmp_high = vreinterpret_u8_m64(a); \ + ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ + } \ + } \ + ret; \ + }) + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of b and places it into the high end of the result. +FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a32, b10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in high +// end of result takes the higher two 32 bit values from b and swaps them and +// places in low end of result. +FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b23 = vrev64_f32(vget_high_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b23)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b) +{ + float32x2_t a21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a21, b03)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b) +{ + float32x2_t a03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a03, b21)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a01, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b01)); +} + +// keeps the low 64 bits of b in the low and puts the high 64 bits of a in the +// high +FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b) +{ + float32x2_t a11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a11, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b) +{ + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a22, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b) +{ + float32x2_t a00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a00, b22)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b) +{ + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t a02 = vset_lane_f32(a0, a22, 1); /* TODO: use vzip ?*/ + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a02, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b) +{ + float32x2_t a33 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 1); + return vreinterpretq_m128_f32(vcombine_f32(a33, b11)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a10, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a01, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); +} + +// NEON does not support a general purpose permute intrinsic +// Selects four specific single-precision, floating-point values from a and b, +// based on the mask i. +// +// C equivalent: +// __m128 _mm_shuffle_ps_default(__m128 a, __m128 b, +// __constrange(0, 255) int imm) { +// __m128 ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = b[(imm >> 4) & 0x03]; ret[3] = b[(imm >> 6) & 0x03]; +// return ret; +// } +// +// https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx +#define _mm_shuffle_ps_default(a, b, imm) \ + __extension__({ \ + float32x4_t ret; \ + ret = vmovq_n_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128_f32(ret); \ + }) + +// FORCE_INLINE __m128 _mm_shuffle_ps(__m128 a, __m128 b, __constrange(0,255) +// int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_ps(a, b, imm) \ + __extension__({ \ + float32x4_t _input1 = vreinterpretq_f32_m128(a); \ + float32x4_t _input2 = vreinterpretq_f32_m128(b); \ + float32x4_t _shuf = __builtin_shufflevector( \ + _input1, _input2, (imm) & (0x3), ((imm) >> 2) & 0x3, \ + (((imm) >> 4) & 0x3) + 4, (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128_f32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_ps(a, b, imm) \ + __extension__({ \ + __m128 ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_ps_1032((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_ps_2301((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_ps_0321((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_ps_2103((a), (b)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_movelh_ps((a), (b)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_ps_1001((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_ps_0101((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 1, 0): \ + ret = _mm_shuffle_ps_3210((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 0, 1, 1): \ + ret = _mm_shuffle_ps_0011((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 0, 2, 2): \ + ret = _mm_shuffle_ps_0022((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 2, 0, 0): \ + ret = _mm_shuffle_ps_2200((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 0, 2): \ + ret = _mm_shuffle_ps_3202((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 3, 2): \ + ret = _mm_movehl_ps((b), (a)); \ + break; \ + case _MM_SHUFFLE(1, 1, 3, 3): \ + ret = _mm_shuffle_ps_1133((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 1, 0): \ + ret = _mm_shuffle_ps_2010((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 0, 1): \ + ret = _mm_shuffle_ps_2001((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 3, 2): \ + ret = _mm_shuffle_ps_2032((a), (b)); \ + break; \ + default: \ + ret = _mm_shuffle_ps_default((a), (b), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of a and places it into the high end of the result. +FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in low end +// of result takes the higher two 32 bit values from a and swaps them and places +// in high end of result. +FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); +} + +// rotates the least significant 32 bits into the most signficant 32 bits, and +// shifts the rest down +FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); +} + +// rotates the most significant 32 bits into the least signficant 32 bits, and +// shifts the rest up +FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); +} + +// gets the lower 64 bits of a, and places it in the upper 64 bits +// gets the lower 64 bits of a and places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) +{ + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the +// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the +// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and +// places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) +{ + int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) +{ + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8 +FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) +{ + int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a + uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b + uint8x16_t idx_masked = + vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); +#elif defined(__GNUC__) + int8x16_t ret; + // %e and %f represent the even and odd D registers + // respectively. + __asm__ __volatile__( + "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" + "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" + : [ret] "=&w"(ret) + : [tbl] "w"(tbl), [idx] "w"(idx_masked)); + return vreinterpretq_m128i_s8(ret); +#else + // use this line if testing on aarch64 + int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)}; + return vreinterpretq_m128i_s8( + vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)), + vtbl2_s8(a_split, vget_high_u8(idx_masked)))); +#endif +} + +// C equivalent: +// __m128i _mm_shuffle_epi32_default(__m128i a, +// __constrange(0, 255) int imm) { +// __m128i ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03]; +// return ret; +// } +#define _mm_shuffle_epi32_default(a, imm) \ + __extension__({ \ + int32x4_t ret; \ + ret = vmovq_n_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128i_s32(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) +// int imm) +#if defined(__aarch64__) +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ + }) +#else +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ + }) +#endif + +// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. +// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + int32x4_t _input = vreinterpretq_s32_m128i(a); \ + int32x4_t _shuf = __builtin_shufflevector( \ + _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \ + ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ + vreinterpretq_m128i_s32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_epi_1032((a)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_epi_2301((a)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_epi_0321((a)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_epi_2103((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_shuffle_epi_1010((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_epi_1001((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_epi_0101((a)); \ + break; \ + case _MM_SHUFFLE(2, 2, 1, 1): \ + ret = _mm_shuffle_epi_2211((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 2, 2): \ + ret = _mm_shuffle_epi_0122((a)); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 2): \ + ret = _mm_shuffle_epi_3332((a)); \ + break; \ + case _MM_SHUFFLE(0, 0, 0, 0): \ + ret = _mm_shuffle_epi32_splat((a), 0); \ + break; \ + case _MM_SHUFFLE(1, 1, 1, 1): \ + ret = _mm_shuffle_epi32_splat((a), 1); \ + break; \ + case _MM_SHUFFLE(2, 2, 2, 2): \ + ret = _mm_shuffle_epi32_splat((a), 2); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 3): \ + ret = _mm_shuffle_epi32_splat((a), 3); \ + break; \ + default: \ + ret = _mm_shuffle_epi32_default((a), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif + +// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) +// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflelo_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t lowBits = vget_low_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflelo_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \ + (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) +#endif + +// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflehi_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t highBits = vget_high_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ + 5); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ + 6); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ + 7); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflehi_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \ + (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \ + (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) +#endif + +// Shuffle double-precision (64-bit) floating-point elements using the control +// in imm8, and store the results in dst. +// +// dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64] +// dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_pd(a, b, imm8) \ + vreinterpretq_m128d_s64(__builtin_shufflevector( \ + vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b), imm8 & 0x1, \ + ((imm8 & 0x2) >> 1) + 2)) +#else +#define _mm_shuffle_pd(a, b, imm8) \ + _mm_castsi128_pd(_mm_set_epi64x( \ + vgetq_lane_s64(vreinterpretq_s64_m128d(b), (imm8 & 0x2) >> 1), \ + vgetq_lane_s64(vreinterpretq_s64_m128d(a), imm8 & 0x1))) +#endif + +// Blend packed 16-bit integers from a and b using control mask imm8, and store +// the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[j] +// dst[i+15:i] := b[i+15:i] +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI +// ENDFOR +// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, +// __constrange(0,255) int imm) +#define _mm_blend_epi16(a, b, imm) \ + __extension__({ \ + const uint16_t _mask[8] = {((imm) & (1 << 0)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 1)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 2)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 3)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 4)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 5)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 6)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 7)) ? 0xFFFF : 0x0000}; \ + uint16x8_t _mask_vec = vld1q_u16(_mask); \ + uint16x8_t _a = vreinterpretq_u16_m128i(a); \ + uint16x8_t _b = vreinterpretq_u16_m128i(b); \ + vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ + }) + +// Blend packed 8-bit integers from a and b using mask, and store the results in +// dst. +// +// FOR j := 0 to 15 +// i := j*8 +// IF mask[i+7] +// dst[i+7:i] := b[i+7:i] +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) +{ + // Use a signed shift right to create a mask with the sign bit + uint8x16_t mask = + vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); + uint8x16_t a = vreinterpretq_u8_m128i(_a); + uint8x16_t b = vreinterpretq_u8_m128i(_b); + return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); +} + +/* Shifts */ + + +// Shift packed 16-bit integers in a right by imm while shifting in sign +// bits, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16 +FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) +{ + const int count = (imm & ~15) ? 15 : imm; + return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); +} + +// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// ... +// r7 := a7 << count +// +// https://msdn.microsoft.com/en-us/library/es73bcsy(v=vs.90).aspx +#define _mm_slli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm)) <= 0) { \ + ret = a; \ + } \ + if (unlikely((imm) > 15)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s16( \ + vshlq_n_s16(vreinterpretq_s16_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while +// shifting in zeros. : +// https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, __constrange(0,255) int imm) +FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm) +{ + if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */ + return a; + if (unlikely(imm > 31)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s32( + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm))); +} + +// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) +{ + if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */ + return a; + if (unlikely(imm > 63)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s64( + vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm))); +} + +// Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16 +#define _mm_srli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely(imm) == 0) { \ + ret = a; \ + } \ + if (likely(0 < (imm) && (imm) < 16)) { \ + ret = vreinterpretq_m128i_u16( \ + vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \ + } else { \ + ret = _mm_setzero_si128(); \ + } \ + ret; \ + }) + +// Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32 +// FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm) == 0)) { \ + ret = a; \ + } \ + if (likely(0 < (imm) && (imm) < 32)) { \ + ret = vreinterpretq_m128i_u32( \ + vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \ + } else { \ + ret = _mm_setzero_si128(); \ + } \ + ret; \ + }) + +// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF imm8[7:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64 +#define _mm_srli_epi64(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm) == 0)) { \ + ret = a; \ + } \ + if (likely(0 < (imm) && (imm) < 64)) { \ + ret = vreinterpretq_m128i_u64( \ + vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \ + } else { \ + ret = _mm_setzero_si128(); \ + } \ + ret; \ + }) + +// Shift packed 32-bit integers in a right by imm8 while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) +// ELSE +// dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32 +// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srai_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm) == 0)) { \ + ret = a; \ + } \ + if (likely(0 < (imm) && (imm) < 32)) { \ + ret = vreinterpretq_m128i_s32( \ + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ + } \ + ret; \ + }) + +// Shifts the 128 - bit value in a right by imm bytes while shifting in +// zeros.imm must be an immediate. +// +// r := srl(a, imm*8) +// +// https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx +// FORCE_INLINE _mm_srli_si128(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_si128(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm) <= 0)) { \ + ret = a; \ + } \ + if (unlikely((imm) > 15)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s8( \ + vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm +// must be an immediate. +// +// r := a << (imm * 8) +// +// https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_slli_si128(__m128i a, __constrange(0,255) int imm) +#define _mm_slli_si128(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (unlikely((imm) <= 0)) { \ + ret = a; \ + } \ + if (unlikely((imm) > 15)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s8(vextq_s8( \ + vdupq_n_s8(0), vreinterpretq_s8_m128i(a), 16 - (imm))); \ + } \ + ret; \ + }) + +// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// ... +// r7 := a7 << count +// +// https://msdn.microsoft.com/en-us/library/c79w388h(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (unlikely(c > 15)) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16((int16_t) c); + return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); +} + +// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// r2 := a2 << count +// r3 := a3 << count +// +// https://msdn.microsoft.com/en-us/library/6fe5a6s9(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (unlikely(c > 31)) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32((int32_t) c); + return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc)); +} + +// Shifts the 2 signed or unsigned 64-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// +// https://msdn.microsoft.com/en-us/library/6ta9dffd(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (unlikely(c > 63)) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64((int64_t) c); + return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc)); +} + +// Shifts the 8 signed or unsigned 16-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// ... +// r7 := srl(a7, count) +// +// https://msdn.microsoft.com/en-us/library/wd5ax830(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (unlikely(c > 15)) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16(-(int16_t) c); + return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc)); +} + +// Shifts the 4 signed or unsigned 32-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// r2 := srl(a2, count) +// r3 := srl(a3, count) +// +// https://msdn.microsoft.com/en-us/library/a9cbttf4(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (unlikely(c > 31)) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32(-(int32_t) c); + return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc)); +} + +// Shifts the 2 signed or unsigned 64-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// +// https://msdn.microsoft.com/en-us/library/yf6cf9k8(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (unlikely(c > 63)) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64(-(int64_t) c); + return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc)); +} + +// NEON does not provide a version of this function. +// Creates a 16-bit mask from the most significant bits of the 16 signed or +// unsigned 8-bit integers in a and zero extends the upper bits. +// https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_epi8(__m128i a) +{ + // Use increasingly wide shifts+adds to collect the sign bits + // together. + // Since the widening shifts would be rather confusing to follow in little + // endian, everything will be illustrated in big endian order instead. This + // has a different result - the bits would actually be reversed on a big + // endian machine. + + // Starting input (only half the elements are shown): + // 89 ff 1d c0 00 10 99 33 + uint8x16_t input = vreinterpretq_u8_m128i(a); + + // Shift out everything but the sign bits with an unsigned shift right. + // + // Bytes of the vector:: + // 89 ff 1d c0 00 10 99 33 + // \ \ \ \ \ \ \ \ high_bits = (uint16x4_t)(input >> 7) + // | | | | | | | | + // 01 01 00 01 00 00 01 00 + // + // Bits of first important lane(s): + // 10001001 (89) + // \______ + // | + // 00000001 (01) + uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7)); + + // Merge the even lanes together with a 16-bit unsigned shift right + add. + // 'xx' represents garbage data which will be ignored in the final result. + // In the important bytes, the add functions like a binary OR. + // + // 01 01 00 01 00 00 01 00 + // \_ | \_ | \_ | \_ | paired16 = (uint32x4_t)(input + (input >> 7)) + // \| \| \| \| + // xx 03 xx 01 xx 00 xx 02 + // + // 00000001 00000001 (01 01) + // \_______ | + // \| + // xxxxxxxx xxxxxx11 (xx 03) + uint32x4_t paired16 = + vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); + + // Repeat with a wider 32-bit shift + add. + // xx 03 xx 01 xx 00 xx 02 + // \____ | \____ | paired32 = (uint64x1_t)(paired16 + (paired16 >> + // 14)) + // \| \| + // xx xx xx 0d xx xx xx 02 + // + // 00000011 00000001 (03 01) + // \\_____ || + // '----.\|| + // xxxxxxxx xxxx1101 (xx 0d) + uint64x2_t paired32 = + vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); + + // Last, an even wider 64-bit shift + add to get our result in the low 8 bit + // lanes. xx xx xx 0d xx xx xx 02 + // \_________ | paired64 = (uint8x8_t)(paired32 + (paired32 >> + // 28)) + // \| + // xx xx xx xx xx xx xx d2 + // + // 00001101 00000010 (0d 02) + // \ \___ | | + // '---. \| | + // xxxxxxxx 11010010 (xx d2) + uint8x16_t paired64 = + vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); + + // Extract the low 8 bits from each 64-bit lane with 2 8-bit extracts. + // xx xx xx xx xx xx xx d2 + // || return paired64[0] + // d2 + // Note: Little endian would return the correct value 4b (01001011) instead. + return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8); +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movepi64_pi64 +FORCE_INLINE __m64 _mm_movepi64_pi64(__m128i a) +{ + return vreinterpret_m64_s64(vget_low_s64(vreinterpretq_s64_m128i(a))); +} + +// Copy the 64-bit integer a to the lower element of dst, and zero the upper +// element. +// +// dst[63:0] := a[63:0] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movpi64_epi64 +FORCE_INLINE __m128i _mm_movpi64_epi64(__m64 a) +{ + return vreinterpretq_m128i_s64( + vcombine_s64(vreinterpret_s64_m64(a), vdup_n_s64(0))); +} + +// NEON does not provide this method +// Creates a 4-bit mask from the most significant bits of the four +// single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_ps(__m128 a) +{ + uint32x4_t input = vreinterpretq_u32_m128(a); +#if defined(__aarch64__) + static const int32x4_t shift = {0, 1, 2, 3}; + uint32x4_t tmp = vshrq_n_u32(input, 31); + return vaddvq_u32(vshlq_u32(tmp, shift)); +#else + // Uses the exact same method as _mm_movemask_epi8, see that for details. + // Shift out everything but the sign bits with a 32-bit unsigned shift + // right. + uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); + // Merge the two pairs together with a 64-bit unsigned shift right + add. + uint8x16_t paired = + vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); + // Extract the result. + return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); +#endif +} + +// Compute the bitwise NOT of a and then AND with a 128-bit vector containing +// all 1's, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones +FORCE_INLINE int _mm_test_all_ones(__m128i a) +{ + return (uint64_t)(vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) == + ~(uint64_t) 0; +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros +FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +{ + int64x2_t a_and_mask = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); + return (vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)) ? 0 + : 1; +} + +/* Math operations */ + +// Subtracts the four single-precision, floating-point values of a and b. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Subtract the lower single-precision (32-bit) floating-point element in b from +// the lower single-precision (32-bit) floating-point element in a, store the +// result in the lower element of dst, and copy the upper 3 packed elements from +// a to the upper elements of dst. +// +// dst[31:0] := a[31:0] - b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss +FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_sub_ps(a, b)); +} + +// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, +// and store the results in dst. +// r0 := a0 - b0 +// r1 := a1 - b1 +FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or +// unsigned 32-bit integers of a. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx +FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Subtract packed 16-bit integers in b from packed 16-bit integers in a, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi16 +FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Subtract packed 8-bit integers in b from packed 8-bit integers in a, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi8 +FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Subtract 64-bit integer b from 64-bit integer a, and store the result in dst. +// +// dst[63:0] := a[63:0] - b[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64 +FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} + +// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit +// integers of a and saturates.. +// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx +FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit +// integers of a and saturates. +// +// r0 := UnsignedSaturate(a0 - b0) +// r1 := UnsignedSaturate(a1 - b1) +// ... +// r15 := UnsignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r15 := SignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r7 := SignedSaturate(a7 - b7) +// +// https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Subtract packed double-precision (64-bit) floating-point elements in b from +// packed double-precision (64-bit) floating-point elements in a, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] - b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_sub_pd +FORCE_INLINE __m128d _mm_sub_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vsubq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] - db[0]; + c[1] = da[1] - db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Subtract the lower double-precision (64-bit) floating-point element in b from +// the lower double-precision (64-bit) floating-point element in a, store the +// result in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_sd +FORCE_INLINE __m128d _mm_sub_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_sub_pd(a, b)); +} + +// Add packed unsigned 16-bit integers in a and b using saturation, and store +// the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epu16 +FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Negate packed 8-bit integers in a when the corresponding signed +// 8-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..15 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) +{ + int8x16_t a = vreinterpretq_s8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 +#if defined(__aarch64__) + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); +#else + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); +#endif + + // bitwise select either a or nagative 'a' (vnegq_s8(a) return nagative 'a') + // based on ltMask + int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a); + // res = masked & (~zeroMask) + int8x16_t res = vbicq_s8(masked, zeroMask); + + return vreinterpretq_m128i_s8(res); +} + +// Negate packed 16-bit integers in a when the corresponding signed +// 16-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..7 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15)); + // (b == 0) ? 0xFFFF : 0 +#if defined(__aarch64__) + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqzq_s16(b)); +#else + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, vdupq_n_s16(0))); +#endif + + // bitwise select either a or negative 'a' (vnegq_s16(a) equals to negative + // 'a') based on ltMask + int16x8_t masked = vbslq_s16(ltMask, vnegq_s16(a), a); + // res = masked & (~zeroMask) + int16x8_t res = vbicq_s16(masked, zeroMask); + return vreinterpretq_m128i_s16(res); +} + +// Negate packed 32-bit integers in a when the corresponding signed +// 32-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..3 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31)); + + // (b == 0) ? 0xFFFFFFFF : 0 +#if defined(__aarch64__) + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqzq_s32(b)); +#else + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, vdupq_n_s32(0))); +#endif + + // bitwise select either a or negative 'a' (vnegq_s32(a) equals to negative + // 'a') based on ltMask + int32x4_t masked = vbslq_s32(ltMask, vnegq_s32(a), a); + // res = masked & (~zeroMask) + int32x4_t res = vbicq_s32(masked, zeroMask); + return vreinterpretq_m128i_s32(res); +} + +// Negate packed 16-bit integers in a when the corresponding signed 16-bit +// integer in b is negative, and store the results in dst. Element in dst are +// zeroed out when the corresponding element in b is zero. +// +// FOR j := 0 to 3 +// i := j*16 +// IF b[i+15:i] < 0 +// dst[i+15:i] := -(a[i+15:i]) +// ELSE IF b[i+15:i] == 0 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi16 +FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b) +{ + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x4_t ltMask = vreinterpret_u16_s16(vshr_n_s16(b, 15)); + + // (b == 0) ? 0xFFFF : 0 +#if defined(__aarch64__) + int16x4_t zeroMask = vreinterpret_s16_u16(vceqz_s16(b)); +#else + int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s16(a) return nagative 'a') + // based on ltMask + int16x4_t masked = vbsl_s16(ltMask, vneg_s16(a), a); + // res = masked & (~zeroMask) + int16x4_t res = vbic_s16(masked, zeroMask); + + return vreinterpret_m64_s16(res); +} + +// Negate packed 32-bit integers in a when the corresponding signed 32-bit +// integer in b is negative, and store the results in dst. Element in dst are +// zeroed out when the corresponding element in b is zero. +// +// FOR j := 0 to 1 +// i := j*32 +// IF b[i+31:i] < 0 +// dst[i+31:i] := -(a[i+31:i]) +// ELSE IF b[i+31:i] == 0 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := a[i+31:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi32 +FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b) +{ + int32x2_t a = vreinterpret_s32_m64(_a); + int32x2_t b = vreinterpret_s32_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x2_t ltMask = vreinterpret_u32_s32(vshr_n_s32(b, 31)); + + // (b == 0) ? 0xFFFFFFFF : 0 +#if defined(__aarch64__) + int32x2_t zeroMask = vreinterpret_s32_u32(vceqz_s32(b)); +#else + int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s32(a) return nagative 'a') + // based on ltMask + int32x2_t masked = vbsl_s32(ltMask, vneg_s32(a), a); + // res = masked & (~zeroMask) + int32x2_t res = vbic_s32(masked, zeroMask); + + return vreinterpret_m64_s32(res); +} + +// Negate packed 8-bit integers in a when the corresponding signed 8-bit integer +// in b is negative, and store the results in dst. Element in dst are zeroed out +// when the corresponding element in b is zero. +// +// FOR j := 0 to 7 +// i := j*8 +// IF b[i+7:i] < 0 +// dst[i+7:i] := -(a[i+7:i]) +// ELSE IF b[i+7:i] == 0 +// dst[i+7:i] := 0 +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi8 +FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) +{ + int8x8_t a = vreinterpret_s8_m64(_a); + int8x8_t b = vreinterpret_s8_m64(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x8_t ltMask = vreinterpret_u8_s8(vshr_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 +#if defined(__aarch64__) + int8x8_t zeroMask = vreinterpret_s8_u8(vceqz_s8(b)); +#else + int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0))); +#endif + + // bitwise select either a or nagative 'a' (vneg_s8(a) return nagative 'a') + // based on ltMask + int8x8_t masked = vbsl_s8(ltMask, vneg_s8(a), a); + // res = masked & (~zeroMask) + int8x8_t res = vbic_s8(masked, zeroMask); + + return vreinterpret_m64_s8(res); +} + +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16 +FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b) +{ + return vreinterpret_m64_u16( + vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8 +FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb +#define _m_pavgb(a, b) _mm_avg_pu8(a, b) + +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw +#define _m_pavgw(a, b) _mm_avg_pu16(a, b) + +// Extract a 16-bit integer from a, selected with imm8, and store the result in +// the lower element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pextrw +#define _m_pextrw(a, imm) _mm_extract_pi16(a, imm) + +// Copy a to dst, and insert the 16-bit integer i into dst at the location +// specified by imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_pinsrw +#define _m_pinsrw(a, i, imm) _mm_insert_pi16(a, i, imm) + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxsw +#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxub +#define _m_pmaxub(a, b) _mm_max_pu8(a, b) + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminsw +#define _m_pminsw(a, b) _mm_min_pi16(a, b) + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminub +#define _m_pminub(a, b) _mm_min_pu8(a, b) + +// Computes the average of the 16 unsigned 8-bit integers in a and the 16 +// unsigned 8-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r15 := (a15 + b15) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the average of the 8 unsigned 16-bit integers in a and the 8 +// unsigned 16-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r7 := (a7 + b7) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) +{ + return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), + vreinterpretq_u16_m128i(b)); +} + +// Adds the four single-precision, floating-point values of a and b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Add packed double-precision (64-bit) floating-point elements in a and b, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd +FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1] + db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Add the lower double-precision (64-bit) floating-point element in a and b, +// store the result in the lower element of dst, and copy the upper element from +// a to the upper element of dst. +// +// dst[63:0] := a[63:0] + b[63:0] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_sd +FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_add_pd(a, b)); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Add 64-bit integers a and b, and store the result in dst. +// +// dst[63:0] := a[63:0] + b[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64 +FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} + +// adds the scalar single-precision floating point values of a and b. +// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) +{ + float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); + float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); + // the upper values in the result must be the remnants of <a>. + return vreinterpretq_m128_f32(vaddq_f32(a, value)); +} + +// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or +// unsigned 16-bit integers in b. +// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or +// unsigned 8-bit integers in b. +// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) +FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b +// and saturates. +// +// r0 := SignedSaturate(a0 + b0) +// r1 := SignedSaturate(a1 + b1) +// ... +// r7 := SignedSaturate(a7 + b7) +// +// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Add packed signed 8-bit integers in a and b using saturation, and store the +// results in dst. +// +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] ) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8 +FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in +// b and saturates.. +// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or +// unsigned 16-bit integers from b. +// +// r0 := (a0 * b0)[15:0] +// r1 := (a1 * b1)[15:0] +// ... +// r7 := (a7 * b7)[15:0] +// +// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or +// unsigned 32-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// tmp[31:0] := a[i+15:i] * b[i+15:i] +// dst[i+15:i] := tmp[31:16] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw +#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) + +// Multiplies the four single-precision, floating-point values of a and b. +// +// r0 := a0 * b0 +// r1 := a1 * b1 +// r2 := a2 * b2 +// r3 := a3 * b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx +FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Multiply packed double-precision (64-bit) floating-point elements in a and b, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd +FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] * db[0]; + c[1] = da[1] * db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Multiply the lower double-precision (64-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper element +// from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_mul_sd +FORCE_INLINE __m128d _mm_mul_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_mul_pd(a, b)); +} + +// Multiply the lower single-precision (32-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper 3 packed +// elements from a to the upper elements of dst. +// +// dst[31:0] := a[31:0] * b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss +FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_mul_ps(a, b)); +} + +// Multiply the low unsigned 32-bit integers from each packed 64-bit element in +// a and b, and store the unsigned 64-bit results in dst. +// +// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) +// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) +FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) +{ + // vmull_u32 upcasts instead of masking, so we downcast. + uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); + uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); + return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); +} + +// Multiply the low unsigned 32-bit integers from a and b, and store the +// unsigned 64-bit result in dst. +// +// dst[63:0] := a[31:0] * b[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32 +FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b) +{ + return vreinterpret_m64_u64(vget_low_u64( + vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b)))); +} + +// Multiply the low signed 32-bit integers from each packed 64-bit element in +// a and b, and store the signed 64-bit results in dst. +// +// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 +// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 +FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) +{ + // vmull_s32 upcasts instead of masking, so we downcast. + int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); + int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0) + (a1 * b1) +// r1 := (a2 * b2) + (a3 * b3) +// r2 := (a4 * b4) + (a5 * b5) +// r3 := (a6 * b6) + (a7 * b7) +// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx +FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +{ + int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); + int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); + + return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); +} + +// Multiply packed signed 16-bit integers in a and b, producing intermediate +// signed 32-bit integers. Shift right by 15 bits while rounding up, and store +// the packed 16-bit integers in dst. +// +// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) +// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) +// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) +// ... +// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) +FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) +{ + // Has issues due to saturation + // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); + + // Multiply + int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + // Rounding narrowing shift right + // narrow = (int16_t)((mul + 16384) >> 15); + int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); + int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); + + // Join together + return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); +} + +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, +// and pack the saturated results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + +// a[i+7:i]*b[i+7:i] ) +// ENDFOR +FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + uint8x16_t a = vreinterpretq_u8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), + vmovl_s8(vget_low_s8(b))); + int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))), + vmovl_s8(vget_high_s8(b))); + return vreinterpretq_m128i_s16( + vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th))); +#else + // This would be much simpler if x86 would choose to zero extend OR sign + // extend, not both. This could probably be optimized better. + uint16x8_t a = vreinterpretq_u16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // Zero extend a + int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); + int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); + + // Sign extend by shifting left then shifting right. + int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); + int16x8_t b_odd = vshrq_n_s16(b, 8); + + // multiply + int16x8_t prod1 = vmulq_s16(a_even, b_even); + int16x8_t prod2 = vmulq_s16(a_odd, b_odd); + + // saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); +#endif +} + +// Computes the fused multiple add product of 32-bit floating point numbers. +// +// Return Value +// Multiplies A and B, and adds C to the temporary result before returning it. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_fmadd +FORCE_INLINE __m128 _mm_fmadd_ps(__m128 a, __m128 b, __m128 c) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(c), + vreinterpretq_f32_m128(b), + vreinterpretq_f32_m128(a))); +#else + return _mm_add_ps(_mm_mul_ps(a, b), c); +#endif +} + +// Alternatively add and subtract packed single-precision (32-bit) +// floating-point elements in a to/from packed elements in b, and store the +// results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps +FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) +{ + __m128 mask = {-1.0f, 1.0f, -1.0f, 1.0f}; + return _mm_fmadd_ps(b, mask, a); +} + +// Horizontally add adjacent pairs of double-precision (64-bit) floating-point +// elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pd +FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[] = {da[0] + da[1], db[0] + db[1]}; + return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); +#endif +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce two +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of 64-bit elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8 +FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) +{ + uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); + uint16_t r0 = t[0] + t[1] + t[2] + t[3]; + uint16_t r4 = t[4] + t[5] + t[6] + t[7]; + uint16x8_t r = vsetq_lane_u16(r0, vdupq_n_u16(0), 0); + return (__m128i) vsetq_lane_u16(r4, r, 4); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8 +FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) +{ + uint16x4_t t = + vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); + uint16_t r0 = t[0] + t[1] + t[2] + t[3]; + return vreinterpret_m64_u16(vset_lane_u16(r0, vdup_n_u16(0), 0)); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// +// FOR j := 0 to 7 +// i := j*8 +// tmp[i+7:i] := ABS(a[i+7:i] - b[i+7:i]) +// ENDFOR +// dst[15:0] := tmp[7:0] + tmp[15:8] + tmp[23:16] + tmp[31:24] + tmp[39:32] + +// tmp[47:40] + tmp[55:48] + tmp[63:56] dst[63:16] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_psadbw +#define _m_psadbw(a, b) _mm_sad_pu8(a, b) + +// Divides the four single-precision, floating-point values of a and b. +// +// r0 := a0 / b0 +// r1 := a1 / b1 +// r2 := a2 / b2 +// r3 := a3 / b3 +// +// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV + return vreinterpretq_m128_f32( + vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); +#if SSE2NEON_PRECISE_DIV + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); +#endif + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip)); +#endif +} + +// Divides the scalar single-precision floating point value of a by b. +// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Divide packed double-precision (64-bit) floating-point elements in a by +// packed elements in b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 64*j +// dst[i+63:i] := a[i+63:i] / b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_pd +FORCE_INLINE __m128d _mm_div_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] / db[0]; + c[1] = da[1] / db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Divide the lower double-precision (64-bit) floating-point element in a by the +// lower double-precision (64-bit) floating-point element in b, store the result +// in the lower element of dst, and copy the upper element from a to the upper +// element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_sd +FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + float64x2_t tmp = + vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)); + return vreinterpretq_m128d_f64( + vsetq_lane_f64(vgetq_lane_f64(vreinterpretq_f64_m128d(a), 1), tmp, 1)); +#else + return _mm_move_sd(a, _mm_div_pd(a, b)); +#endif +} + +// Compute the approximate reciprocal of packed single-precision (32-bit) +// floating-point elements in a, and store the results in dst. The maximum +// relative error for this approximation is less than 1.5*2^-12. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps +FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) +{ + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#if SSE2NEON_PRECISE_DIV + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#endif + return vreinterpretq_m128_f32(recip); +} + +// Compute the approximate reciprocal of the lower single-precision (32-bit) +// floating-point element in a, store the result in the lower element of dst, +// and copy the upper 3 packed elements from a to the upper elements of dst. The +// maximum relative error for this approximation is less than 1.5*2^-12. +// +// dst[31:0] := (1.0 / a[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss +FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) +{ + return _mm_move_ss(a, _mm_rcp_ps(a)); +} + +// Computes the approximations of square roots of the four single-precision, +// floating-point values of a. First computes reciprocal square roots and then +// reciprocals of the four values. +// +// r0 := sqrt(a0) +// r1 := sqrt(a1) +// r2 := sqrt(a2) +// r3 := sqrt(a3) +// +// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) +{ +#if SSE2NEON_PRECISE_SQRT + float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + + // Test for vrsqrteq_f32(0) -> positive infinity case. + // Change to zero, so that s * 1/sqrt(s) result is zero too. + const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000); + const uint32x4_t div_by_zero = + vceqq_u32(pos_inf, vreinterpretq_u32_f32(recip)); + recip = vreinterpretq_f32_u32( + vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip))); + + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32( + vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), + recip); + recip = vmulq_f32( + vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), + recip); + + // sqrt(s) = s * 1/sqrt(s) + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip)); +#elif defined(__aarch64__) + return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); +#else + float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + float32x4_t sq = vrecpeq_f32(recipsq); + return vreinterpretq_m128_f32(sq); +#endif +} + +// Computes the approximation of the square root of the scalar single-precision +// floating point value of in. +// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); +} + +// Computes the approximations of the reciprocal square roots of the four +// single-precision floating point values of in. +// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx +FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) +{ + float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); +#if SSE2NEON_PRECISE_RSQRT + // Additional Netwon-Raphson iteration for accuracy + out = vmulq_f32( + out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); + out = vmulq_f32( + out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); +#endif + return vreinterpretq_m128_f32(out); +} + +// Compute the approximate reciprocal square root of the lower single-precision +// (32-bit) floating-point element in a, store the result in the lower element +// of dst, and copy the upper 3 packed elements from a to the upper elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss +FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) +{ + return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0); +} + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 +FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 +#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) + +// Computes the maximums of the four single-precision, floating-point values of +// a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) +{ +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vbslq_f32(vcltq_f32(_b, _a), _a, _b); +#else + return vreinterpretq_m128_f32( + vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 +FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 +#define _m_pmaxub(a, b) _mm_max_pu8(a, b) + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 +FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 +#define _m_pminsw(a, b) _mm_min_pi16(a, b) + +// Computes the minima of the four single-precision, floating-point values of a +// and b. +// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) +{ +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vbslq_f32(vcltq_f32(_a, _b), _a, _b); +#else + return vreinterpretq_m128_f32( + vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 +FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 +#define _m_pminub(a, b) _mm_min_pu8(a, b) + +// Computes the maximum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Computes the minimum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/en-us/library/st6634za(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx +FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compare packed signed 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8 +FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed unsigned 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16 +FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Compare packed signed 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8 +FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed unsigned 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16 +FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// epi versions of min/max +// Computes the pariwise maximums of the four signed 32-bit integer values of a +// and b. +// +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 > b0) ? a0 : b0 +// r1 := (a1 > b1) ? a1 : b1 +// r2 := (a2 > b2) ? a2 : b2 +// r3 := (a3 > b3) ? a3 : b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the pariwise minima of the four signed 32-bit integer values of a +// and b. +// +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 < b0) ? a0 : b0 +// r1 := (a1 < b1) ? a1 : b1 +// r2 := (a2 < b2) ? a2 : b2 +// r3 := (a3 < b3) ? a3 : b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compare packed unsigned 32-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); +} + +// Compare packed unsigned 32-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16 +FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b) +{ + return vreinterpret_m64_u16(vshrn_n_u32( + vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16)); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0)[31:16] +// r1 := (a1 * b1)[31:16] +// ... +// r7 := (a7 * b7)[31:16] +// +// https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) +{ + /* FIXME: issue with large values because of result saturation */ + // int16x8_t ret = vqdmulhq_s16(vreinterpretq_s16_m128i(a), + // vreinterpretq_s16_m128i(b)); /* =2*a*b */ return + // vreinterpretq_m128i_s16(vshrq_n_s16(ret, 1)); + int16x4_t a3210 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b3210 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab3210 = vmull_s16(a3210, b3210); /* 3333222211110000 */ + int16x4_t a7654 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b7654 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab7654 = vmull_s16(a7654, b7654); /* 7777666655554444 */ + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_s32(ab3210), vreinterpretq_u16_s32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_epu16 +FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) +{ + uint16x4_t a3210 = vget_low_u16(vreinterpretq_u16_m128i(a)); + uint16x4_t b3210 = vget_low_u16(vreinterpretq_u16_m128i(b)); + uint32x4_t ab3210 = vmull_u16(a3210, b3210); +#if defined(__aarch64__) + uint32x4_t ab7654 = + vmull_high_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)); + uint16x8_t r = vuzp2q_u16(vreinterpretq_u16_u32(ab3210), + vreinterpretq_u16_u32(ab7654)); + return vreinterpretq_m128i_u16(r); +#else + uint16x4_t a7654 = vget_high_u16(vreinterpretq_u16_m128i(a)); + uint16x4_t b7654 = vget_high_u16(vreinterpretq_u16_m128i(b)); + uint32x4_t ab7654 = vmull_u16(a7654, b7654); + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_u32(ab3210), vreinterpretq_u16_u32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); +#endif +} + +// Computes pairwise add of each argument as single-precision, floating-point +// values a and b. +// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx +FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32( + vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); +#endif +} + +// Computes pairwise add of each argument as a 16-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); +#else + return vreinterpretq_m128i_s16( + vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)), + vpadd_s16(vget_low_s16(b), vget_high_s16(b)))); +#endif +} + +// Horizontally substract adjacent pairs of single-precision (32-bit) +// floating-point elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps +FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vsubq_f32( + vuzp1q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)), + vuzp2q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)))); +#else + float32x4x2_t c = + vuzpq_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)); + return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1])); +#endif +} + +// Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the +// signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16 +FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the +// signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32 +FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) +{ + return vreinterpret_m64_s32( + vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))); +} + +// Computes pairwise difference of each argument as a 16-bit signed or unsigned +// integer values a and b. +FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Subtract + return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357)); +} + +// Computes saturated pairwise sub of each argument as a 16-bit signed +// integer values a and b. +FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); +#endif +} + +// Computes saturated pairwise difference of each argument as a 16-bit signed +// integer values a and b. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16 +FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated subtract + return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357)); +#endif +} + +// Computes pairwise add of each argument as a 32-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + return vreinterpretq_m128i_s32( + vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)), + vpadd_s32(vget_low_s32(b), vget_high_s32(b)))); +} + +// Computes pairwise difference of each argument as a 32-bit signed or unsigned +// integer values a and b. +FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) +{ + int64x2_t a = vreinterpretq_s64_m128i(_a); + int64x2_t b = vreinterpretq_s64_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|b0|b2] + // [a1|a2|b1|b3] + int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b)); + int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32)); + // Subtract + return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13)); +} + +// Kahan summation for accurate summation of floating-point numbers. +// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html +FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y) +{ + y -= *c; + float t = *sum + y; + *c = (t - *sum) - y; + *sum = t; +} + +// Conditionally multiply the packed single-precision (32-bit) floating-point +// elements in a and b using the high 4 bits in imm8, sum the four products, +// and conditionally store the sum in dst using the low 4 bits of imm. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_ps +FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) +{ +#if defined(__aarch64__) + /* shortcuts */ + if (imm == 0xFF) { + return _mm_set1_ps(vaddvq_f32(_mm_mul_ps(a, b))); + } + if (imm == 0x7F) { + float32x4_t m = _mm_mul_ps(a, b); + m[3] = 0; + return _mm_set1_ps(vaddvq_f32(m)); + } +#endif + + float s = 0, c = 0; + float32x4_t f32a = vreinterpretq_f32_m128(a); + float32x4_t f32b = vreinterpretq_f32_m128(b); + + /* To improve the accuracy of floating-point summation, Kahan algorithm + * is used for each operation. + */ + if (imm & (1 << 4)) + _sse2neon_kadd_f32(&s, &c, f32a[0] * f32b[0]); + if (imm & (1 << 5)) + _sse2neon_kadd_f32(&s, &c, f32a[1] * f32b[1]); + if (imm & (1 << 6)) + _sse2neon_kadd_f32(&s, &c, f32a[2] * f32b[2]); + if (imm & (1 << 7)) + _sse2neon_kadd_f32(&s, &c, f32a[3] * f32b[3]); + s += c; + + float32x4_t res = { + (imm & 0x1) ? s : 0, + (imm & 0x2) ? s : 0, + (imm & 0x4) ? s : 0, + (imm & 0x8) ? s : 0, + }; + return vreinterpretq_m128_f32(res); +} + +/* Compare operations */ + +// Compares for less than +// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100) +FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmplt_ps(a, b)); +} + +// Compares for greater than. +// +// r0 := (a0 > b0) ? 0xffffffff : 0x0 +// r1 := (a1 > b1) ? 0xffffffff : 0x0 +// r2 := (a2 > b2) ? 0xffffffff : 0x0 +// r3 := (a3 > b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpgt_ps(a, b)); +} + +// Compares for greater than or equal. +// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100) +FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpge_ps(a, b)); +} + +// Compares for less than or equal. +// +// r0 := (a0 <= b0) ? 0xffffffff : 0x0 +// r1 := (a1 <= b1) ? 0xffffffff : 0x0 +// r2 := (a2 <= b2) ? 0xffffffff : 0x0 +// r3 := (a3 <= b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100) +FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmple_ps(a, b)); +} + +// Compares for equality. +// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for equality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpeq_ps(a, b)); +} + +// Compares for inequality. +// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for inequality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100) +FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpneq_ps(a, b)); +} + +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b) +{ + return _mm_cmplt_ps(a, b); +} + +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b) +{ + return _mm_cmplt_ss(a, b); +} + +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b) +{ + return _mm_cmple_ps(a, b); +} + +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b) +{ + return _mm_cmple_ss(a, b); +} + +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) +{ + return _mm_cmpgt_ps(a, b); +} + +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b) +{ + return _mm_cmpgt_ss(a, b); +} + +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) +{ + return _mm_cmpge_ps(a, b); +} + +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b) +{ + return _mm_cmpge_ss(a, b); +} + +// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or +// unsigned 8-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for equality, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_pd +FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128d_u32(vandq_u32(cmp, swapped)); +#endif +} + +// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or +// unsigned 16-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compare packed 32-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compare packed 64-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); +#else + // ARMv7 lacks vceqq_u64 + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); +#endif +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for lesser than. +// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xff : 0x0 +// r1 := (a1 > b1) ? 0xff : 0x0 +// ... +// r15 := (a15 > b15) ? 0xff : 0x0 +// +// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for less than. +// +// r0 := (a0 < b0) ? 0xffff : 0x0 +// r1 := (a1 < b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 < b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xffff : 0x0 +// r1 := (a1 > b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 > b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for less than. +// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for greater than. +// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers +// in b for greater than. +FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +#else + // ARMv7 lacks vcgtq_s64. + // This is based off of Clang's SSE2 polyfill: + // (a > b) -> ((a_hi > b_hi) || (a_lo > b_lo && a_hi == b_hi)) + + // Mask the sign bit out since we need a signed AND an unsigned comparison + // and it is ugly to try and split them. + int32x4_t mask = vreinterpretq_s32_s64(vdupq_n_s64(0x80000000ull)); + int32x4_t a_mask = veorq_s32(vreinterpretq_s32_m128i(a), mask); + int32x4_t b_mask = veorq_s32(vreinterpretq_s32_m128i(b), mask); + // Check if a > b + int64x2_t greater = vreinterpretq_s64_u32(vcgtq_s32(a_mask, b_mask)); + // Copy upper mask to lower mask + // a_hi > b_hi + int64x2_t gt_hi = vshrq_n_s64(greater, 63); + // Copy lower mask to upper mask + // a_lo > b_lo + int64x2_t gt_lo = vsliq_n_s64(greater, greater, 32); + // Compare for equality + int64x2_t equal = vreinterpretq_s64_u32(vceqq_s32(a_mask, b_mask)); + // Copy upper mask to lower mask + // a_hi == b_hi + int64x2_t eq_hi = vshrq_n_s64(equal, 63); + // a_hi > b_hi || (a_lo > b_lo && a_hi == b_hi) + int64x2_t ret = vorrq_s64(gt_hi, vandq_s64(gt_lo, eq_hi)); + return vreinterpretq_m128i_s64(ret); +#endif +} + +// Compares the four 32-bit floats in a and b to check if any values are NaN. +// Ordered compare between each value returns true for "orderable" and false for +// "not orderable" (NaN). +// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see +// also: +// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean +// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics +FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) +{ + // Note: NEON does not have ordered compare builtin + // Need to compare a eq a and b eq b to check for NaN + // Do AND of results to get final + uint32x4_t ceqaa = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t ceqbb = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); +} + +// Compares for ordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100) +FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpord_ps(a, b)); +} + +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b) +{ + uint32x4_t f32a = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t f32b = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b))); +} + +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpunord_ps(a, b)); +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than operation. : +// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important +// note!! The documentation on MSDN is incorrect! If either of the values is a +// NAN the docs say you will get a one, but in fact, it will return a zero!! +FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) +{ + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_lt_b = + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_lt_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than operation. : +// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx +FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcgtq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_gt_b = + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_gt_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than or equal operation. : +// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx +FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcleq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_le_b = + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_le_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than or equal operation. : +// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx +FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcgeq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_ge_b = + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_ge_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an equality operation. : +// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx +FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_eq_b = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_eq_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an inequality operation. : +// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx +FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) +{ + // return !vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_or_b_nan = vmvnq_u32(vandq_u32(a_not_nan, b_not_nan)); + uint32x4_t a_neq_b = vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return (vgetq_lane_u32(vorrq_u32(a_or_b_nan, a_neq_b), 0) != 0) ? 1 : 0; +} + +// according to the documentation, these intrinsics behave the same as the +// non-'u' versions. We'll just alias them here. +#define _mm_ucomieq_ss _mm_comieq_ss +#define _mm_ucomige_ss _mm_comige_ss +#define _mm_ucomigt_ss _mm_comigt_ss +#define _mm_ucomile_ss _mm_comile_ss +#define _mm_ucomilt_ss _mm_comilt_ss +#define _mm_ucomineq_ss _mm_comineq_ss + +/* Conversions */ + +// Convert packed signed 32-bit integers in b to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, and copy the upper 2 packed elements from a to the upper elements of +// dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps +FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss +FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +} + +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss +#define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b) + +// Convert the signed 64-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int64_To_FP32(b[63:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss +FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si +FORCE_INLINE int _mm_cvt_ss2si(__m128 a) +{ +#if defined(__aarch64__) + return vgetq_lane_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)), 0); +#else + float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t diff = data - floor(data); + if (diff > 0.5) + return (int32_t) ceil(data); + if (unlikely(diff == 0.5)) { + int32_t f = (int32_t) floor(data); + int32_t c = (int32_t) ceil(data); + return c & 1 ? f : c; + } + return (int32_t) floor(data); +#endif +} + +// Convert packed 16-bit integers in a to packed single-precision (32-bit) +// floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps +FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a) +{ + return vreinterpretq_m128_f32( + vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a)))); +} + +// Convert packed 32-bit integers in b to packed single-precision (32-bit) +// floating-point elements, store the results in the lower 2 elements of dst, +// and copy the upper 2 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps +FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert packed signed 32-bit integers in a to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, then covert the packed signed 32-bit integers in b to +// single-precision (32-bit) floating-point element, and store the results in +// the upper 2 elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(a[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(a[63:32]) +// dst[95:64] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:96] := Convert_Int32_To_FP32(b[63:32]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps +FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)))); +} + +// Convert the lower packed 8-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps +FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a)))))); +} + +// Convert packed unsigned 16-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps +FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a) +{ + return vreinterpretq_m128_f32( + vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a)))); +} + +// Convert the lower packed unsigned 8-bit integers in a to packed +// single-precision (32-bit) floating-point elements, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps +FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_u32( + vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a)))))); +} + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values using truncate. +// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) +{ + return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64 +FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) +{ +#if defined(__aarch64__) + return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); +#else + double ret = *((double *) &a); + return (int64_t) ret; +#endif +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x +#define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a) + +// Converts the four signed 32-bit integer values of a to single-precision, +// floating-point values +// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_u16(u16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx +FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_u32(u32x4); +} + +// Converts the two unsigned 8-bit integers in the lower 16 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_s16(s16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_s32(s32x4); +} + +// Converts the two signed 8-bit integers in the lower 32 bits to four +// signed 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four signed 16-bit integers in the lower 64 bits to four signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32( + vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); +} + +// Converts the two signed 16-bit integers in the lower 32 bits two signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) +{ + int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four unsigned 16-bit integers in the lower 64 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) +{ + return vreinterpretq_m128i_u32( + vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); +} + +// Converts the two unsigned 16-bit integers in the lower 32 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) +{ + uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Converts the two unsigned 32-bit integers in the lower 64 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) +{ + return vreinterpretq_m128i_u64( + vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); +} + +// Converts the two signed 32-bit integers in the lower 64 bits to two signed +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); +} + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values. +// +// r0 := (int) a0 +// r1 := (int) a1 +// r2 := (int) a2 +// r3 := (int) a3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx +// *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A +// does not support! It is supported on ARMv8-A however. +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); +#else + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = + vcvtq_s32_f32(vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128i_s32(vbslq_s32(is_delta_half, r_even, r_normal)); +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 16-bit integers, and store the results in dst. Note: this intrinsic +// will generate 0x7FFF, rather than 0x8000, for input values between 0x7FFF and +// 0x7FFFFFFF. +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi16 +FORCE_INLINE __m64 _mm_cvtps_pi16(__m128 a) +{ + return vreinterpret_m64_s16( + vmovn_s32(vreinterpretq_s32_m128i(_mm_cvtps_epi32(a)))); +} + +// Copy the lower 32-bit integer in a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32 +FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) +{ + return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64 +FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) +{ + return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x +#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) + +// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +// r2 := 0x0 +// r3 := 0x0 +// +// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) +{ + return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); +} + +// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) +{ + return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); +} + +// Cast vector of type __m128 to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd +FORCE_INLINE __m128d _mm_castps_pd(__m128 a) +{ + return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a)); +} + +// Applies a type cast to reinterpret four 32-bit floating point values passed +// in as a 128-bit parameter as packed 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb514099.aspx +FORCE_INLINE __m128i _mm_castps_si128(__m128 a) +{ + return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); +} + +// Cast vector of type __m128i to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_pd +FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a)); +#else + return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a)); +#endif +} + +// Applies a type cast to reinterpret four 32-bit integers passed in as a +// 128-bit parameter as packed 32-bit floating point values. +// https://msdn.microsoft.com/en-us/library/bb514029.aspx +FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) +{ + return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); +} + +// Loads 128-bit value. : +// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx +FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd +FORCE_INLINE __m128d _mm_load1_pd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); +#endif +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 +#define _mm_load_pd1 _mm_load1_pd + +// Load a double-precision (64-bit) floating-point element from memory into the +// upper element of dst, and copy the lower element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := a[63:0] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd +FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); +#else + return vreinterpretq_m128d_f32(vcombine_f32( + vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p))); +#endif +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 +#define _mm_load_pd1 _mm_load1_pd + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd +#define _mm_loaddup_pd _mm_load1_pd + +// Loads 128-bit value. : +// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Load unaligned 32-bit integer from memory into the first element of dst. +// +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[MAX:32] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32 +FORCE_INLINE __m128i _mm_loadu_si32(const void *p) +{ + return vreinterpretq_m128i_s32( + vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0)); +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed single-precision (32-bit) floating-point elements, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k]) +// ENDFOR +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps +FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) +{ +#if defined(__aarch64__) + float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); + return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); +#else + float a0 = (float) ((double *) &a)[0]; + float a1 = (float) ((double *) &a)[1]; + return _mm_set_ps(0, 0, a1, a0); +#endif +} + +// Copy the lower double-precision (64-bit) floating-point element of a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64 +FORCE_INLINE double _mm_cvtsd_f64(__m128d a) +{ +#if defined(__aarch64__) + return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); +#else + return ((double *) &a)[0]; +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed double-precision (64-bit) floating-point elements, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := 64*j +// k := 32*j +// dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd +FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); +#else + double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + return _mm_set_pd(a1, a0); +#endif +} + +// Cast vector of type __m128d to type __m128i. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128 +FORCE_INLINE __m128i _mm_castpd_si128(__m128d a) +{ + return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a)); +} + +// Cast vector of type __m128d to type __m128. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ps +FORCE_INLINE __m128 _mm_castpd_ps(__m128d a) +{ + return vreinterpretq_m128_s64(vreinterpretq_s64_m128d(a)); +} + +// Blend packed single-precision (32-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps +FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask) +{ + // Use a signed shift right to create a mask with the sign bit + uint32x4_t mask = + vreinterpretq_u32_s32(vshrq_n_s32(vreinterpretq_s32_m128(_mask), 31)); + float32x4_t a = vreinterpretq_f32_m128(_a); + float32x4_t b = vreinterpretq_f32_m128(_b); + return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); +} + +// Blend packed single-precision (32-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_ps +FORCE_INLINE __m128 _mm_blend_ps(__m128 _a, __m128 _b, const char imm8) +{ + const uint32_t ALIGN_STRUCT(16) + data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, + ((imm8) & (1 << 1)) ? UINT32_MAX : 0, + ((imm8) & (1 << 2)) ? UINT32_MAX : 0, + ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; + uint32x4_t mask = vld1q_u32(data); + float32x4_t a = vreinterpretq_f32_m128(_a); + float32x4_t b = vreinterpretq_f32_m128(_b); + return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); +} + +// Blend packed double-precision (64-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_pd +FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask) +{ + uint64x2_t mask = + vreinterpretq_u64_s64(vshrq_n_s64(vreinterpretq_s64_m128d(_mask), 63)); +#if defined(__aarch64__) + float64x2_t a = vreinterpretq_f64_m128d(_a); + float64x2_t b = vreinterpretq_f64_m128d(_b); + return vreinterpretq_m128d_f64(vbslq_f64(mask, b, a)); +#else + uint64x2_t a = vreinterpretq_u64_m128d(_a); + uint64x2_t b = vreinterpretq_u64_m128d(_b); + return vreinterpretq_m128d_u64(vbslq_u64(mask, b, a)); +#endif +} + +typedef struct { + uint16_t res0; + uint8_t res1 : 6; + uint8_t bit22 : 1; + uint8_t bit23 : 1; + uint8_t res2; +#if defined(__aarch64__) + uint32_t res3; +#endif +} fpcr_bitfield; + +// Macro: Set the rounding mode bits of the MXCSR control and status register to +// the value in unsigned 32-bit integer a. The rounding mode may contain any of +// the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP, +// _MM_ROUND_TOWARD_ZERO +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_ROUNDING_MODE +FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) +{ + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + switch (rounding) { + case _MM_ROUND_TOWARD_ZERO: + r.field.bit22 = 1; + r.field.bit23 = 1; + break; + case _MM_ROUND_DOWN: + r.field.bit22 = 0; + r.field.bit23 = 1; + break; + case _MM_ROUND_UP: + r.field.bit22 = 1; + r.field.bit23 = 0; + break; + default: //_MM_ROUND_NEAREST + r.field.bit22 = 0; + r.field.bit23 = 0; + } + +#if defined(__aarch64__) + asm volatile("msr FPCR, %0" ::"r"(r)); /* write */ +#else + asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */ +#endif +} + +FORCE_INLINE void _mm_setcsr(unsigned int a) +{ + _MM_SET_ROUNDING_MODE(a); +} + +// Round the packed single-precision (32-bit) floating-point elements in a using +// the rounding parameter, and store the results as packed single-precision +// floating-point elements in dst. +// software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps +FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) +{ +#if defined(__aarch64__) + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a))); + default: //_MM_FROUND_CUR_DIRECTION + return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a))); + } +#else + float *v_float = (float *) &a; + __m128 zero, neg_inf, pos_inf; + + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return _mm_cvtepi32_ps(_mm_cvtps_epi32(a)); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return (__m128){floorf(v_float[0]), floorf(v_float[1]), + floorf(v_float[2]), floorf(v_float[3])}; + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return (__m128){ceilf(v_float[0]), ceilf(v_float[1]), ceilf(v_float[2]), + ceilf(v_float[3])}; + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + zero = _mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f); + neg_inf = _mm_set_ps(floorf(v_float[0]), floorf(v_float[1]), + floorf(v_float[2]), floorf(v_float[3])); + pos_inf = _mm_set_ps(ceilf(v_float[0]), ceilf(v_float[1]), + ceilf(v_float[2]), ceilf(v_float[3])); + return _mm_blendv_ps(pos_inf, neg_inf, _mm_cmple_ps(a, zero)); + default: //_MM_FROUND_CUR_DIRECTION + return (__m128){roundf(v_float[0]), roundf(v_float[1]), + roundf(v_float[2]), roundf(v_float[3])}; + } +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi +FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpret_m64_s32( + vget_low_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)))); +#else + return vreinterpret_m64_s32( + vcvt_s32_f32(vget_low_f32(vreinterpretq_f32_m128( + _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC))))); +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi32 +#define _mm_cvtps_pi32(a) _mm_cvt_ps2pi(a) + +// Round the packed single-precision (32-bit) floating-point elements in a up to +// an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps +FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) +{ + return _mm_round_ps(a, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); +} + +// Round the lower single-precision (32-bit) floating-point element in b up to +// an integer value, store the result as a single-precision floating-point +// element in the lower element of dst, and copy the upper 3 packed elements +// from a to the upper elements of dst. +// +// dst[31:0] := CEIL(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ss +FORCE_INLINE __m128 _mm_ceil_ss(__m128 a, __m128 b) +{ + return _mm_move_ss( + a, _mm_round_ps(b, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC)); +} + +// Round the packed single-precision (32-bit) floating-point elements in a down +// to an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ps +FORCE_INLINE __m128 _mm_floor_ps(__m128 a) +{ + return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +} + +// Round the lower single-precision (32-bit) floating-point element in b down to +// an integer value, store the result as a single-precision floating-point +// element in the lower element of dst, and copy the upper 3 packed elements +// from a to the upper elements of dst. +// +// dst[31:0] := FLOOR(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ss +FORCE_INLINE __m128 _mm_floor_ss(__m128 a, __m128 b) +{ + return _mm_move_ss( + a, _mm_round_ps(b, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC)); +} + +// Load 128-bits of integer data from unaligned memory into dst. This intrinsic +// may perform better than _mm_loadu_si128 when the data crosses a cache line +// boundary. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128 +#define _mm_lddqu_si128 _mm_loadu_si128 + +/* Miscellaneous Operations */ + +// Shifts the 8 signed 16-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// ... +// r7 := a7 >> count +// +// https://msdn.microsoft.com/en-us/library/3c9997dk(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (unlikely(c > 15)) + return _mm_cmplt_epi16(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); +} + +// Shifts the 4 signed 32-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// r2 := a2 >> count +// r3 := a3 >> count +// +// https://msdn.microsoft.com/en-us/library/ce40009e(v%3dvs.100).aspx +FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (unlikely(c > 31)) + return _mm_cmplt_epi32(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); +} + +// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and +// saturates. +// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), + vqmovn_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// ... +// r7 := UnsignedSaturate(a7) +// r8 := UnsignedSaturate(b0) +// r9 := UnsignedSaturate(b1) +// ... +// r15 := UnsignedSaturate(b7) +// +// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) +{ + return vreinterpretq_m128i_u8( + vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), + vqmovun_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers +// and saturates. +// +// r0 := SignedSaturate(a0) +// r1 := SignedSaturate(a1) +// r2 := SignedSaturate(a2) +// r3 := SignedSaturate(a3) +// r4 := SignedSaturate(b0) +// r5 := SignedSaturate(b1) +// r6 := SignedSaturate(b2) +// r7 := SignedSaturate(b3) +// +// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), + vqmovn_s32(vreinterpretq_s32_m128i(b)))); +} + +// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// r2 := UnsignedSaturate(a2) +// r3 := UnsignedSaturate(a3) +// r4 := UnsignedSaturate(b0) +// r5 := UnsignedSaturate(b1) +// r6 := UnsignedSaturate(b2) +// r7 := UnsignedSaturate(b3) +FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)), + vqmovun_s32(vreinterpretq_s32_m128i(b)))); +} + +// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// ... +// r14 := a7 +// r15 := b7 +// +// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the +// lower 4 signed or unsigned 16-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// r4 := a2 +// r5 := b2 +// r6 := a3 +// r7 := b3 +// +// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the +// lower 2 signed or unsigned 32 - bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) +{ + int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); +} + +// Selects and interleaves the lower two single-precision, floating-point values +// from a and b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Unpack and interleave double-precision (64-bit) floating-point elements from +// the low half of a and b, and store the results in dst. +// +// DEFINE INTERLEAVE_QWORDS(src1[127:0], src2[127:0]) { +// dst[63:0] := src1[63:0] +// dst[127:64] := src2[63:0] +// RETURN dst[127:0] +// } +// dst[127:0] := INTERLEAVE_QWORDS(a[127:0], b[127:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpacklo_pd +FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + return vreinterpretq_m128d_s64( + vcombine_s64(vget_low_s64(vreinterpretq_s64_m128d(a)), + vget_low_s64(vreinterpretq_s64_m128d(b)))); +#endif +} + +// Unpack and interleave double-precision (64-bit) floating-point elements from +// the high half of a and b, and store the results in dst. +// +// DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) { +// dst[63:0] := src1[127:64] +// dst[127:64] := src2[127:64] +// RETURN dst[127:0] +// } +// dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpackhi_pd +FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + return vreinterpretq_m128d_s64( + vcombine_s64(vget_high_s64(vreinterpretq_s64_m128d(a)), + vget_high_s64(vreinterpretq_s64_m128d(b)))); +#endif +} + +// Selects and interleaves the upper two single-precision, floating-point values +// from a and b. +// +// r0 := a2 +// r1 := b2 +// r2 := a3 +// r3 := b3 +// +// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a8 +// r1 := b8 +// r2 := a9 +// r3 := b9 +// ... +// r14 := a15 +// r15 := b15 +// +// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the +// upper 4 signed or unsigned 16-bit integers in b. +// +// r0 := a4 +// r1 := b4 +// r2 := a5 +// r3 := b5 +// r4 := a6 +// r5 := b6 +// r6 := a7 +// r7 := b7 +// +// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the +// upper 2 signed or unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper signed or unsigned 64-bit integer in a with the +// upper signed or unsigned 64-bit integer in b. +// +// r0 := a1 +// r1 := b1 +FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) +{ + int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); +} + +// Horizontally compute the minimum amongst the packed unsigned 16-bit integers +// in a, store the minimum and index in dst, and zero the remaining bits in dst. +// +// index[2:0] := 0 +// min[15:0] := a[15:0] +// FOR j := 0 to 7 +// i := j*16 +// IF a[i+15:i] < min[15:0] +// index[2:0] := j +// min[15:0] := a[i+15:i] +// FI +// ENDFOR +// dst[15:0] := min[15:0] +// dst[18:16] := index[2:0] +// dst[127:19] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_minpos_epu16 +FORCE_INLINE __m128i _mm_minpos_epu16(__m128i a) +{ + __m128i dst; + uint16_t min, idx = 0; + // Find the minimum value +#if defined(__aarch64__) + min = vminvq_u16(vreinterpretq_u16_m128i(a)); +#else + __m64 tmp; + tmp = vreinterpret_m64_u16( + vmin_u16(vget_low_u16(vreinterpretq_u16_m128i(a)), + vget_high_u16(vreinterpretq_u16_m128i(a)))); + tmp = vreinterpret_m64_u16( + vpmin_u16(vreinterpret_u16_m64(tmp), vreinterpret_u16_m64(tmp))); + tmp = vreinterpret_m64_u16( + vpmin_u16(vreinterpret_u16_m64(tmp), vreinterpret_u16_m64(tmp))); + min = vget_lane_u16(vreinterpret_u16_m64(tmp), 0); +#endif + // Get the index of the minimum value + int i; + for (i = 0; i < 8; i++) { + if (min == vgetq_lane_u16(vreinterpretq_u16_m128i(a), 0)) { + idx = (uint16_t) i; + break; + } + a = _mm_srli_si128(a, 2); + } + // Generate result + dst = _mm_setzero_si128(); + dst = vreinterpretq_m128i_u16( + vsetq_lane_u16(min, vreinterpretq_u16_m128i(dst), 0)); + dst = vreinterpretq_m128i_u16( + vsetq_lane_u16(idx, vreinterpretq_u16_m128i(dst), 1)); + return dst; +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and b, +// and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the +// bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, +// otherwise set CF to 0. Return the CF value. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testc_si128 +FORCE_INLINE int _mm_testc_si128(__m128i a, __m128i b) +{ + int64x2_t s64 = + vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(vreinterpretq_s32_m128i(a))), + vreinterpretq_s64_m128i(b)); + return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and b, +// and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the +// bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, +// otherwise set CF to 0. Return the ZF value. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testz_si128 +FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b) +{ + int64x2_t s64 = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b)); + return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); +} + +// Extracts the selected signed or unsigned 8-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) +#define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) + +// Inserts the least significant 8 bits of b into the selected 8-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, +// __constrange(0,16) int imm) +#define _mm_insert_epi8(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s8( \ + vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 16-bit integer from a and zero +// extends. +// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx +// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) +#define _mm_extract_epi16(a, imm) \ + vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) + +// Inserts the least significant 16 bits of b into the selected 16-bit integer +// of a. +// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx +// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, +// __constrange(0,8) int imm) +#define _mm_insert_epi16(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s16( \ + vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ + }) + +// Copy a to dst, and insert the 16-bit integer i into dst at the location +// specified by imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_insert_pi16 +#define _mm_insert_pi16(a, b, imm) \ + __extension__({ \ + vreinterpret_m64_s16( \ + vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 32-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) +#define _mm_extract_epi32(a, imm) \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) + +// Extracts the selected single-precision (32-bit) floating-point from a. +// FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm) +#define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm)) + +// Inserts the least significant 32 bits of b into the selected 32-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, +// __constrange(0,4) int imm) +#define _mm_insert_epi32(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 64-bit integer from a and zero +// extends. +// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) +#define _mm_extract_epi64(a, imm) \ + vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) + +// Inserts the least significant 64 bits of b into the selected 64-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, +// __constrange(0,2) int imm) +#define _mm_insert_epi64(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s64( \ + vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ + }) + +// Count the number of bits set to 1 in unsigned 32-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 +FORCE_INLINE int _mm_popcnt_u32(unsigned int a) +{ +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(a); +#else + return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); +#endif +#else + uint32_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + + vst1_u32(&count, count32x2_val); + return count; +#endif +} + +// Count the number of bits set to 1 in unsigned 64-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 +FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) +{ +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcountll) + return __builtin_popcountll(a); +#else + return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); +#endif +#else + uint64_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + uint64x1_t count64x1_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + count64x1_val = vpaddl_u32(count32x2_val); + vst1_u64(&count, count64x1_val); + return count; +#endif +} + +// Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision +// (32-bit) floating-point elements in row0, row1, row2, and row3, and store the +// transposed matrix in these vectors (row0 now contains column 0, etc.). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ + do { \ + float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \ + float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \ + row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \ + vget_low_f32(ROW23.val[0])); \ + row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \ + vget_low_f32(ROW23.val[1])); \ + row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \ + vget_high_f32(ROW23.val[0])); \ + row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \ + vget_high_f32(ROW23.val[1])); \ + } while (0) + +/* Crypto Extensions */ + +#if defined(__ARM_FEATURE_CRYPTO) +// Wraps vmull_p64 +FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); + poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); + return vreinterpretq_u64_p128(vmull_p64(a, b)); +} +#else // ARMv7 polyfill +// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. +// +// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a +// 64-bit->128-bit polynomial multiply. +// +// It needs some work and is somewhat slow, but it is still faster than all +// known scalar methods. +// +// Algorithm adapted to C from +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted +// from "Fast Software Polynomial Multiplication on ARM Processors Using the +// NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab +// (https://hal.inria.fr/hal-01506572) +static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly8x8_t a = vreinterpret_p8_u64(_a); + poly8x8_t b = vreinterpret_p8_u64(_b); + + // Masks + uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), + vcreate_u8(0x00000000ffffffff)); + uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), + vcreate_u8(0x0000000000000000)); + + // Do the multiplies, rotating with vext to get all combinations + uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 + uint8x16_t e = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 + uint8x16_t f = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 + uint8x16_t g = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 + uint8x16_t h = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 + uint8x16_t i = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 + uint8x16_t j = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 + uint8x16_t k = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 + + // Add cross products + uint8x16_t l = veorq_u8(e, f); // L = E + F + uint8x16_t m = veorq_u8(g, h); // M = G + H + uint8x16_t n = veorq_u8(i, j); // N = I + J + + // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL + // instructions. +#if defined(__aarch64__) + uint8x16_t lm_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t lm_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t nk_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); + uint8x16_t nk_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); +#else + uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); + uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); + uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); + uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); +#endif + // t0 = (L) (P0 + P1) << 8 + // t1 = (M) (P2 + P3) << 16 + uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); + uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); + uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); + + // t2 = (N) (P4 + P5) << 24 + // t3 = (K) (P6 + P7) << 32 + uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); + uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); + uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); + + // De-interleave +#if defined(__aarch64__) + uint8x16_t t0 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t1 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t2 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); + uint8x16_t t3 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); +#else + uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); + uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); + uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); + uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); +#endif + // Shift the cross products + uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 + uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 + uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 + uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 + + // Accumulate the products + uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); + uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); + uint8x16_t mix = veorq_u8(d, cross1); + uint8x16_t r = veorq_u8(mix, cross2); + return vreinterpretq_u64_u8(r); +} +#endif // ARMv7 polyfill + +// Perform a carry-less multiplication of two 64-bit integers, selected from a +// and b according to imm8, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clmulepi64_si128 +FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) +{ + uint64x2_t a = vreinterpretq_u64_m128i(_a); + uint64x2_t b = vreinterpretq_u64_m128i(_b); + switch (imm & 0x11) { + case 0x00: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); + case 0x01: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); + case 0x10: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); + case 0x11: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); + default: + abort(); + } +} + +#if !defined(__ARM_FEATURE_CRYPTO) +/* clang-format off */ +#define SSE2NEON_AES_DATA(w) \ + { \ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), \ + w(0xc5), w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), \ + w(0xab), w(0x76), w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), \ + w(0x59), w(0x47), w(0xf0), w(0xad), w(0xd4), w(0xa2), w(0xaf), \ + w(0x9c), w(0xa4), w(0x72), w(0xc0), w(0xb7), w(0xfd), w(0x93), \ + w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc), w(0x34), w(0xa5), \ + w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15), w(0x04), \ + w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a), \ + w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), \ + w(0x75), w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), \ + w(0x5a), w(0xa0), w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), \ + w(0xe3), w(0x2f), w(0x84), w(0x53), w(0xd1), w(0x00), w(0xed), \ + w(0x20), w(0xfc), w(0xb1), w(0x5b), w(0x6a), w(0xcb), w(0xbe), \ + w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf), w(0xd0), w(0xef), \ + w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85), w(0x45), \ + w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8), \ + w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), \ + w(0xf5), w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), \ + w(0xf3), w(0xd2), w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), \ + w(0x97), w(0x44), w(0x17), w(0xc4), w(0xa7), w(0x7e), w(0x3d), \ + w(0x64), w(0x5d), w(0x19), w(0x73), w(0x60), w(0x81), w(0x4f), \ + w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88), w(0x46), w(0xee), \ + w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb), w(0xe0), \ + w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c), \ + w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), \ + w(0x79), w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), \ + w(0x4e), w(0xa9), w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), \ + w(0x7a), w(0xae), w(0x08), w(0xba), w(0x78), w(0x25), w(0x2e), \ + w(0x1c), w(0xa6), w(0xb4), w(0xc6), w(0xe8), w(0xdd), w(0x74), \ + w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a), w(0x70), w(0x3e), \ + w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e), w(0x61), \ + w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e), \ + w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), \ + w(0x94), w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), \ + w(0x28), w(0xdf), w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), \ + w(0xe6), w(0x42), w(0x68), w(0x41), w(0x99), w(0x2d), w(0x0f), \ + w(0xb0), w(0x54), w(0xbb), w(0x16) \ + } +/* clang-format on */ + +/* X Macro trick. See https://en.wikipedia.org/wiki/X_Macro */ +#define SSE2NEON_AES_H0(x) (x) +static const uint8_t SSE2NEON_sbox[256] = SSE2NEON_AES_DATA(SSE2NEON_AES_H0); +#undef SSE2NEON_AES_H0 + +// In the absence of crypto extensions, implement aesenc using regular neon +// intrinsics instead. See: +// https://www.workofard.com/2017/01/accelerated-aes-for-the-arm64-linux-kernel/ +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/ and +// https://github.com/ColinIanKing/linux-next-mirror/blob/b5f466091e130caaf0735976648f72bd5e09aa84/crypto/aegis128-neon-inner.c#L52 +// for more information Reproduced with permission of the author. +FORCE_INLINE __m128i _mm_aesenc_si128(__m128i EncBlock, __m128i RoundKey) +{ +#if defined(__aarch64__) + static const uint8_t shift_rows[] = {0x0, 0x5, 0xa, 0xf, 0x4, 0x9, + 0xe, 0x3, 0x8, 0xd, 0x2, 0x7, + 0xc, 0x1, 0x6, 0xb}; + static const uint8_t ror32by8[] = {0x1, 0x2, 0x3, 0x0, 0x5, 0x6, 0x7, 0x4, + 0x9, 0xa, 0xb, 0x8, 0xd, 0xe, 0xf, 0xc}; + + uint8x16_t v; + uint8x16_t w = vreinterpretq_u8_m128i(EncBlock); + + // shift rows + w = vqtbl1q_u8(w, vld1q_u8(shift_rows)); + + // sub bytes + v = vqtbl4q_u8(_sse2neon_vld1q_u8_x4(SSE2NEON_sbox), w); + v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0x40), w - 0x40); + v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0x80), w - 0x80); + v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0xc0), w - 0xc0); + + // mix columns + w = (v << 1) ^ (uint8x16_t)(((int8x16_t) v >> 7) & 0x1b); + w ^= (uint8x16_t) vrev32q_u16((uint16x8_t) v); + w ^= vqtbl1q_u8(v ^ w, vld1q_u8(ror32by8)); + + // add round key + return vreinterpretq_m128i_u8(w) ^ RoundKey; + +#else /* ARMv7-A NEON implementation */ +#define SSE2NEON_AES_B2W(b0, b1, b2, b3) \ + (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | \ + (b0)) +#define SSE2NEON_AES_F2(x) ((x << 1) ^ (((x >> 7) & 1) * 0x011b /* WPOLY */)) +#define SSE2NEON_AES_F3(x) (SSE2NEON_AES_F2(x) ^ x) +#define SSE2NEON_AES_U0(p) \ + SSE2NEON_AES_B2W(SSE2NEON_AES_F2(p), p, p, SSE2NEON_AES_F3(p)) +#define SSE2NEON_AES_U1(p) \ + SSE2NEON_AES_B2W(SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p), p, p) +#define SSE2NEON_AES_U2(p) \ + SSE2NEON_AES_B2W(p, SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p), p) +#define SSE2NEON_AES_U3(p) \ + SSE2NEON_AES_B2W(p, p, SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p)) + static const uint32_t ALIGN_STRUCT(16) aes_table[4][256] = { + SSE2NEON_AES_DATA(SSE2NEON_AES_U0), + SSE2NEON_AES_DATA(SSE2NEON_AES_U1), + SSE2NEON_AES_DATA(SSE2NEON_AES_U2), + SSE2NEON_AES_DATA(SSE2NEON_AES_U3), + }; +#undef SSE2NEON_AES_B2W +#undef SSE2NEON_AES_F2 +#undef SSE2NEON_AES_F3 +#undef SSE2NEON_AES_U0 +#undef SSE2NEON_AES_U1 +#undef SSE2NEON_AES_U2 +#undef SSE2NEON_AES_U3 + + uint32_t x0 = _mm_cvtsi128_si32(EncBlock); + uint32_t x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0x55)); + uint32_t x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0xAA)); + uint32_t x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0xFF)); + + __m128i out = _mm_set_epi32( + (aes_table[0][x3 & 0xff] ^ aes_table[1][(x0 >> 8) & 0xff] ^ + aes_table[2][(x1 >> 16) & 0xff] ^ aes_table[3][x2 >> 24]), + (aes_table[0][x2 & 0xff] ^ aes_table[1][(x3 >> 8) & 0xff] ^ + aes_table[2][(x0 >> 16) & 0xff] ^ aes_table[3][x1 >> 24]), + (aes_table[0][x1 & 0xff] ^ aes_table[1][(x2 >> 8) & 0xff] ^ + aes_table[2][(x3 >> 16) & 0xff] ^ aes_table[3][x0 >> 24]), + (aes_table[0][x0 & 0xff] ^ aes_table[1][(x1 >> 8) & 0xff] ^ + aes_table[2][(x2 >> 16) & 0xff] ^ aes_table[3][x3 >> 24])); + + return _mm_xor_si128(out, RoundKey); +#endif +} + +// Perform the last round of an AES encryption flow on data (state) in a using +// the round key in RoundKey, and store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenclast_si128 +FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) +{ + /* FIXME: optimized for NEON */ + uint8_t v[4][4] = { + [0] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]}, + [1] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]}, + [2] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]}, + [3] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]}, + }; + for (int i = 0; i < 16; i++) + vreinterpretq_nth_u8_m128i(a, i) = + v[i / 4][i % 4] ^ vreinterpretq_nth_u8_m128i(RoundKey, i); + return a; +} + +// Emits the Advanced Encryption Standard (AES) instruction aeskeygenassist. +// This instruction generates a round key for AES encryption. See +// https://kazakov.life/2017/11/01/cryptocurrency-mining-on-ios-devices/ +// for details. +// +// https://msdn.microsoft.com/en-us/library/cc714138(v=vs.120).aspx +FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i key, const int rcon) +{ + uint32_t X1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0x55)); + uint32_t X3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0xFF)); + for (int i = 0; i < 4; ++i) { + ((uint8_t *) &X1)[i] = SSE2NEON_sbox[((uint8_t *) &X1)[i]]; + ((uint8_t *) &X3)[i] = SSE2NEON_sbox[((uint8_t *) &X3)[i]]; + } + return _mm_set_epi32(((X3 >> 8) | (X3 << 24)) ^ rcon, X3, + ((X1 >> 8) | (X1 << 24)) ^ rcon, X1); +} +#undef SSE2NEON_AES_DATA + +#else /* __ARM_FEATURE_CRYPTO */ +// Implements equivalent of 'aesenc' by combining AESE (with an empty key) and +// AESMC and then manually applying the real key as an xor operation. This +// unfortunately means an additional xor op; the compiler should be able to +// optimize this away for repeated calls however. See +// https://blog.michaelbrase.com/2018/05/08/emulating-x86-aes-intrinsics-on-armv8-a +// for more details. +FORCE_INLINE __m128i _mm_aesenc_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0))) ^ + vreinterpretq_u8_m128i(b)); +} + +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenclast_si128 +FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) +{ + return _mm_xor_si128(vreinterpretq_m128i_u8(vaeseq_u8( + vreinterpretq_u8_m128i(a), vdupq_n_u8(0))), + RoundKey); +} + +FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) +{ + // AESE does ShiftRows and SubBytes on A + uint8x16_t u8 = vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0)); + + uint8x16_t dest = { + // Undo ShiftRows step from AESE and extract X1 and X3 + u8[0x4], u8[0x1], u8[0xE], u8[0xB], // SubBytes(X1) + u8[0x1], u8[0xE], u8[0xB], u8[0x4], // ROT(SubBytes(X1)) + u8[0xC], u8[0x9], u8[0x6], u8[0x3], // SubBytes(X3) + u8[0x9], u8[0x6], u8[0x3], u8[0xC], // ROT(SubBytes(X3)) + }; + uint32x4_t r = {0, (unsigned) rcon, 0, (unsigned) rcon}; + return vreinterpretq_m128i_u8(dest) ^ vreinterpretq_m128i_u32(r); +} +#endif + +/* Streaming Extensions */ + +// Guarantees that every preceding store is globally visible before any +// subsequent store. +// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx +FORCE_INLINE void _mm_sfence(void) +{ + __sync_synchronize(); +} + +// Store 128-bits (composed of 4 packed single-precision (32-bit) floating- +// point elements) from a into memory using a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps +FORCE_INLINE void _mm_stream_ps(float *p, __m128 a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, (float32x4_t *) p); +#else + vst1q_f32(p, vreinterpretq_f32_m128(a)); +#endif +} + +// Stores the data in a to the address p without polluting the caches. If the +// cache line containing address p is already in the cache, the cache will be +// updated. +// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx +FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, p); +#else + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); +#endif +} + +// Load 128-bits of integer data from memory into dst using a non-temporal +// memory hint. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128 +FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p) +{ +#if __has_builtin(__builtin_nontemporal_store) + return __builtin_nontemporal_load(p); +#else + return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p)); +#endif +} + +// Cache line containing p is flushed and invalidated from all caches in the +// coherency domain. : +// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx +FORCE_INLINE void _mm_clflush(void const *p) +{ + (void) p; + // no corollary for Neon? +} + +// Allocate aligned blocks of memory. +// https://software.intel.com/en-us/ +// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks +FORCE_INLINE void *_mm_malloc(size_t size, size_t align) +{ + void *ptr; + if (align == 1) + return malloc(size); + if (align == 2 || (sizeof(void *) == 8 && align == 4)) + align = sizeof(void *); + if (!posix_memalign(&ptr, align, size)) + return ptr; + return NULL; +} + +// Free aligned memory that was allocated with _mm_malloc. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free +FORCE_INLINE void _mm_free(void *addr) +{ + free(addr); +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 8-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc ^= v; + for (int bit = 0; bit < 8; bit++) { + if (crc & 1) + crc = (crc >> 1) ^ UINT32_C(0x82f63b78); + else + crc = (crc >> 1); + } +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 16-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u8(crc, v & 0xff); + crc = _mm_crc32_u8(crc, (v >> 8) & 0xff); +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 32-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u16(crc, v & 0xffff); + crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff); +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 64-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100) +FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u32((uint32_t)(crc), v & 0xffffffff); + crc = _mm_crc32_u32((uint32_t)(crc), (v >> 32) & 0xffffffff); +#endif + return crc; +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma pop_macro("ALIGN_STRUCT") +#pragma pop_macro("FORCE_INLINE") +#endif + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC pop_options +#endif + +#endif diff --git a/thirdparty/embree-aarch64/common/simd/avx.h b/thirdparty/embree/common/simd/avx.h index c840e41805..d3100306ee 100644 --- a/thirdparty/embree-aarch64/common/simd/avx.h +++ b/thirdparty/embree/common/simd/avx.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/simd/avx512.h b/thirdparty/embree/common/simd/avx512.h index 25414ab5b1..d43bbacea1 100644 --- a/thirdparty/embree-aarch64/common/simd/avx512.h +++ b/thirdparty/embree/common/simd/avx512.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/simd/simd.h b/thirdparty/embree/common/simd/simd.h index 647851110b..195506b530 100644 --- a/thirdparty/embree-aarch64/common/simd/simd.h +++ b/thirdparty/embree/common/simd/simd.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -6,7 +6,7 @@ #include "../math/math.h" /* include SSE wrapper classes */ -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined(__SSE__) # include "sse.h" #endif diff --git a/thirdparty/embree-aarch64/common/simd/sse.cpp b/thirdparty/embree/common/simd/sse.cpp index 1732cfa421..535d6943d8 100644 --- a/thirdparty/embree-aarch64/common/simd/sse.cpp +++ b/thirdparty/embree/common/simd/sse.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "sse.h" diff --git a/thirdparty/embree-aarch64/common/simd/sse.h b/thirdparty/embree/common/simd/sse.h index 6bc818b55b..1465fb4fb0 100644 --- a/thirdparty/embree-aarch64/common/simd/sse.h +++ b/thirdparty/embree/common/simd/sse.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,7 +11,7 @@ namespace embree { -#if (defined(__aarch64__) && defined(BUILD_IOS)) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) { return _mm_blendv_ps(f,t,mask); } diff --git a/thirdparty/embree-aarch64/common/simd/varying.h b/thirdparty/embree/common/simd/varying.h index 9a46817da9..9b98d326be 100644 --- a/thirdparty/embree-aarch64/common/simd/varying.h +++ b/thirdparty/embree/common/simd/varying.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -9,7 +9,7 @@ namespace embree { /* Varying numeric types */ template<int N> - struct vfloat + struct vfloat_impl { union { float f[N]; int i[N]; }; __forceinline const float& operator [](size_t index) const { assert(index < N); return f[index]; } @@ -17,7 +17,7 @@ namespace embree }; template<int N> - struct vdouble + struct vdouble_impl { union { double f[N]; long long i[N]; }; __forceinline const double& operator [](size_t index) const { assert(index < N); return f[index]; } @@ -25,7 +25,7 @@ namespace embree }; template<int N> - struct vint + struct vint_impl { int i[N]; __forceinline const int& operator [](size_t index) const { assert(index < N); return i[index]; } @@ -33,7 +33,7 @@ namespace embree }; template<int N> - struct vuint + struct vuint_impl { unsigned int i[N]; __forceinline const unsigned int& operator [](size_t index) const { assert(index < N); return i[index]; } @@ -41,7 +41,7 @@ namespace embree }; template<int N> - struct vllong + struct vllong_impl { long long i[N]; __forceinline const long long& operator [](size_t index) const { assert(index < N); return i[index]; } @@ -49,20 +49,13 @@ namespace embree }; /* Varying bool types */ - template<int N> struct vboolf { int i[N]; }; // for float/int - template<int N> struct vboold { long long i[N]; }; // for double/long long - - /* Aliases to default types */ - template<int N> using vreal = vfloat<N>; - template<int N> using vbool = vboolf<N>; - + template<int N> struct vboolf_impl { int i[N]; }; // for float/int + template<int N> struct vboold_impl { long long i[N]; }; // for double/long long + /* Varying size constants */ #if defined(__AVX512VL__) // SKX const int VSIZEX = 8; // default size const int VSIZEL = 16; // large size -#elif defined(__AVX512F__) // KNL - const int VSIZEX = 16; - const int VSIZEL = 16; #elif defined(__AVX__) const int VSIZEX = 8; const int VSIZEL = 8; @@ -71,21 +64,41 @@ namespace embree const int VSIZEL = 4; #endif - /* Extends varying size N to optimal or up to max(N, N2) */ - template<int N, int N2 = VSIZEX> - struct vextend - { -#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL - /* use 16-wide SIMD calculations on KNL even for 4 and 8 wide SIMD */ - static const int size = (N2 == VSIZEX) ? VSIZEX : N; - #define SIMD_MODE(N) N, 16 -#else - /* calculate with same SIMD width otherwise */ - static const int size = N; - #define SIMD_MODE(N) N, N -#endif + template<int N> + struct vtypes { + using vbool = vboolf_impl<N>; + using vboolf = vboolf_impl<N>; + using vboold = vboold_impl<N>; + using vint = vint_impl<N>; + using vuint = vuint_impl<N>; + using vllong = vllong_impl<N>; + using vfloat = vfloat_impl<N>; + using vdouble = vdouble_impl<N>; + }; + + template<> + struct vtypes<1> { + using vbool = bool; + using vboolf = bool; + using vboold = bool; + using vint = int; + using vuint = unsigned int; + using vllong = long long; + using vfloat = float; + using vdouble = double; }; + /* Aliases to default types */ + template<int N> using vbool = typename vtypes<N>::vbool; + template<int N> using vboolf = typename vtypes<N>::vboolf; + template<int N> using vboold = typename vtypes<N>::vboold; + template<int N> using vint = typename vtypes<N>::vint; + template<int N> using vuint = typename vtypes<N>::vuint; + template<int N> using vllong = typename vtypes<N>::vllong; + template<int N> using vreal = typename vtypes<N>::vfloat; + template<int N> using vfloat = typename vtypes<N>::vfloat; + template<int N> using vdouble = typename vtypes<N>::vdouble; + /* 4-wide shortcuts */ typedef vfloat<4> vfloat4; typedef vdouble<4> vdouble4; diff --git a/thirdparty/embree-aarch64/common/simd/vboold4_avx.h b/thirdparty/embree/common/simd/vboold4_avx.h index 6505ee56f3..7db0d1c5c1 100644 --- a/thirdparty/embree-aarch64/common/simd/vboold4_avx.h +++ b/thirdparty/embree/common/simd/vboold4_avx.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide AVX bool type for 64bit data types*/ @@ -49,19 +57,13 @@ namespace embree #endif } - __forceinline vboold(__m128d a, __m128d b) : vl(a), vh(b) {} - //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline vboold(FalseTy) : v(_mm256_setzero_pd()) {} -#if !defined(__aarch64__) __forceinline vboold(TrueTy) : v(_mm256_cmp_pd(_mm256_setzero_pd(), _mm256_setzero_pd(), _CMP_EQ_OQ)) {} -#else - __forceinline vboold(TrueTy) : v(_mm256_cmpeq_pd(_mm256_setzero_pd(), _mm256_setzero_pd())) {} -#endif - + //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -105,10 +107,9 @@ namespace embree /// Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// -#if !defined(__aarch64__) __forceinline vboold4 unpacklo(const vboold4& a, const vboold4& b) { return _mm256_unpacklo_pd(a, b); } __forceinline vboold4 unpackhi(const vboold4& a, const vboold4& b) { return _mm256_unpackhi_pd(a, b); } -#endif + #if defined(__AVX2__) template<int i0, int i1, int i2, int i3> @@ -158,3 +159,11 @@ namespace embree << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboold4_avx512.h b/thirdparty/embree/common/simd/vboold4_avx512.h index 4fe730d713..ceaad7bba5 100644 --- a/thirdparty/embree-aarch64/common/simd/vboold4_avx512.h +++ b/thirdparty/embree/common/simd/vboold4_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide AVX-512 bool type */ @@ -138,3 +146,11 @@ namespace embree return cout << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboold8_avx512.h b/thirdparty/embree/common/simd/vboold8_avx512.h index fdf3f00de5..66d2054872 100644 --- a/thirdparty/embree-aarch64/common/simd/vboold8_avx512.h +++ b/thirdparty/embree/common/simd/vboold8_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX-512 bool type */ @@ -32,25 +40,12 @@ namespace embree /* return int8 mask */ __forceinline __m128i mask8() const { -#if defined(__AVX512BW__) return _mm_movm_epi8(v); -#else - const __m512i f = _mm512_set1_epi64(0); - const __m512i t = _mm512_set1_epi64(-1); - const __m512i m = _mm512_mask_or_epi64(f,v,t,t); - return _mm512_cvtepi64_epi8(m); -#endif } /* return int64 mask */ __forceinline __m512i mask64() const { -#if defined(__AVX512DQ__) return _mm512_movm_epi64(v); -#else - const __m512i f = _mm512_set1_epi64(0); - const __m512i t = _mm512_set1_epi64(-1); - return _mm512_mask_or_epi64(f,v,t,t); -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -146,3 +141,11 @@ namespace embree return cout << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboolf16_avx512.h b/thirdparty/embree/common/simd/vboolf16_avx512.h index 238cdc8eb9..19841dcea8 100644 --- a/thirdparty/embree-aarch64/common/simd/vboolf16_avx512.h +++ b/thirdparty/embree/common/simd/vboolf16_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 16-wide AVX-512 bool type */ @@ -33,25 +41,12 @@ namespace embree /* return int8 mask */ __forceinline __m128i mask8() const { -#if defined(__AVX512BW__) return _mm_movm_epi8(v); -#else - const __m512i f = _mm512_set1_epi32(0); - const __m512i t = _mm512_set1_epi32(-1); - const __m512i m = _mm512_mask_or_epi32(f,v,t,t); - return _mm512_cvtepi32_epi8(m); -#endif } /* return int32 mask */ __forceinline __m512i mask32() const { -#if defined(__AVX512DQ__) return _mm512_movm_epi32(v); -#else - const __m512i f = _mm512_set1_epi32(0); - const __m512i t = _mm512_set1_epi32(-1); - return _mm512_mask_or_epi32(f,v,t,t); -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -148,3 +143,11 @@ namespace embree return cout << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboolf4_avx512.h b/thirdparty/embree/common/simd/vboolf4_avx512.h index 2ae4c4470e..e65f66b025 100644 --- a/thirdparty/embree-aarch64/common/simd/vboolf4_avx512.h +++ b/thirdparty/embree/common/simd/vboolf4_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide AVX-512 bool type */ @@ -141,3 +149,11 @@ namespace embree return cout << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboolf4_sse2.h b/thirdparty/embree/common/simd/vboolf4_sse2.h index ed53b3c783..fa84b1b6ee 100644 --- a/thirdparty/embree-aarch64/common/simd/vboolf4_sse2.h +++ b/thirdparty/embree/common/simd/vboolf4_sse2.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide SSE bool type */ @@ -37,13 +45,9 @@ namespace embree : v(mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)]) {} __forceinline vboolf(bool a, bool b, bool c, bool d) : v(mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {} -#if defined(__aarch64__) && defined(BUILD_IOS) - __forceinline vboolf(int mask) { v = mm_lookupmask_ps[mask]; } - __forceinline vboolf(unsigned int mask) { v = mm_lookupmask_ps[mask]; } -#else __forceinline vboolf(int mask) { assert(mask >= 0 && mask < 16); v = mm_lookupmask_ps[mask]; } __forceinline vboolf(unsigned int mask) { assert(mask < 16); v = mm_lookupmask_ps[mask]; } -#endif + /* return int32 mask */ __forceinline __m128i mask32() const { return _mm_castps_si128(v); @@ -60,13 +64,8 @@ namespace embree /// Array Access //////////////////////////////////////////////////////////////////////////////// -#if defined(__aarch64__) && defined(BUILD_IOS) - __forceinline bool operator [](size_t index) const { return (_mm_movemask_ps(v) >> index) & 1; } - __forceinline int& operator [](size_t index) { return i[index]; } -#else __forceinline bool operator [](size_t index) const { assert(index < 4); return (_mm_movemask_ps(v) >> index) & 1; } __forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; } -#endif }; //////////////////////////////////////////////////////////////////////////////// @@ -101,7 +100,7 @@ namespace embree __forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); } __forceinline vboolf4 select(const vboolf4& m, const vboolf4& t, const vboolf4& f) { -#if (defined(__aarch64__) && defined(BUILD_IOS)) || defined(__SSE4_1__) +#if defined(__SSE4_1__) return _mm_blendv_ps(f, t, m); #else return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); @@ -115,17 +114,6 @@ namespace embree __forceinline vboolf4 unpacklo(const vboolf4& a, const vboolf4& b) { return _mm_unpacklo_ps(a, b); } __forceinline vboolf4 unpackhi(const vboolf4& a, const vboolf4& b) { return _mm_unpackhi_ps(a, b); } -#if defined(__aarch64__) - template<int i0, int i1, int i2, int i3> - __forceinline vboolf4 shuffle(const vboolf4& v) { - return vreinterpretq_f32_u8(vqtbl1q_u8( vreinterpretq_u8_s32(v), _MN_SHUFFLE(i0, i1, i2, i3))); - } - - template<int i0, int i1, int i2, int i3> - __forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) { - return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); - } -#else template<int i0, int i1, int i2, int i3> __forceinline vboolf4 shuffle(const vboolf4& v) { return _mm_castsi128_ps(_mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0))); @@ -135,8 +123,7 @@ namespace embree __forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } -#endif - + template<int i0> __forceinline vboolf4 shuffle(const vboolf4& v) { return shuffle<i0,i0,i0,i0>(v); @@ -148,7 +135,7 @@ namespace embree template<> __forceinline vboolf4 shuffle<0, 1, 0, 1>(const vboolf4& v) { return _mm_castpd_ps(_mm_movedup_pd(v)); } #endif -#if defined(__SSE4_1__) && !defined(__aarch64__) +#if defined(__SSE4_1__) template<int dst, int src, int clr> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); } template<int dst, int src> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return insert<dst, src, 0>(a, b); } template<int dst> __forceinline vboolf4 insert(const vboolf4& a, const bool b) { return insert<dst, 0>(a, vboolf4(b)); } @@ -170,15 +157,11 @@ namespace embree __forceinline bool none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); } __forceinline size_t movemask(const vboolf4& a) { return _mm_movemask_ps(a); } -#if defined(__aarch64__) && defined(BUILD_IOS) -__forceinline size_t popcnt(const vboolf4& a) { return _mm_movemask_popcnt_ps(a); } -#else #if defined(__SSE4_2__) __forceinline size_t popcnt(const vboolf4& a) { return popcnt((size_t)_mm_movemask_ps(a)); } #else __forceinline size_t popcnt(const vboolf4& a) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); } #endif -#endif //////////////////////////////////////////////////////////////////////////////// /// Get/Set Functions @@ -196,3 +179,11 @@ __forceinline size_t popcnt(const vboolf4& a) { return _mm_movemask_popcnt_ps(a) return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboolf8_avx.h b/thirdparty/embree/common/simd/vboolf8_avx.h index 4f64741b55..ba77cc3c5e 100644 --- a/thirdparty/embree-aarch64/common/simd/vboolf8_avx.h +++ b/thirdparty/embree/common/simd/vboolf8_avx.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX bool type */ @@ -68,11 +76,8 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf(FalseTy) : v(_mm256_setzero_ps()) {} -#if !defined(__aarch64__) __forceinline vboolf(TrueTy) : v(_mm256_cmp_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _CMP_EQ_OQ)) {} -#else - __forceinline vboolf(TrueTy) : v(_mm256_cmpeq_ps(_mm256_setzero_ps(), _mm256_setzero_ps())) {} -#endif + //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -187,3 +192,11 @@ namespace embree << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vboolf8_avx512.h b/thirdparty/embree/common/simd/vboolf8_avx512.h index 2a52b554c7..73ff5666e1 100644 --- a/thirdparty/embree-aarch64/common/simd/vboolf8_avx512.h +++ b/thirdparty/embree/common/simd/vboolf8_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX-512 bool type */ @@ -141,3 +149,11 @@ namespace embree return cout << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vdouble4_avx.h b/thirdparty/embree/common/simd/vdouble4_avx.h index 1f65b45d7e..55326de7dd 100644 --- a/thirdparty/embree-aarch64/common/simd/vdouble4_avx.h +++ b/thirdparty/embree/common/simd/vdouble4_avx.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide AVX 64-bit double type */ @@ -181,20 +189,13 @@ namespace embree __forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a, b, _MM_CMPINT_GE); } __forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a, b, _MM_CMPINT_GT); } __forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a, b, _MM_CMPINT_LE); } -#elif !defined(__aarch64__) +#else __forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_EQ_OQ); } __forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_NEQ_UQ); } __forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_LT_OS); } __forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_NLT_US); } __forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_NLE_US); } __forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a, b, _CMP_LE_OS); } -#else - __forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmpeq_pd(a, b); } - __forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmpneq_pd(a, b); } - __forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmplt_pd(a, b); } - __forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmpnlt_pd(a, b); } - __forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmpnle_pd(a, b); } - __forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmple_pd(a, b); } #endif __forceinline vboold4 operator ==(const vdouble4& a, double b) { return a == vdouble4(b); } @@ -246,18 +247,6 @@ namespace embree #endif } - __forceinline void xchg(const vboold4& m, vdouble4& a, vdouble4& b) { - const vdouble4 c = a; a = select(m,b,a); b = select(m,c,b); - } - - __forceinline vboold4 test(const vdouble4& a, const vdouble4& b) { -#if defined(__AVX512VL__) - return _mm256_test_epi64_mask(_mm256_castpd_si256(a),_mm256_castpd_si256(b)); -#else - return _mm256_testz_si256(_mm256_castpd_si256(a),_mm256_castpd_si256(b)); -#endif - } - //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -322,3 +311,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vdouble8_avx512.h b/thirdparty/embree/common/simd/vdouble8_avx512.h index 4eec7d2f6a..98d21bfe4a 100644 --- a/thirdparty/embree-aarch64/common/simd/vdouble8_avx512.h +++ b/thirdparty/embree/common/simd/vdouble8_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX-512 64-bit double type */ @@ -91,15 +99,6 @@ namespace embree _mm512_mask_store_pd(addr, mask, v2); } - /* pass by value to avoid compiler generating inefficient code */ - static __forceinline void storeu_compact(const vboold8 mask,void * addr, const vdouble8& reg) { - _mm512_mask_compressstoreu_pd(addr, mask, reg); - } - - static __forceinline vdouble8 compact64bit(const vboold8& mask, vdouble8& v) { - return _mm512_mask_compress_pd(v, mask, v); - } - static __forceinline vdouble8 compact(const vboold8& mask, vdouble8& v) { return _mm512_mask_compress_pd(v, mask, v); } @@ -260,18 +259,6 @@ namespace embree return _mm512_mask_or_pd(f,m,t,t); } - __forceinline void xchg(const vboold8& m, vdouble8& a, vdouble8& b) { - const vdouble8 c = a; a = select(m,b,a); b = select(m,c,b); - } - - __forceinline vboold8 test(const vboold8& m, const vdouble8& a, const vdouble8& b) { - return _mm512_mask_test_epi64_mask(m,_mm512_castpd_si512(a),_mm512_castpd_si512(b)); - } - - __forceinline vboold8 test(const vdouble8& a, const vdouble8& b) { - return _mm512_test_epi64_mask(_mm512_castpd_si512(a),_mm512_castpd_si512(b)); - } - //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -354,3 +341,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vfloat16_avx512.h b/thirdparty/embree/common/simd/vfloat16_avx512.h index aed2419b77..9f1e2459c4 100644 --- a/thirdparty/embree-aarch64/common/simd/vfloat16_avx512.h +++ b/thirdparty/embree/common/simd/vfloat16_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 16-wide AVX-512 float type */ @@ -73,11 +81,11 @@ namespace embree } /* WARNING: due to f64x4 the mask is considered as an 8bit mask */ - __forceinline vfloat(const vboolf16& mask, const vfloat8& a, const vfloat8& b) { + /*__forceinline vfloat(const vboolf16& mask, const vfloat8& a, const vfloat8& b) { __m512d aa = _mm512_broadcast_f64x4(_mm256_castps_pd(a)); aa = _mm512_mask_broadcast_f64x4(aa,mask,_mm256_castps_pd(b)); v = _mm512_castpd_ps(aa); - } + }*/ __forceinline explicit vfloat(const vint16& a) { v = _mm512_cvtepi32_ps(a); @@ -123,30 +131,6 @@ namespace embree return _mm512_set1_ps(*f); } - static __forceinline vfloat16 compact(const vboolf16& mask, vfloat16 &v) { - return _mm512_mask_compress_ps(v, mask, v); - } - static __forceinline vfloat16 compact(const vboolf16& mask, vfloat16 &a, const vfloat16& b) { - return _mm512_mask_compress_ps(a, mask, b); - } - - static __forceinline vfloat16 expand(const vboolf16& mask, const vfloat16& a, vfloat16& b) { - return _mm512_mask_expand_ps(b, mask, a); - } - - static __forceinline vfloat16 loadu_compact(const vboolf16& mask, const void* ptr) { - return _mm512_mask_expandloadu_ps(_mm512_setzero_ps(), mask, (float*)ptr); - } - - static __forceinline void storeu_compact(const vboolf16& mask, float *addr, const vfloat16 reg) { - _mm512_mask_compressstoreu_ps(addr, mask, reg); - } - - static __forceinline void storeu_compact_single(const vboolf16& mask, float * addr, const vfloat16& reg) { - //_mm512_mask_compressstoreu_ps(addr,mask,reg); - *addr = mm512_cvtss_f32(_mm512_mask_compress_ps(reg, mask, reg)); - } - template<int scale = 4> static __forceinline vfloat16 gather(const float* ptr, const vint16& index) { return _mm512_i32gather_ps(index, ptr, scale); @@ -194,12 +178,8 @@ namespace embree __forceinline vfloat16 signmsk(const vfloat16& a) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x80000000))); } __forceinline vfloat16 rcp(const vfloat16& a) { -#if defined(__AVX512ER__) - return _mm512_rcp28_ps(a); -#else const vfloat16 r = _mm512_rcp14_ps(a); return _mm512_mul_ps(r, _mm512_fnmadd_ps(r, a, vfloat16(2.0f))); -#endif } __forceinline vfloat16 sqr (const vfloat16& a) { return _mm512_mul_ps(a,a); } @@ -207,13 +187,9 @@ namespace embree __forceinline vfloat16 rsqrt(const vfloat16& a) { -#if defined(__AVX512VL__) const vfloat16 r = _mm512_rsqrt14_ps(a); return _mm512_fmadd_ps(_mm512_set1_ps(1.5f), r, _mm512_mul_ps(_mm512_mul_ps(_mm512_mul_ps(a, _mm512_set1_ps(-0.5f)), r), _mm512_mul_ps(r, r))); -#else - return _mm512_rsqrt28_ps(a); -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -242,54 +218,26 @@ namespace embree return _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(a),_mm512_castps_si512(b))); } - __forceinline vfloat16 min(const vfloat16& a, const vfloat16& b) { - return _mm512_min_ps(a,b); - } - __forceinline vfloat16 min(const vfloat16& a, float b) { - return _mm512_min_ps(a,vfloat16(b)); - } - __forceinline vfloat16 min(const float& a, const vfloat16& b) { - return _mm512_min_ps(vfloat16(a),b); - } - - __forceinline vfloat16 max(const vfloat16& a, const vfloat16& b) { - return _mm512_max_ps(a,b); - } - __forceinline vfloat16 max(const vfloat16& a, float b) { - return _mm512_max_ps(a,vfloat16(b)); - } - __forceinline vfloat16 max(const float& a, const vfloat16& b) { - return _mm512_max_ps(vfloat16(a),b); - } + __forceinline vfloat16 min(const vfloat16& a, const vfloat16& b) { return _mm512_min_ps(a,b); } + __forceinline vfloat16 min(const vfloat16& a, float b) { return _mm512_min_ps(a,vfloat16(b)); } + __forceinline vfloat16 min(const float& a, const vfloat16& b) { return _mm512_min_ps(vfloat16(a),b); } - __forceinline vfloat16 mask_add(const vboolf16& mask, const vfloat16& c, const vfloat16& a, const vfloat16& b) { return _mm512_mask_add_ps (c,mask,a,b); } - __forceinline vfloat16 mask_min(const vboolf16& mask, const vfloat16& c, const vfloat16& a, const vfloat16& b) { - return _mm512_mask_min_ps(c,mask,a,b); - }; - __forceinline vfloat16 mask_max(const vboolf16& mask, const vfloat16& c, const vfloat16& a, const vfloat16& b) { - return _mm512_mask_max_ps(c,mask,a,b); - }; + __forceinline vfloat16 max(const vfloat16& a, const vfloat16& b) { return _mm512_max_ps(a,b); } + __forceinline vfloat16 max(const vfloat16& a, float b) { return _mm512_max_ps(a,vfloat16(b)); } + __forceinline vfloat16 max(const float& a, const vfloat16& b) { return _mm512_max_ps(vfloat16(a),b); } __forceinline vfloat16 mini(const vfloat16& a, const vfloat16& b) { -#if !defined(__AVX512ER__) // SKX const vint16 ai = _mm512_castps_si512(a); const vint16 bi = _mm512_castps_si512(b); const vint16 ci = _mm512_min_epi32(ai,bi); return _mm512_castsi512_ps(ci); -#else // KNL - return min(a,b); -#endif } __forceinline vfloat16 maxi(const vfloat16& a, const vfloat16& b) { -#if !defined(__AVX512ER__) // SKX const vint16 ai = _mm512_castps_si512(a); const vint16 bi = _mm512_castps_si512(b); const vint16 ci = _mm512_max_epi32(ai,bi); return _mm512_castsi512_ps(ci); -#else // KNL - return max(a,b); -#endif } //////////////////////////////////////////////////////////////////////////////// @@ -300,43 +248,6 @@ namespace embree __forceinline vfloat16 msub (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmsub_ps(a,b,c); } __forceinline vfloat16 nmadd(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmadd_ps(a,b,c); } __forceinline vfloat16 nmsub(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmsub_ps(a,b,c); } - - __forceinline vfloat16 mask_msub(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_ps(a,mask,b,c); } - - __forceinline vfloat16 madd231 (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_ps(c,b,a); } - __forceinline vfloat16 msub213 (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmsub_ps(a,b,c); } - __forceinline vfloat16 msub231 (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmsub_ps(c,b,a); } - __forceinline vfloat16 msubr231(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmadd_ps(c,b,a); } - - - //////////////////////////////////////////////////////////////////////////////// - /// Operators with rounding - //////////////////////////////////////////////////////////////////////////////// - - __forceinline vfloat16 madd_round_down(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_round_ps(a,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 madd_round_up (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_round_ps(a,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 mul_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_mul_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 mul_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_mul_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 add_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_add_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 add_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_add_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 sub_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_sub_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 sub_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_sub_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 div_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_div_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 div_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_div_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 mask_msub_round_down(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 mask_msub_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 mask_mul_round_down(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_mul_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 mask_mul_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_mul_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - - __forceinline vfloat16 mask_sub_round_down(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_sub_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); } - __forceinline vfloat16 mask_sub_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_sub_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); } - //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators @@ -404,13 +315,6 @@ namespace embree return madd(t,b-a,a); } - __forceinline void xchg(vboolf16 m, vfloat16& a, vfloat16& b) - { - vfloat16 c = a; - a = select(m,b,a); - b = select(m,c,b); - } - //////////////////////////////////////////////////////////////////////////////// /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// @@ -455,24 +359,6 @@ namespace embree return _mm512_shuffle_f32x4(v, v, _MM_SHUFFLE(i3, i2, i1, i0)); } - __forceinline vfloat16 interleave_even(const vfloat16& a, const vfloat16& b) { - return _mm512_castsi512_ps(_mm512_mask_shuffle_epi32(_mm512_castps_si512(a), mm512_int2mask(0xaaaa), _mm512_castps_si512(b), (_MM_PERM_ENUM)0xb1)); - } - - __forceinline vfloat16 interleave_odd(const vfloat16& a, const vfloat16& b) { - return _mm512_castsi512_ps(_mm512_mask_shuffle_epi32(_mm512_castps_si512(b), mm512_int2mask(0x5555), _mm512_castps_si512(a), (_MM_PERM_ENUM)0xb1)); - } - - __forceinline vfloat16 interleave2_even(const vfloat16& a, const vfloat16& b) { - /* mask should be 8-bit but is 16-bit to reuse for interleave_even */ - return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(a), mm512_int2mask(0xaaaa), _mm512_castps_si512(b), (_MM_PERM_ENUM)0xb1)); - } - - __forceinline vfloat16 interleave2_odd(const vfloat16& a, const vfloat16& b) { - /* mask should be 8-bit but is 16-bit to reuse for interleave_odd */ - return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(b), mm512_int2mask(0x5555), _mm512_castps_si512(a), (_MM_PERM_ENUM)0xb1)); - } - __forceinline vfloat16 interleave4_even(const vfloat16& a, const vfloat16& b) { return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(a), mm512_int2mask(0xcc), _mm512_castps_si512(b), (_MM_PERM_ENUM)0x4e)); } @@ -537,17 +423,6 @@ namespace embree __forceinline void transpose(const vfloat16& r0, const vfloat16& r1, const vfloat16& r2, const vfloat16& r3, vfloat16& c0, vfloat16& c1, vfloat16& c2, vfloat16& c3) { -#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL - vfloat16 a0a1_c0c1 = interleave_even(r0, r1); - vfloat16 a2a3_c2c3 = interleave_even(r2, r3); - vfloat16 b0b1_d0d1 = interleave_odd (r0, r1); - vfloat16 b2b3_d2d3 = interleave_odd (r2, r3); - - c0 = interleave2_even(a0a1_c0c1, a2a3_c2c3); - c1 = interleave2_even(b0b1_d0d1, b2b3_d2d3); - c2 = interleave2_odd (a0a1_c0c1, a2a3_c2c3); - c3 = interleave2_odd (b0b1_d0d1, b2b3_d2d3); -#else vfloat16 a0a2_b0b2 = unpacklo(r0, r2); vfloat16 c0c2_d0d2 = unpackhi(r0, r2); vfloat16 a1a3_b1b3 = unpacklo(r1, r3); @@ -557,7 +432,6 @@ namespace embree c1 = unpackhi(a0a2_b0b2, a1a3_b1b3); c2 = unpacklo(c0c2_d0d2, c1c3_d1d3); c3 = unpackhi(c0c2_d0d2, c1c3_d1d3); -#endif } __forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, @@ -715,44 +589,6 @@ namespace embree return v; } - //////////////////////////////////////////////////////////////////////////////// - /// Memory load and store operations - //////////////////////////////////////////////////////////////////////////////// - - __forceinline vfloat16 loadAOS4to16f(const float& x, const float& y, const float& z) - { - vfloat16 f = zero; - f = select(0x1111,vfloat16::broadcast(&x),f); - f = select(0x2222,vfloat16::broadcast(&y),f); - f = select(0x4444,vfloat16::broadcast(&z),f); - return f; - } - - __forceinline vfloat16 loadAOS4to16f(unsigned int index, - const vfloat16& x, - const vfloat16& y, - const vfloat16& z) - { - vfloat16 f = zero; - f = select(0x1111,vfloat16::broadcast((float*)&x + index),f); - f = select(0x2222,vfloat16::broadcast((float*)&y + index),f); - f = select(0x4444,vfloat16::broadcast((float*)&z + index),f); - return f; - } - - __forceinline vfloat16 loadAOS4to16f(unsigned int index, - const vfloat16& x, - const vfloat16& y, - const vfloat16& z, - const vfloat16& fill) - { - vfloat16 f = fill; - f = select(0x1111,vfloat16::broadcast((float*)&x + index),f); - f = select(0x2222,vfloat16::broadcast((float*)&y + index),f); - f = select(0x4444,vfloat16::broadcast((float*)&z + index),f); - return f; - } - __forceinline vfloat16 rcp_safe(const vfloat16& a) { return rcp(select(a != vfloat16(zero), a, vfloat16(min_rcp_input))); } @@ -769,3 +605,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vfloat4_sse2.h b/thirdparty/embree/common/simd/vfloat4_sse2.h index 5732c0fbc8..5215bf9730 100644 --- a/thirdparty/embree-aarch64/common/simd/vfloat4_sse2.h +++ b/thirdparty/embree/common/simd/vfloat4_sse2.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide SSE float type */ @@ -10,18 +18,18 @@ namespace embree struct vfloat<4> { ALIGNED_STRUCT_(16); - + typedef vboolf4 Bool; typedef vint4 Int; typedef vfloat4 Float; - + enum { size = 4 }; // number of SIMD elements union { __m128 v; float f[4]; int i[4]; }; // data //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// - + __forceinline vfloat() {} __forceinline vfloat(const vfloat4& other) { v = other.v; } __forceinline vfloat4& operator =(const vfloat4& other) { v = other.v; return *this; } @@ -34,19 +42,14 @@ namespace embree __forceinline vfloat(float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {} __forceinline explicit vfloat(const vint4& a) : v(_mm_cvtepi32_ps(a)) {} -#if defined(__aarch64__) - __forceinline explicit vfloat(const vuint4& x) { - v = vcvtq_f32_u32(vreinterpretq_u32_s32(x.v)); - } -#else __forceinline explicit vfloat(const vuint4& x) { const __m128i a = _mm_and_si128(x,_mm_set1_epi32(0x7FFFFFFF)); - const __m128i b = _mm_and_si128(_mm_srai_epi32(x,31),_mm_set1_epi32(0x4F000000)); //0x4F000000 = 2^31 + const __m128i b = _mm_and_si128(_mm_srai_epi32(x,31),_mm_set1_epi32(0x4F000000)); //0x4F000000 = 2^31 const __m128 af = _mm_cvtepi32_ps(a); - const __m128 bf = _mm_castsi128_ps(b); + const __m128 bf = _mm_castsi128_ps(b); v = _mm_add_ps(af,bf); } -#endif + //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// @@ -71,13 +74,6 @@ namespace embree #if defined(__AVX512VL__) - static __forceinline vfloat4 compact(const vboolf4& mask, vfloat4 &v) { - return _mm_mask_compress_ps(v, mask, v); - } - static __forceinline vfloat4 compact(const vboolf4& mask, vfloat4 &a, const vfloat4& b) { - return _mm_mask_compress_ps(a, mask, b); - } - static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_ps (_mm_setzero_ps(),mask,(float*)ptr); } static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_ps(_mm_setzero_ps(),mask,(float*)ptr); } @@ -107,44 +103,32 @@ namespace embree #if defined (__SSE4_1__) return _mm_castsi128_ps(_mm_stream_load_si128((__m128i*)ptr)); #else - return _mm_load_ps(ptr); + return _mm_load_ps(ptr); #endif } -#if defined(__aarch64__) - static __forceinline vfloat4 load(const int8_t* ptr) { - return __m128(_mm_load4epi8_f32(((__m128i*)ptr))); - } -#elif defined(__SSE4_1__) - static __forceinline vfloat4 load(const int8_t* ptr) { +#if defined(__SSE4_1__) + static __forceinline vfloat4 load(const char* ptr) { return _mm_cvtepi32_ps(_mm_cvtepi8_epi32(_mm_loadu_si128((__m128i*)ptr))); } #else - static __forceinline vfloat4 load(const int8_t* ptr) { + static __forceinline vfloat4 load(const char* ptr) { return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif -#if defined(__aarch64__) - static __forceinline vfloat4 load(const uint8_t* ptr) { - return __m128(_mm_load4epu8_f32(((__m128i*)ptr))); - } -#elif defined(__SSE4_1__) - static __forceinline vfloat4 load(const uint8_t* ptr) { +#if defined(__SSE4_1__) + static __forceinline vfloat4 load(const unsigned char* ptr) { return _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr))); } #else - static __forceinline vfloat4 load(const uint8_t* ptr) { + static __forceinline vfloat4 load(const unsigned char* ptr) { //return _mm_cvtpu8_ps(*(__m64*)ptr); // don't enable, will use MMX instructions return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif -#if defined(__aarch64__) - static __forceinline vfloat4 load(const short* ptr) { - return __m128(_mm_load4epi16_f32(((__m128i*)ptr))); - } -#elif defined(__SSE4_1__) +#if defined(__SSE4_1__) static __forceinline vfloat4 load(const short* ptr) { return _mm_cvtepi32_ps(_mm_cvtepi16_epi32(_mm_loadu_si128((__m128i*)ptr))); } @@ -157,15 +141,11 @@ namespace embree static __forceinline vfloat4 load(const unsigned short* ptr) { return _mm_mul_ps(vfloat4(vint4::load(ptr)),vfloat4(1.0f/65535.0f)); } - + static __forceinline void store_nt(void* ptr, const vfloat4& v) { #if defined (__SSE4_1__) -#if defined(__aarch64__) - _mm_stream_ps((float*)ptr,vreinterpretq_s32_f32(v.v)); -#else _mm_stream_ps((float*)ptr,v); -#endif #else _mm_store_ps((float*)ptr,v); #endif @@ -173,14 +153,14 @@ namespace embree template<int scale = 4> static __forceinline vfloat4 gather(const float* ptr, const vint4& index) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _mm_i32gather_ps(ptr, index, scale); #else return vfloat4( - *(float*)(((int8_t*)ptr)+scale*index[0]), - *(float*)(((int8_t*)ptr)+scale*index[1]), - *(float*)(((int8_t*)ptr)+scale*index[2]), - *(float*)(((int8_t*)ptr)+scale*index[3])); + *(float*)(((char*)ptr)+scale*index[0]), + *(float*)(((char*)ptr)+scale*index[1]), + *(float*)(((char*)ptr)+scale*index[2]), + *(float*)(((char*)ptr)+scale*index[3])); #endif } @@ -189,13 +169,13 @@ namespace embree vfloat4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_ps(r, mask, index, ptr, scale); -#elif defined(__AVX2__) && !defined(__aarch64__) +#elif defined(__AVX2__) return _mm_mask_i32gather_ps(r, ptr, index, mask, scale); #else - if (likely(mask[0])) r[0] = *(float*)(((int8_t*)ptr)+scale*index[0]); - if (likely(mask[1])) r[1] = *(float*)(((int8_t*)ptr)+scale*index[1]); - if (likely(mask[2])) r[2] = *(float*)(((int8_t*)ptr)+scale*index[2]); - if (likely(mask[3])) r[3] = *(float*)(((int8_t*)ptr)+scale*index[3]); + if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]); + if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]); + if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]); + if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]); return r; #endif } @@ -206,10 +186,10 @@ namespace embree #if defined(__AVX512VL__) _mm_i32scatter_ps((float*)ptr, index, v, scale); #else - *(float*)(((int8_t*)ptr)+scale*index[0]) = v[0]; - *(float*)(((int8_t*)ptr)+scale*index[1]) = v[1]; - *(float*)(((int8_t*)ptr)+scale*index[2]) = v[2]; - *(float*)(((int8_t*)ptr)+scale*index[3]) = v[3]; + *(float*)(((char*)ptr)+scale*index[0]) = v[0]; + *(float*)(((char*)ptr)+scale*index[1]) = v[1]; + *(float*)(((char*)ptr)+scale*index[2]) = v[2]; + *(float*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } @@ -219,20 +199,20 @@ namespace embree #if defined(__AVX512VL__) _mm_mask_i32scatter_ps((float*)ptr ,mask, index, v, scale); #else - if (likely(mask[0])) *(float*)(((int8_t*)ptr)+scale*index[0]) = v[0]; - if (likely(mask[1])) *(float*)(((int8_t*)ptr)+scale*index[1]) = v[1]; - if (likely(mask[2])) *(float*)(((int8_t*)ptr)+scale*index[2]) = v[2]; - if (likely(mask[3])) *(float*)(((int8_t*)ptr)+scale*index[3]) = v[3]; + if (likely(mask[0])) *(float*)(((char*)ptr)+scale*index[0]) = v[0]; + if (likely(mask[1])) *(float*)(((char*)ptr)+scale*index[1]) = v[1]; + if (likely(mask[2])) *(float*)(((char*)ptr)+scale*index[2]) = v[2]; + if (likely(mask[3])) *(float*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } - static __forceinline void store(const vboolf4& mask, int8_t* ptr, const vint4& ofs, const vfloat4& v) { + static __forceinline void store(const vboolf4& mask, char* ptr, const vint4& ofs, const vfloat4& v) { scatter<1>(mask,ptr,ofs,v); } static __forceinline void store(const vboolf4& mask, float* ptr, const vint4& ofs, const vfloat4& v) { scatter<4>(mask,ptr,ofs,v); } - + //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -243,15 +223,27 @@ namespace embree friend __forceinline vfloat4 select(const vboolf4& m, const vfloat4& t, const vfloat4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_ps(m, f, t); -#elif defined(__SSE4_1__) || (defined(__aarch64__)) - return _mm_blendv_ps(f, t, m); +#elif defined(__SSE4_1__) + return _mm_blendv_ps(f, t, m); #else - return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); + return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); #endif } }; + //////////////////////////////////////////////////////////////////////////////// + /// Load/Store + //////////////////////////////////////////////////////////////////////////////// + template<> struct mem<vfloat4> + { + static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return vfloat4::load (mask,ptr); } + static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return vfloat4::loadu(mask,ptr); } + + static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { vfloat4::store (mask,ptr,v); } + static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { vfloat4::storeu(mask,ptr,v); } + }; + //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// @@ -264,47 +256,18 @@ namespace embree __forceinline vfloat4 toFloat(const vint4& a) { return vfloat4(a); } __forceinline vfloat4 operator +(const vfloat4& a) { return a; } -#if defined(__aarch64__) - __forceinline vfloat4 operator -(const vfloat4& a) { - return vnegq_f32(a); - } -#else __forceinline vfloat4 operator -(const vfloat4& a) { return _mm_xor_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); } -#endif -#if defined(__aarch64__) - __forceinline vfloat4 abs(const vfloat4& a) { return _mm_abs_ps(a); } -#else __forceinline vfloat4 abs(const vfloat4& a) { return _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); } -#endif - #if defined(__AVX512VL__) __forceinline vfloat4 sign(const vfloat4& a) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); } #else __forceinline vfloat4 sign(const vfloat4& a) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); } #endif - -#if defined(__aarch64__) - __forceinline vfloat4 signmsk(const vfloat4& a) { return _mm_and_ps(a, vreinterpretq_f32_u32(v0x80000000)); } -#else __forceinline vfloat4 signmsk(const vfloat4& a) { return _mm_and_ps(a,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); } -#endif - + __forceinline vfloat4 rcp(const vfloat4& a) { -#if defined(__aarch64__) -#if defined(BUILD_IOS) - return vfloat4(vdivq_f32(vdupq_n_f32(1.0f),a.v)); -#else //BUILD_IOS - __m128 reciprocal = _mm_rcp_ps(a); - reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); - reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); - // +1 round since NEON's reciprocal estimate instruction has less accuracy than SSE2's rcp. - reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); - return (const vfloat4)reciprocal; -#endif // BUILD_IOS -#else - #if defined(__AVX512VL__) const vfloat4 r = _mm_rcp14_ps(a); #else @@ -316,45 +279,31 @@ namespace embree #else return _mm_mul_ps(r,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r, a))); #endif - -#endif //defined(__aarch64__) } __forceinline vfloat4 sqr (const vfloat4& a) { return _mm_mul_ps(a,a); } __forceinline vfloat4 sqrt(const vfloat4& a) { return _mm_sqrt_ps(a); } __forceinline vfloat4 rsqrt(const vfloat4& a) { -#if defined(__aarch64__) - vfloat4 r = _mm_rsqrt_ps(a); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); - r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); - return r; -#else - #if defined(__AVX512VL__) - const vfloat4 r = _mm_rsqrt14_ps(a); + vfloat4 r = _mm_rsqrt14_ps(a); #else - const vfloat4 r = _mm_rsqrt_ps(a); + vfloat4 r = _mm_rsqrt_ps(a); #endif -#if defined(__AVX2__) - return _mm_fmadd_ps(_mm_set1_ps(1.5f), r, - _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); +#if defined(__ARM_NEON) + r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); + r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); +#elif defined(__AVX2__) + r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #else - return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f), r), - _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); -#endif - + r = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f), r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #endif + return r; } __forceinline vboolf4 isnan(const vfloat4& a) { -#if defined(__aarch64__) - const vfloat4 b = _mm_and_ps(a, vreinterpretq_f32_u32(v0x7fffffff)); -#else const vfloat4 b = _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); -#endif #if defined(__AVX512VL__) return _mm_cmp_epi32_mask(_mm_castps_si128(b), _mm_set1_epi32(0x7f800000), _MM_CMPINT_GT); #else @@ -395,8 +344,7 @@ namespace embree __forceinline vfloat4 max(const vfloat4& a, float b) { return _mm_max_ps(a,vfloat4(b)); } __forceinline vfloat4 max(float a, const vfloat4& b) { return _mm_max_ps(vfloat4(a),b); } -#if defined(__SSE4_1__) || defined(__aarch64__) - +#if defined(__SSE4_1__) __forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); @@ -438,31 +386,17 @@ namespace embree /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// -#if defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); } __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); } __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); } __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); } #else - -#if defined(__aarch64__) - __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { - return _mm_madd_ps(a, b, c); //a*b+c; - } - __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { - return _mm_msub_ps(a, b, c); //-a*b+c; - } - __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { - return vnegq_f32(vfmaq_f32(c,a, b)); - } -#else __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; } + __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; } __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;} __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; } #endif - __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; } - -#endif //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators @@ -495,13 +429,8 @@ namespace embree __forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmpeq_ps (a, b); } __forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmpneq_ps(a, b); } __forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmplt_ps (a, b); } -#if defined(__aarch64__) - __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpge_ps (a, b); } - __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpgt_ps (a, b); } -#else __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpnlt_ps(a, b); } __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpnle_ps(a, b); } -#endif __forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmple_ps (a, b); } #endif @@ -513,7 +442,7 @@ namespace embree __forceinline vboolf4 operator < (const vfloat4& a, float b) { return a < vfloat4(b); } __forceinline vboolf4 operator < (float a, const vfloat4& b) { return vfloat4(a) < b; } - + __forceinline vboolf4 operator >=(const vfloat4& a, float b) { return a >= vfloat4(b); } __forceinline vboolf4 operator >=(float a, const vfloat4& b) { return vfloat4(a) >= b; } @@ -549,68 +478,17 @@ namespace embree template<int mask> __forceinline vfloat4 select(const vfloat4& t, const vfloat4& f) { -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) return _mm_blend_ps(f, t, mask); #else return select(vboolf4(mask), t, f); #endif } - -#if defined(__aarch64__) - template<> __forceinline vfloat4 select<0>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vzero)); - } - template<> __forceinline vfloat4 select<1>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v000F)); - } - template<> __forceinline vfloat4 select<2>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v00F0)); - } - template<> __forceinline vfloat4 select<3>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v00FF)); - } - template<> __forceinline vfloat4 select<4>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v0F00)); - } - template<> __forceinline vfloat4 select<5>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v0F0F)); - } - template<> __forceinline vfloat4 select<6>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v0FF0)); - } - template<> __forceinline vfloat4 select<7>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(v0FFF)); - } - template<> __forceinline vfloat4 select<8>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vF000)); - } - template<> __forceinline vfloat4 select<9>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vF00F)); - } - template<> __forceinline vfloat4 select<10>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vF0F0)); - } - template<> __forceinline vfloat4 select<11>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vF0FF)); - } - template<> __forceinline vfloat4 select<12>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vFF00)); - } - template<> __forceinline vfloat4 select<13>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vFF0F)); - } - template<> __forceinline vfloat4 select<14>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vFFF0)); - } - template<> __forceinline vfloat4 select<15>(const vfloat4& t, const vfloat4& f) { - return _mm_blendv_ps(f, t, vreinterpretq_f32_u32(vFFFF)); - } -#endif - + __forceinline vfloat4 lerp(const vfloat4& a, const vfloat4& b, const vfloat4& t) { return madd(t,b-a,a); } - + __forceinline bool isvalid(const vfloat4& v) { return all((v > vfloat4(-FLT_LARGE)) & (v < vfloat4(+FLT_LARGE))); } @@ -622,21 +500,21 @@ namespace embree __forceinline bool is_finite(const vboolf4& valid, const vfloat4& a) { return all(valid, (a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX))); } - + //////////////////////////////////////////////////////////////////////////////// /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) - __forceinline vfloat4 floor(const vfloat4& a) { return vrndmq_f32(a.v); } // towards -inf - __forceinline vfloat4 ceil (const vfloat4& a) { return vrndpq_f32(a.v); } // toward +inf - __forceinline vfloat4 trunc(const vfloat4& a) { return vrndq_f32(a.v); } // towards 0 - __forceinline vfloat4 round(const vfloat4& a) { return vrndnq_f32(a.v); } // to nearest, ties to even. NOTE(LTE): arm clang uses vrndnq, old gcc uses vrndqn? + __forceinline vfloat4 floor(const vfloat4& a) { return vrndmq_f32(a.v); } + __forceinline vfloat4 ceil (const vfloat4& a) { return vrndpq_f32(a.v); } + __forceinline vfloat4 trunc(const vfloat4& a) { return vrndq_f32(a.v); } + __forceinline vfloat4 round(const vfloat4& a) { return vrndnq_f32(a.v); } #elif defined (__SSE4_1__) - __forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); } - __forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); } - __forceinline vfloat4 trunc(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); } - __forceinline vfloat4 round(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); } // (even) https://www.felixcloutier.com/x86/roundpd + __forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); } + __forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); } + __forceinline vfloat4 trunc(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); } + __forceinline vfloat4 round(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); } #else __forceinline vfloat4 floor(const vfloat4& a) { return vfloat4(floorf(a[0]),floorf(a[1]),floorf(a[2]),floorf(a[3])); } __forceinline vfloat4 ceil (const vfloat4& a) { return vfloat4(ceilf (a[0]),ceilf (a[1]),ceilf (a[2]),ceilf (a[3])); } @@ -646,9 +524,7 @@ namespace embree __forceinline vfloat4 frac(const vfloat4& a) { return a-floor(a); } __forceinline vint4 floori(const vfloat4& a) { -#if defined(__aarch64__) - return vcvtq_s32_f32(floor(a)); -#elif defined(__SSE4_1__) +#if defined(__SSE4_1__) return vint4(floor(a)); #else return vint4(a-vfloat4(0.5f)); @@ -662,16 +538,6 @@ namespace embree __forceinline vfloat4 unpacklo(const vfloat4& a, const vfloat4& b) { return _mm_unpacklo_ps(a, b); } __forceinline vfloat4 unpackhi(const vfloat4& a, const vfloat4& b) { return _mm_unpackhi_ps(a, b); } -#if defined(__aarch64__) - template<int i0, int i1, int i2, int i3> - __forceinline vfloat4 shuffle(const vfloat4& v) { - return vreinterpretq_f32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); - } - template<int i0, int i1, int i2, int i3> - __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) { - return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); - } -#else template<int i0, int i1, int i2, int i3> __forceinline vfloat4 shuffle(const vfloat4& v) { return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(v), _MM_SHUFFLE(i3, i2, i1, i0))); @@ -681,19 +547,8 @@ namespace embree __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } -#endif - -#if defined (__SSSE3__) - __forceinline vfloat4 shuffle8(const vfloat4& a, const vint4& shuf) { - return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf)); - } -#endif -#if defined(__aarch64__) - template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return __m128(vqtbl1q_u8( uint8x16_t(v.v), v0022 )); } - template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return __m128(vqtbl1q_u8( uint8x16_t(v.v), v1133)); } - template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return __m128(vqtbl1q_u8( uint8x16_t(v.v), v0101)); } -#elif defined(__SSE3__) +#if defined(__SSE3__) template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return _mm_moveldup_ps(v); } template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return _mm_movehdup_ps(v); } template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(v))); } @@ -704,56 +559,10 @@ namespace embree return shuffle<i,i,i,i>(v); } -#if defined(__aarch64__) - template<int i> __forceinline float extract(const vfloat4& a); - template<> __forceinline float extract<0>(const vfloat4& b) { - return b[0]; - } - template<> __forceinline float extract<1>(const vfloat4& b) { - return b[1]; - } - template<> __forceinline float extract<2>(const vfloat4& b) { - return b[2]; - } - template<> __forceinline float extract<3>(const vfloat4& b) { - return b[3]; - } -#elif defined (__SSE4_1__) && !defined(__GNUC__) - template<int i> __forceinline float extract(const vfloat4& a) { return _mm_cvtss_f32(_mm_extract_ps(a,i)); } - template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); } -#else - template<int i> __forceinline float extract(const vfloat4& a) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); } - template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); } -#endif - + template<int i> __forceinline float extract (const vfloat4& a) { return _mm_cvtss_f32(shuffle<i>(a)); } + template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); } -#if defined(__aarch64__) - template<int dst> __forceinline vfloat4 insert(const vfloat4& a, float b); - template<> __forceinline vfloat4 insert<0>(const vfloat4& a, float b) - { - vfloat4 c = a; - c[0] = b; - return c; - } - template<> __forceinline vfloat4 insert<1>(const vfloat4& a, float b) - { - vfloat4 c = a; - c[1] = b; - return c; - } - template<> __forceinline vfloat4 insert<2>(const vfloat4& a, float b) - { - vfloat4 c = a; - c[2] = b; - return c; - } - template<> __forceinline vfloat4 insert<3>(const vfloat4& a, float b) - { - vfloat4 c = a; - c[3] = b; - return c; - } -#elif defined (__SSE4_1__) +#if defined (__SSE4_1__) template<int dst, int src, int clr> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); } template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return insert<dst, src, 0>(a, b); } template<int dst> __forceinline vfloat4 insert(const vfloat4& a, const float b) { return insert<dst, 0>(a, _mm_set_ss(b)); } @@ -762,19 +571,10 @@ namespace embree template<int dst> __forceinline vfloat4 insert(const vfloat4& a, float b) { vfloat4 c = a; c[dst&3] = b; return c; } #endif -#if defined(__aarch64__) - __forceinline float toScalar(const vfloat4& v) { - return v[0]; - } -#else __forceinline float toScalar(const vfloat4& v) { return _mm_cvtss_f32(v); } -#endif - __forceinline vfloat4 broadcast4f(const vfloat4& a, size_t k) { - return vfloat4::broadcast(&a[k]); - } __forceinline vfloat4 shift_right_1(const vfloat4& x) { - return _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(x), 4)); + return _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(x), 4)); } #if defined (__AVX2__) @@ -790,7 +590,7 @@ namespace embree template<int i> __forceinline vfloat4 align_shift_right(const vfloat4& a, const vfloat4& b) { return _mm_castsi128_ps(_mm_alignr_epi32(_mm_castps_si128(a), _mm_castps_si128(b), i)); - } + } #endif @@ -864,39 +664,28 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// -#if defined(__aarch64__) - __forceinline vfloat4 vreduce_min(const vfloat4& v) { float h = vminvq_f32(v); return vdupq_n_f32(h); } - __forceinline vfloat4 vreduce_max(const vfloat4& v) { float h = vmaxvq_f32(v); return vdupq_n_f32(h); } - __forceinline vfloat4 vreduce_add(const vfloat4& v) { float h = vaddvq_f32(v); return vdupq_n_f32(h); } -#else + __forceinline vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } -#endif -#if defined(__aarch64__) - __forceinline float reduce_min(const vfloat4& v) { return vminvq_f32(v); } - __forceinline float reduce_max(const vfloat4& v) { return vmaxvq_f32(v); } - __forceinline float reduce_add(const vfloat4& v) { return vaddvq_f32(v); } -#else __forceinline float reduce_min(const vfloat4& v) { return _mm_cvtss_f32(vreduce_min(v)); } __forceinline float reduce_max(const vfloat4& v) { return _mm_cvtss_f32(vreduce_max(v)); } __forceinline float reduce_add(const vfloat4& v) { return _mm_cvtss_f32(vreduce_add(v)); } -#endif - __forceinline size_t select_min(const vboolf4& valid, const vfloat4& v) - { - const vfloat4 a = select(valid,v,vfloat4(pos_inf)); + __forceinline size_t select_min(const vboolf4& valid, const vfloat4& v) + { + const vfloat4 a = select(valid,v,vfloat4(pos_inf)); const vbool4 valid_min = valid & (a == vreduce_min(a)); - return bsf(movemask(any(valid_min) ? valid_min : valid)); + return bsf(movemask(any(valid_min) ? valid_min : valid)); } - __forceinline size_t select_max(const vboolf4& valid, const vfloat4& v) - { - const vfloat4 a = select(valid,v,vfloat4(neg_inf)); + __forceinline size_t select_max(const vboolf4& valid, const vfloat4& v) + { + const vfloat4 a = select(valid,v,vfloat4(neg_inf)); const vbool4 valid_max = valid & (a == vreduce_max(a)); - return bsf(movemask(any(valid_max) ? valid_max : valid)); + return bsf(movemask(any(valid_max) ? valid_max : valid)); } - + //////////////////////////////////////////////////////////////////////////////// /// Euclidian Space Operators //////////////////////////////////////////////////////////////////////////////// @@ -911,7 +700,7 @@ namespace embree const vfloat4 b0 = shuffle<1,2,0,3>(b); const vfloat4 a1 = shuffle<1,2,0,3>(a); const vfloat4 b1 = b; - return shuffle<1,2,0,3>(prod_diff(a0,b0,a1,b1)); + return shuffle<1,2,0,3>(msub(a0,b0,a1*b1)); } //////////////////////////////////////////////////////////////////////////////// @@ -923,3 +712,11 @@ namespace embree } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vfloat8_avx.h b/thirdparty/embree/common/simd/vfloat8_avx.h index 3c7e4a8cdc..13446454e8 100644 --- a/thirdparty/embree-aarch64/common/simd/vfloat8_avx.h +++ b/thirdparty/embree/common/simd/vfloat8_avx.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX float type */ @@ -33,7 +41,7 @@ namespace embree __forceinline explicit vfloat(const vfloat4& a) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {} __forceinline vfloat(const vfloat4& a, const vfloat4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {} - __forceinline explicit vfloat(const int8_t* a) : v(_mm256_loadu_ps((const float*)a)) {} + __forceinline explicit vfloat(const char* a) : v(_mm256_loadu_ps((const float*)a)) {} __forceinline vfloat(float a) : v(_mm256_set1_ps(a)) {} __forceinline vfloat(float a, float b) : v(_mm256_set_ps(b, a, b, a, b, a, b, a)) {} __forceinline vfloat(float a, float b, float c, float d) : v(_mm256_set_ps(d, c, b, a, d, c, b, a)) {} @@ -61,21 +69,7 @@ namespace embree return _mm256_broadcast_ss((float*)a); } - static __forceinline vfloat8 broadcast2(const float* a, const float* b) { -#if defined(__INTEL_COMPILER) - const vfloat8 v0 = _mm256_broadcast_ss(a); - const vfloat8 v1 = _mm256_broadcast_ss(b); - return _mm256_blend_ps(v1, v0, 0xf); -#else - return _mm256_set_ps(*b,*b,*b,*b,*a,*a,*a,*a); -#endif - } - - static __forceinline vfloat8 broadcast4f(const vfloat4* ptr) { - return _mm256_broadcast_ps((__m128*)ptr); - } - - static __forceinline vfloat8 load(const int8_t* ptr) { + static __forceinline vfloat8 load(const char* ptr) { #if defined(__AVX2__) return _mm256_cvtepi32_ps(_mm256_cvtepi8_epi32(_mm_loadu_si128((__m128i*)ptr))); #else @@ -83,7 +77,7 @@ namespace embree #endif } - static __forceinline vfloat8 load(const uint8_t* ptr) { + static __forceinline vfloat8 load(const unsigned char* ptr) { #if defined(__AVX2__) return _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr))); #else @@ -107,24 +101,11 @@ namespace embree #if defined(__AVX512VL__) - static __forceinline vfloat8 compact(const vboolf8& mask, vfloat8 &v) { - return _mm256_mask_compress_ps(v, mask, v); - } - static __forceinline vfloat8 compact(const vboolf8& mask, vfloat8 &a, const vfloat8& b) { - return _mm256_mask_compress_ps(a, mask, b); - } - static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_mask_load_ps (_mm256_setzero_ps(),mask,(float*)ptr); } static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_mask_loadu_ps(_mm256_setzero_ps(),mask,(float*)ptr); } static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_store_ps ((float*)ptr,mask,v); } static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_storeu_ps((float*)ptr,mask,v); } -#elif defined(__aarch64__) - static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask.v); } - static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask.v); } - - static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask.v,v); } - static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask.v,v); } #else static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); } static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); } @@ -145,18 +126,18 @@ namespace embree template<int scale = 4> static __forceinline vfloat8 gather(const float* ptr, const vint8& index) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _mm256_i32gather_ps(ptr, index ,scale); #else return vfloat8( - *(float*)(((int8_t*)ptr)+scale*index[0]), - *(float*)(((int8_t*)ptr)+scale*index[1]), - *(float*)(((int8_t*)ptr)+scale*index[2]), - *(float*)(((int8_t*)ptr)+scale*index[3]), - *(float*)(((int8_t*)ptr)+scale*index[4]), - *(float*)(((int8_t*)ptr)+scale*index[5]), - *(float*)(((int8_t*)ptr)+scale*index[6]), - *(float*)(((int8_t*)ptr)+scale*index[7])); + *(float*)(((char*)ptr)+scale*index[0]), + *(float*)(((char*)ptr)+scale*index[1]), + *(float*)(((char*)ptr)+scale*index[2]), + *(float*)(((char*)ptr)+scale*index[3]), + *(float*)(((char*)ptr)+scale*index[4]), + *(float*)(((char*)ptr)+scale*index[5]), + *(float*)(((char*)ptr)+scale*index[6]), + *(float*)(((char*)ptr)+scale*index[7])); #endif } @@ -165,17 +146,17 @@ namespace embree vfloat8 r = zero; #if defined(__AVX512VL__) return _mm256_mmask_i32gather_ps(r, mask, index, ptr, scale); -#elif defined(__AVX2__) && !defined(__aarch64__) +#elif defined(__AVX2__) return _mm256_mask_i32gather_ps(r, ptr, index, mask, scale); #else - if (likely(mask[0])) r[0] = *(float*)(((int8_t*)ptr)+scale*index[0]); - if (likely(mask[1])) r[1] = *(float*)(((int8_t*)ptr)+scale*index[1]); - if (likely(mask[2])) r[2] = *(float*)(((int8_t*)ptr)+scale*index[2]); - if (likely(mask[3])) r[3] = *(float*)(((int8_t*)ptr)+scale*index[3]); - if (likely(mask[4])) r[4] = *(float*)(((int8_t*)ptr)+scale*index[4]); - if (likely(mask[5])) r[5] = *(float*)(((int8_t*)ptr)+scale*index[5]); - if (likely(mask[6])) r[6] = *(float*)(((int8_t*)ptr)+scale*index[6]); - if (likely(mask[7])) r[7] = *(float*)(((int8_t*)ptr)+scale*index[7]); + if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]); + if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]); + if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]); + if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]); + if (likely(mask[4])) r[4] = *(float*)(((char*)ptr)+scale*index[4]); + if (likely(mask[5])) r[5] = *(float*)(((char*)ptr)+scale*index[5]); + if (likely(mask[6])) r[6] = *(float*)(((char*)ptr)+scale*index[6]); + if (likely(mask[7])) r[7] = *(float*)(((char*)ptr)+scale*index[7]); return r; #endif } @@ -186,14 +167,14 @@ namespace embree #if defined(__AVX512VL__) _mm256_i32scatter_ps((float*)ptr, ofs, v, scale); #else - *(float*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - *(float*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - *(float*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - *(float*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - *(float*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - *(float*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - *(float*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - *(float*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + *(float*)(((char*)ptr)+scale*ofs[0]) = v[0]; + *(float*)(((char*)ptr)+scale*ofs[1]) = v[1]; + *(float*)(((char*)ptr)+scale*ofs[2]) = v[2]; + *(float*)(((char*)ptr)+scale*ofs[3]) = v[3]; + *(float*)(((char*)ptr)+scale*ofs[4]) = v[4]; + *(float*)(((char*)ptr)+scale*ofs[5]) = v[5]; + *(float*)(((char*)ptr)+scale*ofs[6]) = v[6]; + *(float*)(((char*)ptr)+scale*ofs[7]) = v[7]; #endif } @@ -203,24 +184,17 @@ namespace embree #if defined(__AVX512VL__) _mm256_mask_i32scatter_ps((float*)ptr, mask, ofs, v, scale); #else - if (likely(mask[0])) *(float*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - if (likely(mask[1])) *(float*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - if (likely(mask[2])) *(float*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - if (likely(mask[3])) *(float*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - if (likely(mask[4])) *(float*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - if (likely(mask[5])) *(float*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - if (likely(mask[6])) *(float*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - if (likely(mask[7])) *(float*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + if (likely(mask[0])) *(float*)(((char*)ptr)+scale*ofs[0]) = v[0]; + if (likely(mask[1])) *(float*)(((char*)ptr)+scale*ofs[1]) = v[1]; + if (likely(mask[2])) *(float*)(((char*)ptr)+scale*ofs[2]) = v[2]; + if (likely(mask[3])) *(float*)(((char*)ptr)+scale*ofs[3]) = v[3]; + if (likely(mask[4])) *(float*)(((char*)ptr)+scale*ofs[4]) = v[4]; + if (likely(mask[5])) *(float*)(((char*)ptr)+scale*ofs[5]) = v[5]; + if (likely(mask[6])) *(float*)(((char*)ptr)+scale*ofs[6]) = v[6]; + if (likely(mask[7])) *(float*)(((char*)ptr)+scale*ofs[7]) = v[7]; #endif } - static __forceinline void store(const vboolf8& mask, int8_t* ptr, const vint8& ofs, const vfloat8& v) { - scatter<1>(mask,ptr,ofs,v); - } - static __forceinline void store(const vboolf8& mask, float* ptr, const vint8& ofs, const vfloat8& v) { - scatter<4>(mask,ptr,ofs,v); - } - //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -241,60 +215,27 @@ namespace embree __forceinline vfloat8 toFloat(const vint8& a) { return vfloat8(a); } __forceinline vfloat8 operator +(const vfloat8& a) { return a; } -#if !defined(__aarch64__) __forceinline vfloat8 operator -(const vfloat8& a) { const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000)); return _mm256_xor_ps(a, mask); } -#else - __forceinline vfloat8 operator -(const vfloat8& a) { - __m256 res; - res.lo = vnegq_f32(a.v.lo); - res.hi = vnegq_f32(a.v.hi); - return res; -} -#endif - -#if !defined(__aarch64__) -__forceinline vfloat8 abs(const vfloat8& a) { - const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff)); - return _mm256_and_ps(a, mask); -} -#else -__forceinline vfloat8 abs(const vfloat8& a) { - __m256 res; - res.lo = vabsq_f32(a.v.lo); - res.hi = vabsq_f32(a.v.hi); - return res; -} -#endif - -#if !defined(__aarch64__) + __forceinline vfloat8 abs(const vfloat8& a) { + const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff)); + return _mm256_and_ps(a, mask); + } __forceinline vfloat8 sign (const vfloat8& a) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmp_ps(a, vfloat8(zero), _CMP_NGE_UQ)); } -#else - __forceinline vfloat8 sign (const vfloat8& a) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmplt_ps(a, vfloat8(zero))); } -#endif __forceinline vfloat8 signmsk(const vfloat8& a) { return _mm256_and_ps(a,_mm256_castsi256_ps(_mm256_set1_epi32(0x80000000))); } static __forceinline vfloat8 rcp(const vfloat8& a) { -#if defined(BUILD_IOS) && defined(__aarch64__) - // ios devices are faster doing full divide, no need for NR fixup - vfloat8 ret; - const float32x4_t one = vdupq_n_f32(1.0f); - ret.v.lo = vdivq_f32(one, a.v.lo); - ret.v.hi = vdivq_f32(one, a.v.hi); - return ret; -#endif - #if defined(__AVX512VL__) const vfloat8 r = _mm256_rcp14_ps(a); #else const vfloat8 r = _mm256_rcp_ps(a); #endif - -#if defined(__AVX2__) //&& !defined(aarch64) + +#if defined(__AVX2__) return _mm256_mul_ps(r, _mm256_fnmadd_ps(r, a, vfloat8(2.0f))); #else return _mm256_mul_ps(r, _mm256_sub_ps(vfloat8(2.0f), _mm256_mul_ps(r, a))); @@ -443,29 +384,17 @@ __forceinline vfloat8 abs(const vfloat8& a) { static __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { return _mm256_mask_blend_ps(m, f, t); } -#elif !defined(__aarch64__) - __forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ); } - __forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NEQ_UQ); } - __forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LT_OS); } - __forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NLT_US); } - __forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NLE_US); } - __forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LE_OS); } - - __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { - return _mm256_blendv_ps(f, t, m); - } #else - __forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmpeq_ps(a, b); } - __forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmpneq_ps(a, b); } - __forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmplt_ps(a, b); } - __forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmpge_ps(a, b); } - __forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmpgt_ps(a, b); } - __forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmple_ps(a, b); } + static __forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ); } + static __forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NEQ_UQ); } + static __forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LT_OS); } + static __forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NLT_US); } + static __forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NLE_US); } + static __forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LE_OS); } - __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { - return _mm256_blendv_ps(f, t, m); + static __forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) { + return _mm256_blendv_ps(f, t, m); } - #endif template<int mask> @@ -534,17 +463,10 @@ __forceinline vfloat8 abs(const vfloat8& a) { /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// -#if !defined(__aarch64__) __forceinline vfloat8 floor(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_NEG_INF ); } __forceinline vfloat8 ceil (const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_POS_INF ); } __forceinline vfloat8 trunc(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_ZERO ); } __forceinline vfloat8 round(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_NEAREST_INT); } -#else - __forceinline vfloat8 floor(const vfloat8& a) { return _mm256_floor_ps(a); } - __forceinline vfloat8 ceil (const vfloat8& a) { return _mm256_ceil_ps(a); } -#endif - - __forceinline vfloat8 frac (const vfloat8& a) { return a-floor(a); } //////////////////////////////////////////////////////////////////////////////// @@ -579,11 +501,9 @@ __forceinline vfloat8 abs(const vfloat8& a) { return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } -#if !defined(__aarch64__) template<> __forceinline vfloat8 shuffle<0, 0, 2, 2>(const vfloat8& v) { return _mm256_moveldup_ps(v); } template<> __forceinline vfloat8 shuffle<1, 1, 3, 3>(const vfloat8& v) { return _mm256_movehdup_ps(v); } template<> __forceinline vfloat8 shuffle<0, 1, 0, 1>(const vfloat8& v) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(v))); } -#endif __forceinline vfloat8 broadcast(const float* ptr) { return _mm256_broadcast_ss(ptr); } template<size_t i> __forceinline vfloat8 insert4(const vfloat8& a, const vfloat4& b) { return _mm256_insertf128_ps(a, b, i); } @@ -592,10 +512,8 @@ __forceinline vfloat8 abs(const vfloat8& a) { __forceinline float toScalar(const vfloat8& v) { return _mm_cvtss_f32(_mm256_castps256_ps128(v)); } - __forceinline vfloat8 assign(const vfloat4& a) { return _mm256_castps128_ps256(a); } - -#if defined (__AVX2__) && !defined(__aarch64__) - __forceinline vfloat8 permute(const vfloat8& a, const __m256i& index) { +#if defined (__AVX2__) + static __forceinline vfloat8 permute(const vfloat8& a, const __m256i& index) { return _mm256_permutevar8x32_ps(a, index); } #endif @@ -618,14 +536,6 @@ __forceinline vfloat8 abs(const vfloat8& a) { } #endif - __forceinline vfloat4 broadcast4f(const vfloat8& a, const size_t k) { - return vfloat4::broadcast(&a[k]); - } - - __forceinline vfloat8 broadcast8f(const vfloat8& a, const size_t k) { - return vfloat8::broadcast(&a[k]); - } - #if defined(__AVX512VL__) static __forceinline vfloat8 shift_right_1(const vfloat8& x) { return align_shift_right<1>(zero,x); @@ -699,7 +609,7 @@ __forceinline vfloat8 abs(const vfloat8& a) { //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// -#if !defined(__aarch64__) + __forceinline vfloat8 vreduce_min2(const vfloat8& v) { return min(v,shuffle<1,0,3,2>(v)); } __forceinline vfloat8 vreduce_min4(const vfloat8& v) { vfloat8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); } __forceinline vfloat8 vreduce_min (const vfloat8& v) { vfloat8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); } @@ -715,14 +625,7 @@ __forceinline vfloat8 abs(const vfloat8& a) { __forceinline float reduce_min(const vfloat8& v) { return toScalar(vreduce_min(v)); } __forceinline float reduce_max(const vfloat8& v) { return toScalar(vreduce_max(v)); } __forceinline float reduce_add(const vfloat8& v) { return toScalar(vreduce_add(v)); } -#else - __forceinline float reduce_min(const vfloat8& v) { return vminvq_f32(_mm_min_ps(v.v.lo,v.v.hi)); } - __forceinline float reduce_max(const vfloat8& v) { return vmaxvq_f32(_mm_max_ps(v.v.lo,v.v.hi)); } - __forceinline vfloat8 vreduce_min(const vfloat8& v) { return vfloat8(reduce_min(v)); } - __forceinline vfloat8 vreduce_max(const vfloat8& v) { return vfloat8(reduce_max(v)); } - __forceinline float reduce_add(const vfloat8& v) { return vaddvq_f32(_mm_add_ps(v.v.lo,v.v.hi)); } -#endif __forceinline size_t select_min(const vboolf8& valid, const vfloat8& v) { const vfloat8 a = select(valid,v,vfloat8(pos_inf)); @@ -845,3 +748,11 @@ __forceinline vfloat8 abs(const vfloat8& a) { return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vint16_avx512.h b/thirdparty/embree/common/simd/vint16_avx512.h index 3249bc2b45..3720c3c9d6 100644 --- a/thirdparty/embree-aarch64/common/simd/vint16_avx512.h +++ b/thirdparty/embree/common/simd/vint16_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 16-wide AVX-512 integer type */ @@ -90,10 +98,10 @@ namespace embree static __forceinline vint16 load (const void* addr) { return _mm512_load_si512((int*)addr); } - static __forceinline vint16 load(const uint8_t* ptr) { return _mm512_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); } + static __forceinline vint16 load(const unsigned char* ptr) { return _mm512_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); } static __forceinline vint16 load(const unsigned short* ptr) { return _mm512_cvtepu16_epi32(_mm256_load_si256((__m256i*)ptr)); } - static __forceinline vint16 loadu(const uint8_t* ptr) { return _mm512_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)); } + static __forceinline vint16 loadu(const unsigned char* ptr) { return _mm512_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)); } static __forceinline vint16 loadu(const unsigned short* ptr) { return _mm512_cvtepu16_epi32(_mm256_loadu_si256((__m256i*)ptr)); } static __forceinline vint16 loadu(const void* addr) { return _mm512_loadu_si512(addr); } @@ -109,20 +117,6 @@ namespace embree static __forceinline void store_nt(void* __restrict__ ptr, const vint16& a) { _mm512_stream_si512((__m512i*)ptr,a); } - /* pass by value to avoid compiler generating inefficient code */ - static __forceinline void storeu_compact(const vboolf16 mask, void* addr, vint16 reg) { - _mm512_mask_compressstoreu_epi32(addr,mask,reg); - } - - static __forceinline void storeu_compact_single(const vboolf16 mask, void* addr, vint16 reg) { - //_mm512_mask_compressstoreu_epi32(addr,mask,reg); - *(float*)addr = mm512_cvtss_f32(_mm512_mask_compress_ps(_mm512_castsi512_ps(reg),mask,_mm512_castsi512_ps(reg))); - } - - static __forceinline vint16 compact64bit(const vboolf16& mask, vint16 &v) { - return _mm512_mask_compress_epi64(v,mask,v); - } - static __forceinline vint16 compact(const vboolf16& mask, vint16 &v) { return _mm512_mask_compress_epi32(v,mask,v); } @@ -160,10 +154,6 @@ namespace embree _mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale); } - static __forceinline vint16 broadcast64bit(size_t v) { - return _mm512_set1_epi64(v); - } - //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -313,18 +303,6 @@ namespace embree return _mm512_mask_or_epi32(f,m,t,t); } - __forceinline void xchg(const vboolf16& m, vint16& a, vint16& b) { - const vint16 c = a; a = select(m,b,a); b = select(m,c,b); - } - - __forceinline vboolf16 test(const vboolf16& m, const vint16& a, const vint16& b) { - return _mm512_mask_test_epi32_mask(m,a,b); - } - - __forceinline vboolf16 test(const vint16& a, const vint16& b) { - return _mm512_test_epi32_mask(a,b); - } - //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -363,10 +341,6 @@ namespace embree template<int i> __forceinline vint16 insert4(const vint16& a, const vint4& b) { return _mm512_inserti32x4(a, b, i); } - __forceinline size_t extract64bit(const vint16& v) { - return _mm_cvtsi128_si64(_mm512_castsi512_si128(v)); - } - template<int N, int i> vint<N> extractN(const vint16& v); @@ -488,3 +462,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vint4_sse2.h b/thirdparty/embree/common/simd/vint4_sse2.h index 96f105a7c5..9814d5c71c 100644 --- a/thirdparty/embree-aarch64/common/simd/vint4_sse2.h +++ b/thirdparty/embree/common/simd/vint4_sse2.h @@ -1,10 +1,18 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../math/math.h" +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide SSE integer type */ @@ -23,7 +31,7 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// - + __forceinline vint() {} __forceinline vint(const vint4& a) { v = a.v; } __forceinline vint4& operator =(const vint4& a) { v = a.v; return *this; } @@ -68,7 +76,7 @@ namespace embree static __forceinline void store (void* ptr, const vint4& v) { _mm_store_si128((__m128i*)ptr,v); } static __forceinline void storeu(void* ptr, const vint4& v) { _mm_storeu_si128((__m128i*)ptr,v); } - + #if defined(__AVX512VL__) static __forceinline vint4 compact(const vboolf4& mask, vint4 &v) { @@ -98,81 +106,61 @@ namespace embree #endif -#if defined(__aarch64__) - static __forceinline vint4 load(const uint8_t* ptr) { - return _mm_load4epu8_epi32(((__m128i*)ptr)); - } - static __forceinline vint4 loadu(const uint8_t* ptr) { - return _mm_load4epu8_epi32(((__m128i*)ptr)); - } -#elif defined(__SSE4_1__) - static __forceinline vint4 load(const uint8_t* ptr) { +#if defined(__SSE4_1__) + static __forceinline vint4 load(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } - static __forceinline vint4 loadu(const uint8_t* ptr) { + static __forceinline vint4 loadu(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } #else - static __forceinline vint4 load(const uint8_t* ptr) { + static __forceinline vint4 load(const unsigned char* ptr) { return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); - } + } - static __forceinline vint4 loadu(const uint8_t* ptr) { + static __forceinline vint4 loadu(const unsigned char* ptr) { return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif static __forceinline vint4 load(const unsigned short* ptr) { -#if defined(__aarch64__) - return __m128i(vmovl_u16(vld1_u16(ptr))); -#elif defined (__SSE4_1__) +#if defined (__SSE4_1__) return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); #else return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); #endif - } + } - static __forceinline void store(uint8_t* ptr, const vint4& v) { -#if defined(__aarch64__) - int32x4_t x = v; - uint16x4_t y = vqmovn_u32(uint32x4_t(x)); - uint8x8_t z = vqmovn_u16(vcombine_u16(y, y)); - vst1_lane_u32((uint32_t *)ptr,uint32x2_t(z), 0); -#elif defined(__SSE4_1__) + static __forceinline void store(unsigned char* ptr, const vint4& v) { +#if defined(__SSE4_1__) __m128i x = v; x = _mm_packus_epi32(x, x); x = _mm_packus_epi16(x, x); *(int*)ptr = _mm_cvtsi128_si32(x); #else for (size_t i=0;i<4;i++) - ptr[i] = (uint8_t)v[i]; + ptr[i] = (unsigned char)v[i]; #endif } static __forceinline void store(unsigned short* ptr, const vint4& v) { -#if defined(__aarch64__) - uint32x4_t x = uint32x4_t(v.v); - uint16x4_t y = vqmovn_u32(x); - vst1_u16(ptr, y); -#else for (size_t i=0;i<4;i++) ptr[i] = (unsigned short)v[i]; -#endif } static __forceinline vint4 load_nt(void* ptr) { -#if defined(__aarch64__) || defined(__SSE4_1__) - return _mm_stream_load_si128((__m128i*)ptr); +#if defined(__SSE4_1__) + return _mm_stream_load_si128((__m128i*)ptr); #else - return _mm_load_si128((__m128i*)ptr); + return _mm_load_si128((__m128i*)ptr); #endif } - + static __forceinline void store_nt(void* ptr, const vint4& v) { -#if !defined(__aarch64__) && defined(__SSE4_1__) +#if defined(__SSE4_1__) _mm_stream_ps((float*)ptr, _mm_castsi128_ps(v)); #else _mm_store_si128((__m128i*)ptr,v); @@ -181,14 +169,14 @@ namespace embree template<int scale = 4> static __forceinline vint4 gather(const int* ptr, const vint4& index) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _mm_i32gather_epi32(ptr, index, scale); #else return vint4( - *(int*)(((int8_t*)ptr)+scale*index[0]), - *(int*)(((int8_t*)ptr)+scale*index[1]), - *(int*)(((int8_t*)ptr)+scale*index[2]), - *(int*)(((int8_t*)ptr)+scale*index[3])); + *(int*)(((char*)ptr)+scale*index[0]), + *(int*)(((char*)ptr)+scale*index[1]), + *(int*)(((char*)ptr)+scale*index[2]), + *(int*)(((char*)ptr)+scale*index[3])); #endif } @@ -197,13 +185,13 @@ namespace embree vint4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale); -#elif defined(__AVX2__) && !defined(__aarch64__) +#elif defined(__AVX2__) return _mm_mask_i32gather_epi32(r, ptr, index, mask, scale); #else - if (likely(mask[0])) r[0] = *(int*)(((int8_t*)ptr)+scale*index[0]); - if (likely(mask[1])) r[1] = *(int*)(((int8_t*)ptr)+scale*index[1]); - if (likely(mask[2])) r[2] = *(int*)(((int8_t*)ptr)+scale*index[2]); - if (likely(mask[3])) r[3] = *(int*)(((int8_t*)ptr)+scale*index[3]); + if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]); + if (likely(mask[1])) r[1] = *(int*)(((char*)ptr)+scale*index[1]); + if (likely(mask[2])) r[2] = *(int*)(((char*)ptr)+scale*index[2]); + if (likely(mask[3])) r[3] = *(int*)(((char*)ptr)+scale*index[3]); return r; #endif } @@ -214,10 +202,10 @@ namespace embree #if defined(__AVX512VL__) _mm_i32scatter_epi32((int*)ptr, index, v, scale); #else - *(int*)(((int8_t*)ptr)+scale*index[0]) = v[0]; - *(int*)(((int8_t*)ptr)+scale*index[1]) = v[1]; - *(int*)(((int8_t*)ptr)+scale*index[2]) = v[2]; - *(int*)(((int8_t*)ptr)+scale*index[3]) = v[3]; + *(int*)(((char*)ptr)+scale*index[0]) = v[0]; + *(int*)(((char*)ptr)+scale*index[1]) = v[1]; + *(int*)(((char*)ptr)+scale*index[2]) = v[2]; + *(int*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } @@ -227,14 +215,14 @@ namespace embree #if defined(__AVX512VL__) _mm_mask_i32scatter_epi32((int*)ptr, mask, index, v, scale); #else - if (likely(mask[0])) *(int*)(((int8_t*)ptr)+scale*index[0]) = v[0]; - if (likely(mask[1])) *(int*)(((int8_t*)ptr)+scale*index[1]) = v[1]; - if (likely(mask[2])) *(int*)(((int8_t*)ptr)+scale*index[2]) = v[2]; - if (likely(mask[3])) *(int*)(((int8_t*)ptr)+scale*index[3]) = v[3]; + if (likely(mask[0])) *(int*)(((char*)ptr)+scale*index[0]) = v[0]; + if (likely(mask[1])) *(int*)(((char*)ptr)+scale*index[1]) = v[1]; + if (likely(mask[2])) *(int*)(((char*)ptr)+scale*index[2]) = v[2]; + if (likely(mask[3])) *(int*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) static __forceinline vint4 broadcast64(long long a) { return _mm_set1_epi64x(a); } #endif @@ -248,12 +236,10 @@ namespace embree friend __forceinline vint4 select(const vboolf4& m, const vint4& t, const vint4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_epi32(m, (__m128i)f, (__m128i)t); -#elif defined(__aarch64__) - return _mm_castps_si128(_mm_blendv_ps((__m128)f.v,(__m128) t.v, (__m128)m.v)); #elif defined(__SSE4_1__) - return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); + return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); #else - return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f)); + return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f)); #endif } }; @@ -270,9 +256,7 @@ namespace embree __forceinline vint4 operator +(const vint4& a) { return a; } __forceinline vint4 operator -(const vint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); } -#if defined(__aarch64__) - __forceinline vint4 abs(const vint4& a) { return vabsq_s32(a.v); } -#elif defined(__SSSE3__) +#if defined(__SSSE3__) __forceinline vint4 abs(const vint4& a) { return _mm_abs_epi32(a); } #endif @@ -288,7 +272,7 @@ namespace embree __forceinline vint4 operator -(const vint4& a, int b) { return a - vint4(b); } __forceinline vint4 operator -(int a, const vint4& b) { return vint4(a) - b; } -#if (defined(__aarch64__)) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline vint4 operator *(const vint4& a, const vint4& b) { return _mm_mullo_epi32(a, b); } #else __forceinline vint4 operator *(const vint4& a, const vint4& b) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); } @@ -308,34 +292,34 @@ namespace embree __forceinline vint4 operator ^(const vint4& a, int b) { return a ^ vint4(b); } __forceinline vint4 operator ^(int a, const vint4& b) { return vint4(a) ^ b; } - __forceinline vint4 operator <<(const vint4& a, const int n) { return _mm_slli_epi32(a, n); } - __forceinline vint4 operator >>(const vint4& a, const int n) { return _mm_srai_epi32(a, n); } + __forceinline vint4 operator <<(const vint4& a, int n) { return _mm_slli_epi32(a, n); } + __forceinline vint4 operator >>(const vint4& a, int n) { return _mm_srai_epi32(a, n); } __forceinline vint4 sll (const vint4& a, int b) { return _mm_slli_epi32(a, b); } __forceinline vint4 sra (const vint4& a, int b) { return _mm_srai_epi32(a, b); } __forceinline vint4 srl (const vint4& a, int b) { return _mm_srli_epi32(a, b); } - + //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vint4& operator +=(vint4& a, const vint4& b) { return a = a + b; } __forceinline vint4& operator +=(vint4& a, int b) { return a = a + b; } - + __forceinline vint4& operator -=(vint4& a, const vint4& b) { return a = a - b; } __forceinline vint4& operator -=(vint4& a, int b) { return a = a - b; } -#if (defined(__aarch64__)) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline vint4& operator *=(vint4& a, const vint4& b) { return a = a * b; } __forceinline vint4& operator *=(vint4& a, int b) { return a = a * b; } #endif - + __forceinline vint4& operator &=(vint4& a, const vint4& b) { return a = a & b; } __forceinline vint4& operator &=(vint4& a, int b) { return a = a & b; } - + __forceinline vint4& operator |=(vint4& a, const vint4& b) { return a = a | b; } __forceinline vint4& operator |=(vint4& a, int b) { return a = a | b; } - + __forceinline vint4& operator <<=(vint4& a, int b) { return a = a << b; } __forceinline vint4& operator >>=(vint4& a, int b) { return a = a >> b; } @@ -402,15 +386,14 @@ namespace embree template<int mask> __forceinline vint4 select(const vint4& t, const vint4& f) { -#if defined(__SSE4_1__) +#if defined(__SSE4_1__) return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask)); #else return select(vboolf4(mask), t, f); -#endif +#endif } - -#if defined(__aarch64__) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline vint4 min(const vint4& a, const vint4& b) { return _mm_min_epi32(a, b); } __forceinline vint4 max(const vint4& a, const vint4& b) { return _mm_max_epi32(a, b); } @@ -434,25 +417,16 @@ namespace embree __forceinline vint4 unpacklo(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } __forceinline vint4 unpackhi(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } -#if defined(__aarch64__) - template<int i0, int i1, int i2, int i3> - __forceinline vint4 shuffle(const vint4& v) { - return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); - } - template<int i0, int i1, int i2, int i3> - __forceinline vint4 shuffle(const vint4& a, const vint4& b) { - return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); - } -#else template<int i0, int i1, int i2, int i3> __forceinline vint4 shuffle(const vint4& v) { return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0)); } + template<int i0, int i1, int i2, int i3> __forceinline vint4 shuffle(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); } -#endif + #if defined(__SSE3__) template<> __forceinline vint4 shuffle<0, 0, 2, 2>(const vint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vint4 shuffle<1, 1, 3, 3>(const vint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); } @@ -464,10 +438,7 @@ namespace embree return shuffle<i,i,i,i>(v); } -#if defined(__aarch64__) - template<int src> __forceinline int extract(const vint4& b); - template<int dst> __forceinline vint4 insert(const vint4& a, const int b); -#elif defined(__SSE4_1__) +#if defined(__SSE4_1__) template<int src> __forceinline int extract(const vint4& b) { return _mm_extract_epi32(b, src); } template<int dst> __forceinline vint4 insert(const vint4& a, const int b) { return _mm_insert_epi32(a, b, dst); } #else @@ -475,69 +446,19 @@ namespace embree template<int dst> __forceinline vint4 insert(const vint4& a, int b) { vint4 c = a; c[dst&3] = b; return c; } #endif -#if defined(__aarch64__) - template<> __forceinline int extract<0>(const vint4& b) { - return b.v[0]; - } - template<> __forceinline int extract<1>(const vint4& b) { - return b.v[1]; - } - template<> __forceinline int extract<2>(const vint4& b) { - return b.v[2]; - } - template<> __forceinline int extract<3>(const vint4& b) { - return b.v[3]; - } - template<> __forceinline vint4 insert<0>(const vint4& a, int b) - { - vint4 c = a; - c[0] = b; - return c; - } - template<> __forceinline vint4 insert<1>(const vint4& a, int b) - { - vint4 c = a; - c[1] = b; - return c; - } - template<> __forceinline vint4 insert<2>(const vint4& a, int b) - { - vint4 c = a; - c[2] = b; - return c; - } - template<> __forceinline vint4 insert<3>(const vint4& a, int b) - { - vint4 c = a; - c[3] = b; - return c; - } - - __forceinline int toScalar(const vint4& v) { - return v[0]; - } - - __forceinline size_t toSizeT(const vint4& v) { - uint64x2_t x = uint64x2_t(v.v); - return x[0]; - } -#else + template<> __forceinline int extract<0>(const vint4& b) { return _mm_cvtsi128_si32(b); } __forceinline int toScalar(const vint4& v) { return _mm_cvtsi128_si32(v); } - __forceinline size_t toSizeT(const vint4& v) { + __forceinline size_t toSizeT(const vint4& v) { #if defined(__WIN32__) && !defined(__X86_64__) // win32 workaround return toScalar(v); -#elif defined(__ARM_NEON) - // FIXME(LTE): Do we need a swap(i.e. use lane 1)? - return vgetq_lane_u64(*(reinterpret_cast<const uint64x2_t *>(&v)), 0); #else - return _mm_cvtsi128_si64(v); + return _mm_cvtsi128_si64(v); #endif } -#endif - + #if defined(__AVX512VL__) __forceinline vint4 permute(const vint4 &a, const vint4 &index) { @@ -546,25 +467,15 @@ namespace embree template<int i> __forceinline vint4 align_shift_right(const vint4& a, const vint4& b) { - return _mm_alignr_epi32(a, b, i); - } + return _mm_alignr_epi32(a, b, i); + } #endif //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// -#if defined(__aarch64__) || defined(__SSE4_1__) - -#if defined(__aarch64__) - __forceinline vint4 vreduce_min(const vint4& v) { int h = vminvq_s32(v); return vdupq_n_s32(h); } - __forceinline vint4 vreduce_max(const vint4& v) { int h = vmaxvq_s32(v); return vdupq_n_s32(h); } - __forceinline vint4 vreduce_add(const vint4& v) { int h = vaddvq_s32(v); return vdupq_n_s32(h); } - - __forceinline int reduce_min(const vint4& v) { return vminvq_s32(v); } - __forceinline int reduce_max(const vint4& v) { return vmaxvq_s32(v); } - __forceinline int reduce_add(const vint4& v) { return vaddvq_s32(v); } -#else +#if defined(__SSE4_1__) __forceinline vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } @@ -572,8 +483,7 @@ namespace embree __forceinline int reduce_min(const vint4& v) { return toScalar(vreduce_min(v)); } __forceinline int reduce_max(const vint4& v) { return toScalar(vreduce_max(v)); } __forceinline int reduce_add(const vint4& v) { return toScalar(vreduce_add(v)); } -#endif - + __forceinline size_t select_min(const vint4& v) { return bsf(movemask(v == vreduce_min(v))); } __forceinline size_t select_max(const vint4& v) { return bsf(movemask(v == vreduce_max(v))); } @@ -592,7 +502,7 @@ namespace embree /// Sorting networks //////////////////////////////////////////////////////////////////////////////// -#if (defined(__aarch64__)) || defined(__SSE4_1__) +#if defined(__SSE4_1__) __forceinline vint4 usort_ascending(const vint4& v) { @@ -679,3 +589,10 @@ namespace embree } } +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vint8_avx.h b/thirdparty/embree/common/simd/vint8_avx.h index 25a771284d..f43e9a8c22 100644 --- a/thirdparty/embree-aarch64/common/simd/vint8_avx.h +++ b/thirdparty/embree/common/simd/vint8_avx.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX integer type */ @@ -71,25 +79,20 @@ namespace embree static __forceinline void store (void* ptr, const vint8& f) { _mm256_store_ps((float*)ptr,_mm256_castsi256_ps(f)); } static __forceinline void storeu(void* ptr, const vint8& f) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(f)); } -#if !defined(__aarch64__) static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } -#else - static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask.v,_mm256_castsi256_ps(f)); } - static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask.v,_mm256_castsi256_ps(f)); } -#endif static __forceinline void store_nt(void* ptr, const vint8& v) { _mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v)); } - static __forceinline vint8 load(const uint8_t* ptr) { + static __forceinline vint8 load(const unsigned char* ptr) { vint4 il = vint4::load(ptr+0); vint4 ih = vint4::load(ptr+4); return vint8(il,ih); } - static __forceinline vint8 loadu(const uint8_t* ptr) { + static __forceinline vint8 loadu(const unsigned char* ptr) { vint4 il = vint4::loadu(ptr+0); vint4 ih = vint4::loadu(ptr+4); return vint8(il,ih); @@ -107,7 +110,7 @@ namespace embree return vint8(il,ih); } - static __forceinline void store(uint8_t* ptr, const vint8& i) { + static __forceinline void store(unsigned char* ptr, const vint8& i) { vint4 il(i.vl); vint4 ih(i.vh); vint4::store(ptr + 0,il); @@ -122,54 +125,54 @@ namespace embree template<int scale = 4> static __forceinline vint8 gather(const int* ptr, const vint8& index) { return vint8( - *(int*)(((int8_t*)ptr)+scale*index[0]), - *(int*)(((int8_t*)ptr)+scale*index[1]), - *(int*)(((int8_t*)ptr)+scale*index[2]), - *(int*)(((int8_t*)ptr)+scale*index[3]), - *(int*)(((int8_t*)ptr)+scale*index[4]), - *(int*)(((int8_t*)ptr)+scale*index[5]), - *(int*)(((int8_t*)ptr)+scale*index[6]), - *(int*)(((int8_t*)ptr)+scale*index[7])); + *(int*)(((char*)ptr)+scale*index[0]), + *(int*)(((char*)ptr)+scale*index[1]), + *(int*)(((char*)ptr)+scale*index[2]), + *(int*)(((char*)ptr)+scale*index[3]), + *(int*)(((char*)ptr)+scale*index[4]), + *(int*)(((char*)ptr)+scale*index[5]), + *(int*)(((char*)ptr)+scale*index[6]), + *(int*)(((char*)ptr)+scale*index[7])); } template<int scale = 4> static __forceinline vint8 gather(const vboolf8& mask, const int* ptr, const vint8& index) { vint8 r = zero; - if (likely(mask[0])) r[0] = *(int*)(((int8_t*)ptr)+scale*index[0]); - if (likely(mask[1])) r[1] = *(int*)(((int8_t*)ptr)+scale*index[1]); - if (likely(mask[2])) r[2] = *(int*)(((int8_t*)ptr)+scale*index[2]); - if (likely(mask[3])) r[3] = *(int*)(((int8_t*)ptr)+scale*index[3]); - if (likely(mask[4])) r[4] = *(int*)(((int8_t*)ptr)+scale*index[4]); - if (likely(mask[5])) r[5] = *(int*)(((int8_t*)ptr)+scale*index[5]); - if (likely(mask[6])) r[6] = *(int*)(((int8_t*)ptr)+scale*index[6]); - if (likely(mask[7])) r[7] = *(int*)(((int8_t*)ptr)+scale*index[7]); + if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]); + if (likely(mask[1])) r[1] = *(int*)(((char*)ptr)+scale*index[1]); + if (likely(mask[2])) r[2] = *(int*)(((char*)ptr)+scale*index[2]); + if (likely(mask[3])) r[3] = *(int*)(((char*)ptr)+scale*index[3]); + if (likely(mask[4])) r[4] = *(int*)(((char*)ptr)+scale*index[4]); + if (likely(mask[5])) r[5] = *(int*)(((char*)ptr)+scale*index[5]); + if (likely(mask[6])) r[6] = *(int*)(((char*)ptr)+scale*index[6]); + if (likely(mask[7])) r[7] = *(int*)(((char*)ptr)+scale*index[7]); return r; } template<int scale = 4> static __forceinline void scatter(void* ptr, const vint8& ofs, const vint8& v) { - *(int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - *(int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - *(int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - *(int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - *(int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - *(int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - *(int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - *(int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + *(int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + *(int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + *(int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + *(int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + *(int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + *(int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + *(int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + *(int*)(((char*)ptr)+scale*ofs[7]) = v[7]; } template<int scale = 4> static __forceinline void scatter(const vboolf8& mask, void* ptr, const vint8& ofs, const vint8& v) { - if (likely(mask[0])) *(int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - if (likely(mask[1])) *(int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - if (likely(mask[2])) *(int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - if (likely(mask[3])) *(int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - if (likely(mask[4])) *(int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - if (likely(mask[5])) *(int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - if (likely(mask[6])) *(int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - if (likely(mask[7])) *(int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + if (likely(mask[0])) *(int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + if (likely(mask[1])) *(int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + if (likely(mask[2])) *(int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + if (likely(mask[3])) *(int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + if (likely(mask[4])) *(int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + if (likely(mask[5])) *(int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + if (likely(mask[6])) *(int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + if (likely(mask[7])) *(int*)(((char*)ptr)+scale*ofs[7]) = v[7]; } @@ -315,11 +318,6 @@ namespace embree return _mm256_castps_si256(_mm256_blendv_ps(_mm256_castsi256_ps(f), _mm256_castsi256_ps(t), m)); } - __forceinline vint8 notand(const vboolf8& m, const vint8& f) { - return _mm256_castps_si256(_mm256_andnot_ps(m, _mm256_castsi256_ps(f))); - } - - //////////////////////////////////////////////////////////////////////////////// /// Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -462,3 +460,11 @@ namespace embree return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vint8_avx2.h b/thirdparty/embree/common/simd/vint8_avx2.h index 4937d972cf..e04737ffbe 100644 --- a/thirdparty/embree-aarch64/common/simd/vint8_avx2.h +++ b/thirdparty/embree/common/simd/vint8_avx2.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX integer type */ @@ -67,8 +75,8 @@ namespace embree /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// - static __forceinline vint8 load(const uint8_t* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } - static __forceinline vint8 loadu(const uint8_t* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } + static __forceinline vint8 load(const unsigned char* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } + static __forceinline vint8 loadu(const unsigned char* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } static __forceinline vint8 load(const unsigned short* ptr) { return _mm256_cvtepu16_epi32(_mm_load_si128((__m128i*)ptr)); } static __forceinline vint8 loadu(const unsigned short* ptr) { return _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); } @@ -108,7 +116,7 @@ namespace embree _mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v)); } - static __forceinline void store(uint8_t* ptr, const vint8& i) + static __forceinline void store(unsigned char* ptr, const vint8& i) { for (size_t j=0; j<8; j++) ptr[j] = i[j]; @@ -140,14 +148,14 @@ namespace embree #if defined(__AVX512VL__) _mm256_i32scatter_epi32((int*)ptr, ofs, v, scale); #else - *(int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - *(int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - *(int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - *(int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - *(int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - *(int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - *(int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - *(int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + *(int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + *(int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + *(int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + *(int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + *(int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + *(int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + *(int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + *(int*)(((char*)ptr)+scale*ofs[7]) = v[7]; #endif } @@ -157,14 +165,14 @@ namespace embree #if defined(__AVX512VL__) _mm256_mask_i32scatter_epi32((int*)ptr, mask, ofs, v, scale); #else - if (likely(mask[0])) *(int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - if (likely(mask[1])) *(int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - if (likely(mask[2])) *(int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - if (likely(mask[3])) *(int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - if (likely(mask[4])) *(int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - if (likely(mask[5])) *(int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - if (likely(mask[6])) *(int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - if (likely(mask[7])) *(int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + if (likely(mask[0])) *(int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + if (likely(mask[1])) *(int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + if (likely(mask[2])) *(int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + if (likely(mask[3])) *(int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + if (likely(mask[4])) *(int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + if (likely(mask[5])) *(int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + if (likely(mask[6])) *(int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + if (likely(mask[7])) *(int*)(((char*)ptr)+scale*ofs[7]) = v[7]; #endif } @@ -385,9 +393,7 @@ namespace embree __forceinline int toScalar(const vint8& v) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(v)); } -#if !defined(__aarch64__) - -__forceinline vint8 permute(const vint8& v, const __m256i& index) { + __forceinline vint8 permute(const vint8& v, const __m256i& index) { return _mm256_permutevar8x32_epi32(v, index); } @@ -395,8 +401,6 @@ __forceinline vint8 permute(const vint8& v, const __m256i& index) { return _mm256_castps_si256(_mm256_permutevar_ps(_mm256_castsi256_ps(v), index)); } - - template<int i> static __forceinline vint8 align_shift_right(const vint8& a, const vint8& b) { #if defined(__AVX512VL__) @@ -406,9 +410,6 @@ __forceinline vint8 permute(const vint8& v, const __m256i& index) { #endif } -#endif - - //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// @@ -435,9 +436,6 @@ __forceinline vint8 permute(const vint8& v, const __m256i& index) { __forceinline size_t select_min(const vboolf8& valid, const vint8& v) { const vint8 a = select(valid,v,vint8(pos_inf)); return bsf(movemask(valid & (a == vreduce_min(a)))); } __forceinline size_t select_max(const vboolf8& valid, const vint8& v) { const vint8 a = select(valid,v,vint8(neg_inf)); return bsf(movemask(valid & (a == vreduce_max(a)))); } - - __forceinline vint8 assign(const vint4& a) { return _mm256_castsi128_si256(a); } - //////////////////////////////////////////////////////////////////////////////// /// Sorting networks //////////////////////////////////////////////////////////////////////////////// @@ -510,3 +508,11 @@ __forceinline vint8 permute(const vint8& v, const __m256i& index) { return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vllong4_avx2.h b/thirdparty/embree/common/simd/vllong4_avx2.h index de3ebc16a7..6c86845877 100644 --- a/thirdparty/embree-aarch64/common/simd/vllong4_avx2.h +++ b/thirdparty/embree/common/simd/vllong4_avx2.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide AVX2 64-bit long long type */ @@ -95,16 +103,6 @@ namespace embree #endif } - static __forceinline vllong4 broadcast64bit(size_t v) { - return _mm256_set1_epi64x(v); - } - - static __forceinline size_t extract64bit(const vllong4& v) - { - return _mm_cvtsi128_si64(_mm256_castsi256_si128(v)); - } - - //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -276,18 +274,6 @@ namespace embree __forceinline vboold4 le(const vboold4& mask, const vllong4& a, const vllong4& b) { return mask & (a <= b); } #endif - __forceinline void xchg(const vboold4& m, vllong4& a, vllong4& b) { - const vllong4 c = a; a = select(m,b,a); b = select(m,c,b); - } - - __forceinline vboold4 test(const vllong4& a, const vllong4& b) { -#if defined(__AVX512VL__) - return _mm256_test_epi64_mask(a,b); -#else - return _mm256_testz_si256(a,b); -#endif - } - //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -356,3 +342,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vllong8_avx512.h b/thirdparty/embree/common/simd/vllong8_avx512.h index 76dddd8991..ee69411637 100644 --- a/thirdparty/embree-aarch64/common/simd/vllong8_avx512.h +++ b/thirdparty/embree/common/simd/vllong8_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX-512 64-bit long long type */ @@ -78,7 +86,7 @@ namespace embree return _mm512_load_si512(addr); } - static __forceinline vllong8 load(const uint8_t* ptr) { + static __forceinline vllong8 load(const unsigned char* ptr) { return _mm512_cvtepu8_epi64(*(__m128i*)ptr); } @@ -98,19 +106,6 @@ namespace embree _mm512_mask_store_epi64(addr,mask,v2); } - /* pass by value to avoid compiler generating inefficient code */ - static __forceinline void storeu_compact(const vboold8 mask, void* addr, const vllong8& reg) { - _mm512_mask_compressstoreu_epi64(addr,mask,reg); - } - - static __forceinline vllong8 compact64bit(const vboold8& mask, vllong8& v) { - return _mm512_mask_compress_epi64(v,mask,v); - } - - static __forceinline vllong8 compact64bit(const vboold8& mask, vllong8& dest, const vllong8& source) { - return _mm512_mask_compress_epi64(dest,mask,source); - } - static __forceinline vllong8 compact(const vboold8& mask, vllong8& v) { return _mm512_mask_compress_epi64(v,mask,v); } @@ -123,16 +118,6 @@ namespace embree return _mm512_mask_expand_epi64(b,mask,a); } - static __forceinline vllong8 broadcast64bit(size_t v) { - return _mm512_set1_epi64(v); - } - - static __forceinline size_t extract64bit(const vllong8& v) - { - return _mm_cvtsi128_si64(_mm512_castsi512_si128(v)); - } - - //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -271,18 +256,6 @@ namespace embree return _mm512_mask_or_epi64(f,m,t,t); } - __forceinline void xchg(const vboold8& m, vllong8& a, vllong8& b) { - const vllong8 c = a; a = select(m,b,a); b = select(m,c,b); - } - - __forceinline vboold8 test(const vboold8& m, const vllong8& a, const vllong8& b) { - return _mm512_mask_test_epi64_mask(m,a,b); - } - - __forceinline vboold8 test(const vllong8& a, const vllong8& b) { - return _mm512_test_epi64_mask(a,b); - } - //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -321,10 +294,6 @@ namespace embree return _mm_cvtsi128_si64(_mm512_castsi512_si128(v)); } - __forceinline vllong8 zeroExtend32Bit(const __m512i& a) { - return _mm512_cvtepu32_epi64(_mm512_castsi512_si256(a)); - } - //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// @@ -379,3 +348,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vuint16_avx512.h b/thirdparty/embree/common/simd/vuint16_avx512.h index 39752611bb..c9eb6682ff 100644 --- a/thirdparty/embree-aarch64/common/simd/vuint16_avx512.h +++ b/thirdparty/embree/common/simd/vuint16_avx512.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 16-wide AVX-512 unsigned integer type */ @@ -83,7 +91,7 @@ namespace embree return _mm512_loadu_si512(addr); } - static __forceinline vuint16 loadu(const uint8_t* ptr) { return _mm512_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)); } + static __forceinline vuint16 loadu(const unsigned char* ptr) { return _mm512_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)); } static __forceinline vuint16 loadu(const unsigned short* ptr) { return _mm512_cvtepu16_epi32(_mm256_loadu_si256((__m256i*)ptr)); } static __forceinline vuint16 load(const vuint16* addr) { @@ -113,20 +121,6 @@ namespace embree _mm512_mask_store_epi32(addr,mask,v2); } - /* pass by value to avoid compiler generating inefficient code */ - static __forceinline void storeu_compact(const vboolf16 mask, void* addr, const vuint16 reg) { - _mm512_mask_compressstoreu_epi32(addr,mask,reg); - } - - static __forceinline void storeu_compact_single(const vboolf16 mask, void* addr, vuint16 reg) { - //_mm512_mask_compressstoreu_epi32(addr,mask,reg); - *(float*)addr = mm512_cvtss_f32(_mm512_mask_compress_ps(_mm512_castsi512_ps(reg),mask,_mm512_castsi512_ps(reg))); - } - - static __forceinline vuint16 compact64bit(const vboolf16& mask, vuint16& v) { - return _mm512_mask_compress_epi64(v,mask,v); - } - static __forceinline vuint16 compact(const vboolf16& mask, vuint16& v) { return _mm512_mask_compress_epi32(v,mask,v); } @@ -164,15 +158,6 @@ namespace embree _mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale); } - static __forceinline vuint16 broadcast64bit(size_t v) { - return _mm512_set1_epi64(v); - } - - static __forceinline size_t extract64bit(const vuint16& v) - { - return _mm_cvtsi128_si64(_mm512_castsi512_si128(v)); - } - //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// @@ -315,18 +300,6 @@ namespace embree return _mm512_mask_or_epi32(f,m,t,t); } - __forceinline void xchg(const vboolf16& m, vuint16& a, vuint16& b) { - const vuint16 c = a; a = select(m,b,a); b = select(m,c,b); - } - - __forceinline vboolf16 test(const vboolf16& m, const vuint16& a, const vuint16& b) { - return _mm512_mask_test_epi32_mask(m,a,b); - } - - __forceinline vboolf16 test(const vuint16& a, const vuint16& b) { - return _mm512_test_epi32_mask(a,b); - } - //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// @@ -441,3 +414,11 @@ namespace embree return cout; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vuint4_sse2.h b/thirdparty/embree/common/simd/vuint4_sse2.h index a3f393ebf2..0601b9ab80 100644 --- a/thirdparty/embree-aarch64/common/simd/vuint4_sse2.h +++ b/thirdparty/embree/common/simd/vuint4_sse2.h @@ -1,10 +1,18 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../math/math.h" +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 4-wide SSE integer type */ @@ -87,64 +95,27 @@ namespace embree static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); } #endif -#if defined(__aarch64__) - static __forceinline vuint4 load(const uint8_t* ptr) { - return _mm_load4epu8_epi32(((__m128i*)ptr)); - } - static __forceinline vuint4 loadu(const uint8_t* ptr) { - return _mm_load4epu8_epi32(((__m128i*)ptr)); - } -#elif defined(__SSE4_1__) - static __forceinline vuint4 load(const uint8_t* ptr) { +#if defined(__SSE4_1__) + static __forceinline vuint4 load(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } - static __forceinline vuint4 loadu(const uint8_t* ptr) { + static __forceinline vuint4 loadu(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } #endif static __forceinline vuint4 load(const unsigned short* ptr) { -#if defined(__aarch64__) - return _mm_load4epu16_epi32(((__m128i*)ptr)); -#elif defined (__SSE4_1__) +#if defined (__SSE4_1__) return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); #else return vuint4(ptr[0],ptr[1],ptr[2],ptr[3]); #endif } - static __forceinline void store_uint8(uint8_t* ptr, const vuint4& v) { -#if defined(__aarch64__) - uint32x4_t x = uint32x4_t(v.v); - uint16x4_t y = vqmovn_u32(x); - uint8x8_t z = vqmovn_u16(vcombine_u16(y, y)); - vst1_lane_u32((uint32_t *)ptr, uint32x2_t(z), 0); -#elif defined(__SSE4_1__) - __m128i x = v; - x = _mm_packus_epi32(x, x); - x = _mm_packus_epi16(x, x); - *(unsigned*)ptr = _mm_cvtsi128_si32(x); -#else - for (size_t i=0;i<4;i++) - ptr[i] = (uint8_t)v[i]; -#endif - } - - static __forceinline void store_uint8(unsigned short* ptr, const vuint4& v) { -#if defined(__aarch64__) - uint32x4_t x = (uint32x4_t)v.v; - uint16x4_t y = vqmovn_u32(x); - vst1_u16(ptr, y); -#else - for (size_t i=0;i<4;i++) - ptr[i] = (unsigned short)v[i]; -#endif - } - static __forceinline vuint4 load_nt(void* ptr) { -#if (defined(__aarch64__)) || defined(__SSE4_1__) +#if defined(__SSE4_1__) return _mm_stream_load_si128((__m128i*)ptr); #else return _mm_load_si128((__m128i*)ptr); @@ -152,8 +123,8 @@ namespace embree } static __forceinline void store_nt(void* ptr, const vuint4& v) { -#if !defined(__aarch64__) && defined(__SSE4_1__) - _mm_stream_ps((float*)ptr, _mm_castsi128_ps(v)); +#if defined(__SSE4_1__) + _mm_stream_ps((float*)ptr,_mm_castsi128_ps(v)); #else _mm_store_si128((__m128i*)ptr,v); #endif @@ -161,14 +132,14 @@ namespace embree template<int scale = 4> static __forceinline vuint4 gather(const unsigned int* ptr, const vint4& index) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _mm_i32gather_epi32((const int*)ptr, index, scale); #else return vuint4( - *(unsigned int*)(((int8_t*)ptr)+scale*index[0]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[1]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[2]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[3])); + *(unsigned int*)(((char*)ptr)+scale*index[0]), + *(unsigned int*)(((char*)ptr)+scale*index[1]), + *(unsigned int*)(((char*)ptr)+scale*index[2]), + *(unsigned int*)(((char*)ptr)+scale*index[3])); #endif } @@ -177,13 +148,13 @@ namespace embree vuint4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale); -#elif defined(__AVX2__) && !defined(__aarch64__) +#elif defined(__AVX2__) return _mm_mask_i32gather_epi32(r, (const int*)ptr, index, mask, scale); #else - if (likely(mask[0])) r[0] = *(unsigned int*)(((int8_t*)ptr)+scale*index[0]); - if (likely(mask[1])) r[1] = *(unsigned int*)(((int8_t*)ptr)+scale*index[1]); - if (likely(mask[2])) r[2] = *(unsigned int*)(((int8_t*)ptr)+scale*index[2]); - if (likely(mask[3])) r[3] = *(unsigned int*)(((int8_t*)ptr)+scale*index[3]); + if (likely(mask[0])) r[0] = *(unsigned int*)(((char*)ptr)+scale*index[0]); + if (likely(mask[1])) r[1] = *(unsigned int*)(((char*)ptr)+scale*index[1]); + if (likely(mask[2])) r[2] = *(unsigned int*)(((char*)ptr)+scale*index[2]); + if (likely(mask[3])) r[3] = *(unsigned int*)(((char*)ptr)+scale*index[3]); return r; #endif } @@ -373,25 +344,16 @@ namespace embree __forceinline vuint4 unpacklo(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } __forceinline vuint4 unpackhi(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } -#if defined(__aarch64__) - template<int i0, int i1, int i2, int i3> - __forceinline vuint4 shuffle(const vuint4& v) { - return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); - } - template<int i0, int i1, int i2, int i3> - __forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { - return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); - } -#else template<int i0, int i1, int i2, int i3> __forceinline vuint4 shuffle(const vuint4& v) { return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0)); } + template<int i0, int i1, int i2, int i3> __forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); } -#endif + #if defined(__SSE3__) template<> __forceinline vuint4 shuffle<0, 0, 2, 2>(const vuint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vuint4 shuffle<1, 1, 3, 3>(const vuint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); } @@ -403,10 +365,7 @@ namespace embree return shuffle<i,i,i,i>(v); } -#if defined(__aarch64__) - template<int src> __forceinline unsigned int extract(const vuint4& b); - template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b); -#elif defined(__SSE4_1__) +#if defined(__SSE4_1__) template<int src> __forceinline unsigned int extract(const vuint4& b) { return _mm_extract_epi32(b, src); } template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { return _mm_insert_epi32(a, b, dst); } #else @@ -414,50 +373,11 @@ namespace embree template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { vuint4 c = a; c[dst&3] = b; return c; } #endif -#if defined(__aarch64__) - template<> __forceinline unsigned int extract<0>(const vuint4& b) { - return b[0]; - } - template<> __forceinline unsigned int extract<1>(const vuint4& b) { - return b[1]; - } - template<> __forceinline unsigned int extract<2>(const vuint4& b) { - return b[2]; - } - template<> __forceinline unsigned int extract<3>(const vuint4& b) { - return b[3]; - } - - template<> __forceinline vuint4 insert<0>(const vuint4& a, unsigned b){ - vuint4 c = a; - c[0] = b; - return c; - } - template<> __forceinline vuint4 insert<1>(const vuint4& a, unsigned b){ - vuint4 c = a; - c[1] = b; - return c; - } - template<> __forceinline vuint4 insert<2>(const vuint4& a, unsigned b){ - vuint4 c = a; - c[2] = b; - return c; - } - template<> __forceinline vuint4 insert<3>(const vuint4& a, unsigned b){ - vuint4 c = a; - c[3] = b; - return c; - } - - __forceinline unsigned int toScalar(const vuint4& v) { - return v[0]; - } -#else + template<> __forceinline unsigned int extract<0>(const vuint4& b) { return _mm_cvtsi128_si32(b); } __forceinline unsigned int toScalar(const vuint4& v) { return _mm_cvtsi128_si32(v); } -#endif - + //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// @@ -497,3 +417,10 @@ namespace embree } } +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vuint8_avx.h b/thirdparty/embree/common/simd/vuint8_avx.h index d4e86ae92d..589cd9d731 100644 --- a/thirdparty/embree-aarch64/common/simd/vuint8_avx.h +++ b/thirdparty/embree/common/simd/vuint8_avx.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX integer type */ @@ -69,24 +77,20 @@ namespace embree static __forceinline void store (void* ptr, const vuint8& f) { _mm256_store_ps((float*)ptr,_mm256_castsi256_ps(f)); } static __forceinline void storeu(void* ptr, const vuint8& f) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(f)); } -#if !defined(__aarch64__) static __forceinline void store (const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } static __forceinline void storeu(const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); } -#else - static __forceinline void store (const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask.v,_mm256_castsi256_ps(f)); } - static __forceinline void storeu(const vboolf8& mask, void* ptr, const vuint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask.v,_mm256_castsi256_ps(f)); } -#endif + static __forceinline void store_nt(void* ptr, const vuint8& v) { _mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v)); } - static __forceinline vuint8 load(const uint8_t* ptr) { + static __forceinline vuint8 load(const unsigned char* ptr) { vuint4 il = vuint4::load(ptr+0); vuint4 ih = vuint4::load(ptr+4); return vuint8(il,ih); } - static __forceinline vuint8 loadu(const uint8_t* ptr) { + static __forceinline vuint8 loadu(const unsigned char* ptr) { vuint4 il = vuint4::loadu(ptr+0); vuint4 ih = vuint4::loadu(ptr+4); return vuint8(il,ih); @@ -104,7 +108,7 @@ namespace embree return vuint8(il,ih); } - static __forceinline void store(uint8_t* ptr, const vuint8& i) { + static __forceinline void store(unsigned char* ptr, const vuint8& i) { vuint4 il(i.vl); vuint4 ih(i.vh); vuint4::store(ptr + 0,il); @@ -119,54 +123,54 @@ namespace embree template<int scale = 4> static __forceinline vuint8 gather(const unsigned int* ptr, const vint8& index) { return vuint8( - *(unsigned int*)(((int8_t*)ptr)+scale*index[0]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[1]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[2]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[3]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[4]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[5]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[6]), - *(unsigned int*)(((int8_t*)ptr)+scale*index[7])); + *(unsigned int*)(((char*)ptr)+scale*index[0]), + *(unsigned int*)(((char*)ptr)+scale*index[1]), + *(unsigned int*)(((char*)ptr)+scale*index[2]), + *(unsigned int*)(((char*)ptr)+scale*index[3]), + *(unsigned int*)(((char*)ptr)+scale*index[4]), + *(unsigned int*)(((char*)ptr)+scale*index[5]), + *(unsigned int*)(((char*)ptr)+scale*index[6]), + *(unsigned int*)(((char*)ptr)+scale*index[7])); } template<int scale = 4> static __forceinline vuint8 gather(const vboolf8& mask, const unsigned int* ptr, const vint8& index) { vuint8 r = zero; - if (likely(mask[0])) r[0] = *(unsigned int*)(((int8_t*)ptr)+scale*index[0]); - if (likely(mask[1])) r[1] = *(unsigned int*)(((int8_t*)ptr)+scale*index[1]); - if (likely(mask[2])) r[2] = *(unsigned int*)(((int8_t*)ptr)+scale*index[2]); - if (likely(mask[3])) r[3] = *(unsigned int*)(((int8_t*)ptr)+scale*index[3]); - if (likely(mask[4])) r[4] = *(unsigned int*)(((int8_t*)ptr)+scale*index[4]); - if (likely(mask[5])) r[5] = *(unsigned int*)(((int8_t*)ptr)+scale*index[5]); - if (likely(mask[6])) r[6] = *(unsigned int*)(((int8_t*)ptr)+scale*index[6]); - if (likely(mask[7])) r[7] = *(unsigned int*)(((int8_t*)ptr)+scale*index[7]); + if (likely(mask[0])) r[0] = *(unsigned int*)(((char*)ptr)+scale*index[0]); + if (likely(mask[1])) r[1] = *(unsigned int*)(((char*)ptr)+scale*index[1]); + if (likely(mask[2])) r[2] = *(unsigned int*)(((char*)ptr)+scale*index[2]); + if (likely(mask[3])) r[3] = *(unsigned int*)(((char*)ptr)+scale*index[3]); + if (likely(mask[4])) r[4] = *(unsigned int*)(((char*)ptr)+scale*index[4]); + if (likely(mask[5])) r[5] = *(unsigned int*)(((char*)ptr)+scale*index[5]); + if (likely(mask[6])) r[6] = *(unsigned int*)(((char*)ptr)+scale*index[6]); + if (likely(mask[7])) r[7] = *(unsigned int*)(((char*)ptr)+scale*index[7]); return r; } template<int scale = 4> static __forceinline void scatter(void* ptr, const vint8& ofs, const vuint8& v) { - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - *(unsigned int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + *(unsigned int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + *(unsigned int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + *(unsigned int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + *(unsigned int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + *(unsigned int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + *(unsigned int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + *(unsigned int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + *(unsigned int*)(((char*)ptr)+scale*ofs[7]) = v[7]; } template<int scale = 4> static __forceinline void scatter(const vboolf8& mask, void* ptr, const vint8& ofs, const vuint8& v) { - if (likely(mask[0])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - if (likely(mask[1])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - if (likely(mask[2])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - if (likely(mask[3])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - if (likely(mask[4])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - if (likely(mask[5])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - if (likely(mask[6])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - if (likely(mask[7])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + if (likely(mask[0])) *(unsigned int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + if (likely(mask[1])) *(unsigned int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + if (likely(mask[2])) *(unsigned int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + if (likely(mask[3])) *(unsigned int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + if (likely(mask[4])) *(unsigned int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + if (likely(mask[5])) *(unsigned int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + if (likely(mask[6])) *(unsigned int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + if (likely(mask[7])) *(unsigned int*)(((char*)ptr)+scale*ofs[7]) = v[7]; } @@ -294,10 +298,6 @@ namespace embree return _mm256_castps_si256(_mm256_blendv_ps(_mm256_castsi256_ps(f), _mm256_castsi256_ps(t), m)); } - __forceinline vuint8 notand(const vboolf8& m, const vuint8& f) { - return _mm256_castps_si256(_mm256_andnot_ps(m, _mm256_castsi256_ps(f))); - } - //////////////////////////////////////////////////////////////////////////////// /// Movement/Shifting/Shuffling Functions @@ -335,7 +335,6 @@ namespace embree template<> __forceinline vuint8 shuffle<1, 1, 3, 3>(const vuint8& v) { return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(v))); } template<> __forceinline vuint8 shuffle<0, 1, 0, 1>(const vuint8& v) { return _mm256_castps_si256(_mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(v))))); } - __forceinline vuint8 broadcast(const unsigned int* ptr) { return _mm256_castps_si256(_mm256_broadcast_ss((const float*)ptr)); } template<int i> __forceinline vuint8 insert4(const vuint8& a, const vuint4& b) { return _mm256_insertf128_si256(a, b, i); } template<int i> __forceinline vuint4 extract4(const vuint8& a) { return _mm256_extractf128_si256(a, i); } template<> __forceinline vuint4 extract4<0>(const vuint8& a) { return _mm256_castsi256_si128(a); } @@ -377,3 +376,11 @@ namespace embree return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/simd/vuint8_avx2.h b/thirdparty/embree/common/simd/vuint8_avx2.h index b2a965448d..17b994522f 100644 --- a/thirdparty/embree-aarch64/common/simd/vuint8_avx2.h +++ b/thirdparty/embree/common/simd/vuint8_avx2.h @@ -1,8 +1,16 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once +#define vboolf vboolf_impl +#define vboold vboold_impl +#define vint vint_impl +#define vuint vuint_impl +#define vllong vllong_impl +#define vfloat vfloat_impl +#define vdouble vdouble_impl + namespace embree { /* 8-wide AVX integer type */ @@ -66,8 +74,8 @@ namespace embree /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// - static __forceinline vuint8 load(const uint8_t* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } - static __forceinline vuint8 loadu(const uint8_t* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } + static __forceinline vuint8 load(const unsigned char* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } + static __forceinline vuint8 loadu(const unsigned char* ptr) { return _mm256_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } static __forceinline vuint8 load(const unsigned short* ptr) { return _mm256_cvtepu16_epi32(_mm_load_si128((__m128i*)ptr)); } static __forceinline vuint8 loadu(const unsigned short* ptr) { return _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); } @@ -107,7 +115,7 @@ namespace embree _mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v)); } - static __forceinline void store(uint8_t* ptr, const vuint8& i) + static __forceinline void store(unsigned char* ptr, const vuint8& i) { for (size_t j=0; j<8; j++) ptr[j] = i[j]; @@ -139,14 +147,14 @@ namespace embree #if defined(__AVX512VL__) _mm256_i32scatter_epi32((int*)ptr, ofs, v, scale); #else - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[0]) = v[0]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[1]) = v[1]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[2]) = v[2]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[3]) = v[3]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[4]) = v[4]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[5]) = v[5]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[6]) = v[6]; - *(unsigned int*)(((int8_t*)ptr) + scale * ofs[7]) = v[7]; + *(unsigned int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + *(unsigned int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + *(unsigned int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + *(unsigned int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + *(unsigned int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + *(unsigned int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + *(unsigned int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + *(unsigned int*)(((char*)ptr)+scale*ofs[7]) = v[7]; #endif } @@ -156,14 +164,14 @@ namespace embree #if defined(__AVX512VL__) _mm256_mask_i32scatter_epi32((int*)ptr, mask, ofs, v, scale); #else - if (likely(mask[0])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[0]) = v[0]; - if (likely(mask[1])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[1]) = v[1]; - if (likely(mask[2])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[2]) = v[2]; - if (likely(mask[3])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[3]) = v[3]; - if (likely(mask[4])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[4]) = v[4]; - if (likely(mask[5])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[5]) = v[5]; - if (likely(mask[6])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[6]) = v[6]; - if (likely(mask[7])) *(unsigned int*)(((int8_t*)ptr)+scale*ofs[7]) = v[7]; + if (likely(mask[0])) *(unsigned int*)(((char*)ptr)+scale*ofs[0]) = v[0]; + if (likely(mask[1])) *(unsigned int*)(((char*)ptr)+scale*ofs[1]) = v[1]; + if (likely(mask[2])) *(unsigned int*)(((char*)ptr)+scale*ofs[2]) = v[2]; + if (likely(mask[3])) *(unsigned int*)(((char*)ptr)+scale*ofs[3]) = v[3]; + if (likely(mask[4])) *(unsigned int*)(((char*)ptr)+scale*ofs[4]) = v[4]; + if (likely(mask[5])) *(unsigned int*)(((char*)ptr)+scale*ofs[5]) = v[5]; + if (likely(mask[6])) *(unsigned int*)(((char*)ptr)+scale*ofs[6]) = v[6]; + if (likely(mask[7])) *(unsigned int*)(((char*)ptr)+scale*ofs[7]) = v[7]; #endif } @@ -371,16 +379,12 @@ namespace embree template<> __forceinline vuint8 shuffle<1, 1, 3, 3>(const vuint8& v) { return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(v))); } template<> __forceinline vuint8 shuffle<0, 1, 0, 1>(const vuint8& v) { return _mm256_castps_si256(_mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(v))))); } - __forceinline vuint8 broadcast(const unsigned int* ptr) { return _mm256_castps_si256(_mm256_broadcast_ss((const float*)ptr)); } - template<int i> __forceinline vuint8 insert4(const vuint8& a, const vuint4& b) { return _mm256_insertf128_si256(a, b, i); } template<int i> __forceinline vuint4 extract4(const vuint8& a) { return _mm256_extractf128_si256(a, i); } template<> __forceinline vuint4 extract4<0>(const vuint8& a) { return _mm256_castsi256_si128(a); } __forceinline int toScalar(const vuint8& v) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(v)); } -#if !defined(__aarch64__) - __forceinline vuint8 permute(const vuint8& v, const __m256i& index) { return _mm256_permutevar8x32_epi32(v, index); } @@ -396,10 +400,7 @@ namespace embree #else return _mm256_alignr_epi8(a, b, 4*i); #endif - } - -#endif - + } //////////////////////////////////////////////////////////////////////////////// /// Reductions @@ -427,8 +428,6 @@ namespace embree //__forceinline size_t select_min(const vboolf8& valid, const vuint8& v) { const vuint8 a = select(valid,v,vuint8(pos_inf)); return bsf(movemask(valid & (a == vreduce_min(a)))); } //__forceinline size_t select_max(const vboolf8& valid, const vuint8& v) { const vuint8 a = select(valid,v,vuint8(neg_inf)); return bsf(movemask(valid & (a == vreduce_max(a)))); } - __forceinline vuint8 assign(const vuint4& a) { return _mm256_castsi128_si256(a); } - //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// @@ -437,3 +436,11 @@ namespace embree return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">"; } } + +#undef vboolf +#undef vboold +#undef vint +#undef vuint +#undef vllong +#undef vfloat +#undef vdouble diff --git a/thirdparty/embree-aarch64/common/sys/alloc.cpp b/thirdparty/embree/common/sys/alloc.cpp index 12f143f131..abdd269069 100644 --- a/thirdparty/embree-aarch64/common/sys/alloc.cpp +++ b/thirdparty/embree/common/sys/alloc.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "alloc.h" @@ -23,7 +23,7 @@ namespace embree if (size != 0 && ptr == nullptr) // -- GODOT start -- // throw std::bad_alloc(); - abort(); + abort(); // -- GODOT end -- return ptr; diff --git a/thirdparty/embree-aarch64/common/sys/alloc.h b/thirdparty/embree/common/sys/alloc.h index 5898ecda70..4fa474ec1d 100644 --- a/thirdparty/embree-aarch64/common/sys/alloc.h +++ b/thirdparty/embree/common/sys/alloc.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/array.h b/thirdparty/embree/common/sys/array.h index 77722a39f6..dd9190c52a 100644 --- a/thirdparty/embree-aarch64/common/sys/array.h +++ b/thirdparty/embree/common/sys/array.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -139,7 +139,7 @@ namespace embree __forceinline Ty& operator[](const unsigned i) { assert(i<N); return data[i]; } __forceinline const Ty& operator[](const unsigned i) const { assert(i<N); return data[i]; } -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) __forceinline Ty& operator[](const size_t i) { assert(i<N); return data[i]; } __forceinline const Ty& operator[](const size_t i) const { assert(i<N); return data[i]; } #endif @@ -196,7 +196,7 @@ namespace embree __forceinline Ty& operator[](const int i) { assert(i>=0 && i<max_total_elements); resize(i+1); return data[i]; } __forceinline Ty& operator[](const unsigned i) { assert(i<max_total_elements); resize(i+1); return data[i]; } -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) __forceinline Ty& operator[](const size_t i) { assert(i<max_total_elements); resize(i+1); return data[i]; } #endif diff --git a/thirdparty/embree-aarch64/common/sys/atomic.h b/thirdparty/embree/common/sys/atomic.h index ebfb8552c3..67af254f36 100644 --- a/thirdparty/embree-aarch64/common/sys/atomic.h +++ b/thirdparty/embree/common/sys/atomic.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/barrier.cpp b/thirdparty/embree/common/sys/barrier.cpp index 0061d18db2..0c0e39d92d 100644 --- a/thirdparty/embree-aarch64/common/sys/barrier.cpp +++ b/thirdparty/embree/common/sys/barrier.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "barrier.h" diff --git a/thirdparty/embree-aarch64/common/sys/barrier.h b/thirdparty/embree/common/sys/barrier.h index 89607b8685..37fc036291 100644 --- a/thirdparty/embree-aarch64/common/sys/barrier.h +++ b/thirdparty/embree/common/sys/barrier.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/condition.cpp b/thirdparty/embree/common/sys/condition.cpp index 0e7ca7af39..606a1d0b04 100644 --- a/thirdparty/embree-aarch64/common/sys/condition.cpp +++ b/thirdparty/embree/common/sys/condition.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "condition.h" @@ -40,19 +40,23 @@ namespace embree struct ConditionImplementation { __forceinline ConditionImplementation () { - pthread_cond_init(&cond,nullptr); + if (pthread_cond_init(&cond,nullptr) != 0) + THROW_RUNTIME_ERROR("pthread_cond_init failed"); } __forceinline ~ConditionImplementation() { - pthread_cond_destroy(&cond); - } + MAYBE_UNUSED bool ok = pthread_cond_destroy(&cond) == 0; + assert(ok); + } __forceinline void wait(MutexSys& mutex) { - pthread_cond_wait(&cond, (pthread_mutex_t*)mutex.mutex); + if (pthread_cond_wait(&cond, (pthread_mutex_t*)mutex.mutex) != 0) + THROW_RUNTIME_ERROR("pthread_cond_wait failed"); } __forceinline void notify_all() { - pthread_cond_broadcast(&cond); + if (pthread_cond_broadcast(&cond) != 0) + THROW_RUNTIME_ERROR("pthread_cond_broadcast failed"); } public: diff --git a/thirdparty/embree-aarch64/common/sys/condition.h b/thirdparty/embree/common/sys/condition.h index 7a3a05aa81..557c6e3482 100644 --- a/thirdparty/embree-aarch64/common/sys/condition.h +++ b/thirdparty/embree/common/sys/condition.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/filename.cpp b/thirdparty/embree/common/sys/filename.cpp index 86182c1afb..f55b224302 100644 --- a/thirdparty/embree-aarch64/common/sys/filename.cpp +++ b/thirdparty/embree/common/sys/filename.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "filename.h" diff --git a/thirdparty/embree-aarch64/common/sys/filename.h b/thirdparty/embree/common/sys/filename.h index 58f881b14d..d5929cd836 100644 --- a/thirdparty/embree-aarch64/common/sys/filename.h +++ b/thirdparty/embree/common/sys/filename.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -73,7 +73,7 @@ namespace embree friend bool operator!=(const FileName& a, const FileName& b); /*! output operator */ - friend embree_ostream operator<<(embree_ostream cout, const FileName& filename); + friend std::ostream& operator<<(std::ostream& cout, const FileName& filename); private: std::string filename; diff --git a/thirdparty/embree-aarch64/common/sys/intrinsics.h b/thirdparty/embree/common/sys/intrinsics.h index 44cdbd8f0f..ed8dd7d40a 100644 --- a/thirdparty/embree-aarch64/common/sys/intrinsics.h +++ b/thirdparty/embree/common/sys/intrinsics.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -10,10 +10,7 @@ #endif #if defined(__ARM_NEON) -#include "../math/SSE2NEON.h" -#if defined(NEON_AVX2_EMULATION) -#include "../math/AVX2NEON.h" -#endif +#include "../simd/arm/emulation.h" #else #include <immintrin.h> #endif @@ -27,14 +24,6 @@ #endif #endif -#if defined(__aarch64__) -#if !defined(_lzcnt_u32) - #define _lzcnt_u32 __builtin_clz -#endif -#if !defined(_lzcnt_u32) - #define _lzcnt_u32 __builtin_clzll -#endif -#else #if defined(__LZCNT__) #if !defined(_lzcnt_u32) #define _lzcnt_u32 __lzcnt32 @@ -43,13 +32,16 @@ #define _lzcnt_u64 __lzcnt64 #endif #endif -#endif #if defined(__WIN32__) -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include <windows.h> +// -- GODOT start -- +#if !defined(NOMINMAX) +// -- GODOT end -- +#define NOMINMAX +// -- GODOT start -- +#endif +#include "windows.h" +// -- GODOT end -- #endif /* normally defined in pmmintrin.h, but we always need this */ @@ -62,133 +54,133 @@ namespace embree { - + //////////////////////////////////////////////////////////////////////////////// /// Windows Platform //////////////////////////////////////////////////////////////////////////////// - + #if defined(__WIN32__) - - __forceinline size_t read_tsc() + + __forceinline size_t read_tsc() { LARGE_INTEGER li; QueryPerformanceCounter(&li); return (size_t)li.QuadPart; } - + __forceinline int bsf(int v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _tzcnt_u32(v); #else unsigned long r = 0; _BitScanForward(&r,v); return r; #endif } - + __forceinline unsigned bsf(unsigned v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _tzcnt_u32(v); #else unsigned long r = 0; _BitScanForward(&r,v); return r; #endif } - + #if defined(__X86_64__) __forceinline size_t bsf(size_t v) { -#if defined(__AVX2__) +#if defined(__AVX2__) return _tzcnt_u64(v); #else unsigned long r = 0; _BitScanForward64(&r,v); return r; #endif } #endif - - __forceinline int bscf(int& v) + + __forceinline int bscf(int& v) { int i = bsf(v); v &= v-1; return i; } - - __forceinline unsigned bscf(unsigned& v) + + __forceinline unsigned bscf(unsigned& v) { unsigned i = bsf(v); v &= v-1; return i; } - + #if defined(__X86_64__) - __forceinline size_t bscf(size_t& v) + __forceinline size_t bscf(size_t& v) { size_t i = bsf(v); v &= v-1; return i; } #endif - + __forceinline int bsr(int v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return 31 - _lzcnt_u32(v); #else unsigned long r = 0; _BitScanReverse(&r,v); return r; #endif } - + __forceinline unsigned bsr(unsigned v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return 31 - _lzcnt_u32(v); #else unsigned long r = 0; _BitScanReverse(&r,v); return r; #endif } - + #if defined(__X86_64__) __forceinline size_t bsr(size_t v) { -#if defined(__AVX2__) +#if defined(__AVX2__) return 63 -_lzcnt_u64(v); #else unsigned long r = 0; _BitScanReverse64(&r, v); return r; #endif } #endif - + __forceinline int lzcnt(const int x) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _lzcnt_u32(x); #else if (unlikely(x == 0)) return 32; - return 31 - bsr(x); + return 31 - bsr(x); #endif } - + __forceinline int btc(int v, int i) { long r = v; _bittestandcomplement(&r,i); return r; } - + __forceinline int bts(int v, int i) { long r = v; _bittestandset(&r,i); return r; } - + __forceinline int btr(int v, int i) { long r = v; _bittestandreset(&r,i); return r; } - + #if defined(__X86_64__) - + __forceinline size_t btc(size_t v, size_t i) { size_t r = v; _bittestandcomplement64((__int64*)&r,i); return r; } - + __forceinline size_t bts(size_t v, size_t i) { __int64 r = v; _bittestandset64(&r,i); return r; } - + __forceinline size_t btr(size_t v, size_t i) { __int64 r = v; _bittestandreset64(&r,i); return r; } - + #endif - + __forceinline int32_t atomic_cmpxchg(volatile int32_t* p, const int32_t c, const int32_t v) { return _InterlockedCompareExchange((volatile long*)p,v,c); } @@ -196,174 +188,160 @@ namespace embree //////////////////////////////////////////////////////////////////////////////// /// Unix Platform //////////////////////////////////////////////////////////////////////////////// - + #else - + #if defined(__i386__) && defined(__PIC__) - - __forceinline void __cpuid(int out[4], int op) + + __forceinline void __cpuid(int out[4], int op) { asm volatile ("xchg{l}\t{%%}ebx, %1\n\t" "cpuid\n\t" "xchg{l}\t{%%}ebx, %1\n\t" - : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) - : "0"(op)); + : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) + : "0"(op)); } - - __forceinline void __cpuid_count(int out[4], int op1, int op2) + + __forceinline void __cpuid_count(int out[4], int op1, int op2) { asm volatile ("xchg{l}\t{%%}ebx, %1\n\t" "cpuid\n\t" "xchg{l}\t{%%}ebx, %1\n\t" : "=a" (out[0]), "=r" (out[1]), "=c" (out[2]), "=d" (out[3]) - : "0" (op1), "2" (op2)); + : "0" (op1), "2" (op2)); } - -#else + +#elif defined(__X86_ASM__) __forceinline void __cpuid(int out[4], int op) { -#if defined(__ARM_NEON) - if (op == 0) { // Get CPU name - out[0] = 0x41524d20; - out[1] = 0x41524d20; - out[2] = 0x41524d20; - out[3] = 0x41524d20; - } -#else - asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op)); -#endif + asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op)); } - -#if !defined(__ARM_NEON) + __forceinline void __cpuid_count(int out[4], int op1, int op2) { - asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op1), "c"(op2)); + asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op1), "c"(op2)); } + #endif - -#endif - + __forceinline uint64_t read_tsc() { -#if defined(__ARM_NEON) - return 0; // FIXME(LTE): mimic rdtsc -#else +#if defined(__X86_ASM__) uint32_t high,low; asm volatile ("rdtsc" : "=d"(high), "=a"(low)); return (((uint64_t)high) << 32) + (uint64_t)low; +#else + /* Not supported yet, meaning measuring traversal cost per pixel does not work. */ + return 0; #endif } - + __forceinline int bsf(int v) { -#if defined(__ARM_NEON) - return __builtin_ctz(v); -#else -#if defined(__AVX2__) +#if defined(__AVX2__) return _tzcnt_u32(v); -#else +#elif defined(__X86_ASM__) int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; -#endif +#else + return __builtin_ctz(v); #endif } - -#if defined(__X86_64__) || defined(__aarch64__) - __forceinline unsigned bsf(unsigned v) + +#if defined(__64BIT__) + __forceinline unsigned bsf(unsigned v) { -#if defined(__ARM_NEON) - return __builtin_ctz(v); -#else -#if defined(__AVX2__) +#if defined(__AVX2__) return _tzcnt_u32(v); -#else +#elif defined(__X86_ASM__) unsigned r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; -#endif +#else + return __builtin_ctz(v); #endif } #endif - + __forceinline size_t bsf(size_t v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) #if defined(__X86_64__) return _tzcnt_u64(v); #else return _tzcnt_u32(v); #endif -#elif defined(__ARM_NEON) - return __builtin_ctzl(v); -#else +#elif defined(__X86_ASM__) size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; +#else + return __builtin_ctzl(v); #endif } - __forceinline int bscf(int& v) + __forceinline int bscf(int& v) { int i = bsf(v); v &= v-1; return i; } - -#if defined(__X86_64__) || defined(__aarch64__) - __forceinline unsigned int bscf(unsigned int& v) + +#if defined(__64BIT__) + __forceinline unsigned int bscf(unsigned int& v) { unsigned int i = bsf(v); v &= v-1; return i; } #endif - - __forceinline size_t bscf(size_t& v) + + __forceinline size_t bscf(size_t& v) { size_t i = bsf(v); v &= v-1; return i; } - + __forceinline int bsr(int v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return 31 - _lzcnt_u32(v); -#elif defined(__ARM_NEON) - return __builtin_clz(v)^31; -#else +#elif defined(__X86_ASM__) int r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; +#else + return __builtin_clz(v) ^ 31; #endif } - -#if defined(__X86_64__) || defined(__aarch64__) + +#if defined(__64BIT__) __forceinline unsigned bsr(unsigned v) { -#if defined(__AVX2__) +#if defined(__AVX2__) return 31 - _lzcnt_u32(v); -#elif defined(__ARM_NEON) - return __builtin_clz(v)^31; -#else +#elif defined(__X86_ASM__) unsigned r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; +#else + return __builtin_clz(v) ^ 31; #endif } #endif - + __forceinline size_t bsr(size_t v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) #if defined(__X86_64__) return 63 - _lzcnt_u64(v); #else return 31 - _lzcnt_u32(v); #endif -#elif defined(__aarch64__) - return (sizeof(v) * 8 - 1) - __builtin_clzl(v); -#else +#elif defined(__X86_ASM__) size_t r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; +#else + return (sizeof(v) * 8 - 1) - __builtin_clzl(v); #endif } - + __forceinline int lzcnt(const int x) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) return _lzcnt_u32(x); #else if (unlikely(x == 0)) return 32; - return 31 - bsr(x); + return 31 - bsr(x); #endif } __forceinline size_t blsr(size_t v) { -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) #if defined(__INTEL_COMPILER) return _blsr_u64(v); #else @@ -377,79 +355,65 @@ namespace embree return v & (v-1); #endif } - + __forceinline int btc(int v, int i) { -#if defined(__aarch64__) - // _bittestandcomplement(long *a, long b) { - // unsigned char x = (*a >> b) & 1; - // *a = *a ^ (1 << b); - // return x; - - // We only need `*a` - return (v ^ (1 << i)); -#else +#if defined(__X86_ASM__) int r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r; +#else + return (v ^ (1 << i)); #endif } - + __forceinline int bts(int v, int i) { -#if defined(__aarch64__) - // _bittestandset(long *a, long b) { - // unsigned char x = (*a >> b) & 1; - // *a = *a | (1 << b); - // return x; - return (v | (v << i)); -#else +#if defined(__X86_ASM__) int r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; +#else + return (v | (v << i)); #endif } - + __forceinline int btr(int v, int i) { -#if defined(__aarch64__) - // _bittestandreset(long *a, long b) { - // unsigned char x = (*a >> b) & 1; - // *a = *a & ~(1 << b); - // return x; - return (v & ~(v << i)); -#else +#if defined(__X86_ASM__) int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; +#else + return (v & ~(v << i)); #endif } - + __forceinline size_t btc(size_t v, size_t i) { -#if defined(__aarch64__) - return (v ^ (1 << i)); -#else +#if defined(__X86_ASM__) size_t r = 0; asm ("btc %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags" ); return r; +#else + return (v ^ (1 << i)); #endif } - + __forceinline size_t bts(size_t v, size_t i) { -#if defined(__aarch64__) - return (v | (v << i)); -#else +#if defined(__X86_ASM__) size_t r = 0; asm ("bts %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; +#else + return (v | (v << i)); #endif } - + __forceinline size_t btr(size_t v, size_t i) { -#if defined(__ARM_NEON) - return (v & ~(v << i)); -#else +#if defined(__X86_ASM__) size_t r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; +#else + return (v & ~(v << i)); #endif } __forceinline int32_t atomic_cmpxchg(int32_t volatile* value, int32_t comparand, const int32_t input) { return __sync_val_compare_and_swap(value, comparand, input); } - + #endif - + //////////////////////////////////////////////////////////////////////////////// /// All Platforms //////////////////////////////////////////////////////////////////////////////// - + #if defined(__clang__) || defined(__GNUC__) #if !defined(_mm_undefined_ps) __forceinline __m128 _mm_undefined_ps() { return _mm_setzero_ps(); } @@ -471,39 +435,41 @@ namespace embree #endif #endif -#if defined(__SSE4_2__) || defined(__ARM_NEON) - +#if defined(__SSE4_2__) + __forceinline int popcnt(int in) { return _mm_popcnt_u32(in); } - + __forceinline unsigned popcnt(unsigned in) { return _mm_popcnt_u32(in); } - -#if defined(__X86_64__) || defined(__ARM_NEON) + +#if defined(__64BIT__) __forceinline size_t popcnt(size_t in) { return _mm_popcnt_u64(in); } #endif - + #endif +#if defined(__X86_ASM__) __forceinline uint64_t rdtsc() { - int dummy[4]; - __cpuid(dummy,0); - uint64_t clock = read_tsc(); - __cpuid(dummy,0); + int dummy[4]; + __cpuid(dummy,0); + uint64_t clock = read_tsc(); + __cpuid(dummy,0); return clock; } - +#endif + __forceinline void pause_cpu(const size_t N = 8) { for (size_t i=0; i<N; i++) - _mm_pause(); + _mm_pause(); } - + /* prefetches */ __forceinline void prefetchL1 (const void* ptr) { _mm_prefetch((const char*)ptr,_MM_HINT_T0); } __forceinline void prefetchL2 (const void* ptr) { _mm_prefetch((const char*)ptr,_MM_HINT_T1); } @@ -513,18 +479,18 @@ namespace embree #if defined(__INTEL_COMPILER) _mm_prefetch((const char*)ptr,_MM_HINT_ET0); #else - _mm_prefetch((const char*)ptr,_MM_HINT_T0); + _mm_prefetch((const char*)ptr,_MM_HINT_T0); #endif } - __forceinline void prefetchL1EX(const void* ptr) { - prefetchEX(ptr); + __forceinline void prefetchL1EX(const void* ptr) { + prefetchEX(ptr); } - - __forceinline void prefetchL2EX(const void* ptr) { - prefetchEX(ptr); + + __forceinline void prefetchL2EX(const void* ptr) { + prefetchEX(ptr); } -#if defined(__AVX2__) && !defined(__aarch64__) +#if defined(__AVX2__) __forceinline unsigned int pext(unsigned int a, unsigned int b) { return _pext_u32(a, b); } __forceinline unsigned int pdep(unsigned int a, unsigned int b) { return _pdep_u32(a, b); } #if defined(__X86_64__) diff --git a/thirdparty/embree-aarch64/common/sys/library.cpp b/thirdparty/embree/common/sys/library.cpp index 899267a1e4..fc983dffd5 100644 --- a/thirdparty/embree-aarch64/common/sys/library.cpp +++ b/thirdparty/embree/common/sys/library.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "library.h" @@ -27,7 +27,7 @@ namespace embree /* returns address of a symbol from the library */ void* getSymbol(lib_t lib, const std::string& sym) { - return reinterpret_cast<void *>(GetProcAddress(HMODULE(lib),sym.c_str())); + return (void*)GetProcAddress(HMODULE(lib),sym.c_str()); } /* closes the shared library */ @@ -61,7 +61,7 @@ namespace embree lib = dlopen((executable.path() + fullName).c_str(),RTLD_NOW); if (lib == nullptr) { const char* error = dlerror(); - if (error) { + if (error) { THROW_RUNTIME_ERROR(error); } else { THROW_RUNTIME_ERROR("could not load library "+executable.str()); diff --git a/thirdparty/embree-aarch64/common/sys/library.h b/thirdparty/embree/common/sys/library.h index c2164e9fbe..67e14d2420 100644 --- a/thirdparty/embree-aarch64/common/sys/library.h +++ b/thirdparty/embree/common/sys/library.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/mutex.cpp b/thirdparty/embree/common/sys/mutex.cpp index 11779bc9b9..789feaf2d8 100644 --- a/thirdparty/embree-aarch64/common/sys/mutex.cpp +++ b/thirdparty/embree/common/sys/mutex.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "mutex.h" @@ -36,7 +36,6 @@ namespace embree MAYBE_UNUSED bool ok = pthread_mutex_destroy((pthread_mutex_t*)mutex) == 0; assert(ok); delete (pthread_mutex_t*)mutex; - mutex = nullptr; } void MutexSys::lock() diff --git a/thirdparty/embree-aarch64/common/sys/mutex.h b/thirdparty/embree/common/sys/mutex.h index 1164210f23..4cb3626d92 100644 --- a/thirdparty/embree-aarch64/common/sys/mutex.h +++ b/thirdparty/embree/common/sys/mutex.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/platform.h b/thirdparty/embree/common/sys/platform.h index 737f14aa6e..697e07bb86 100644 --- a/thirdparty/embree-aarch64/common/sys/platform.h +++ b/thirdparty/embree/common/sys/platform.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -23,9 +23,17 @@ /// detect platform //////////////////////////////////////////////////////////////////////////////// -/* detect 32 or 64 platform */ +/* detect 32 or 64 Intel platform */ #if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64) #define __X86_64__ +#define __X86_ASM__ +#elif defined(__i386__) || defined(_M_IX86) +#define __X86_ASM__ +#endif + +/* detect 64 bit platform */ +#if defined(__X86_64__) || defined(__aarch64__) +#define __64BIT__ #endif /* detect Linux platform */ @@ -88,10 +96,12 @@ #define dll_import __declspec(dllimport) #else #define dll_export __attribute__ ((visibility ("default"))) -#define dll_import +#define dll_import #endif -#ifdef __WIN32__ +// -- GODOT start -- +#if defined(__WIN32__) && !defined(__MINGW32__) +// -- GODOT end -- #if !defined(__noinline) #define __noinline __declspec(noinline) #endif @@ -103,16 +113,11 @@ #define __restrict__ //__restrict // causes issues with MSVC #endif #if !defined(__thread) -// NOTE: Require `-fms-extensions` for clang #define __thread __declspec(thread) #endif #if !defined(__aligned) -#if defined(__MINGW32__) -#define __aligned(...) __attribute__((aligned(__VA_ARGS__))) -#else #define __aligned(...) __declspec(align(__VA_ARGS__)) #endif -#endif //#define __FUNCTION__ __FUNCTION__ #define debugbreak() __debugbreak() @@ -147,7 +152,7 @@ #endif // -- GODOT start -- -#ifndef likely +#if !defined(likely) // -- GODOT end -- #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #define likely(expr) (expr) @@ -205,7 +210,7 @@ namespace embree { /* windows does not have ssize_t */ #if defined(__WIN32__) -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) typedef int64_t ssize_t; #else typedef int32_t ssize_t; @@ -329,7 +334,7 @@ __forceinline std::string toString(long long value) { /// Some macros for static profiling //////////////////////////////////////////////////////////////////////////////// -#if defined (__GNUC__) +#if defined (__GNUC__) #define IACA_SSC_MARK( MARK_ID ) \ __asm__ __volatile__ ( \ "\n\t movl $"#MARK_ID", %%ebx" \ @@ -368,7 +373,7 @@ namespace embree bool active; const Closure f; }; - + template <typename Closure> OnScopeExitHelper<Closure> OnScopeExit(const Closure f) { return OnScopeExitHelper<Closure>(f); diff --git a/thirdparty/embree-aarch64/common/sys/ref.h b/thirdparty/embree/common/sys/ref.h index 24648e6234..c2b56c1908 100644 --- a/thirdparty/embree-aarch64/common/sys/ref.h +++ b/thirdparty/embree/common/sys/ref.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/regression.cpp b/thirdparty/embree/common/sys/regression.cpp index d95ff8dfe0..45315b1105 100644 --- a/thirdparty/embree-aarch64/common/sys/regression.cpp +++ b/thirdparty/embree/common/sys/regression.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "regression.h" diff --git a/thirdparty/embree-aarch64/common/sys/regression.h b/thirdparty/embree/common/sys/regression.h index 632f8d92cf..bb0bb94006 100644 --- a/thirdparty/embree-aarch64/common/sys/regression.h +++ b/thirdparty/embree/common/sys/regression.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/string.cpp b/thirdparty/embree/common/sys/string.cpp index 931244383e..f42fdc8536 100644 --- a/thirdparty/embree-aarch64/common/sys/string.cpp +++ b/thirdparty/embree/common/sys/string.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "string.h" diff --git a/thirdparty/embree-aarch64/common/sys/string.h b/thirdparty/embree/common/sys/string.h index 2e9b0f88c3..820076b21c 100644 --- a/thirdparty/embree-aarch64/common/sys/string.h +++ b/thirdparty/embree/common/sys/string.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp index 1d11436770..f1a59e511e 100644 --- a/thirdparty/embree-aarch64/common/sys/sysinfo.cpp +++ b/thirdparty/embree/common/sys/sysinfo.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "sysinfo.h" @@ -18,44 +18,32 @@ typedef cpuset_t cpu_set_t; namespace embree { NullTy null; - - std::string getPlatformName() + + std::string getPlatformName() { -#if defined(__LINUX__) && defined(__ANDROID__) && defined(__aarch64__) && defined(__ARM_NEON) - return "Android Linux (aarch64 / arm64)"; -#elif defined(__LINUX__) && defined(__ANDROID__) && defined(__X86_64__) - return "Android Linux (x64)"; -#elif defined(__LINUX__) && defined(__ANDROID__) && (defined(_X86_) || defined(__X86__) || defined(_M_IX86)) - return "Android Linux (x86)"; -#elif defined(__LINUX__) && !defined(__X86_64__) +#if defined(__LINUX__) && !defined(__64BIT__) return "Linux (32bit)"; -#elif defined(__LINUX__) && defined(__X86_64__) +#elif defined(__LINUX__) && defined(__64BIT__) return "Linux (64bit)"; -#elif defined(__FREEBSD__) && !defined(__X86_64__) +#elif defined(__FREEBSD__) && !defined(__64BIT__) return "FreeBSD (32bit)"; -#elif defined(__FREEBSD__) && defined(__X86_64__) +#elif defined(__FREEBSD__) && defined(__64BIT__) return "FreeBSD (64bit)"; -#elif defined(__CYGWIN__) && !defined(__X86_64__) +#elif defined(__CYGWIN__) && !defined(__64BIT__) return "Cygwin (32bit)"; -#elif defined(__CYGWIN__) && defined(__X86_64__) +#elif defined(__CYGWIN__) && defined(__64BIT__) return "Cygwin (64bit)"; -#elif defined(__WIN32__) && !defined(__X86_64__) +#elif defined(__WIN32__) && !defined(__64BIT__) return "Windows (32bit)"; -#elif defined(__WIN32__) && defined(__X86_64__) +#elif defined(__WIN32__) && defined(__64BIT__) return "Windows (64bit)"; -#elif defined(TARGET_IPHONE_SIMULATOR) && defined(__X86_64__) - return "iOS Simulator (x64)"; -#elif defined(TARGET_OS_IPHONE) && defined(__aarch64__) && defined(__ARM_NEON) - return "iOS (aarch64 / arm64)"; -#elif defined(__MACOSX__) && !defined(__X86_64__) +#elif defined(__MACOSX__) && !defined(__64BIT__) return "Mac OS X (32bit)"; -#elif defined(__MACOSX__) && defined(__X86_64__) +#elif defined(__MACOSX__) && defined(__64BIT__) return "Mac OS X (64bit)"; -#elif defined(__UNIX__) && defined(__aarch64__) - return "Unix (aarch64)"; -#elif defined(__UNIX__) && !defined(__X86_64__) +#elif defined(__UNIX__) && !defined(__64BIT__) return "Unix (32bit)"; -#elif defined(__UNIX__) && defined(__X86_64__) +#elif defined(__UNIX__) && defined(__64BIT__) return "Unix (64bit)"; #else return "Unknown"; @@ -91,21 +79,28 @@ namespace embree std::string getCPUVendor() { - int cpuinfo[4]; - __cpuid (cpuinfo, 0); +#if defined(__X86_ASM__) + int cpuinfo[4]; + __cpuid (cpuinfo, 0); int name[4]; name[0] = cpuinfo[1]; name[1] = cpuinfo[3]; name[2] = cpuinfo[2]; name[3] = 0; return (char*)name; +#elif defined(__ARM_NEON) + return "ARM"; +#else + return "Unknown"; +#endif } - CPU getCPUModel() + CPU getCPUModel() { +#if defined(__X86_ASM__) if (getCPUVendor() != "GenuineIntel") return CPU::UNKNOWN; - + int out[4]; __cpuid(out, 0); if (out[0] < 1) return CPU::UNKNOWN; @@ -169,6 +164,10 @@ namespace embree if (DisplayFamily_DisplayModel == 0x0685) return CPU::XEON_PHI_KNIGHTS_MILL; if (DisplayFamily_DisplayModel == 0x0657) return CPU::XEON_PHI_KNIGHTS_LANDING; +#elif defined(__ARM_NEON) + return CPU::ARM; +#endif + return CPU::UNKNOWN; } @@ -195,13 +194,13 @@ namespace embree case CPU::NEHALEM : return "Nehalem"; case CPU::CORE2 : return "Core2"; case CPU::CORE1 : return "Core"; - case CPU::ARM : return "Arm"; + case CPU::ARM : return "ARM"; case CPU::UNKNOWN : return "Unknown CPU"; } return "Unknown CPU (error)"; } -#if !defined(__ARM_NEON) +#if defined(__X86_ASM__) /* constants to access destination registers of CPUID instruction */ static const int EAX = 0; static const int EBX = 1; @@ -241,16 +240,17 @@ namespace embree static const int CPU_FEATURE_BIT_AVX512BW = 1 << 30; // AVX512BW (byte and word instructions) static const int CPU_FEATURE_BIT_AVX512VL = 1 << 31; // AVX512VL (vector length extensions) static const int CPU_FEATURE_BIT_AVX512IFMA = 1 << 21; // AVX512IFMA (integer fused multiple-add instructions) - + /* cpuid[eax=7,ecx=0].ecx */ static const int CPU_FEATURE_BIT_AVX512VBMI = 1 << 1; // AVX512VBMI (vector bit manipulation instructions) #endif -#if !defined(__ARM_NEON) - __noinline int64_t get_xcr0() +#if defined(__X86_ASM__) + __noinline int64_t get_xcr0() { - // https://github.com/opencv/opencv/blob/master/modules/core/src/system.cpp#L466 -#if defined (__WIN32__) && defined(_XCR_XFEATURE_ENABLED_MASK) +// -- GODOT start -- +#if defined (__WIN32__) && !defined (__MINGW32__) +// -- GODOT end -- int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 xcr0 = _xgetbv(0); return xcr0; @@ -264,40 +264,19 @@ namespace embree int getCPUFeatures() { -#if defined(__ARM_NEON) - int cpu_features = CPU_FEATURE_NEON|CPU_FEATURE_SSE|CPU_FEATURE_SSE2; -#if defined(NEON_AVX2_EMULATION) - cpu_features |= CPU_FEATURE_SSE3|CPU_FEATURE_SSSE3|CPU_FEATURE_SSE42; - cpu_features |= CPU_FEATURE_XMM_ENABLED; - cpu_features |= CPU_FEATURE_YMM_ENABLED; - cpu_features |= CPU_FEATURE_SSE41 | CPU_FEATURE_RDRAND | CPU_FEATURE_F16C; - cpu_features |= CPU_FEATURE_POPCNT; - cpu_features |= CPU_FEATURE_AVX; - cpu_features |= CPU_FEATURE_AVX2; - cpu_features |= CPU_FEATURE_FMA3; - cpu_features |= CPU_FEATURE_LZCNT; - cpu_features |= CPU_FEATURE_BMI1; - cpu_features |= CPU_FEATURE_BMI2; - cpu_features |= CPU_FEATURE_NEON_2X; - - - -#endif - return cpu_features; - -#else +#if defined(__X86_ASM__) /* cache CPU features access */ static int cpu_features = 0; - if (cpu_features) + if (cpu_features) return cpu_features; /* get number of CPUID leaves */ - int cpuid_leaf0[4]; + int cpuid_leaf0[4]; __cpuid(cpuid_leaf0, 0x00000000); - unsigned nIds = cpuid_leaf0[EAX]; + unsigned nIds = cpuid_leaf0[EAX]; /* get number of extended CPUID leaves */ - int cpuid_leafe[4]; + int cpuid_leafe[4]; __cpuid(cpuid_leafe, 0x80000000); unsigned nExIds = cpuid_leafe[EAX]; @@ -329,7 +308,7 @@ namespace embree if (xmm_enabled) cpu_features |= CPU_FEATURE_XMM_ENABLED; if (ymm_enabled) cpu_features |= CPU_FEATURE_YMM_ENABLED; if (zmm_enabled) cpu_features |= CPU_FEATURE_ZMM_ENABLED; - + if (cpuid_leaf_1[EDX] & CPU_FEATURE_BIT_SSE ) cpu_features |= CPU_FEATURE_SSE; if (cpuid_leaf_1[EDX] & CPU_FEATURE_BIT_SSE2 ) cpu_features |= CPU_FEATURE_SSE2; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE3 ) cpu_features |= CPU_FEATURE_SSE3; @@ -337,8 +316,8 @@ namespace embree if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE4_1) cpu_features |= CPU_FEATURE_SSE41; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE4_2) cpu_features |= CPU_FEATURE_SSE42; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_POPCNT) cpu_features |= CPU_FEATURE_POPCNT; + if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_AVX ) cpu_features |= CPU_FEATURE_AVX; - if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_F16C ) cpu_features |= CPU_FEATURE_F16C; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_RDRAND) cpu_features |= CPU_FEATURE_RDRAND; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX2 ) cpu_features |= CPU_FEATURE_AVX2; @@ -350,7 +329,7 @@ namespace embree if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512F ) cpu_features |= CPU_FEATURE_AVX512F; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512DQ ) cpu_features |= CPU_FEATURE_AVX512DQ; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512PF ) cpu_features |= CPU_FEATURE_AVX512PF; - if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512ER ) cpu_features |= CPU_FEATURE_AVX512ER; + if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512ER ) cpu_features |= CPU_FEATURE_AVX512ER; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512CD ) cpu_features |= CPU_FEATURE_AVX512CD; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512BW ) cpu_features |= CPU_FEATURE_AVX512BW; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512IFMA) cpu_features |= CPU_FEATURE_AVX512IFMA; @@ -358,6 +337,12 @@ namespace embree if (cpuid_leaf_7[ECX] & CPU_FEATURE_BIT_AVX512VBMI) cpu_features |= CPU_FEATURE_AVX512VBMI; return cpu_features; +#elif defined(__ARM_NEON) + /* emulated features with sse2neon */ + return CPU_FEATURE_SSE|CPU_FEATURE_SSE2|CPU_FEATURE_XMM_ENABLED; +#else + /* Unknown CPU. */ + return 0; #endif } @@ -391,11 +376,9 @@ namespace embree if (features & CPU_FEATURE_AVX512VL) str += "AVX512VL "; if (features & CPU_FEATURE_AVX512IFMA) str += "AVX512IFMA "; if (features & CPU_FEATURE_AVX512VBMI) str += "AVX512VBMI "; - if (features & CPU_FEATURE_NEON) str += "NEON "; - if (features & CPU_FEATURE_NEON_2X) str += "2xNEON "; return str; } - + std::string stringOfISA (int isa) { if (isa == SSE) return "SSE"; @@ -406,17 +389,14 @@ namespace embree if (isa == SSE42) return "SSE4.2"; if (isa == AVX) return "AVX"; if (isa == AVX2) return "AVX2"; - if (isa == AVX512KNL) return "AVX512KNL"; - if (isa == AVX512SKX) return "AVX512SKX"; - if (isa == NEON) return "NEON"; - if (isa == NEON_2X) return "2xNEON"; + if (isa == AVX512) return "AVX512"; return "UNKNOWN"; } bool hasISA(int features, int isa) { return (features & isa) == isa; } - + std::string supportedTargetList (int features) { std::string v; @@ -429,10 +409,7 @@ namespace embree if (hasISA(features,AVX)) v += "AVX "; if (hasISA(features,AVXI)) v += "AVXI "; if (hasISA(features,AVX2)) v += "AVX2 "; - if (hasISA(features,AVX512KNL)) v += "AVX512KNL "; - if (hasISA(features,AVX512SKX)) v += "AVX512SKX "; - if (hasISA(features,NEON)) v += "NEON "; - if (hasISA(features,NEON_2X)) v += "2xNEON "; + if (hasISA(features,AVX512)) v += "AVX512 "; return v; } } @@ -456,7 +433,7 @@ namespace embree return std::string(filename); } - unsigned int getNumberOfLogicalThreads() + unsigned int getNumberOfLogicalThreads() { static int nThreads = -1; if (nThreads != -1) return nThreads; @@ -467,11 +444,11 @@ namespace embree GetActiveProcessorGroupCountFunc pGetActiveProcessorGroupCount = (GetActiveProcessorGroupCountFunc)GetProcAddress(hlib, "GetActiveProcessorGroupCount"); GetActiveProcessorCountFunc pGetActiveProcessorCount = (GetActiveProcessorCountFunc) GetProcAddress(hlib, "GetActiveProcessorCount"); - if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount) + if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount) { int groups = pGetActiveProcessorGroupCount(); int totalProcessors = 0; - for (int i = 0; i < groups; i++) + for (int i = 0; i < groups; i++) totalProcessors += pGetActiveProcessorCount(i); nThreads = totalProcessors; } @@ -485,7 +462,7 @@ namespace embree return nThreads; } - int getTerminalWidth() + int getTerminalWidth() { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); if (handle == INVALID_HANDLE_VALUE) return 80; @@ -495,7 +472,7 @@ namespace embree return info.dwSize.X; } - double getSeconds() + double getSeconds() { LARGE_INTEGER freq, val; QueryPerformanceFrequency(&freq); @@ -534,7 +511,7 @@ namespace embree namespace embree { - std::string getExecutableFileName() + std::string getExecutableFileName() { std::string pid = "/proc/" + toString(getpid()) + "/exe"; char buf[4096]; @@ -587,7 +564,7 @@ namespace embree size_t getVirtualMemoryBytes() { return 0; } - + size_t getResidentMemoryBytes() { return 0; } @@ -617,7 +594,7 @@ namespace embree size_t getVirtualMemoryBytes() { return 0; } - + size_t getResidentMemoryBytes() { return 0; } @@ -638,12 +615,15 @@ namespace embree namespace embree { - unsigned int getNumberOfLogicalThreads() + unsigned int getNumberOfLogicalThreads() { static int nThreads = -1; if (nThreads != -1) return nThreads; +// -- GODOT start -- +// #if defined(__MACOSX__) #if defined(__MACOSX__) || defined(__ANDROID__) +// -- GODOT end -- nThreads = sysconf(_SC_NPROCESSORS_ONLN); // does not work in Linux LXC container assert(nThreads); #else @@ -651,12 +631,12 @@ namespace embree if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0) nThreads = CPU_COUNT(&set); #endif - + assert(nThreads); return nThreads; } - int getTerminalWidth() + int getTerminalWidth() { struct winsize info; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &info) < 0) return 80; diff --git a/thirdparty/embree-aarch64/common/sys/sysinfo.h b/thirdparty/embree/common/sys/sysinfo.h index 8e313a59b3..72351d12e4 100644 --- a/thirdparty/embree-aarch64/common/sys/sysinfo.h +++ b/thirdparty/embree/common/sys/sysinfo.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -16,13 +16,9 @@ /* define isa namespace and ISA bitvector */ #if defined (__AVX512VL__) -# define isa avx512skx -# define ISA AVX512SKX -# define ISA_STR "AVX512SKX" -#elif defined (__AVX512F__) -# define isa avx512knl -# define ISA AVX512KNL -# define ISA_STR "AVX512KNL" +# define isa avx512 +# define ISA AVX512 +# define ISA_STR "AVX512" #elif defined (__AVX2__) # define isa avx2 # define ISA AVX2 @@ -59,12 +55,7 @@ # define isa sse # define ISA SSE # define ISA_STR "SSE" -#elif defined(__ARM_NEON) -// NOTE(LTE): Use sse2 for `isa` for the compatibility at the moment. -#define isa sse2 -#define ISA NEON -#define ISA_STR "NEON" -#else +#else #error Unknown ISA #endif @@ -120,7 +111,7 @@ namespace embree static const int CPU_FEATURE_SSE3 = 1 << 2; static const int CPU_FEATURE_SSSE3 = 1 << 3; static const int CPU_FEATURE_SSE41 = 1 << 4; - static const int CPU_FEATURE_SSE42 = 1 << 5; + static const int CPU_FEATURE_SSE42 = 1 << 5; static const int CPU_FEATURE_POPCNT = 1 << 6; static const int CPU_FEATURE_AVX = 1 << 7; static const int CPU_FEATURE_F16C = 1 << 8; @@ -131,7 +122,7 @@ namespace embree static const int CPU_FEATURE_BMI1 = 1 << 13; static const int CPU_FEATURE_BMI2 = 1 << 14; static const int CPU_FEATURE_AVX512F = 1 << 16; - static const int CPU_FEATURE_AVX512DQ = 1 << 17; + static const int CPU_FEATURE_AVX512DQ = 1 << 17; static const int CPU_FEATURE_AVX512PF = 1 << 18; static const int CPU_FEATURE_AVX512ER = 1 << 19; static const int CPU_FEATURE_AVX512CD = 1 << 20; @@ -142,9 +133,7 @@ namespace embree static const int CPU_FEATURE_XMM_ENABLED = 1 << 25; static const int CPU_FEATURE_YMM_ENABLED = 1 << 26; static const int CPU_FEATURE_ZMM_ENABLED = 1 << 27; - static const int CPU_FEATURE_NEON = 1 << 28; - static const int CPU_FEATURE_NEON_2X = 1 << 29; - + /*! get CPU features */ int getCPUFeatures(); @@ -155,7 +144,7 @@ namespace embree std::string supportedTargetList (int isa); /*! ISAs */ - static const int SSE = CPU_FEATURE_SSE | CPU_FEATURE_XMM_ENABLED; + static const int SSE = CPU_FEATURE_SSE | CPU_FEATURE_XMM_ENABLED; static const int SSE2 = SSE | CPU_FEATURE_SSE2; static const int SSE3 = SSE2 | CPU_FEATURE_SSE3; static const int SSSE3 = SSE3 | CPU_FEATURE_SSSE3; @@ -164,10 +153,7 @@ namespace embree static const int AVX = SSE42 | CPU_FEATURE_AVX | CPU_FEATURE_YMM_ENABLED; static const int AVXI = AVX | CPU_FEATURE_F16C | CPU_FEATURE_RDRAND; static const int AVX2 = AVXI | CPU_FEATURE_AVX2 | CPU_FEATURE_FMA3 | CPU_FEATURE_BMI1 | CPU_FEATURE_BMI2 | CPU_FEATURE_LZCNT; - static const int AVX512KNL = AVX2 | CPU_FEATURE_AVX512F | CPU_FEATURE_AVX512PF | CPU_FEATURE_AVX512ER | CPU_FEATURE_AVX512CD | CPU_FEATURE_ZMM_ENABLED; - static const int AVX512SKX = AVX2 | CPU_FEATURE_AVX512F | CPU_FEATURE_AVX512DQ | CPU_FEATURE_AVX512CD | CPU_FEATURE_AVX512BW | CPU_FEATURE_AVX512VL | CPU_FEATURE_ZMM_ENABLED; - static const int NEON = CPU_FEATURE_NEON | CPU_FEATURE_SSE | CPU_FEATURE_SSE2; - static const int NEON_2X = CPU_FEATURE_NEON_2X | AVX2; + static const int AVX512 = AVX2 | CPU_FEATURE_AVX512F | CPU_FEATURE_AVX512DQ | CPU_FEATURE_AVX512CD | CPU_FEATURE_AVX512BW | CPU_FEATURE_AVX512VL | CPU_FEATURE_ZMM_ENABLED; /*! converts ISA bitvector into a string */ std::string stringOfISA(int features); diff --git a/thirdparty/embree-aarch64/common/sys/thread.cpp b/thirdparty/embree/common/sys/thread.cpp index f9ea5b7d96..f4014be89b 100644 --- a/thirdparty/embree-aarch64/common/sys/thread.cpp +++ b/thirdparty/embree/common/sys/thread.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "thread.h" @@ -7,7 +7,7 @@ #include <iostream> #if defined(__ARM_NEON) -#include "../math/SSE2NEON.h" +#include "../simd/arm/emulation.h" #else #include <xmmintrin.h> #endif @@ -39,7 +39,7 @@ namespace embree GetActiveProcessorCountFunc pGetActiveProcessorCount = (GetActiveProcessorCountFunc)GetProcAddress(hlib, "GetActiveProcessorCount"); SetThreadGroupAffinityFunc pSetThreadGroupAffinity = (SetThreadGroupAffinityFunc)GetProcAddress(hlib, "SetThreadGroupAffinity"); SetThreadIdealProcessorExFunc pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExFunc)GetProcAddress(hlib, "SetThreadIdealProcessorEx"); - if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount && pSetThreadGroupAffinity && pSetThreadIdealProcessorEx) + if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount && pSetThreadGroupAffinity && pSetThreadIdealProcessorEx) { int groups = pGetActiveProcessorGroupCount(); int totalProcessors = 0, group = 0, number = 0; @@ -52,7 +52,7 @@ namespace embree } totalProcessors += processors; } - + GROUP_AFFINITY groupAffinity; groupAffinity.Group = (WORD)group; groupAffinity.Mask = (KAFFINITY)(uint64_t(1) << number); @@ -61,15 +61,15 @@ namespace embree groupAffinity.Reserved[2] = 0; if (!pSetThreadGroupAffinity(thread, &groupAffinity, nullptr)) WARNING("SetThreadGroupAffinity failed"); // on purpose only a warning - + PROCESSOR_NUMBER processorNumber; processorNumber.Group = group; processorNumber.Number = number; processorNumber.Reserved = 0; if (!pSetThreadIdealProcessorEx(thread, &processorNumber, nullptr)) WARNING("SetThreadIdealProcessorEx failed"); // on purpose only a warning - } - else + } + else { if (!SetThreadAffinityMask(thread, DWORD_PTR(uint64_t(1) << affinity))) WARNING("SetThreadAffinityMask failed"); // on purpose only a warning @@ -83,10 +83,10 @@ namespace embree setAffinity(GetCurrentThread(), affinity); } - struct ThreadStartupData + struct ThreadStartupData { public: - ThreadStartupData (thread_func f, void* arg) + ThreadStartupData (thread_func f, void* arg) : f(f), arg(arg) {} public: thread_func f; @@ -99,7 +99,6 @@ namespace embree _mm_setcsr(_mm_getcsr() | /*FTZ:*/ (1<<15) | /*DAZ:*/ (1<<6)); parg->f(parg->arg); delete parg; - parg = nullptr; return 0; } @@ -125,6 +124,12 @@ namespace embree CloseHandle(HANDLE(tid)); } + /*! destroy a hardware thread by its handle */ + void destroyThread(thread_t tid) { + TerminateThread(HANDLE(tid),0); + CloseHandle(HANDLE(tid)); + } + /*! creates thread local storage */ tls_t createTls() { return tls_t(size_t(TlsAlloc())); @@ -153,27 +158,24 @@ namespace embree /// Linux Platform //////////////////////////////////////////////////////////////////////////////// -#if defined(__LINUX__) +// -- GODOT start -- +#if defined(__LINUX__) && !defined(__ANDROID__) +// -- GODOT end -- #include <fstream> #include <sstream> #include <algorithm> -#if defined(__ANDROID__) -#include <pthread.h> -#endif - namespace embree { static MutexSys mutex; static std::vector<size_t> threadIDs; - -#if !defined(__ANDROID__) // TODO(LTE): Implement for Android target + /* changes thread ID mapping such that we first fill up all thread on one core */ size_t mapThreadID(size_t threadID) { Lock<MutexSys> lock(mutex); - + if (threadIDs.size() == 0) { /* parse thread/CPU topology */ @@ -185,11 +187,11 @@ namespace embree if (fs.fail()) break; int i; - while (fs >> i) + while (fs >> i) { if (std::none_of(threadIDs.begin(),threadIDs.end(),[&] (int id) { return id == i; })) threadIDs.push_back(i); - if (fs.peek() == ',') + if (fs.peek() == ',') fs.ignore(); } fs.close(); @@ -233,24 +235,41 @@ namespace embree return ID; } -#endif /*! set affinity of the calling thread */ void setAffinity(ssize_t affinity) { -#if defined(__ANDROID__) - // TODO(LTE): Implement -#else cpu_set_t cset; CPU_ZERO(&cset); size_t threadID = mapThreadID(affinity); CPU_SET(threadID, &cset); pthread_setaffinity_np(pthread_self(), sizeof(cset), &cset); + } +} #endif + +// -- GODOT start -- +//////////////////////////////////////////////////////////////////////////////// +/// Android Platform +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__ANDROID__) + +namespace embree +{ + /*! set affinity of the calling thread */ + void setAffinity(ssize_t affinity) + { + cpu_set_t cset; + CPU_ZERO(&cset); + CPU_SET(affinity, &cset); + + sched_setaffinity(0, sizeof(cset), &cset); } } #endif +// -- GODOT end -- //////////////////////////////////////////////////////////////////////////////// /// FreeBSD Platform @@ -289,10 +308,14 @@ namespace embree /*! set affinity of the calling thread */ void setAffinity(ssize_t affinity) { +#if !defined(__ARM_NEON) // affinity seems not supported on M1 chip + thread_affinity_policy ap; ap.affinity_tag = affinity; if (thread_policy_set(mach_thread_self(),THREAD_AFFINITY_POLICY,(thread_policy_t)&ap,THREAD_AFFINITY_POLICY_COUNT) != KERN_SUCCESS) WARNING("setting thread affinity failed"); // on purpose only a warning + +#endif } } #endif @@ -312,21 +335,21 @@ namespace embree namespace embree { - struct ThreadStartupData + struct ThreadStartupData { public: - ThreadStartupData (thread_func f, void* arg, int affinity) + ThreadStartupData (thread_func f, void* arg, int affinity) : f(f), arg(arg), affinity(affinity) {} - public: + public: thread_func f; void* arg; ssize_t affinity; }; - + static void* threadStartup(ThreadStartupData* parg) { _mm_setcsr(_mm_getcsr() | /*FTZ:*/ (1<<15) | /*DAZ:*/ (1<<6)); - + /*! Mac OS X does not support setting affinity at thread creation time */ #if defined(__MACOSX__) if (parg->affinity >= 0) @@ -335,7 +358,6 @@ namespace embree parg->f(parg->arg); delete parg; - parg = nullptr; return nullptr; } @@ -351,13 +373,15 @@ namespace embree pthread_t* tid = new pthread_t; if (pthread_create(tid,&attr,(void*(*)(void*))threadStartup,new ThreadStartupData(f,arg,threadID)) != 0) { pthread_attr_destroy(&attr); - delete tid; + delete tid; FATAL("pthread_create failed"); } pthread_attr_destroy(&attr); /* set affinity */ +// -- GODOT start -- #if defined(__LINUX__) && !defined(__ANDROID__) +// -- GODOT end -- if (threadID >= 0) { cpu_set_t cset; CPU_ZERO(&cset); @@ -372,7 +396,16 @@ namespace embree CPU_SET(threadID, &cset); pthread_setaffinity_np(*tid, sizeof(cset), &cset); } +// -- GODOT start -- +#elif defined(__ANDROID__) + if (threadID >= 0) { + cpu_set_t cset; + CPU_ZERO(&cset); + CPU_SET(threadID, &cset); + sched_setaffinity(pthread_gettid_np(*tid), sizeof(cset), &cset); + } #endif +// -- GODOT end -- return thread_t(tid); } @@ -389,8 +422,20 @@ namespace embree delete (pthread_t*)tid; } + /*! destroy a hardware thread by its handle */ + void destroyThread(thread_t tid) { +// -- GODOT start -- +#if defined(__ANDROID__) + FATAL("Can't destroy threads on Android."); +#else + pthread_cancel(*(pthread_t*)tid); + delete (pthread_t*)tid; +#endif +// -- GODOT end -- + } + /*! creates thread local storage */ - tls_t createTls() + tls_t createTls() { pthread_key_t* key = new pthread_key_t; if (pthread_key_create(key,nullptr) != 0) { @@ -402,14 +447,14 @@ namespace embree } /*! return the thread local storage pointer */ - void* getTls(tls_t tls) + void* getTls(tls_t tls) { assert(tls); return pthread_getspecific(*(pthread_key_t*)tls); } /*! set the thread local storage pointer */ - void setTls(tls_t tls, void* const ptr) + void setTls(tls_t tls, void* const ptr) { assert(tls); if (pthread_setspecific(*(pthread_key_t*)tls, ptr) != 0) @@ -417,7 +462,7 @@ namespace embree } /*! destroys thread local storage identifier */ - void destroyTls(tls_t tls) + void destroyTls(tls_t tls) { assert(tls); if (pthread_key_delete(*(pthread_key_t*)tls) != 0) diff --git a/thirdparty/embree-aarch64/common/sys/thread.h b/thirdparty/embree/common/sys/thread.h index 45da6e6a70..92a10d5c5d 100644 --- a/thirdparty/embree-aarch64/common/sys/thread.h +++ b/thirdparty/embree/common/sys/thread.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -29,6 +29,9 @@ namespace embree /*! waits until the given thread has terminated */ void join(thread_t tid); + /*! destroy handle of a thread */ + void destroyThread(thread_t tid); + /*! type for handle to thread local storage */ typedef struct opaque_tls_t* tls_t; diff --git a/thirdparty/embree-aarch64/common/sys/vector.h b/thirdparty/embree/common/sys/vector.h index e41794de7c..f832626789 100644 --- a/thirdparty/embree-aarch64/common/sys/vector.h +++ b/thirdparty/embree/common/sys/vector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/tasking/taskscheduler.h b/thirdparty/embree/common/tasking/taskscheduler.h index 9940e068d0..8f3dd87689 100644 --- a/thirdparty/embree-aarch64/common/tasking/taskscheduler.h +++ b/thirdparty/embree/common/tasking/taskscheduler.h @@ -1,12 +1,10 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #if defined(TASKING_INTERNAL) # include "taskschedulerinternal.h" -#elif defined(TASKING_GCD) && defined(BUILD_IOS) -# include "taskschedulergcd.h" #elif defined(TASKING_TBB) # include "taskschedulertbb.h" #elif defined(TASKING_PPL) diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.cpp b/thirdparty/embree/common/tasking/taskschedulerinternal.cpp index ebf656d1a0..ad438588a3 100644 --- a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.cpp +++ b/thirdparty/embree/common/tasking/taskschedulerinternal.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "taskschedulerinternal.h" @@ -154,12 +154,6 @@ namespace embree assert(newNumThreads); newNumThreads = min(newNumThreads, (size_t) getNumberOfLogicalThreads()); - // We are observing a few % gain by increasing number threads by 2 on aarch64. -#if defined(__aarch64__) && defined(BUILD_IOS) - numThreads = newNumThreads*2; -#else - numThreads = newNumThreads; -#endif numThreads = newNumThreads; if (!startThreads && !running) return; running = true; @@ -382,10 +376,10 @@ namespace embree yield(); #endif } - // -- GODOT start -- - // return except; - return; - // -- GODOT end -- + // -- GODOT start -- + // return except; + return; + // -- GODOT end -- } bool TaskScheduler::steal_from_other_threads(Thread& thread) diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.h b/thirdparty/embree/common/tasking/taskschedulerinternal.h index 8bd70b2b8c..8fa6bb12fa 100644 --- a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.h +++ b/thirdparty/embree/common/tasking/taskschedulerinternal.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -135,16 +135,15 @@ namespace embree __forceinline void push_right(Thread& thread, const size_t size, const Closure& closure) { if (right >= TASK_STACK_SIZE) - // -- GODOT start -- - // throw std::runtime_error("task stack overflow"); - abort(); - // -- GODOT end -- + // -- GODOT start -- + // throw std::runtime_error("task stack overflow"); + abort(); + // -- GODOT end -- /* allocate new task on right side of stack */ size_t oldStackPtr = stackPtr; TaskFunction* func = new (alloc(sizeof(ClosureTaskFunction<Closure>))) ClosureTaskFunction<Closure>(closure); - /* gcc 8 or later fails to compile without explicit .load() */ - new (&(tasks[right.load()])) Task(func,thread.task,oldStackPtr,size); + new (&tasks[right]) Task(func,thread.task,oldStackPtr,size); right++; /* also move left pointer */ diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulerppl.h b/thirdparty/embree/common/tasking/taskschedulerppl.h index 776f98cdac..cbc2ecdbb8 100644 --- a/thirdparty/embree-aarch64/common/tasking/taskschedulerppl.h +++ b/thirdparty/embree/common/tasking/taskschedulerppl.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulertbb.h b/thirdparty/embree/common/tasking/taskschedulertbb.h index 98dba26871..35bd49849f 100644 --- a/thirdparty/embree-aarch64/common/tasking/taskschedulertbb.h +++ b/thirdparty/embree/common/tasking/taskschedulertbb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -12,7 +12,13 @@ #include "../sys/ref.h" #if defined(__WIN32__) +// -- GODOT start -- +#if !defined(NOMINMAX) +// -- GODOT end -- # define NOMINMAX +// -- GODOT start -- +#endif +// -- GODOT end -- #endif // We need to define these to avoid implicit linkage against diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore.h b/thirdparty/embree/include/embree3/rtcore.h index 5830bb5880..450ab4c535 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore.h +++ b/thirdparty/embree/include/embree3/rtcore.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_buffer.h b/thirdparty/embree/include/embree3/rtcore_buffer.h index 400b604aa5..6b8eba9769 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_buffer.h +++ b/thirdparty/embree/include/embree3/rtcore_buffer.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_builder.h b/thirdparty/embree/include/embree3/rtcore_builder.h index d62a7f72cc..4bff999fed 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_builder.h +++ b/thirdparty/embree/include/embree3/rtcore_builder.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_common.h b/thirdparty/embree/include/embree3/rtcore_common.h index 890e06faa3..4857e1e05e 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_common.h +++ b/thirdparty/embree/include/embree3/rtcore_common.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -19,7 +19,9 @@ typedef int ssize_t; #endif #endif -#if defined(_WIN32) && !defined(__MINGW32__) +// -- GODOT start -- +#if defined(_WIN32) && defined(_MSC_VER) +// -- GODOT end -- # define RTC_ALIGN(...) __declspec(align(__VA_ARGS__)) #else # define RTC_ALIGN(...) __attribute__((aligned(__VA_ARGS__))) @@ -35,7 +37,7 @@ typedef int ssize_t; #endif #endif -#if defined(_WIN32) +#if defined(_WIN32) # define RTC_FORCEINLINE __forceinline #else # define RTC_FORCEINLINE inline __attribute__((always_inline)) @@ -224,13 +226,13 @@ RTC_FORCEINLINE void rtcInitIntersectContext(struct RTCIntersectContext* context } /* Point query structure for closest point query */ -struct RTC_ALIGN(16) RTCPointQuery +struct RTC_ALIGN(16) RTCPointQuery { float x; // x coordinate of the query point float y; // y coordinate of the query point float z; // z coordinate of the query point float time; // time of the point query - float radius; // radius of the point query + float radius; // radius of the point query }; /* Structure of a packet of 4 query points */ @@ -250,7 +252,7 @@ struct RTC_ALIGN(32) RTCPointQuery8 float y[8]; // y coordinate of the query point float z[8]; // z coordinate of the query point float time[8]; // time of the point query - float radius[8]; // radius ofr the point query + float radius[8]; // radius ofr the point query }; /* Structure of a packet of 16 query points */ @@ -269,11 +271,11 @@ struct RTC_ALIGN(16) RTCPointQueryContext { // accumulated 4x4 column major matrices from world space to instance space. // undefined if size == 0. - float world2inst[RTC_MAX_INSTANCE_LEVEL_COUNT][16]; + float world2inst[RTC_MAX_INSTANCE_LEVEL_COUNT][16]; // accumulated 4x4 column major matrices from instance space to world space. // undefined if size == 0. - float inst2world[RTC_MAX_INSTANCE_LEVEL_COUNT][16]; + float inst2world[RTC_MAX_INSTANCE_LEVEL_COUNT][16]; // instance ids. unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; @@ -301,13 +303,13 @@ struct RTC_ALIGN(16) RTCPointQueryFunctionArguments void* userPtr; // primitive and geometry ID of primitive - unsigned int primID; - unsigned int geomID; + unsigned int primID; + unsigned int geomID; // the context with transformation and instance ID stack struct RTCPointQueryContext* context; - // If the current instance transform M (= context->world2inst[context->instStackSize]) + // If the current instance transform M (= context->world2inst[context->instStackSize]) // is a similarity matrix, i.e there is a constant factor similarityScale such that, // for all x,y: dist(Mx, My) = similarityScale * dist(x, y), // The similarity scale is 0, if the current instance transform is not a @@ -322,5 +324,5 @@ struct RTC_ALIGN(16) RTCPointQueryFunctionArguments }; typedef bool (*RTCPointQueryFunction)(struct RTCPointQueryFunctionArguments* args); - + RTC_NAMESPACE_END diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_config.h b/thirdparty/embree/include/embree3/rtcore_config.h index 337d4e9487..3a9819c9f1 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_config.h +++ b/thirdparty/embree/include/embree3/rtcore_config.h @@ -1,14 +1,14 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define RTC_VERSION_MAJOR 3 -#define RTC_VERSION_MINOR 12 -#define RTC_VERSION_PATCH 1 -#define RTC_VERSION 31201 -#define RTC_VERSION_STRING "3.12.1" +#define RTC_VERSION_MINOR 13 +#define RTC_VERSION_PATCH 0 +#define RTC_VERSION 31300 +#define RTC_VERSION_STRING "3.13.0" #define RTC_MAX_INSTANCE_LEVEL_COUNT 1 diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_device.h b/thirdparty/embree/include/embree3/rtcore_device.h index 594e2b755d..2dd3047603 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_device.h +++ b/thirdparty/embree/include/embree3/rtcore_device.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_geometry.h b/thirdparty/embree/include/embree3/rtcore_geometry.h index c70f1b0e5c..d1de17491c 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_geometry.h +++ b/thirdparty/embree/include/embree3/rtcore_geometry.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_quaternion.h b/thirdparty/embree/include/embree3/rtcore_quaternion.h index 449cdedfdc..6489fa3467 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_quaternion.h +++ b/thirdparty/embree/include/embree3/rtcore_quaternion.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_ray.h b/thirdparty/embree/include/embree3/rtcore_ray.h index 1ae3309ef1..a2ee6dabbb 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_ray.h +++ b/thirdparty/embree/include/embree3/rtcore_ray.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/include/embree3/rtcore_scene.h b/thirdparty/embree/include/embree3/rtcore_scene.h index 0cd6401593..5878a3d402 100644 --- a/thirdparty/embree-aarch64/include/embree3/rtcore_scene.h +++ b/thirdparty/embree/include/embree3/rtcore_scene.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_hair.h b/thirdparty/embree/kernels/builders/bvh_builder_hair.h index 755ce255fb..d83e8918a1 100644 --- a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_hair.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_hair.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_morton.h b/thirdparty/embree/kernels/builders/bvh_builder_morton.h index 92be2f7e65..8f21e3254f 100644 --- a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_morton.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_morton.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h b/thirdparty/embree/kernels/builders/bvh_builder_msmblur.h index 4c138dacdb..f9a08d65cd 100644 --- a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_msmblur.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -297,7 +297,7 @@ namespace embree if (object_split_sah < 0.50f*leaf_sah) return object_split; - /* do temporal splits only if the the time range is big enough */ + /* do temporal splits only if the time range is big enough */ if (set.time_range.size() > 1.01f/float(set.max_num_time_segments)) { const Split temporal_split = heuristicTemporalSplit.find(set,cfg.logBlockSize); diff --git a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur_hair.h b/thirdparty/embree/kernels/builders/bvh_builder_msmblur_hair.h index e477c313a3..397e8636b1 100644 --- a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur_hair.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_msmblur_hair.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_sah.h b/thirdparty/embree/kernels/builders/bvh_builder_sah.h index 3f7e678a10..fff4bf2a35 100644 --- a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_sah.h +++ b/thirdparty/embree/kernels/builders/bvh_builder_sah.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,7 +43,7 @@ namespace embree { if (RTC_BUILD_ARGUMENTS_HAS(settings,maxBranchingFactor)) branchingFactor = settings.maxBranchingFactor; if (RTC_BUILD_ARGUMENTS_HAS(settings,maxDepth )) maxDepth = settings.maxDepth; - if (RTC_BUILD_ARGUMENTS_HAS(settings,sahBlockSize )) logBlockSize = bsr(static_cast<size_t>(settings.sahBlockSize)); + if (RTC_BUILD_ARGUMENTS_HAS(settings,sahBlockSize )) logBlockSize = bsr(settings.sahBlockSize); if (RTC_BUILD_ARGUMENTS_HAS(settings,minLeafSize )) minLeafSize = settings.minLeafSize; if (RTC_BUILD_ARGUMENTS_HAS(settings,maxLeafSize )) maxLeafSize = settings.maxLeafSize; if (RTC_BUILD_ARGUMENTS_HAS(settings,traversalCost )) travCost = settings.traversalCost; diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_binning.h b/thirdparty/embree/kernels/builders/heuristic_binning.h index a4d3b68e46..ee29d09ac9 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_binning.h +++ b/thirdparty/embree/kernels/builders/heuristic_binning.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -444,482 +444,6 @@ namespace embree BBox _bounds[BINS][3]; //!< geometry bounds for each bin in each dimension vuint4 _counts[BINS]; //!< counts number of primitives that map into the bins }; - -#if defined(__AVX512ER__) // KNL - - /*! mapping into bins */ - template<> - struct BinMapping<16> - { - public: - __forceinline BinMapping() {} - - /*! calculates the mapping */ - template<typename PrimInfo> - __forceinline BinMapping(const PrimInfo& pinfo) - { - num = 16; - const vfloat4 eps = 1E-34f; - const vfloat4 diag = max(eps,(vfloat4) pinfo.centBounds.size()); - scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f)); - ofs = (vfloat4) pinfo.centBounds.lower; - scale16 = scale; - ofs16 = ofs; - } - - /*! returns number of bins */ - __forceinline size_t size() const { return num; } - - __forceinline vint16 bin16(const Vec3fa& p) const { - return vint16(vint4(floori((vfloat4(p)-ofs)*scale))); - } - - __forceinline vint16 bin16(const vfloat16& p) const { - return floori((p-ofs16)*scale16); - } - - __forceinline int bin_unsafe(const PrimRef& ref, - const vint16& vSplitPos, - const vbool16& splitDimMask) const // FIXME: rename to isLeft - { - const vfloat16 lower(*(vfloat4*)&ref.lower); - const vfloat16 upper(*(vfloat4*)&ref.upper); - const vfloat16 p = lower + upper; - const vint16 i = floori((p-ofs16)*scale16); - return lt(splitDimMask,i,vSplitPos); - } - - /*! returns true if the mapping is invalid in some dimension */ - __forceinline bool invalid(const size_t dim) const { - return scale[dim] == 0.0f; - } - - public: - size_t num; - vfloat4 ofs,scale; //!< linear function that maps to bin ID - vfloat16 ofs16,scale16; //!< linear function that maps to bin ID - }; - - /* 16 bins in-register binner */ - template<typename PrimRef> - struct __aligned(64) BinInfoT<16,PrimRef,BBox3fa> - { - typedef BinSplit<16> Split; - typedef vbool16 vbool; - typedef vint16 vint; - typedef vfloat16 vfloat; - - __forceinline BinInfoT() { - } - - __forceinline BinInfoT(EmptyTy) { - clear(); - } - - /*! clears the bin info */ - __forceinline void clear() - { - lower[0] = lower[1] = lower[2] = pos_inf; - upper[0] = upper[1] = upper[2] = neg_inf; - count[0] = count[1] = count[2] = 0; - } - - - static __forceinline vfloat16 prefix_area_rl(const vfloat16 min_x, - const vfloat16 min_y, - const vfloat16 min_z, - const vfloat16 max_x, - const vfloat16 max_y, - const vfloat16 max_z) - { - const vfloat16 r_min_x = reverse_prefix_min(min_x); - const vfloat16 r_min_y = reverse_prefix_min(min_y); - const vfloat16 r_min_z = reverse_prefix_min(min_z); - const vfloat16 r_max_x = reverse_prefix_max(max_x); - const vfloat16 r_max_y = reverse_prefix_max(max_y); - const vfloat16 r_max_z = reverse_prefix_max(max_z); - const vfloat16 dx = r_max_x - r_min_x; - const vfloat16 dy = r_max_y - r_min_y; - const vfloat16 dz = r_max_z - r_min_z; - const vfloat16 area_rl = madd(dx,dy,madd(dx,dz,dy*dz)); - return area_rl; - } - - static __forceinline vfloat16 prefix_area_lr(const vfloat16 min_x, - const vfloat16 min_y, - const vfloat16 min_z, - const vfloat16 max_x, - const vfloat16 max_y, - const vfloat16 max_z) - { - const vfloat16 r_min_x = prefix_min(min_x); - const vfloat16 r_min_y = prefix_min(min_y); - const vfloat16 r_min_z = prefix_min(min_z); - const vfloat16 r_max_x = prefix_max(max_x); - const vfloat16 r_max_y = prefix_max(max_y); - const vfloat16 r_max_z = prefix_max(max_z); - const vfloat16 dx = r_max_x - r_min_x; - const vfloat16 dy = r_max_y - r_min_y; - const vfloat16 dz = r_max_z - r_min_z; - const vfloat16 area_lr = madd(dx,dy,madd(dx,dz,dy*dz)); - return area_lr; - } - - - /*! bins an array of primitives */ - __forceinline void bin (const PrimRef* prims, size_t N, const BinMapping<16>& mapping) - { - if (unlikely(N == 0)) return; - - const vfloat16 init_min(pos_inf); - const vfloat16 init_max(neg_inf); - - vfloat16 min_x0,min_x1,min_x2; - vfloat16 min_y0,min_y1,min_y2; - vfloat16 min_z0,min_z1,min_z2; - vfloat16 max_x0,max_x1,max_x2; - vfloat16 max_y0,max_y1,max_y2; - vfloat16 max_z0,max_z1,max_z2; - vuint16 count0,count1,count2; - - min_x0 = init_min; - min_x1 = init_min; - min_x2 = init_min; - min_y0 = init_min; - min_y1 = init_min; - min_y2 = init_min; - min_z0 = init_min; - min_z1 = init_min; - min_z2 = init_min; - - max_x0 = init_max; - max_x1 = init_max; - max_x2 = init_max; - max_y0 = init_max; - max_y1 = init_max; - max_y2 = init_max; - max_z0 = init_max; - max_z1 = init_max; - max_z2 = init_max; - - count0 = zero; - count1 = zero; - count2 = zero; - - const vint16 step16(step); - size_t i; - for (i=0; i<N-1; i+=2) - { - /*! map even and odd primitive to bin */ - const BBox3fa primA = prims[i+0].bounds(); - const vfloat16 centerA = vfloat16((vfloat4)primA.lower) + vfloat16((vfloat4)primA.upper); - const vint16 binA = mapping.bin16(centerA); - - const BBox3fa primB = prims[i+1].bounds(); - const vfloat16 centerB = vfloat16((vfloat4)primB.lower) + vfloat16((vfloat4)primB.upper); - const vint16 binB = mapping.bin16(centerB); - - /* A */ - { - const vfloat16 b_min_x = prims[i+0].lower.x; - const vfloat16 b_min_y = prims[i+0].lower.y; - const vfloat16 b_min_z = prims[i+0].lower.z; - const vfloat16 b_max_x = prims[i+0].upper.x; - const vfloat16 b_max_y = prims[i+0].upper.y; - const vfloat16 b_max_z = prims[i+0].upper.z; - - const vint16 bin0 = shuffle<0>(binA); - const vint16 bin1 = shuffle<1>(binA); - const vint16 bin2 = shuffle<2>(binA); - - const vbool16 m_update_x = step16 == bin0; - const vbool16 m_update_y = step16 == bin1; - const vbool16 m_update_z = step16 == bin2; - - assert(popcnt((size_t)m_update_x) == 1); - assert(popcnt((size_t)m_update_y) == 1); - assert(popcnt((size_t)m_update_z) == 1); - - min_x0 = mask_min(m_update_x,min_x0,min_x0,b_min_x); - min_y0 = mask_min(m_update_x,min_y0,min_y0,b_min_y); - min_z0 = mask_min(m_update_x,min_z0,min_z0,b_min_z); - // ------------------------------------------------------------------------ - max_x0 = mask_max(m_update_x,max_x0,max_x0,b_max_x); - max_y0 = mask_max(m_update_x,max_y0,max_y0,b_max_y); - max_z0 = mask_max(m_update_x,max_z0,max_z0,b_max_z); - // ------------------------------------------------------------------------ - min_x1 = mask_min(m_update_y,min_x1,min_x1,b_min_x); - min_y1 = mask_min(m_update_y,min_y1,min_y1,b_min_y); - min_z1 = mask_min(m_update_y,min_z1,min_z1,b_min_z); - // ------------------------------------------------------------------------ - max_x1 = mask_max(m_update_y,max_x1,max_x1,b_max_x); - max_y1 = mask_max(m_update_y,max_y1,max_y1,b_max_y); - max_z1 = mask_max(m_update_y,max_z1,max_z1,b_max_z); - // ------------------------------------------------------------------------ - min_x2 = mask_min(m_update_z,min_x2,min_x2,b_min_x); - min_y2 = mask_min(m_update_z,min_y2,min_y2,b_min_y); - min_z2 = mask_min(m_update_z,min_z2,min_z2,b_min_z); - // ------------------------------------------------------------------------ - max_x2 = mask_max(m_update_z,max_x2,max_x2,b_max_x); - max_y2 = mask_max(m_update_z,max_y2,max_y2,b_max_y); - max_z2 = mask_max(m_update_z,max_z2,max_z2,b_max_z); - // ------------------------------------------------------------------------ - count0 = mask_add(m_update_x,count0,count0,vuint16(1)); - count1 = mask_add(m_update_y,count1,count1,vuint16(1)); - count2 = mask_add(m_update_z,count2,count2,vuint16(1)); - } - - - /* B */ - { - const vfloat16 b_min_x = prims[i+1].lower.x; - const vfloat16 b_min_y = prims[i+1].lower.y; - const vfloat16 b_min_z = prims[i+1].lower.z; - const vfloat16 b_max_x = prims[i+1].upper.x; - const vfloat16 b_max_y = prims[i+1].upper.y; - const vfloat16 b_max_z = prims[i+1].upper.z; - - const vint16 bin0 = shuffle<0>(binB); - const vint16 bin1 = shuffle<1>(binB); - const vint16 bin2 = shuffle<2>(binB); - - const vbool16 m_update_x = step16 == bin0; - const vbool16 m_update_y = step16 == bin1; - const vbool16 m_update_z = step16 == bin2; - - assert(popcnt((size_t)m_update_x) == 1); - assert(popcnt((size_t)m_update_y) == 1); - assert(popcnt((size_t)m_update_z) == 1); - - min_x0 = mask_min(m_update_x,min_x0,min_x0,b_min_x); - min_y0 = mask_min(m_update_x,min_y0,min_y0,b_min_y); - min_z0 = mask_min(m_update_x,min_z0,min_z0,b_min_z); - // ------------------------------------------------------------------------ - max_x0 = mask_max(m_update_x,max_x0,max_x0,b_max_x); - max_y0 = mask_max(m_update_x,max_y0,max_y0,b_max_y); - max_z0 = mask_max(m_update_x,max_z0,max_z0,b_max_z); - // ------------------------------------------------------------------------ - min_x1 = mask_min(m_update_y,min_x1,min_x1,b_min_x); - min_y1 = mask_min(m_update_y,min_y1,min_y1,b_min_y); - min_z1 = mask_min(m_update_y,min_z1,min_z1,b_min_z); - // ------------------------------------------------------------------------ - max_x1 = mask_max(m_update_y,max_x1,max_x1,b_max_x); - max_y1 = mask_max(m_update_y,max_y1,max_y1,b_max_y); - max_z1 = mask_max(m_update_y,max_z1,max_z1,b_max_z); - // ------------------------------------------------------------------------ - min_x2 = mask_min(m_update_z,min_x2,min_x2,b_min_x); - min_y2 = mask_min(m_update_z,min_y2,min_y2,b_min_y); - min_z2 = mask_min(m_update_z,min_z2,min_z2,b_min_z); - // ------------------------------------------------------------------------ - max_x2 = mask_max(m_update_z,max_x2,max_x2,b_max_x); - max_y2 = mask_max(m_update_z,max_y2,max_y2,b_max_y); - max_z2 = mask_max(m_update_z,max_z2,max_z2,b_max_z); - // ------------------------------------------------------------------------ - count0 = mask_add(m_update_x,count0,count0,vuint16(1)); - count1 = mask_add(m_update_y,count1,count1,vuint16(1)); - count2 = mask_add(m_update_z,count2,count2,vuint16(1)); - } - - } - - if (i < N) - { - const BBox3fa prim0 = prims[i].bounds(); - const vfloat16 center0 = vfloat16((vfloat4)prim0.lower) + vfloat16((vfloat4)prim0.upper); - const vint16 bin = mapping.bin16(center0); - - const vfloat16 b_min_x = prims[i].lower.x; - const vfloat16 b_min_y = prims[i].lower.y; - const vfloat16 b_min_z = prims[i].lower.z; - const vfloat16 b_max_x = prims[i].upper.x; - const vfloat16 b_max_y = prims[i].upper.y; - const vfloat16 b_max_z = prims[i].upper.z; - - const vint16 bin0 = shuffle<0>(bin); - const vint16 bin1 = shuffle<1>(bin); - const vint16 bin2 = shuffle<2>(bin); - - const vbool16 m_update_x = step16 == bin0; - const vbool16 m_update_y = step16 == bin1; - const vbool16 m_update_z = step16 == bin2; - - assert(popcnt((size_t)m_update_x) == 1); - assert(popcnt((size_t)m_update_y) == 1); - assert(popcnt((size_t)m_update_z) == 1); - - min_x0 = mask_min(m_update_x,min_x0,min_x0,b_min_x); - min_y0 = mask_min(m_update_x,min_y0,min_y0,b_min_y); - min_z0 = mask_min(m_update_x,min_z0,min_z0,b_min_z); - // ------------------------------------------------------------------------ - max_x0 = mask_max(m_update_x,max_x0,max_x0,b_max_x); - max_y0 = mask_max(m_update_x,max_y0,max_y0,b_max_y); - max_z0 = mask_max(m_update_x,max_z0,max_z0,b_max_z); - // ------------------------------------------------------------------------ - min_x1 = mask_min(m_update_y,min_x1,min_x1,b_min_x); - min_y1 = mask_min(m_update_y,min_y1,min_y1,b_min_y); - min_z1 = mask_min(m_update_y,min_z1,min_z1,b_min_z); - // ------------------------------------------------------------------------ - max_x1 = mask_max(m_update_y,max_x1,max_x1,b_max_x); - max_y1 = mask_max(m_update_y,max_y1,max_y1,b_max_y); - max_z1 = mask_max(m_update_y,max_z1,max_z1,b_max_z); - // ------------------------------------------------------------------------ - min_x2 = mask_min(m_update_z,min_x2,min_x2,b_min_x); - min_y2 = mask_min(m_update_z,min_y2,min_y2,b_min_y); - min_z2 = mask_min(m_update_z,min_z2,min_z2,b_min_z); - // ------------------------------------------------------------------------ - max_x2 = mask_max(m_update_z,max_x2,max_x2,b_max_x); - max_y2 = mask_max(m_update_z,max_y2,max_y2,b_max_y); - max_z2 = mask_max(m_update_z,max_z2,max_z2,b_max_z); - // ------------------------------------------------------------------------ - count0 = mask_add(m_update_x,count0,count0,vuint16(1)); - count1 = mask_add(m_update_y,count1,count1,vuint16(1)); - count2 = mask_add(m_update_z,count2,count2,vuint16(1)); - } - - lower[0] = Vec3vf16( min_x0, min_y0, min_z0 ); - lower[1] = Vec3vf16( min_x1, min_y1, min_z1 ); - lower[2] = Vec3vf16( min_x2, min_y2, min_z2 ); - - upper[0] = Vec3vf16( max_x0, max_y0, max_z0 ); - upper[1] = Vec3vf16( max_x1, max_y1, max_z1 ); - upper[2] = Vec3vf16( max_x2, max_y2, max_z2 ); - - count[0] = count0; - count[1] = count1; - count[2] = count2; - } - - __forceinline void bin(const PrimRef* prims, size_t begin, size_t end, const BinMapping<16>& mapping) { - bin(prims+begin,end-begin,mapping); - } - - /*! merges in other binning information */ - __forceinline void merge (const BinInfoT& other, size_t numBins) - { - for (size_t i=0; i<3; i++) - { - lower[i] = min(lower[i],other.lower[i]); - upper[i] = max(upper[i],other.upper[i]); - count[i] += other.count[i]; - } - } - - /*! reducesr binning information */ - static __forceinline const BinInfoT reduce (const BinInfoT& a, const BinInfoT& b) - { - BinInfoT c; - for (size_t i=0; i<3; i++) - { - c.counts[i] = a.counts[i] + b.counts[i]; - c.lower[i] = min(a.lower[i],b.lower[i]); - c.upper[i] = max(a.upper[i],b.upper[i]); - } - return c; - } - - /*! finds the best split by scanning binning information */ - __forceinline Split best(const BinMapping<16>& mapping, const size_t blocks_shift) const - { - /* find best dimension */ - float bestSAH = inf; - int bestDim = -1; - int bestPos = 0; - const vuint16 blocks_add = (1 << blocks_shift)-1; - const vfloat16 inf(pos_inf); - for (size_t dim=0; dim<3; dim++) - { - /* ignore zero sized dimensions */ - if (unlikely(mapping.invalid(dim))) - continue; - - const vfloat16 rArea16 = prefix_area_rl(lower[dim].x,lower[dim].y,lower[dim].z, upper[dim].x,upper[dim].y,upper[dim].z); - const vfloat16 lArea16 = prefix_area_lr(lower[dim].x,lower[dim].y,lower[dim].z, upper[dim].x,upper[dim].y,upper[dim].z); - const vuint16 lCount16 = prefix_sum(count[dim]); - const vuint16 rCount16 = reverse_prefix_sum(count[dim]); - - /* compute best split in this dimension */ - const vfloat16 leftArea = lArea16; - const vfloat16 rightArea = align_shift_right<1>(zero,rArea16); - const vuint16 lC = lCount16; - const vuint16 rC = align_shift_right<1>(zero,rCount16); - const vuint16 leftCount = ( lC + blocks_add) >> blocks_shift; - const vuint16 rightCount = ( rC + blocks_add) >> blocks_shift; - const vbool16 valid = (leftArea < inf) & (rightArea < inf) & vbool16(0x7fff); // handles inf entries - const vfloat16 sah = select(valid,madd(leftArea,vfloat16(leftCount),rightArea*vfloat16(rightCount)),vfloat16(pos_inf)); - /* test if this is a better dimension */ - if (any(sah < vfloat16(bestSAH))) - { - const size_t index = select_min(sah); - assert(index < 15); - assert(sah[index] < bestSAH); - bestDim = dim; - bestPos = index+1; - bestSAH = sah[index]; - } - } - - return Split(bestSAH,bestDim,bestPos,mapping); - - } - - /*! calculates extended split information */ - __forceinline void getSplitInfo(const BinMapping<16>& mapping, const Split& split, SplitInfo& info) const - { - if (split.dim == -1) { - new (&info) SplitInfo(0,empty,0,empty); - return; - } - // FIXME: horizontal reduction! - - size_t leftCount = 0; - BBox3fa leftBounds = empty; - for (size_t i=0; i<(size_t)split.pos; i++) { - leftCount += count[split.dim][i]; - Vec3fa bounds_lower(lower[split.dim].x[i],lower[split.dim].y[i],lower[split.dim].z[i]); - Vec3fa bounds_upper(upper[split.dim].x[i],upper[split.dim].y[i],upper[split.dim].z[i]); - leftBounds.extend(BBox3fa(bounds_lower,bounds_upper)); - } - size_t rightCount = 0; - BBox3fa rightBounds = empty; - for (size_t i=split.pos; i<mapping.size(); i++) { - rightCount += count[split.dim][i]; - Vec3fa bounds_lower(lower[split.dim].x[i],lower[split.dim].y[i],lower[split.dim].z[i]); - Vec3fa bounds_upper(upper[split.dim].x[i],upper[split.dim].y[i],upper[split.dim].z[i]); - rightBounds.extend(BBox3fa(bounds_lower,bounds_upper)); - } - new (&info) SplitInfo(leftCount,leftBounds,rightCount,rightBounds); - } - - /*! gets the number of primitives left of the split */ - __forceinline size_t getLeftCount(const BinMapping<16>& mapping, const Split& split) const - { - if (unlikely(split.dim == -1)) return -1; - - size_t leftCount = 0; - for (size_t i = 0; i < (size_t)split.pos; i++) { - leftCount += count[split.dim][i]; - } - return leftCount; - } - - /*! gets the number of primitives right of the split */ - __forceinline size_t getRightCount(const BinMapping<16>& mapping, const Split& split) const - { - if (unlikely(split.dim == -1)) return -1; - - size_t rightCount = 0; - for (size_t i = (size_t)split.pos; i<mapping.size(); i++) { - rightCount += count[split.dim][i]; - } - return rightCount; - } - - private: - Vec3vf16 lower[3]; - Vec3vf16 upper[3]; - vuint16 count[3]; - }; -#endif } template<typename BinInfoT, typename BinMapping, typename PrimRef> diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_binning_array_aligned.h b/thirdparty/embree/kernels/builders/heuristic_binning_array_aligned.h index a4c272f015..ab3b97efb9 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_binning_array_aligned.h +++ b/thirdparty/embree/kernels/builders/heuristic_binning_array_aligned.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -40,15 +40,10 @@ namespace embree typedef BinInfoT<BINS,PrimRef,BBox3fa> Binner; typedef range<size_t> Set; -#if defined(__AVX512ER__) // KNL - static const size_t PARALLEL_THRESHOLD = 4*768; - static const size_t PARALLEL_FIND_BLOCK_SIZE = 768; - static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 768; -#else static const size_t PARALLEL_THRESHOLD = 3 * 1024; static const size_t PARALLEL_FIND_BLOCK_SIZE = 1024; static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128; -#endif + __forceinline HeuristicArrayBinningSAH () : prims(nullptr) {} diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_binning_array_unaligned.h b/thirdparty/embree/kernels/builders/heuristic_binning_array_unaligned.h index 1370244586..34a7f121bb 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_binning_array_unaligned.h +++ b/thirdparty/embree/kernels/builders/heuristic_binning_array_unaligned.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_openmerge_array.h b/thirdparty/embree/kernels/builders/heuristic_openmerge_array.h index 21f18c0208..4249d16ea1 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_openmerge_array.h +++ b/thirdparty/embree/kernels/builders/heuristic_openmerge_array.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // TODO: diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_spatial.h b/thirdparty/embree/kernels/builders/heuristic_spatial.h index d8ca6cb92c..a6939ba258 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_spatial.h +++ b/thirdparty/embree/kernels/builders/heuristic_spatial.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_spatial_array.h b/thirdparty/embree/kernels/builders/heuristic_spatial_array.h index 911dcf950c..60d235f48d 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_spatial_array.h +++ b/thirdparty/embree/kernels/builders/heuristic_spatial_array.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -107,15 +107,9 @@ namespace embree //typedef extended_range<size_t> Set; typedef Split2<ObjectSplit,SpatialSplit> Split; -#if defined(__AVX512ER__) // KNL - static const size_t PARALLEL_THRESHOLD = 3*1024; - static const size_t PARALLEL_FIND_BLOCK_SIZE = 768; - static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128; -#else static const size_t PARALLEL_THRESHOLD = 3*1024; static const size_t PARALLEL_FIND_BLOCK_SIZE = 1024; static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128; -#endif static const size_t MOVE_STEP_SIZE = 64; static const size_t CREATE_SPLITS_STEP_SIZE = 64; diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_strand_array.h b/thirdparty/embree/kernels/builders/heuristic_strand_array.h index ede0d04c78..19c7fcdaa8 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_strand_array.h +++ b/thirdparty/embree/kernels/builders/heuristic_strand_array.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/heuristic_timesplit_array.h b/thirdparty/embree/kernels/builders/heuristic_timesplit_array.h index c999941a11..b968e01c90 100644 --- a/thirdparty/embree-aarch64/kernels/builders/heuristic_timesplit_array.h +++ b/thirdparty/embree/kernels/builders/heuristic_timesplit_array.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/priminfo.h b/thirdparty/embree/kernels/builders/priminfo.h index 06c1388742..fee515247a 100644 --- a/thirdparty/embree-aarch64/kernels/builders/priminfo.h +++ b/thirdparty/embree/kernels/builders/priminfo.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/primrefgen.cpp b/thirdparty/embree/kernels/builders/primrefgen.cpp index e23de3df28..d279dc4993 100644 --- a/thirdparty/embree-aarch64/kernels/builders/primrefgen.cpp +++ b/thirdparty/embree/kernels/builders/primrefgen.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "primrefgen.h" @@ -11,7 +11,7 @@ namespace embree { namespace isa { - PrimInfo createPrimRefArray(Geometry* geometry, unsigned int geomID, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor) + PrimInfo createPrimRefArray(Geometry* geometry, unsigned int geomID, const size_t numPrimRefs, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor) { ParallelPrefixSumState<PrimInfo> pstate; @@ -22,7 +22,7 @@ namespace embree }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); /* if we need to filter out geometry, run again */ - if (pinfo.size() != prims.size()) + if (pinfo.size() != numPrimRefs) { progressMonitor(0); pinfo = parallel_prefix_sum( pstate, size_t(0), geometry->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo { @@ -32,7 +32,7 @@ namespace embree return pinfo; } - PrimInfo createPrimRefArray(Scene* scene, Geometry::GTypeMask types, bool mblur, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor) + PrimInfo createPrimRefArray(Scene* scene, Geometry::GTypeMask types, bool mblur, const size_t numPrimRefs, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor) { ParallelForForPrefixSumState<PrimInfo> pstate; Scene::Iterator2 iter(scene,types,mblur); @@ -45,7 +45,7 @@ namespace embree }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); /* if we need to filter out geometry, run again */ - if (pinfo.size() != prims.size()) + if (pinfo.size() != numPrimRefs) { progressMonitor(0); pinfo = parallel_for_for_prefix_sum1( pstate, iter, PrimInfo(empty), [&](Geometry* mesh, const range<size_t>& r, size_t k, size_t geomID, const PrimInfo& base) -> PrimInfo { @@ -55,7 +55,7 @@ namespace embree return pinfo; } - PrimInfo createPrimRefArrayMBlur(Scene* scene, Geometry::GTypeMask types, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor, size_t itime) + PrimInfo createPrimRefArrayMBlur(Scene* scene, Geometry::GTypeMask types, const size_t numPrimRefs, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor, size_t itime) { ParallelForForPrefixSumState<PrimInfo> pstate; Scene::Iterator2 iter(scene,types,true); @@ -68,7 +68,7 @@ namespace embree }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); /* if we need to filter out geometry, run again */ - if (pinfo.size() != prims.size()) + if (pinfo.size() != numPrimRefs) { progressMonitor(0); pinfo = parallel_for_for_prefix_sum1( pstate, iter, PrimInfo(empty), [&](Geometry* mesh, const range<size_t>& r, size_t k, size_t geomID, const PrimInfo& base) -> PrimInfo { @@ -78,7 +78,7 @@ namespace embree return pinfo; } - PrimInfoMB createPrimRefArrayMSMBlur(Scene* scene, Geometry::GTypeMask types, mvector<PrimRefMB>& prims, BuildProgressMonitor& progressMonitor, BBox1f t0t1) + PrimInfoMB createPrimRefArrayMSMBlur(Scene* scene, Geometry::GTypeMask types, const size_t numPrimRefs, mvector<PrimRefMB>& prims, BuildProgressMonitor& progressMonitor, BBox1f t0t1) { ParallelForForPrefixSumState<PrimInfoMB> pstate; Scene::Iterator2 iter(scene,types,true); @@ -91,7 +91,7 @@ namespace embree }, [](const PrimInfoMB& a, const PrimInfoMB& b) -> PrimInfoMB { return PrimInfoMB::merge2(a,b); }); /* if we need to filter out geometry, run again */ - if (pinfo.size() != prims.size()) + if (pinfo.size() != numPrimRefs) { progressMonitor(0); pinfo = parallel_for_for_prefix_sum1( pstate, iter, PrimInfoMB(empty), [&](Geometry* mesh, const range<size_t>& r, size_t k, size_t geomID, const PrimInfoMB& base) -> PrimInfoMB { @@ -182,56 +182,124 @@ namespace embree // ==================================================================================================== // ==================================================================================================== - // template for grid meshes + // special variants for grid meshes -#if 0 - template<> - PrimInfo createPrimRefArray<GridMesh,false>(Scene* scene, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor) +// -- GODOT start -- +#if defined(EMBREE_GEOMETRY_GRID) +// -- GODOT end -- + PrimInfo createPrimRefArrayGrids(Scene* scene, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids) { - PING; + PrimInfo pinfo(empty); + size_t numPrimitives = 0; + + /* first run to get #primitives */ + ParallelForForPrefixSumState<PrimInfo> pstate; Scene::Iterator<GridMesh,false> iter(scene); - - /* first try */ - progressMonitor(0); + pstate.init(iter,size_t(1024)); - PrimInfo pinfo = parallel_for_for_prefix_sum0( pstate, iter, PrimInfo(empty), [&](GridMesh* mesh, const range<size_t>& r, size_t k) -> PrimInfo - { - PrimInfo pinfo(empty); - for (size_t j=r.begin(); j<r.end(); j++) - { - BBox3fa bounds = empty; - if (!mesh->buildBounds(j,&bounds)) continue; - const PrimRef prim(bounds,mesh->geomID,unsigned(j)); - pinfo.add_center2(prim); - prims[k++] = prim; - } - return pinfo; - }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); - - /* if we need to filter out geometry, run again */ - if (pinfo.size() != prims.size()) - { - progressMonitor(0); - pinfo = parallel_for_for_prefix_sum1( pstate, iter, PrimInfo(empty), [&](GridMesh* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo - { - k = base.size(); + + /* iterate over all meshes in the scene */ + pinfo = parallel_for_for_prefix_sum0( pstate, iter, PrimInfo(empty), [&](GridMesh* mesh, const range<size_t>& r, size_t k, size_t geomID) -> PrimInfo { PrimInfo pinfo(empty); for (size_t j=r.begin(); j<r.end(); j++) { + if (!mesh->valid(j)) continue; BBox3fa bounds = empty; - if (!mesh->buildBounds(j,&bounds)) continue; - const PrimRef prim(bounds,mesh->geomID,unsigned(j)); - pinfo.add_center2(prim); - prims[k++] = prim; + const PrimRef prim(bounds,(unsigned)geomID,(unsigned)j); + if (!mesh->valid(j)) continue; + pinfo.add_center2(prim,mesh->getNumSubGrids(j)); } return pinfo; }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); - } + numPrimitives = pinfo.size(); + + /* resize arrays */ + sgrids.resize(numPrimitives); + prims.resize(numPrimitives); + + /* second run to fill primrefs and SubGridBuildData arrays */ + pinfo = parallel_for_for_prefix_sum1( pstate, iter, PrimInfo(empty), [&](GridMesh* mesh, const range<size_t>& r, size_t k, size_t geomID, const PrimInfo& base) -> PrimInfo { + k = base.size(); + size_t p_index = k; + PrimInfo pinfo(empty); + for (size_t j=r.begin(); j<r.end(); j++) + { + if (!mesh->valid(j)) continue; + const GridMesh::Grid &g = mesh->grid(j); + for (unsigned int y=0; y<g.resY-1u; y+=2) + for (unsigned int x=0; x<g.resX-1u; x+=2) + { + BBox3fa bounds = empty; + if (!mesh->buildBounds(g,x,y,bounds)) continue; // get bounds of subgrid + const PrimRef prim(bounds,(unsigned)geomID,(unsigned)p_index); + pinfo.add_center2(prim); + sgrids[p_index] = SubGridBuildData(x | g.get3x3FlagsX(x), y | g.get3x3FlagsY(y), unsigned(j)); + prims[p_index++] = prim; + } + } + return pinfo; + }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); + assert(pinfo.size() == numPrimitives); return pinfo; } -#endif + PrimInfo createPrimRefArrayGrids(GridMesh* mesh, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids) + { + unsigned int geomID_ = std::numeric_limits<unsigned int>::max (); + + PrimInfo pinfo(empty); + size_t numPrimitives = 0; + + ParallelPrefixSumState<PrimInfo> pstate; + /* iterate over all grids in a single mesh */ + pinfo = parallel_prefix_sum( pstate, size_t(0), mesh->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo + { + PrimInfo pinfo(empty); + for (size_t j=r.begin(); j<r.end(); j++) + { + if (!mesh->valid(j)) continue; + BBox3fa bounds = empty; + const PrimRef prim(bounds,geomID_,unsigned(j)); + pinfo.add_center2(prim,mesh->getNumSubGrids(j)); + } + return pinfo; + }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); + numPrimitives = pinfo.size(); + /* resize arrays */ + sgrids.resize(numPrimitives); + prims.resize(numPrimitives); + + /* second run to fill primrefs and SubGridBuildData arrays */ + pinfo = parallel_prefix_sum( pstate, size_t(0), mesh->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo + { + + size_t p_index = base.size(); + PrimInfo pinfo(empty); + for (size_t j=r.begin(); j<r.end(); j++) + { + if (!mesh->valid(j)) continue; + const GridMesh::Grid &g = mesh->grid(j); + for (unsigned int y=0; y<g.resY-1u; y+=2) + for (unsigned int x=0; x<g.resX-1u; x+=2) + { + BBox3fa bounds = empty; + if (!mesh->buildBounds(g,x,y,bounds)) continue; // get bounds of subgrid + const PrimRef prim(bounds,geomID_,unsigned(p_index)); + pinfo.add_center2(prim); + sgrids[p_index] = SubGridBuildData(x | g.get3x3FlagsX(x), y | g.get3x3FlagsY(y), unsigned(j)); + prims[p_index++] = prim; + } + } + return pinfo; + }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); + + return pinfo; + } +// -- GODOT start -- +#endif +// -- GODOT end -- + // ==================================================================================================== // ==================================================================================================== // ==================================================================================================== diff --git a/thirdparty/embree/kernels/builders/primrefgen.h b/thirdparty/embree/kernels/builders/primrefgen.h new file mode 100644 index 0000000000..c09a848ba3 --- /dev/null +++ b/thirdparty/embree/kernels/builders/primrefgen.h @@ -0,0 +1,34 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "../common/scene.h" +#include "../common/primref.h" +#include "../common/primref_mb.h" +#include "priminfo.h" +#include "bvh_builder_morton.h" + +namespace embree +{ + namespace isa + { + PrimInfo createPrimRefArray(Geometry* geometry, unsigned int geomID, size_t numPrimitives, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor); + + PrimInfo createPrimRefArray(Scene* scene, Geometry::GTypeMask types, bool mblur, size_t numPrimitives, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor); + + PrimInfo createPrimRefArrayMBlur(Scene* scene, Geometry::GTypeMask types, size_t numPrimitives, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor, size_t itime = 0); + + PrimInfoMB createPrimRefArrayMSMBlur(Scene* scene, Geometry::GTypeMask types, size_t numPrimitives, mvector<PrimRefMB>& prims, BuildProgressMonitor& progressMonitor, BBox1f t0t1 = BBox1f(0.0f,1.0f)); + + template<typename Mesh> + size_t createMortonCodeArray(Mesh* mesh, mvector<BVHBuilderMorton::BuildPrim>& morton, BuildProgressMonitor& progressMonitor); + + /* special variants for grids */ + PrimInfo createPrimRefArrayGrids(Scene* scene, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids); + + PrimInfo createPrimRefArrayGrids(GridMesh* mesh, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids); + + } +} + diff --git a/thirdparty/embree-aarch64/kernels/builders/primrefgen_presplit.h b/thirdparty/embree/kernels/builders/primrefgen_presplit.h index 8bdb38b955..8cd251ddd2 100644 --- a/thirdparty/embree-aarch64/kernels/builders/primrefgen_presplit.h +++ b/thirdparty/embree/kernels/builders/primrefgen_presplit.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/builders/splitter.h b/thirdparty/embree/kernels/builders/splitter.h index dbd6cf07c7..f7720bd284 100644 --- a/thirdparty/embree-aarch64/kernels/builders/splitter.h +++ b/thirdparty/embree/kernels/builders/splitter.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -164,6 +164,28 @@ namespace embree private: const Scene* scene; }; + + + struct DummySplitter + { + __forceinline DummySplitter(const Scene* scene, const PrimRef& prim) + { + } + }; + + struct DummySplitterFactory + { + __forceinline DummySplitterFactory(const Scene* scene) + : scene(scene) {} + + __forceinline DummySplitter operator() (const PrimRef& prim) const { + return DummySplitter(scene,prim); + } + + private: + const Scene* scene; + }; + } } diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh.cpp b/thirdparty/embree/kernels/bvh/bvh.cpp index bd102bd6ef..a84295f0da 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh.cpp +++ b/thirdparty/embree/kernels/bvh/bvh.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh.h" @@ -51,7 +51,7 @@ namespace embree template<int N> void BVHN<N>::layoutLargeNodes(size_t num) { -#if defined(__X86_64__) || defined(__aarch64__) // do not use tree rotations on 32 bit platforms, barrier bit in NodeRef will cause issues +#if defined(__64BIT__) // do not use tree rotations on 32 bit platforms, barrier bit in NodeRef will cause issues struct NodeArea { __forceinline NodeArea() {} @@ -183,7 +183,7 @@ namespace embree template class BVHN<8>; #endif -#if !defined(__AVX__) || !defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42) || defined(__aarch64__) +#if !defined(__AVX__) || !defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42) template class BVHN<4>; #endif } diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh.h b/thirdparty/embree/kernels/bvh/bvh.h index 8fdf912e52..565eec5a58 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh.h +++ b/thirdparty/embree/kernels/bvh/bvh.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -81,7 +81,7 @@ namespace embree struct CreateAlloc : public FastAllocator::Create { __forceinline CreateAlloc (BVHN* bvh) : FastAllocator::Create(&bvh->alloc) {} }; - + typedef BVHNodeRecord<NodeRef> NodeRecord; typedef BVHNodeRecordMB<NodeRef> NodeRecordMB; typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D; diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh4_factory.cpp b/thirdparty/embree/kernels/bvh/bvh4_factory.cpp index 23f4f63d45..890d5e7b7c 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh4_factory.cpp +++ b/thirdparty/embree/kernels/bvh/bvh4_factory.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh4_factory.h" @@ -260,12 +260,12 @@ namespace embree void BVH4Factory::selectBuilders(int features) { - IF_ENABLED_TRIS (SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4BuilderTwoLevelTriangle4MeshSAH)); - IF_ENABLED_TRIS (SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4BuilderTwoLevelTriangle4iMeshSAH)); - IF_ENABLED_TRIS (SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4BuilderTwoLevelTriangle4vMeshSAH)); - IF_ENABLED_QUADS (SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4BuilderTwoLevelQuadMeshSAH)); - IF_ENABLED_USER (SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4BuilderTwoLevelVirtualSAH)); - IF_ENABLED_INSTANCE (SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4BuilderTwoLevelInstanceSAH)); + IF_ENABLED_TRIS (SELECT_SYMBOL_DEFAULT_AVX(features,BVH4BuilderTwoLevelTriangle4MeshSAH)); + IF_ENABLED_TRIS (SELECT_SYMBOL_DEFAULT_AVX(features,BVH4BuilderTwoLevelTriangle4iMeshSAH)); + IF_ENABLED_TRIS (SELECT_SYMBOL_DEFAULT_AVX(features,BVH4BuilderTwoLevelTriangle4vMeshSAH)); + IF_ENABLED_QUADS (SELECT_SYMBOL_DEFAULT_AVX(features,BVH4BuilderTwoLevelQuadMeshSAH)); + IF_ENABLED_USER (SELECT_SYMBOL_DEFAULT_AVX(features,BVH4BuilderTwoLevelVirtualSAH)); + IF_ENABLED_INSTANCE (SELECT_SYMBOL_DEFAULT_AVX(features,BVH4BuilderTwoLevelInstanceSAH)); IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Curve4vBuilder_OBB_New)); IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Curve4iBuilder_OBB_New)); @@ -273,15 +273,15 @@ namespace embree IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX(features,BVH4Curve8iBuilder_OBB_New)); IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX(features,BVH4OBBCurve8iMBBuilder_OBB)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4Triangle4SceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4Triangle4vSceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4Triangle4iSceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Triangle4SceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Triangle4vSceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Triangle4iSceneBuilderSAH)); IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Triangle4iMBSceneBuilderSAH)); IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Triangle4vMBSceneBuilderSAH)); IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4QuantizedTriangle4iSceneBuilderSAH)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4Quad4vSceneBuilderSAH)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4Quad4iSceneBuilderSAH)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Quad4vSceneBuilderSAH)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Quad4iSceneBuilderSAH)); IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Quad4iMBSceneBuilderSAH)); IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4QuantizedQuad4iSceneBuilderSAH)); @@ -291,207 +291,207 @@ namespace embree IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4Quad4vSceneBuilderFastSpatialSAH)); - IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4VirtualSceneBuilderSAH)); + IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4VirtualSceneBuilderSAH)); IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4VirtualMBSceneBuilderSAH)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4InstanceSceneBuilderSAH)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4InstanceSceneBuilderSAH)); IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4InstanceMBSceneBuilderSAH)); IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4GridSceneBuilderSAH)); IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4GridMBSceneBuilderSAH)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4SubdivPatch1BuilderSAH)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,BVH4SubdivPatch1MBBuilderSAH)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4SubdivPatch1BuilderSAH)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_AVX(features,BVH4SubdivPatch1MBBuilderSAH)); } void BVH4Factory::selectIntersectors(int features) { - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector4i)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector8i)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector4v)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector8v)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector4iMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector8iMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,VirtualCurveIntersector4i)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,VirtualCurveIntersector8i)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,VirtualCurveIntersector4v)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,VirtualCurveIntersector8v)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,VirtualCurveIntersector4iMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,VirtualCurveIntersector8iMB)); /* select intersectors1 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersector1)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersector1MB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust1)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust1MB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersector1)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersector1MB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust1)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust1MB)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4Intersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,BVH4Triangle4iIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,BVH4Triangle4vIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,BVH4Triangle4iIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4Triangle4Intersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,BVH4Triangle4iIntersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,BVH4Triangle4vIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,BVH4Triangle4iIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vMBIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iMBIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vMBIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iMBIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4vMBIntersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iMBIntersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4vMBIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iMBIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector1Moeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iIntersector1Moeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iIntersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iMBIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iMBIntersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iMBIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iMBIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,QBVH4Triangle4iIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,QBVH4Quad4iIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,QBVH4Triangle4iIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,QBVH4Quad4iIntersector1Pluecker)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4SubdivPatch1Intersector1)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4SubdivPatch1MBIntersector1)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4SubdivPatch1Intersector1)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4SubdivPatch1MBIntersector1)); - IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4VirtualIntersector1)); - IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4VirtualMBIntersector1)); + IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4VirtualIntersector1)); + IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4VirtualMBIntersector1)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4InstanceIntersector1)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4InstanceMBIntersector1)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4InstanceIntersector1)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4InstanceMBIntersector1)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4GridIntersector1Moeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4GridMBIntersector1Moeller)) - IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4GridIntersector1Pluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4GridIntersector1Moeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4GridMBIntersector1Moeller)) + IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4GridIntersector1Pluecker)); #if defined (EMBREE_RAY_PACKETS) /* select intersectors4 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersector4Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersector4HybridMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust4Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust4HybridMB)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4Intersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4Intersector4HybridMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iIntersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vIntersector4HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iIntersector4HybridPluecker)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vMBIntersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iMBIntersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vMBIntersector4HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iMBIntersector4HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector4HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector4HybridMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iIntersector4HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector4HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iIntersector4HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iMBIntersector4HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4iMBIntersector4HybridPluecker)); - - IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4SubdivPatch1Intersector4)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4SubdivPatch1MBIntersector4)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersector4Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersector4HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust4Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust4HybridMB)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4Intersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4Intersector4HybridMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iIntersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4vIntersector4HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iIntersector4HybridPluecker)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4vMBIntersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iMBIntersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4vMBIntersector4HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iMBIntersector4HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector4HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector4HybridMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iIntersector4HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector4HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iIntersector4HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iMBIntersector4HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iMBIntersector4HybridPluecker)); + + IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4SubdivPatch1Intersector4)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4SubdivPatch1MBIntersector4)); - IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4VirtualIntersector4Chunk)); - IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4VirtualMBIntersector4Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4VirtualIntersector4Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4VirtualMBIntersector4Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4InstanceIntersector4Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4InstanceMBIntersector4Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4InstanceIntersector4Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4InstanceMBIntersector4Chunk)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector4HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector4HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4GridIntersector4HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4GridMBIntersector4HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,BVH4GridIntersector4HybridPluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4GridIntersector4HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4GridMBIntersector4HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4GridIntersector4HybridPluecker)); /* select intersectors8 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersector8Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersector8HybridMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust8Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust8HybridMB)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4Intersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4Intersector8HybridMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iIntersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vIntersector8HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iIntersector8HybridPluecker)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vMBIntersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iMBIntersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4vMBIntersector8HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Triangle4iMBIntersector8HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector8HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector8HybridMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4iIntersector8HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4vIntersector8HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4iIntersector8HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4iMBIntersector8HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4Quad4iMBIntersector8HybridPluecker)); - - IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4SubdivPatch1Intersector8)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4SubdivPatch1MBIntersector8)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersector8Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersector8HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust8Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust8HybridMB)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4Intersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4Intersector8HybridMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4iIntersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4vIntersector8HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4iIntersector8HybridPluecker)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4vMBIntersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4iMBIntersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4vMBIntersector8HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Triangle4iMBIntersector8HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector8HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector8HybridMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4iIntersector8HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4vIntersector8HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4iIntersector8HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4iMBIntersector8HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4Quad4iMBIntersector8HybridPluecker)); + + IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4SubdivPatch1Intersector8)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4SubdivPatch1MBIntersector8)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4VirtualIntersector8Chunk)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4VirtualMBIntersector8Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4VirtualIntersector8Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4VirtualMBIntersector8Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4InstanceIntersector8Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4InstanceMBIntersector8Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4InstanceIntersector8Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4InstanceMBIntersector8Chunk)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4GridIntersector8HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4GridMBIntersector8HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH4GridIntersector8HybridPluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4GridIntersector8HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4GridMBIntersector8HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH4GridIntersector8HybridPluecker)); /* select intersectors16 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4OBBVirtualCurveIntersector16Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4OBBVirtualCurveIntersector16HybridMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust16Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4OBBVirtualCurveIntersectorRobust16HybridMB)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4Intersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4Intersector16HybridMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4iIntersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4vIntersector16HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4iIntersector16HybridPluecker)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4vMBIntersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4iMBIntersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4vMBIntersector16HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Triangle4iMBIntersector16HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4vIntersector16HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4vIntersector16HybridMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4iIntersector16HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4vIntersector16HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4iIntersector16HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4iMBIntersector16HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4Quad4iMBIntersector16HybridPluecker)); - - IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4SubdivPatch1Intersector16)); - IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4SubdivPatch1MBIntersector16)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH4OBBVirtualCurveIntersector16Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH4OBBVirtualCurveIntersector16HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust16Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH4OBBVirtualCurveIntersectorRobust16HybridMB)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4Intersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4Intersector16HybridMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4iIntersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4vIntersector16HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4iIntersector16HybridPluecker)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4vMBIntersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4iMBIntersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4vMBIntersector16HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Triangle4iMBIntersector16HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4vIntersector16HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4vIntersector16HybridMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4iIntersector16HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4vIntersector16HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4iIntersector16HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4iMBIntersector16HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH4Quad4iMBIntersector16HybridPluecker)); + + IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX512(features,BVH4SubdivPatch1Intersector16)); + IF_ENABLED_SUBDIV(SELECT_SYMBOL_INIT_AVX512(features,BVH4SubdivPatch1MBIntersector16)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4VirtualIntersector16Chunk)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4VirtualMBIntersector16Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512(features,BVH4VirtualIntersector16Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512(features,BVH4VirtualMBIntersector16Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4InstanceIntersector16Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4InstanceMBIntersector16Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512(features,BVH4InstanceIntersector16Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512(features,BVH4InstanceMBIntersector16Chunk)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4GridIntersector16HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4GridMBIntersector16HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH4GridIntersector16HybridPluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512(features,BVH4GridIntersector16HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512(features,BVH4GridMBIntersector16HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512(features,BVH4GridIntersector16HybridPluecker)); /* select stream intersectors */ - SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4IntersectorStreamPacketFallback); + SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4IntersectorStreamPacketFallback); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4IntersectorStreamMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4IntersectorStreamMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4iIntersectorStreamMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4vIntersectorStreamPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4iIntersectorStreamPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4IntersectorStreamMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4IntersectorStreamMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iIntersectorStreamMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4vIntersectorStreamPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Triangle4iIntersectorStreamPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Quad4vIntersectorStreamMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Quad4vIntersectorStreamMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Quad4iIntersectorStreamMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Quad4vIntersectorStreamPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Quad4iIntersectorStreamPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersectorStreamMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersectorStreamMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iIntersectorStreamMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4vIntersectorStreamPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4Quad4iIntersectorStreamPluecker)); - IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4VirtualIntersectorStream)); + IF_ENABLED_USER(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4VirtualIntersectorStream)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4InstanceIntersectorStream)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,BVH4InstanceIntersectorStream)); #endif } diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh4_factory.h b/thirdparty/embree/kernels/bvh/bvh4_factory.h index a68227b41f..30973971a4 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh4_factory.h +++ b/thirdparty/embree/kernels/bvh/bvh4_factory.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh8_factory.cpp b/thirdparty/embree/kernels/bvh/bvh8_factory.cpp index 9fe057c392..d4521af241 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh8_factory.cpp +++ b/thirdparty/embree/kernels/bvh/bvh8_factory.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "../common/isa.h" // to define EMBREE_TARGET_SIMD8 @@ -238,17 +238,17 @@ namespace embree IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX(features,BVH8Curve8vBuilder_OBB_New)); IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX(features,BVH8OBBCurve8iMBBuilder_OBB)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4SceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4vSceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4iSceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4iMBSceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4vMBSceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4SceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4vSceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4iSceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4iMBSceneBuilderSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4vMBSceneBuilderSAH)); IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8QuantizedTriangle4iSceneBuilderSAH)); IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8QuantizedTriangle4SceneBuilderSAH)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Quad4vSceneBuilderSAH)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Quad4iSceneBuilderSAH)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Quad4iMBSceneBuilderSAH)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX(features,BVH8Quad4vSceneBuilderSAH)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX(features,BVH8Quad4iSceneBuilderSAH)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX(features,BVH8Quad4iMBSceneBuilderSAH)); IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX(features,BVH8QuantizedQuad4iSceneBuilderSAH)); IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX(features,BVH8VirtualSceneBuilderSAH)); @@ -260,189 +260,189 @@ namespace embree IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX(features,BVH8GridSceneBuilderSAH)); IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX(features,BVH8GridMBSceneBuilderSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4SceneBuilderFastSpatialSAH)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Triangle4vSceneBuilderFastSpatialSAH)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8Quad4vSceneBuilderFastSpatialSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4SceneBuilderFastSpatialSAH)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX(features,BVH8Triangle4vSceneBuilderFastSpatialSAH)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX(features,BVH8Quad4vSceneBuilderFastSpatialSAH)); - IF_ENABLED_TRIS (SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8BuilderTwoLevelTriangle4MeshSAH)); - IF_ENABLED_TRIS (SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8BuilderTwoLevelTriangle4vMeshSAH)); - IF_ENABLED_TRIS (SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8BuilderTwoLevelTriangle4iMeshSAH)); - IF_ENABLED_QUADS (SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8BuilderTwoLevelQuadMeshSAH)); - IF_ENABLED_USER (SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8BuilderTwoLevelVirtualSAH)); - IF_ENABLED_INSTANCE (SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,BVH8BuilderTwoLevelInstanceSAH)); + IF_ENABLED_TRIS (SELECT_SYMBOL_INIT_AVX(features,BVH8BuilderTwoLevelTriangle4MeshSAH)); + IF_ENABLED_TRIS (SELECT_SYMBOL_INIT_AVX(features,BVH8BuilderTwoLevelTriangle4vMeshSAH)); + IF_ENABLED_TRIS (SELECT_SYMBOL_INIT_AVX(features,BVH8BuilderTwoLevelTriangle4iMeshSAH)); + IF_ENABLED_QUADS (SELECT_SYMBOL_INIT_AVX(features,BVH8BuilderTwoLevelQuadMeshSAH)); + IF_ENABLED_USER (SELECT_SYMBOL_INIT_AVX(features,BVH8BuilderTwoLevelVirtualSAH)); + IF_ENABLED_INSTANCE (SELECT_SYMBOL_INIT_AVX(features,BVH8BuilderTwoLevelInstanceSAH)); } void BVH8Factory::selectIntersectors(int features) { - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector8v)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,VirtualCurveIntersector8iMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,VirtualCurveIntersector8v)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,VirtualCurveIntersector8iMB)); /* select intersectors1 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersector1)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersector1MB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust1)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust1MB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersector1)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersector1MB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust1)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust1MB)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4Intersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4vIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4Intersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4vIntersector1Woop)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vIntersector1Woop)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4vMBIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iMBIntersector1Moeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4vMBIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iMBIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vMBIntersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iMBIntersector1Moeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vMBIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iMBIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersector1Moeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4iIntersector1Moeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4iIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersector1Pluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4iMBIntersector1Moeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4iMBIntersector1Pluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iMBIntersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iMBIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,QBVH8Triangle4iIntersector1Pluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,QBVH8Triangle4Intersector1Moeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,QBVH8Quad4iIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,QBVH8Triangle4iIntersector1Pluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,QBVH8Triangle4Intersector1Moeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,QBVH8Quad4iIntersector1Pluecker)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8VirtualIntersector1)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8VirtualMBIntersector1)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualIntersector1)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualMBIntersector1)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8InstanceIntersector1)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8InstanceMBIntersector1)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceIntersector1)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceMBIntersector1)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridIntersector1Moeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridMBIntersector1Moeller)) - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridIntersector1Pluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridIntersector1Moeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridMBIntersector1Moeller)) + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridIntersector1Pluecker)); #if defined (EMBREE_RAY_PACKETS) /* select intersectors4 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersector4Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersector4HybridMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust4Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust4HybridMB)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4Intersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4Intersector4HybridMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iIntersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4vIntersector4HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iIntersector4HybridPluecker)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4vMBIntersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iMBIntersector4HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4vMBIntersector4HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iMBIntersector4HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4vIntersector4HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4vIntersector4HybridMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4iIntersector4HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4vIntersector4HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4iIntersector4HybridPluecker)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersector4Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersector4HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust4Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust4HybridMB)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4Intersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4Intersector4HybridMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vIntersector4HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersector4HybridPluecker)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vMBIntersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iMBIntersector4HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vMBIntersector4HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iMBIntersector4HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector4HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector4HybridMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersector4HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector4HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersector4HybridPluecker)); IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2(features,BVH8Quad4iMBIntersector4HybridMoeller)); IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2(features,BVH8Quad4iMBIntersector4HybridPluecker)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8VirtualIntersector4Chunk)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8VirtualMBIntersector4Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualIntersector4Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualMBIntersector4Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8InstanceIntersector4Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8InstanceMBIntersector4Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceIntersector4Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceMBIntersector4Chunk)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridIntersector4HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridIntersector4HybridPluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridIntersector4HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridIntersector4HybridPluecker)); /* select intersectors8 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersector8Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersector8HybridMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust8Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust8HybridMB)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4Intersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4Intersector8HybridMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iIntersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4vIntersector8HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iIntersector8HybridPluecker)); - - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4vMBIntersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iMBIntersector8HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4vMBIntersector8HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Triangle4iMBIntersector8HybridPluecker)); - - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4vIntersector8HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4vIntersector8HybridMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4iIntersector8HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4vIntersector8HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8Quad4iIntersector8HybridPluecker)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersector8Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersector8HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust8Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust8HybridMB)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4Intersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4Intersector8HybridMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vIntersector8HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersector8HybridPluecker)); + + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vMBIntersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iMBIntersector8HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vMBIntersector8HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iMBIntersector8HybridPluecker)); + + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector8HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector8HybridMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersector8HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersector8HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersector8HybridPluecker)); IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2(features,BVH8Quad4iMBIntersector8HybridMoeller)); IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2(features,BVH8Quad4iMBIntersector8HybridPluecker)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8VirtualIntersector8Chunk)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8VirtualMBIntersector8Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualIntersector8Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualMBIntersector8Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8InstanceIntersector8Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8InstanceMBIntersector8Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceIntersector8Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceMBIntersector8Chunk)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridIntersector8HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,BVH8GridIntersector8HybridPluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridIntersector8HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8GridIntersector8HybridPluecker)); /* select intersectors16 */ - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersector16Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersector16HybridMB)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust16Hybrid)); - IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8OBBVirtualCurveIntersectorRobust16HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH8OBBVirtualCurveIntersector16Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH8OBBVirtualCurveIntersector16HybridMB)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust16Hybrid)); + IF_ENABLED_CURVES_OR_POINTS(SELECT_SYMBOL_INIT_AVX512(features,BVH8OBBVirtualCurveIntersectorRobust16HybridMB)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4Intersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4Intersector16HybridMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4vIntersector16HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersector16HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4Intersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4Intersector16HybridMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4iIntersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4vIntersector16HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4iIntersector16HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4vMBIntersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4iMBIntersector16HybridMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4vMBIntersector16HybridPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Triangle4iMBIntersector16HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4vMBIntersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4iMBIntersector16HybridMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4vMBIntersector16HybridPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Triangle4iMBIntersector16HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersector16HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersector16HybridMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4iIntersector16HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersector16HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4iIntersector16HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4vIntersector16HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4vIntersector16HybridMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4iIntersector16HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4vIntersector16HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4iIntersector16HybridPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4iMBIntersector16HybridMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8Quad4iMBIntersector16HybridPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4iMBIntersector16HybridMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX512(features,BVH8Quad4iMBIntersector16HybridPluecker)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8VirtualIntersector16Chunk)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8VirtualMBIntersector16Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512(features,BVH8VirtualIntersector16Chunk)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512(features,BVH8VirtualMBIntersector16Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8InstanceIntersector16Chunk)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8InstanceMBIntersector16Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512(features,BVH8InstanceIntersector16Chunk)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX512(features,BVH8InstanceMBIntersector16Chunk)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8GridIntersector16HybridMoeller)); - IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8GridIntersector16HybridPluecker)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512(features,BVH8GridIntersector16HybridMoeller)); + IF_ENABLED_GRIDS(SELECT_SYMBOL_INIT_AVX512(features,BVH8GridIntersector16HybridPluecker)); /* select stream intersectors */ - SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8IntersectorStreamPacketFallback); + SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8IntersectorStreamPacketFallback); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4IntersectorStreamMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4IntersectorStreamMoellerNoFilter)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersectorStreamMoeller)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4vIntersectorStreamPluecker)); - IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersectorStreamPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4IntersectorStreamMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4IntersectorStreamMoellerNoFilter)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersectorStreamMoeller)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4vIntersectorStreamPluecker)); + IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Triangle4iIntersectorStreamPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersectorStreamMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersectorStreamMoellerNoFilter)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4iIntersectorStreamMoeller)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4vIntersectorStreamPluecker)); - IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Quad4iIntersectorStreamPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersectorStreamMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersectorStreamMoellerNoFilter)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersectorStreamMoeller)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4vIntersectorStreamPluecker)); + IF_ENABLED_QUADS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8Quad4iIntersectorStreamPluecker)); - IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8VirtualIntersectorStream)); + IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8VirtualIntersectorStream)); - IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8InstanceIntersectorStream)); + IF_ENABLED_INSTANCE(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,BVH8InstanceIntersectorStream)); #endif } diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh8_factory.h b/thirdparty/embree/kernels/bvh/bvh8_factory.h index b92188e7d3..198d6f1df0 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh8_factory.h +++ b/thirdparty/embree/kernels/bvh/bvh8_factory.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder.cpp b/thirdparty/embree/kernels/bvh/bvh_builder.cpp index e832537ec5..161d01bb5c 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_builder.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_builder.h" diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder.h b/thirdparty/embree/kernels/bvh/bvh_builder.h index 1b86bb45ad..e35d052a62 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder.h +++ b/thirdparty/embree/kernels/bvh/bvh_builder.h @@ -1,8 +1,9 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh.h" #include "../builders/bvh_builder_sah.h" +#include "../builders/bvh_builder_msmblur.h" namespace embree { diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_morton.cpp b/thirdparty/embree/kernels/bvh/bvh_builder_morton.cpp index 64759c1294..4a4d8d71df 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_morton.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_builder_morton.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh.h" @@ -18,7 +18,7 @@ #include "../geometry/object.h" #include "../geometry/instance.h" -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) # define ROTATE_TREE 1 // specifies number of tree rotation rounds to perform #else # define ROTATE_TREE 0 // do not use tree rotations on 32 bit platforms, barrier bit in NodeRef will cause issues diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_sah.cpp b/thirdparty/embree/kernels/bvh/bvh_builder_sah.cpp index cf5b2eb47f..fad02fcc04 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_sah.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_builder_sah.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh.h" @@ -153,8 +153,8 @@ namespace embree prims.resize(numPrimitives); PrimInfo pinfo = mesh ? - createPrimRefArray(mesh,geomID_,prims,bvh->scene->progressInterface) : - createPrimRefArray(scene,gtype_,false,prims,bvh->scene->progressInterface); + createPrimRefArray(mesh,geomID_,numPrimitives,prims,bvh->scene->progressInterface) : + createPrimRefArray(scene,gtype_,false,numPrimitives,prims,bvh->scene->progressInterface); /* pinfo might has zero size due to invalid geometry */ if (unlikely(pinfo.size() == 0)) @@ -242,8 +242,8 @@ namespace embree /* create primref array */ prims.resize(numPrimitives); PrimInfo pinfo = mesh ? - createPrimRefArray(mesh,geomID_,prims,bvh->scene->progressInterface) : - createPrimRefArray(scene,gtype_,false,prims,bvh->scene->progressInterface); + createPrimRefArray(mesh,geomID_,numPrimitives,prims,bvh->scene->progressInterface) : + createPrimRefArray(scene,gtype_,false,numPrimitives,prims,bvh->scene->progressInterface); /* enable os_malloc for two level build */ if (mesh) @@ -356,7 +356,7 @@ namespace embree mvector<PrimRef> prims; mvector<SubGridBuildData> sgrids; GeneralBVHBuilder::Settings settings; - unsigned int geomID_ = std::numeric_limits<unsigned int>::max(); + const unsigned int geomID_ = std::numeric_limits<unsigned int>::max(); unsigned int numPreviousPrimitives = 0; BVHNBuilderSAHGrid (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const size_t mode) @@ -378,109 +378,10 @@ namespace embree const size_t numGridPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(GridMesh::geom_type,false); numPreviousPrimitives = numGridPrimitives; - - PrimInfo pinfo(empty); - size_t numPrimitives = 0; - - if (!mesh) - { - /* first run to get #primitives */ - - ParallelForForPrefixSumState<PrimInfo> pstate; - Scene::Iterator<GridMesh,false> iter(scene); - - pstate.init(iter,size_t(1024)); - - /* iterate over all meshes in the scene */ - pinfo = parallel_for_for_prefix_sum0( pstate, iter, PrimInfo(empty), [&](GridMesh* mesh, const range<size_t>& r, size_t k, size_t geomID) -> PrimInfo { - PrimInfo pinfo(empty); - for (size_t j=r.begin(); j<r.end(); j++) - { - if (!mesh->valid(j)) continue; - BBox3fa bounds = empty; - const PrimRef prim(bounds,(unsigned)geomID,(unsigned)j); - if (!mesh->valid(j)) continue; - pinfo.add_center2(prim,mesh->getNumSubGrids(j)); - } - return pinfo; - }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); - numPrimitives = pinfo.size(); - - /* resize arrays */ - sgrids.resize(numPrimitives); - prims.resize(numPrimitives); - - /* second run to fill primrefs and SubGridBuildData arrays */ - pinfo = parallel_for_for_prefix_sum1( pstate, iter, PrimInfo(empty), [&](GridMesh* mesh, const range<size_t>& r, size_t k, size_t geomID, const PrimInfo& base) -> PrimInfo { - k = base.size(); - size_t p_index = k; - PrimInfo pinfo(empty); - for (size_t j=r.begin(); j<r.end(); j++) - { - if (!mesh->valid(j)) continue; - const GridMesh::Grid &g = mesh->grid(j); - for (unsigned int y=0; y<g.resY-1u; y+=2) - for (unsigned int x=0; x<g.resX-1u; x+=2) - { - BBox3fa bounds = empty; - if (!mesh->buildBounds(g,x,y,bounds)) continue; // get bounds of subgrid - const PrimRef prim(bounds,(unsigned)geomID,(unsigned)p_index); - pinfo.add_center2(prim); - sgrids[p_index] = SubGridBuildData(x | g.get3x3FlagsX(x), y | g.get3x3FlagsY(y), unsigned(j)); - prims[p_index++] = prim; - } - } - return pinfo; - }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); - assert(pinfo.size() == numPrimitives); - } - else - { - ParallelPrefixSumState<PrimInfo> pstate; - /* iterate over all grids in a single mesh */ - pinfo = parallel_prefix_sum( pstate, size_t(0), mesh->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo - { - PrimInfo pinfo(empty); - for (size_t j=r.begin(); j<r.end(); j++) - { - if (!mesh->valid(j)) continue; - BBox3fa bounds = empty; - const PrimRef prim(bounds,geomID_,unsigned(j)); - pinfo.add_center2(prim,mesh->getNumSubGrids(j)); - } - return pinfo; - }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); - numPrimitives = pinfo.size(); - /* resize arrays */ - sgrids.resize(numPrimitives); - prims.resize(numPrimitives); - - /* second run to fill primrefs and SubGridBuildData arrays */ - pinfo = parallel_prefix_sum( pstate, size_t(0), mesh->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo - { - - size_t p_index = base.size(); - PrimInfo pinfo(empty); - for (size_t j=r.begin(); j<r.end(); j++) - { - if (!mesh->valid(j)) continue; - const GridMesh::Grid &g = mesh->grid(j); - for (unsigned int y=0; y<g.resY-1u; y+=2) - for (unsigned int x=0; x<g.resX-1u; x+=2) - { - BBox3fa bounds = empty; - if (!mesh->buildBounds(g,x,y,bounds)) continue; // get bounds of subgrid - const PrimRef prim(bounds,geomID_,unsigned(p_index)); - pinfo.add_center2(prim); - sgrids[p_index] = SubGridBuildData(x | g.get3x3FlagsX(x), y | g.get3x3FlagsY(y), unsigned(j)); - prims[p_index++] = prim; - } - } - return pinfo; - }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); - } + PrimInfo pinfo = mesh ? createPrimRefArrayGrids(mesh,prims,sgrids) : createPrimRefArrayGrids(scene,prims,sgrids); + const size_t numPrimitives = pinfo.size(); /* no primitives */ if (numPrimitives == 0) { bvh->clear(); @@ -546,6 +447,7 @@ namespace embree /************************************************************************************/ /************************************************************************************/ + #if defined(EMBREE_GEOMETRY_TRIANGLE) Builder* BVH4Triangle4MeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Triangle4>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); } Builder* BVH4Triangle4vMeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Triangle4v>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); } @@ -555,7 +457,6 @@ namespace embree Builder* BVH4Triangle4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4v>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); } Builder* BVH4Triangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4i>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type,true); } - Builder* BVH4QuantizedTriangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Triangle4i>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); } #if defined(__AVX__) Builder* BVH8Triangle4MeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<8,Triangle4>((BVH8*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); } @@ -568,6 +469,8 @@ namespace embree Builder* BVH8QuantizedTriangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Triangle4i>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); } Builder* BVH8QuantizedTriangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Triangle4>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); } + + #endif #endif diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_sah_mb.cpp b/thirdparty/embree/kernels/bvh/bvh_builder_sah_mb.cpp index 9c01553ec6..d163a80ab1 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_sah_mb.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_builder_sah_mb.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh.h" @@ -142,7 +142,7 @@ namespace embree { /* create primref array */ mvector<PrimRef> prims(scene->device,numPrimitives); - const PrimInfo pinfo = createPrimRefArrayMBlur(scene,gtype_,prims,bvh->scene->progressInterface,0); + const PrimInfo pinfo = createPrimRefArrayMBlur(scene,gtype_,numPrimitives,prims,bvh->scene->progressInterface,0); /* early out if no valid primitives */ if (pinfo.size() == 0) { bvh->clear(); return; } /* estimate acceleration structure size */ @@ -175,7 +175,7 @@ namespace embree { /* create primref array */ mvector<PrimRefMB> prims(scene->device,numPrimitives); - PrimInfoMB pinfo = createPrimRefArrayMSMBlur(scene,gtype_,prims,bvh->scene->progressInterface); + PrimInfoMB pinfo = createPrimRefArrayMSMBlur(scene,gtype_,numPrimitives,prims,bvh->scene->progressInterface); /* early out if no valid primitives */ if (pinfo.size() == 0) { bvh->clear(); return; } diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_sah_spatial.cpp b/thirdparty/embree/kernels/bvh/bvh_builder_sah_spatial.cpp index 285b38c39d..a4e55d7484 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_sah_spatial.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_builder_sah_spatial.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh.h" @@ -127,8 +127,8 @@ namespace embree { /* standard spatial split SAH BVH builder */ pinfo = mesh ? - createPrimRefArray(mesh,geomID_,/*numSplitPrimitives,*/prims0,bvh->scene->progressInterface) : - createPrimRefArray(scene,Mesh::geom_type,false,/*numSplitPrimitives,*/prims0,bvh->scene->progressInterface); + createPrimRefArray(mesh,geomID_,numSplitPrimitives,prims0,bvh->scene->progressInterface) : + createPrimRefArray(scene,Mesh::geom_type,false,numSplitPrimitives,prims0,bvh->scene->progressInterface); Splitter splitter(scene); diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_twolevel.cpp b/thirdparty/embree/kernels/bvh/bvh_builder_twolevel.cpp index 1a78f347ac..5d45ed3748 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_twolevel.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_builder_twolevel.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_builder_twolevel.h" @@ -129,10 +129,6 @@ namespace embree prims.resize(refs.size()); #endif -#if defined(TASKING_TBB) && defined(__AVX512ER__) && USE_TASK_ARENA // KNL - tbb::task_arena limited(min(32,(int)TaskScheduler::threadCount())); - limited.execute([&] -#endif { #if ENABLE_DIRECT_SAH_MERGE_BUILDER @@ -211,10 +207,6 @@ namespace embree bvh->set(root,LBBox3fa(pinfo.geomBounds),numPrimitives); } } -#if defined(TASKING_TBB) && defined(__AVX512ER__) && USE_TASK_ARENA // KNL - ); -#endif - } bvh->alloc.cleanup(); diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_twolevel.h b/thirdparty/embree/kernels/bvh/bvh_builder_twolevel.h index 8f57c3b406..dc7ec7d278 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_twolevel.h +++ b/thirdparty/embree/kernels/bvh/bvh_builder_twolevel.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -137,7 +137,7 @@ namespace embree assert(isSmallGeometry(mesh)); mvector<PrimRef> prefs(topBuilder->scene->device, meshSize); - auto pinfo = createPrimRefArray(mesh,objectID_,prefs,topBuilder->bvh->scene->progressInterface); + auto pinfo = createPrimRefArray(mesh,objectID_,meshSize,prefs,topBuilder->bvh->scene->progressInterface); size_t begin=0; while (begin < pinfo.size()) diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_twolevel_internal.h b/thirdparty/embree/kernels/bvh/bvh_builder_twolevel_internal.h index 1c1ae8d6a7..023b52b780 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_builder_twolevel_internal.h +++ b/thirdparty/embree/kernels/bvh/bvh_builder_twolevel_internal.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_collider.cpp b/thirdparty/embree/kernels/bvh/bvh_collider.cpp index a27be8bae8..9428c0b88e 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_collider.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_collider.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_collider.h" diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_collider.h b/thirdparty/embree/kernels/bvh/bvh_collider.h index ac4f99c96a..3c42f211c1 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_collider.h +++ b/thirdparty/embree/kernels/bvh/bvh_collider.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_factory.h b/thirdparty/embree/kernels/bvh/bvh_factory.h index 54021ca6eb..453d455bd9 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_factory.h +++ b/thirdparty/embree/kernels/bvh/bvh_factory.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector1.cpp b/thirdparty/embree/kernels/bvh/bvh_intersector1.cpp index ea6adc2717..9594f402c3 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector1.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_intersector1.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_intersector1.h" @@ -61,10 +61,10 @@ namespace embree assert(!(types & BVH_MB) || (ray.time() >= 0.0f && ray.time() <= 1.0f)); /* load the ray into SIMD registers */ - TravRay<N,Nx,robust> tray(ray.org, ray.dir, max(ray.tnear(), 0.0f), max(ray.tfar, 0.0f)); + TravRay<N,robust> tray(ray.org, ray.dir, max(ray.tnear(), 0.0f), max(ray.tfar, 0.0f)); /* initialize the node traverser */ - BVHNNodeTraverser1Hit<N, Nx, types> nodeTraverser; + BVHNNodeTraverser1Hit<N, types> nodeTraverser; /* pop loop */ while (true) pop: @@ -75,22 +75,16 @@ namespace embree NodeRef cur = NodeRef(stackPtr->ptr); /* if popped node is too far, pop next one */ -#if defined(__AVX512ER__) - /* much faster on KNL */ - if (unlikely(any(vfloat<Nx>(*(float*)&stackPtr->dist) > tray.tfar))) - continue; -#else if (unlikely(*(float*)&stackPtr->dist > ray.tfar)) continue; -#endif /* downtraversal loop */ while (true) { /* intersect node */ - size_t mask; vfloat<Nx> tNear; + size_t mask; vfloat<N> tNear; STAT3(normal.trav_nodes,1,1,1); - bool nodeIntersected = BVHNNodeIntersector1<N, Nx, types, robust>::intersect(cur, tray, ray.time(), tNear, mask); + bool nodeIntersected = BVHNNodeIntersector1<N, types, robust>::intersect(cur, tray, ray.time(), tNear, mask); if (unlikely(!nodeIntersected)) { STAT3(normal.trav_nodes,-1,-1,-1); break; } /* if no child is hit, pop next node */ @@ -153,10 +147,10 @@ namespace embree assert(!(types & BVH_MB) || (ray.time() >= 0.0f && ray.time() <= 1.0f)); /* load the ray into SIMD registers */ - TravRay<N,Nx,robust> tray(ray.org, ray.dir, max(ray.tnear(), 0.0f), max(ray.tfar, 0.0f)); + TravRay<N,robust> tray(ray.org, ray.dir, max(ray.tnear(), 0.0f), max(ray.tfar, 0.0f)); /* initialize the node traverser */ - BVHNNodeTraverser1Hit<N, Nx, types> nodeTraverser; + BVHNNodeTraverser1Hit<N, types> nodeTraverser; /* pop loop */ while (true) pop: @@ -170,9 +164,9 @@ namespace embree while (true) { /* intersect node */ - size_t mask; vfloat<Nx> tNear; + size_t mask; vfloat<N> tNear; STAT3(shadow.trav_nodes,1,1,1); - bool nodeIntersected = BVHNNodeIntersector1<N, Nx, types, robust>::intersect(cur, tray, ray.time(), tNear, mask); + bool nodeIntersected = BVHNNodeIntersector1<N, types, robust>::intersect(cur, tray, ray.time(), tNear, mask); if (unlikely(!nodeIntersected)) { STAT3(shadow.trav_nodes,-1,-1,-1); break; } /* if no child is hit, pop next node */ @@ -213,9 +207,6 @@ namespace embree static const size_t stackSize = 1+(N-1)*BVH::maxDepth+3; // +3 due to 16-wide store - /* right now AVX512KNL SIMD extension only for standard node types */ - static const size_t Nx = (types == BVH_AN1 || types == BVH_QN1) ? vextend<N>::size : N; - static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context) { const BVH* __restrict__ bvh = (const BVH*)This->ptr; @@ -238,7 +229,7 @@ namespace embree TravPointQuery<N> tquery(query->p, context->query_radius); /* initialize the node traverser */ - BVHNNodeTraverser1Hit<N, N, types> nodeTraverser; + BVHNNodeTraverser1Hit<N,types> nodeTraverser; bool changed = false; float cull_radius = context->query_type == POINT_QUERY_TYPE_SPHERE diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector1.h b/thirdparty/embree/kernels/bvh/bvh_intersector1.h index 1a269c319a..2df3d6eddb 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector1.h +++ b/thirdparty/embree/kernels/bvh/bvh_intersector1.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -25,9 +25,6 @@ namespace embree static const size_t stackSize = 1+(N-1)*BVH::maxDepth+3; // +3 due to 16-wide store - /* right now AVX512KNL SIMD extension only for standard node types */ - static const size_t Nx = (types == BVH_AN1 || types == BVH_QN1) ? vextend<N>::size : N; - public: static void intersect (const Accel::Intersectors* This, RayHit& ray, IntersectContext* context); static void occluded (const Accel::Intersectors* This, Ray& ray, IntersectContext* context); diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector1_bvh4.cpp b/thirdparty/embree/kernels/bvh/bvh_intersector1_bvh4.cpp index 989f7354fd..831d613367 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector1_bvh4.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_intersector1_bvh4.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_intersector1.cpp" @@ -21,15 +21,15 @@ namespace embree IF_ENABLED_CURVES_OR_POINTS(DEFINE_INTERSECTOR1(BVH4OBBVirtualCurveIntersectorRobust1,BVHNIntersector1<4 COMMA BVH_AN1_UN1 COMMA true COMMA VirtualCurveIntersector1 >)); IF_ENABLED_CURVES_OR_POINTS(DEFINE_INTERSECTOR1(BVH4OBBVirtualCurveIntersectorRobust1MB,BVHNIntersector1<4 COMMA BVH_AN2_AN4D_UN2 COMMA true COMMA VirtualCurveIntersector1 >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4Intersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<TriangleMIntersector1Moeller <SIMD_MODE(4) COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<TriangleMiIntersector1Moeller <SIMD_MODE(4) COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4vIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN1 COMMA true COMMA ArrayIntersector1<TriangleMvIntersector1Pluecker<SIMD_MODE(4) COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN1 COMMA true COMMA ArrayIntersector1<TriangleMiIntersector1Pluecker<SIMD_MODE(4) COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4Intersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<TriangleMIntersector1Moeller <4 COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<TriangleMiIntersector1Moeller <4 COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4vIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN1 COMMA true COMMA ArrayIntersector1<TriangleMvIntersector1Pluecker<4 COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN1 COMMA true COMMA ArrayIntersector1<TriangleMiIntersector1Pluecker<4 COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4vMBIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA false COMMA ArrayIntersector1<TriangleMvMBIntersector1Moeller <SIMD_MODE(4) COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iMBIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA false COMMA ArrayIntersector1<TriangleMiMBIntersector1Moeller <SIMD_MODE(4) COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4vMBIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA true COMMA ArrayIntersector1<TriangleMvMBIntersector1Pluecker<SIMD_MODE(4) COMMA true> > >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iMBIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA true COMMA ArrayIntersector1<TriangleMiMBIntersector1Pluecker<SIMD_MODE(4) COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4vMBIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA false COMMA ArrayIntersector1<TriangleMvMBIntersector1Moeller <4 COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iMBIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA false COMMA ArrayIntersector1<TriangleMiMBIntersector1Moeller <4 COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4vMBIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA true COMMA ArrayIntersector1<TriangleMvMBIntersector1Pluecker<4 COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(BVH4Triangle4iMBIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA true COMMA ArrayIntersector1<TriangleMiMBIntersector1Pluecker<4 COMMA true> > >)); IF_ENABLED_QUADS(DEFINE_INTERSECTOR1(BVH4Quad4vIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<QuadMvIntersector1Moeller <4 COMMA true> > >)); IF_ENABLED_QUADS(DEFINE_INTERSECTOR1(BVH4Quad4iIntersector1Moeller, BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<QuadMiIntersector1Moeller <4 COMMA true> > >)); @@ -48,7 +48,7 @@ namespace embree IF_ENABLED_INSTANCE(DEFINE_INTERSECTOR1(BVH4InstanceIntersector1,BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA ArrayIntersector1<InstanceIntersector1> >)); IF_ENABLED_INSTANCE(DEFINE_INTERSECTOR1(BVH4InstanceMBIntersector1,BVHNIntersector1<4 COMMA BVH_AN2_AN4D COMMA false COMMA ArrayIntersector1<InstanceIntersector1MB> >)); - IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(QBVH4Triangle4iIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_QN1 COMMA false COMMA ArrayIntersector1<TriangleMiIntersector1Pluecker<SIMD_MODE(4) COMMA true> > >)); + IF_ENABLED_TRIS(DEFINE_INTERSECTOR1(QBVH4Triangle4iIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_QN1 COMMA false COMMA ArrayIntersector1<TriangleMiIntersector1Pluecker<4 COMMA true> > >)); IF_ENABLED_QUADS(DEFINE_INTERSECTOR1(QBVH4Quad4iIntersector1Pluecker,BVHNIntersector1<4 COMMA BVH_QN1 COMMA false COMMA ArrayIntersector1<QuadMiIntersector1Pluecker<4 COMMA true> > >)); IF_ENABLED_GRIDS(DEFINE_INTERSECTOR1(BVH4GridIntersector1Moeller,BVHNIntersector1<4 COMMA BVH_AN1 COMMA false COMMA SubGridIntersector1Moeller<4 COMMA true> >)); diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector_hybrid.h b/thirdparty/embree/kernels/bvh/bvh_intersector_hybrid.h index d764cc928d..50ebf375c4 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector_hybrid.h +++ b/thirdparty/embree/kernels/bvh/bvh_intersector_hybrid.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -19,9 +19,6 @@ namespace embree template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single = true> class BVHNIntersectorKHybrid { - /* right now AVX512KNL SIMD extension only for standard node types */ - static const size_t Nx = types == BVH_AN1 ? vextend<N>::size : N; - /* shortcuts for frequently used types */ typedef typename PrimitiveIntersectorK::Precalculations Precalculations; typedef typename PrimitiveIntersectorK::Primitive Primitive; diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector_stream.h b/thirdparty/embree/kernels/bvh/bvh_intersector_stream.h index 83d1fb4d3d..717f559677 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector_stream.h +++ b/thirdparty/embree/kernels/bvh/bvh_intersector_stream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -12,11 +12,9 @@ namespace embree namespace isa { /*! BVH ray stream intersector. */ - template<int N, int Nx, int types, bool robust, typename PrimitiveIntersector> + template<int N, int types, bool robust, typename PrimitiveIntersector> class BVHNIntersectorStream { - static const int Nxd = (Nx == N) ? N : Nx/2; - /* shortcuts for frequently used types */ template<int K> using PrimitiveIntersectorK = typename PrimitiveIntersector::template Type<K>; template<int K> using PrimitiveK = typename PrimitiveIntersectorK<K>::PrimitiveK; @@ -128,13 +126,13 @@ namespace embree const AABBNode* __restrict__ node, const Frustum<robust>& frustum, size_t* maskK, - vfloat<Nx>& dist) + vfloat<N>& dist) { - size_t m_node_hit = intersectNodeFrustum<N,Nx>(node, frustum, dist); + size_t m_node_hit = intersectNodeFrustum<N>(node, frustum, dist); const size_t first_index = bsf(m_active); const size_t first_packetID = first_index / K; const size_t first_rayID = first_index % K; - size_t m_first_hit = intersectNode1<N,Nx>(node, packets[first_packetID], first_rayID, frustum.nf); + size_t m_first_hit = intersectNode1<N>(node, packets[first_packetID], first_rayID, frustum.nf); /* this make traversal independent of the ordering of rays */ size_t m_node = m_node_hit ^ m_first_hit; @@ -150,20 +148,20 @@ namespace embree // TODO: explicit 16-wide path for KNL template<int K> - __forceinline static vint<Nx> traverseIncoherentStream(size_t m_active, + __forceinline static vint<N> traverseIncoherentStream(size_t m_active, TravRayKStreamFast<K>* __restrict__ packets, const AABBNode* __restrict__ node, const NearFarPrecalculations& nf, const int shiftTable[32]) { - const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); - const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); - const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); - const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); - const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); - const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); + const vfloat<N> bminX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); + const vfloat<N> bminY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); + const vfloat<N> bminZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); + const vfloat<N> bmaxX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); + const vfloat<N> bmaxY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); + const vfloat<N> bmaxZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); assert(m_active); - vint<Nx> vmask(zero); + vint<N> vmask(zero); do { STAT3(shadow.trav_nodes,1,1,1); @@ -171,58 +169,41 @@ namespace embree assert(rayID < MAX_INTERNAL_STREAM_SIZE); TravRayKStream<K,robust> &p = packets[rayID / K]; const size_t i = rayID % K; - const vint<Nx> bitmask(shiftTable[rayID]); - -#if defined (__aarch64__) - const vfloat<Nx> tNearX = madd(bminX, p.rdir.x[i], p.neg_org_rdir.x[i]); - const vfloat<Nx> tNearY = madd(bminY, p.rdir.y[i], p.neg_org_rdir.y[i]); - const vfloat<Nx> tNearZ = madd(bminZ, p.rdir.z[i], p.neg_org_rdir.z[i]); - const vfloat<Nx> tFarX = madd(bmaxX, p.rdir.x[i], p.neg_org_rdir.x[i]); - const vfloat<Nx> tFarY = madd(bmaxY, p.rdir.y[i], p.neg_org_rdir.y[i]); - const vfloat<Nx> tFarZ = madd(bmaxZ, p.rdir.z[i], p.neg_org_rdir.z[i]); -#else - const vfloat<Nx> tNearX = msub(bminX, p.rdir.x[i], p.org_rdir.x[i]); - const vfloat<Nx> tNearY = msub(bminY, p.rdir.y[i], p.org_rdir.y[i]); - const vfloat<Nx> tNearZ = msub(bminZ, p.rdir.z[i], p.org_rdir.z[i]); - const vfloat<Nx> tFarX = msub(bmaxX, p.rdir.x[i], p.org_rdir.x[i]); - const vfloat<Nx> tFarY = msub(bmaxY, p.rdir.y[i], p.org_rdir.y[i]); - const vfloat<Nx> tFarZ = msub(bmaxZ, p.rdir.z[i], p.org_rdir.z[i]); -#endif - - const vfloat<Nx> tNear = maxi(tNearX, tNearY, tNearZ, vfloat<Nx>(p.tnear[i])); - const vfloat<Nx> tFar = mini(tFarX , tFarY , tFarZ, vfloat<Nx>(p.tfar[i])); - -#if defined(__AVX512ER__) - const vboolx m_node((1 << N)-1); - const vbool<Nx> hit_mask = le(m_node, tNear, tFar); - vmask = mask_or(hit_mask, vmask, vmask, bitmask); -#else - const vbool<Nx> hit_mask = tNear <= tFar; + const vint<N> bitmask(shiftTable[rayID]); + const vfloat<N> tNearX = msub(bminX, p.rdir.x[i], p.org_rdir.x[i]); + const vfloat<N> tNearY = msub(bminY, p.rdir.y[i], p.org_rdir.y[i]); + const vfloat<N> tNearZ = msub(bminZ, p.rdir.z[i], p.org_rdir.z[i]); + const vfloat<N> tFarX = msub(bmaxX, p.rdir.x[i], p.org_rdir.x[i]); + const vfloat<N> tFarY = msub(bmaxY, p.rdir.y[i], p.org_rdir.y[i]); + const vfloat<N> tFarZ = msub(bmaxZ, p.rdir.z[i], p.org_rdir.z[i]); + const vfloat<N> tNear = maxi(tNearX, tNearY, tNearZ, vfloat<N>(p.tnear[i])); + const vfloat<N> tFar = mini(tFarX , tFarY , tFarZ, vfloat<N>(p.tfar[i])); + + const vbool<N> hit_mask = tNear <= tFar; #if defined(__AVX2__) - vmask = vmask | (bitmask & vint<Nx>(hit_mask)); + vmask = vmask | (bitmask & vint<N>(hit_mask)); #else vmask = select(hit_mask, vmask | bitmask, vmask); #endif -#endif } while(m_active); return vmask; } template<int K> - __forceinline static vint<Nx> traverseIncoherentStream(size_t m_active, + __forceinline static vint<N> traverseIncoherentStream(size_t m_active, TravRayKStreamRobust<K>* __restrict__ packets, const AABBNode* __restrict__ node, const NearFarPrecalculations& nf, const int shiftTable[32]) { - const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); - const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); - const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); - const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); - const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); - const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); + const vfloat<N> bminX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); + const vfloat<N> bminY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); + const vfloat<N> bminZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); + const vfloat<N> bmaxX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); + const vfloat<N> bmaxY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); + const vfloat<N> bmaxZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); assert(m_active); - vint<Nx> vmask(zero); + vint<N> vmask(zero); do { STAT3(shadow.trav_nodes,1,1,1); @@ -230,29 +211,23 @@ namespace embree assert(rayID < MAX_INTERNAL_STREAM_SIZE); TravRayKStream<K,robust> &p = packets[rayID / K]; const size_t i = rayID % K; - const vint<Nx> bitmask(shiftTable[rayID]); - const vfloat<Nx> tNearX = (bminX - p.org.x[i]) * p.rdir.x[i]; - const vfloat<Nx> tNearY = (bminY - p.org.y[i]) * p.rdir.y[i]; - const vfloat<Nx> tNearZ = (bminZ - p.org.z[i]) * p.rdir.z[i]; - const vfloat<Nx> tFarX = (bmaxX - p.org.x[i]) * p.rdir.x[i]; - const vfloat<Nx> tFarY = (bmaxY - p.org.y[i]) * p.rdir.y[i]; - const vfloat<Nx> tFarZ = (bmaxZ - p.org.z[i]) * p.rdir.z[i]; - const vfloat<Nx> tNear = maxi(tNearX, tNearY, tNearZ, vfloat<Nx>(p.tnear[i])); - const vfloat<Nx> tFar = mini(tFarX , tFarY , tFarZ, vfloat<Nx>(p.tfar[i])); + const vint<N> bitmask(shiftTable[rayID]); + const vfloat<N> tNearX = (bminX - p.org.x[i]) * p.rdir.x[i]; + const vfloat<N> tNearY = (bminY - p.org.y[i]) * p.rdir.y[i]; + const vfloat<N> tNearZ = (bminZ - p.org.z[i]) * p.rdir.z[i]; + const vfloat<N> tFarX = (bmaxX - p.org.x[i]) * p.rdir.x[i]; + const vfloat<N> tFarY = (bmaxY - p.org.y[i]) * p.rdir.y[i]; + const vfloat<N> tFarZ = (bmaxZ - p.org.z[i]) * p.rdir.z[i]; + const vfloat<N> tNear = maxi(tNearX, tNearY, tNearZ, vfloat<N>(p.tnear[i])); + const vfloat<N> tFar = mini(tFarX , tFarY , tFarZ, vfloat<N>(p.tfar[i])); const float round_down = 1.0f-2.0f*float(ulp); const float round_up = 1.0f+2.0f*float(ulp); -#if defined(__AVX512ER__) - const vboolx m_node((1 << N)-1); - const vbool<Nx> hit_mask = le(m_node, round_down*tNear, round_up*tFar); - vmask = mask_or(hit_mask, vmask, vmask, bitmask); -#else - const vbool<Nx> hit_mask = round_down*tNear <= round_up*tFar; + const vbool<N> hit_mask = round_down*tNear <= round_up*tFar; #if defined(__AVX2__) - vmask = vmask | (bitmask & vint<Nx>(hit_mask)); + vmask = vmask | (bitmask & vint<N>(hit_mask)); #else vmask = select(hit_mask, vmask | bitmask, vmask); #endif -#endif } while(m_active); return vmask; } @@ -277,7 +252,7 @@ namespace embree /*! BVH ray stream intersector with direct fallback to packets. */ - template<int N, int Nx> + template<int N> class BVHNIntersectorStreamPacketFallback { public: diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector_stream_filters.h b/thirdparty/embree/kernels/bvh/bvh_intersector_stream_filters.h index cdeb923637..e7df7c2ae2 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_intersector_stream_filters.h +++ b/thirdparty/embree/kernels/bvh/bvh_intersector_stream_filters.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_aabb.h b/thirdparty/embree/kernels/bvh/bvh_node_aabb.h index baa4a8d805..57530692bc 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_aabb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_aabb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_aabb_mb.h b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h index 501f4bce5b..c4cea7d8ba 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_aabb_mb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_aabb_mb4d.h b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h index e968bbbc39..46a81d7581 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_aabb_mb4d.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_base.h b/thirdparty/embree/kernels/bvh/bvh_node_base.h index 8268f3b932..a5570a7b9e 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_base.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_base.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_obb.h b/thirdparty/embree/kernels/bvh/bvh_node_obb.h index fa7cc08211..e6b500691e 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_obb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_obb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_obb_mb.h b/thirdparty/embree/kernels/bvh/bvh_node_obb_mb.h index 834cf5ec28..c06b1aea5e 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_obb_mb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_obb_mb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_qaabb.h b/thirdparty/embree/kernels/bvh/bvh_node_qaabb.h index 5212821f3f..2afc8c98e7 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_qaabb.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_qaabb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_ref.h b/thirdparty/embree/kernels/bvh/bvh_node_ref.h index 0f6d4dac7e..6f6da758de 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_node_ref.h +++ b/thirdparty/embree/kernels/bvh/bvh_node_ref.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -102,7 +102,7 @@ namespace embree /*! Sets the barrier bit. */ __forceinline void setBarrier() { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) assert(!isBarrier()); ptr |= barrier_mask; #else @@ -112,7 +112,7 @@ namespace embree /*! Clears the barrier bit. */ __forceinline void clearBarrier() { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) ptr &= ~barrier_mask; #else assert(false); diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_refit.cpp b/thirdparty/embree/kernels/bvh/bvh_refit.cpp index a273c21e8b..bf5c8538ba 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_refit.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_refit.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_refit.h" diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_refit.h b/thirdparty/embree/kernels/bvh/bvh_refit.h index 4aa9bdd7cc..09bb3d8da5 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_refit.h +++ b/thirdparty/embree/kernels/bvh/bvh_refit.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_rotate.cpp b/thirdparty/embree/kernels/bvh/bvh_rotate.cpp index 2bb431bf0e..460bd60c62 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_rotate.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_rotate.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_rotate.h" diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_rotate.h b/thirdparty/embree/kernels/bvh/bvh_rotate.h index 009bef339e..61ef64a679 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_rotate.h +++ b/thirdparty/embree/kernels/bvh/bvh_rotate.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.cpp b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp index aa56035026..d857ff7d95 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.cpp +++ b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "bvh_statistics.h" @@ -162,7 +162,7 @@ namespace embree template class BVHNStatistics<8>; #endif -#if !defined(__AVX__) || (!defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42)) || defined(__aarch64__) +#if !defined(__AVX__) || !defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42) template class BVHNStatistics<4>; #endif } diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.h b/thirdparty/embree/kernels/bvh/bvh_statistics.h index 73dfc6fbcc..a28e115f1c 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.h +++ b/thirdparty/embree/kernels/bvh/bvh_statistics.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_traverser1.h b/thirdparty/embree/kernels/bvh/bvh_traverser1.h index 7f17084b81..8ce01b57f5 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_traverser1.h +++ b/thirdparty/embree/kernels/bvh/bvh_traverser1.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -14,213 +14,9 @@ namespace embree namespace isa { /*! BVH regular node traversal for single rays. */ - template<int N, int Nx, int types> + template<int N, int types> class BVHNNodeTraverser1Hit; - /*! Helper functions for fast sorting using AVX512 instructions. */ -#if defined(__AVX512ER__) - - /* KNL code path */ - __forceinline void isort_update(vfloat16 &dist, vllong8 &ptr, const vfloat16 &d, const vllong8 &p) - { - const vfloat16 dist_shift = align_shift_right<15>(dist,dist); - const vllong8 ptr_shift = align_shift_right<7>(ptr,ptr); - const vbool16 m_geq = d >= dist; - const vbool16 m_geq_shift = m_geq << 1; - dist = select(m_geq,d,dist); - ptr = select(vboold8(m_geq),p,ptr); - dist = select(m_geq_shift,dist_shift,dist); - ptr = select(vboold8(m_geq_shift),ptr_shift,ptr); - } - - __forceinline void isort_quick_update(vfloat16 &dist, vllong8 &ptr, const vfloat16 &d, const vllong8 &p) - { - //dist = align_shift_right<15>(dist,d); - //ptr = align_shift_right<7>(ptr,p); - dist = align_shift_right<15>(dist,permute(d,vint16(zero))); - ptr = align_shift_right<7>(ptr,permute(p,vllong8(zero))); - } - - template<int N, int Nx, int types, class NodeRef, class BaseNode> - __forceinline void traverseClosestHitAVX512(NodeRef& cur, - size_t mask, - const vfloat<Nx>& tNear, - StackItemT<NodeRef>*& stackPtr, - StackItemT<NodeRef>* stackEnd) - { - assert(mask != 0); - const BaseNode* node = cur.baseNode(); - - vllong8 children( vllong<N>::loadu((void*)node->children) ); - children = vllong8::compact((int)mask,children); - vfloat16 distance = tNear; - distance = vfloat16::compact((int)mask,distance,tNear); - - cur = toScalar(children); - BVHN<N>::prefetch(cur,types); - - mask &= mask-1; - if (likely(mask == 0)) return; - - /* 2 hits: order A0 B0 */ - const vllong8 c0(children); - const vfloat16 d0(distance); - children = align_shift_right<1>(children,children); - distance = align_shift_right<1>(distance,distance); - const vllong8 c1(children); - const vfloat16 d1(distance); - - cur = toScalar(children); - BVHN<N>::prefetch(cur,types); - - /* a '<' keeps the order for equal distances, scenes like powerplant largely benefit from it */ - const vboolf16 m_dist = d0 < d1; - const vfloat16 dist_A0 = select(m_dist, d0, d1); - const vfloat16 dist_B0 = select(m_dist, d1, d0); - const vllong8 ptr_A0 = select(vboold8(m_dist), c0, c1); - const vllong8 ptr_B0 = select(vboold8(m_dist), c1, c0); - - mask &= mask-1; - if (likely(mask == 0)) { - cur = toScalar(ptr_A0); - stackPtr[0].ptr = toScalar(ptr_B0); - *(float*)&stackPtr[0].dist = toScalar(dist_B0); - stackPtr++; - return; - } - - /* 3 hits: order A1 B1 C1 */ - - children = align_shift_right<1>(children,children); - distance = align_shift_right<1>(distance,distance); - - const vllong8 c2(children); - const vfloat16 d2(distance); - - cur = toScalar(children); - BVHN<N>::prefetch(cur,types); - - const vboolf16 m_dist1 = dist_A0 <= d2; - const vfloat16 dist_tmp_B1 = select(m_dist1, d2, dist_A0); - const vllong8 ptr_A1 = select(vboold8(m_dist1), ptr_A0, c2); - const vllong8 ptr_tmp_B1 = select(vboold8(m_dist1), c2, ptr_A0); - - const vboolf16 m_dist2 = dist_B0 <= dist_tmp_B1; - const vfloat16 dist_B1 = select(m_dist2, dist_B0 , dist_tmp_B1); - const vfloat16 dist_C1 = select(m_dist2, dist_tmp_B1, dist_B0); - const vllong8 ptr_B1 = select(vboold8(m_dist2), ptr_B0, ptr_tmp_B1); - const vllong8 ptr_C1 = select(vboold8(m_dist2), ptr_tmp_B1, ptr_B0); - - mask &= mask-1; - if (likely(mask == 0)) { - cur = toScalar(ptr_A1); - stackPtr[0].ptr = toScalar(ptr_C1); - *(float*)&stackPtr[0].dist = toScalar(dist_C1); - stackPtr[1].ptr = toScalar(ptr_B1); - *(float*)&stackPtr[1].dist = toScalar(dist_B1); - stackPtr+=2; - return; - } - - /* 4 hits: order A2 B2 C2 D2 */ - - const vfloat16 dist_A1 = select(m_dist1, dist_A0, d2); - - children = align_shift_right<1>(children,children); - distance = align_shift_right<1>(distance,distance); - - const vllong8 c3(children); - const vfloat16 d3(distance); - - cur = toScalar(children); - BVHN<N>::prefetch(cur,types); - - const vboolf16 m_dist3 = dist_A1 <= d3; - const vfloat16 dist_tmp_B2 = select(m_dist3, d3, dist_A1); - const vllong8 ptr_A2 = select(vboold8(m_dist3), ptr_A1, c3); - const vllong8 ptr_tmp_B2 = select(vboold8(m_dist3), c3, ptr_A1); - - const vboolf16 m_dist4 = dist_B1 <= dist_tmp_B2; - const vfloat16 dist_B2 = select(m_dist4, dist_B1 , dist_tmp_B2); - const vfloat16 dist_tmp_C2 = select(m_dist4, dist_tmp_B2, dist_B1); - const vllong8 ptr_B2 = select(vboold8(m_dist4), ptr_B1, ptr_tmp_B2); - const vllong8 ptr_tmp_C2 = select(vboold8(m_dist4), ptr_tmp_B2, ptr_B1); - - const vboolf16 m_dist5 = dist_C1 <= dist_tmp_C2; - const vfloat16 dist_C2 = select(m_dist5, dist_C1 , dist_tmp_C2); - const vfloat16 dist_D2 = select(m_dist5, dist_tmp_C2, dist_C1); - const vllong8 ptr_C2 = select(vboold8(m_dist5), ptr_C1, ptr_tmp_C2); - const vllong8 ptr_D2 = select(vboold8(m_dist5), ptr_tmp_C2, ptr_C1); - - mask &= mask-1; - if (likely(mask == 0)) { - cur = toScalar(ptr_A2); - stackPtr[0].ptr = toScalar(ptr_D2); - *(float*)&stackPtr[0].dist = toScalar(dist_D2); - stackPtr[1].ptr = toScalar(ptr_C2); - *(float*)&stackPtr[1].dist = toScalar(dist_C2); - stackPtr[2].ptr = toScalar(ptr_B2); - *(float*)&stackPtr[2].dist = toScalar(dist_B2); - stackPtr+=3; - return; - } - - /* >=5 hits: reverse to descending order for writing to stack */ - - const size_t hits = 4 + popcnt(mask); - const vfloat16 dist_A2 = select(m_dist3, dist_A1, d3); - vfloat16 dist(neg_inf); - vllong8 ptr(zero); - - - isort_quick_update(dist,ptr,dist_A2,ptr_A2); - isort_quick_update(dist,ptr,dist_B2,ptr_B2); - isort_quick_update(dist,ptr,dist_C2,ptr_C2); - isort_quick_update(dist,ptr,dist_D2,ptr_D2); - - do { - - children = align_shift_right<1>(children,children); - distance = align_shift_right<1>(distance,distance); - - cur = toScalar(children); - BVHN<N>::prefetch(cur,types); - - const vfloat16 new_dist(permute(distance,vint16(zero))); - const vllong8 new_ptr(permute(children,vllong8(zero))); - - mask &= mask-1; - isort_update(dist,ptr,new_dist,new_ptr); - - } while(mask); - - const vboold8 m_stack_ptr(0x55); // 10101010 (lsb -> msb) - const vboolf16 m_stack_dist(0x4444); // 0010001000100010 (lsb -> msb) - - /* extract current noderef */ - cur = toScalar(permute(ptr,vllong8(hits-1))); - /* rearrange pointers to beginning of 16 bytes block */ - vllong8 stackElementA0; - stackElementA0 = vllong8::expand(m_stack_ptr,ptr,stackElementA0); - /* put distances in between */ - vuint16 stackElementA1((__m512i)stackElementA0); - stackElementA1 = vuint16::expand(m_stack_dist,asUInt(dist),stackElementA1); - /* write out first 4 x 16 bytes block to stack */ - vuint16::storeu(stackPtr,stackElementA1); - /* get upper half of dist and ptr */ - dist = align_shift_right<4>(dist,dist); - ptr = align_shift_right<4>(ptr,ptr); - /* assemble and write out second block */ - vllong8 stackElementB0; - stackElementB0 = vllong8::expand(m_stack_ptr,ptr,stackElementB0); - vuint16 stackElementB1((__m512i)stackElementB0); - stackElementB1 = vuint16::expand(m_stack_dist,asUInt(dist),stackElementB1); - vuint16::storeu(stackPtr + 4,stackElementB1); - /* increase stack pointer */ - stackPtr += hits-1; - } -#endif - #if defined(__AVX512VL__) // SKX template<int N> @@ -249,8 +45,8 @@ namespace embree #endif /* Specialization for BVH4. */ - template<int Nx, int types> - class BVHNNodeTraverser1Hit<4, Nx, types> + template<int types> + class BVHNNodeTraverser1Hit<4, types> { typedef BVH4 BVH; typedef BVH4::NodeRef NodeRef; @@ -261,14 +57,11 @@ namespace embree /* Traverses a node with at least one hit child. Optimized for finding the closest hit (intersection). */ static __forceinline void traverseClosestHit(NodeRef& cur, size_t mask, - const vfloat<Nx>& tNear, + const vfloat4& tNear, StackItemT<NodeRef>*& stackPtr, StackItemT<NodeRef>* stackEnd) { assert(mask != 0); -#if defined(__AVX512ER__) - traverseClosestHitAVX512<4,Nx,types,NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd); -#else const BaseNode* node = cur.baseNode(); /*! one child is hit, continue with that child */ @@ -344,13 +137,12 @@ namespace embree sort(stackPtr[-1],stackPtr[-2],stackPtr[-3],stackPtr[-4]); cur = (NodeRef) stackPtr[-1].ptr; stackPtr--; #endif -#endif } /* Traverses a node with at least one hit child. Optimized for finding any hit (occlusion). */ static __forceinline void traverseAnyHit(NodeRef& cur, size_t mask, - const vfloat<Nx>& tNear, + const vfloat4& tNear, NodeRef*& stackPtr, NodeRef* stackEnd) { @@ -380,8 +172,8 @@ namespace embree }; /* Specialization for BVH8. */ - template<int Nx, int types> - class BVHNNodeTraverser1Hit<8, Nx, types> + template<int types> + class BVHNNodeTraverser1Hit<8, types> { typedef BVH8 BVH; typedef BVH8::NodeRef NodeRef; @@ -485,10 +277,10 @@ namespace embree const size_t hits = 4 + popcnt(mask); vint8 dist(INT_MIN); // this will work with -0.0f (0x80000000) as distance, isort_update uses >= to insert - isort_quick_update(dist,dist_A2); - isort_quick_update(dist,dist_B2); - isort_quick_update(dist,dist_C2); - isort_quick_update(dist,dist_D2); + isort_quick_update<8>(dist,dist_A2); + isort_quick_update<8>(dist,dist_B2); + isort_quick_update<8>(dist,dist_C2); + isort_quick_update<8>(dist,dist_D2); do { @@ -497,7 +289,7 @@ namespace embree BVH::prefetch(cur,types); const vint8 new_dist(permute(distance_i,vint8(zero))); mask &= mask-1; - isort_update(dist,new_dist); + isort_update<8>(dist,new_dist); } while(mask); @@ -518,14 +310,12 @@ namespace embree public: static __forceinline void traverseClosestHit(NodeRef& cur, size_t mask, - const vfloat<Nx>& tNear, + const vfloat8& tNear, StackItemT<NodeRef>*& stackPtr, StackItemT<NodeRef>* stackEnd) { assert(mask != 0); -#if defined(__AVX512ER__) - traverseClosestHitAVX512<8,Nx,types,NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd); -#elif defined(__AVX512VL__) +#if defined(__AVX512VL__) traverseClosestHitAVX512VL8<NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd); #else @@ -644,7 +434,7 @@ namespace embree static __forceinline void traverseAnyHit(NodeRef& cur, size_t mask, - const vfloat<Nx>& tNear, + const vfloat8& tNear, NodeRef*& stackPtr, NodeRef* stackEnd) { diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_traverser_stream.h b/thirdparty/embree/kernels/bvh/bvh_traverser_stream.h index 9c603babf0..852981e69d 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/bvh_traverser_stream.h +++ b/thirdparty/embree/kernels/bvh/bvh_traverser_stream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,7 +11,7 @@ namespace embree { namespace isa { - template<int N, int Nx, int types> + template<int N, int types> class BVHNNodeTraverserStreamHitCoherent { typedef BVHN<N> BVH; @@ -22,8 +22,8 @@ namespace embree template<class T> static __forceinline void traverseClosestHit(NodeRef& cur, size_t& m_trav_active, - const vbool<Nx>& vmask, - const vfloat<Nx>& tNear, + const vbool<N>& vmask, + const vfloat<N>& tNear, const T* const tMask, StackItemMaskCoherent*& stackPtr) { @@ -79,14 +79,9 @@ namespace embree /*! slow path for more than two hits */ size_t hits = movemask(vmask); - const vint<Nx> dist_i = select(vmask, (asInt(tNear) & 0xfffffff8) | vint<Nx>(step), 0); - #if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL - const vint<N> tmp = extractN<N,0>(dist_i); - const vint<Nx> dist_i_sorted = usort_descending(tmp); - #else - const vint<Nx> dist_i_sorted = usort_descending(dist_i); - #endif - const vint<Nx> sorted_index = dist_i_sorted & 7; + const vint<N> dist_i = select(vmask, (asInt(tNear) & 0xfffffff8) | vint<N>(step), 0); + const vint<N> dist_i_sorted = usort_descending(dist_i); + const vint<N> sorted_index = dist_i_sorted & 7; size_t i = 0; for (;;) @@ -112,7 +107,7 @@ namespace embree template<class T> static __forceinline void traverseAnyHit(NodeRef& cur, size_t& m_trav_active, - const vbool<Nx>& vmask, + const vbool<N>& vmask, const T* const tMask, StackItemMaskCoherent*& stackPtr) { diff --git a/thirdparty/embree-aarch64/kernels/bvh/node_intersector.h b/thirdparty/embree/kernels/bvh/node_intersector.h index a978c0c459..25edaf295d 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/node_intersector.h +++ b/thirdparty/embree/kernels/bvh/node_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/bvh/node_intersector1.h b/thirdparty/embree/kernels/bvh/node_intersector1.h index aa0d4ba4d7..1ec4fc63fc 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/node_intersector1.h +++ b/thirdparty/embree/kernels/bvh/node_intersector1.h @@ -1,19 +1,10 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "node_intersector.h" -#if defined(__AVX2__) -#define __FMA_X4__ -#endif - -#if defined(__aarch64__) -#define __FMA_X4__ -#endif - - namespace embree { namespace isa @@ -22,12 +13,12 @@ namespace embree // Ray structure used in single-ray traversal ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx, bool robust> + template<int N, bool robust> struct TravRayBase; /* Base (without tnear and tfar) */ - template<int N, int Nx> - struct TravRayBase<N,Nx,false> + template<int N> + struct TravRayBase<N,false> { __forceinline TravRayBase() {} @@ -38,15 +29,9 @@ namespace embree org = Vec3vf<N>(ray_org.x,ray_org.y,ray_org.z); dir = Vec3vf<N>(ray_dir.x,ray_dir.y,ray_dir.z); rdir = Vec3vf<N>(ray_rdir.x,ray_rdir.y,ray_rdir.z); -#if defined(__FMA_X4__) +#if defined(__AVX2__) || defined(__ARM_NEON) const Vec3fa ray_org_rdir = ray_org*ray_rdir; -#if !defined(__aarch64__) org_rdir = Vec3vf<N>(ray_org_rdir.x,ray_org_rdir.y,ray_org_rdir.z); -#else - //for aarch64, we do not have msub equal instruction, so we negeate orig and use madd - //x86 will use msub - neg_org_rdir = Vec3vf<N>(-ray_org_rdir.x,-ray_org_rdir.y,-ray_org_rdir.z); -#endif #endif nearX = ray_rdir.x >= 0.0f ? 0*sizeof(vfloat<N>) : 1*sizeof(vfloat<N>); nearY = ray_rdir.y >= 0.0f ? 2*sizeof(vfloat<N>) : 3*sizeof(vfloat<N>); @@ -54,32 +39,18 @@ namespace embree farX = nearX ^ sizeof(vfloat<N>); farY = nearY ^ sizeof(vfloat<N>); farZ = nearZ ^ sizeof(vfloat<N>); - -#if defined(__AVX512ER__) // KNL+ - /* optimization works only for 8-wide BVHs with 16-wide SIMD */ - const vint<16> id(step); - const vint<16> id2 = align_shift_right<16/2>(id, id); - permX = select(vfloat<16>(dir.x) >= 0.0f, id, id2); - permY = select(vfloat<16>(dir.y) >= 0.0f, id, id2); - permZ = select(vfloat<16>(dir.z) >= 0.0f, id, id2); -#endif - } template<int K> - __forceinline TravRayBase(size_t k, const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir, - const Vec3vf<K>& ray_rdir, const Vec3vi<K>& nearXYZ, - size_t flip = sizeof(vfloat<N>)) + __forceinline void init(size_t k, const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir, + const Vec3vf<K>& ray_rdir, const Vec3vi<K>& nearXYZ, + size_t flip = sizeof(vfloat<N>)) { - org = Vec3vf<Nx>(ray_org.x[k], ray_org.y[k], ray_org.z[k]); - dir = Vec3vf<Nx>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]); - rdir = Vec3vf<Nx>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); -#if defined(__FMA_X4__) -#if !defined(__aarch64__) - org_rdir = org*rdir; -#else - neg_org_rdir = -(org*rdir); -#endif + org = Vec3vf<N>(ray_org.x[k], ray_org.y[k], ray_org.z[k]); + dir = Vec3vf<N>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]); + rdir = Vec3vf<N>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); +#if defined(__AVX2__) || defined(__ARM_NEON) + org_rdir = org*rdir; #endif nearX = nearXYZ.x[k]; nearY = nearXYZ.y[k]; @@ -87,39 +58,20 @@ namespace embree farX = nearX ^ flip; farY = nearY ^ flip; farZ = nearZ ^ flip; - -#if defined(__AVX512ER__) // KNL+ - /* optimization works only for 8-wide BVHs with 16-wide SIMD */ - const vint<16> id(step); - const vint<16> id2 = align_shift_right<16/2>(id, id); - permX = select(vfloat<16>(dir.x) >= 0.0f, id, id2); - permY = select(vfloat<16>(dir.y) >= 0.0f, id, id2); - permZ = select(vfloat<16>(dir.z) >= 0.0f, id, id2); -#endif } Vec3fa org_xyz, dir_xyz; - Vec3vf<Nx> org, dir, rdir; -#if defined(__FMA_X4__) -#if !defined(__aarch64__) - Vec3vf<Nx> org_rdir; -#else - //aarch64 version are keeping negation of the org_rdir and use madd - //x86 uses msub - Vec3vf<Nx> neg_org_rdir; -#endif + Vec3vf<N> org, dir, rdir; +#if defined(__AVX2__) || defined(__ARM_NEON) + Vec3vf<N> org_rdir; #endif -#if defined(__AVX512ER__) // KNL+ - vint16 permX, permY, permZ; -#endif - size_t nearX, nearY, nearZ; size_t farX, farY, farZ; }; /* Base (without tnear and tfar) */ - template<int N, int Nx> - struct TravRayBase<N,Nx,true> + template<int N> + struct TravRayBase<N,true> { __forceinline TravRayBase() {} @@ -135,34 +87,26 @@ namespace embree dir = Vec3vf<N>(ray_dir.x,ray_dir.y,ray_dir.z); rdir_near = Vec3vf<N>(ray_rdir_near.x,ray_rdir_near.y,ray_rdir_near.z); rdir_far = Vec3vf<N>(ray_rdir_far .x,ray_rdir_far .y,ray_rdir_far .z); + nearX = ray_rdir_near.x >= 0.0f ? 0*sizeof(vfloat<N>) : 1*sizeof(vfloat<N>); nearY = ray_rdir_near.y >= 0.0f ? 2*sizeof(vfloat<N>) : 3*sizeof(vfloat<N>); nearZ = ray_rdir_near.z >= 0.0f ? 4*sizeof(vfloat<N>) : 5*sizeof(vfloat<N>); farX = nearX ^ sizeof(vfloat<N>); farY = nearY ^ sizeof(vfloat<N>); farZ = nearZ ^ sizeof(vfloat<N>); - -#if defined(__AVX512ER__) // KNL+ - /* optimization works only for 8-wide BVHs with 16-wide SIMD */ - const vint<16> id(step); - const vint<16> id2 = align_shift_right<16/2>(id, id); - permX = select(vfloat<16>(dir.x) >= 0.0f, id, id2); - permY = select(vfloat<16>(dir.y) >= 0.0f, id, id2); - permZ = select(vfloat<16>(dir.z) >= 0.0f, id, id2); -#endif } template<int K> - __forceinline TravRayBase(size_t k, const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir, - const Vec3vf<K>& ray_rdir, const Vec3vi<K>& nearXYZ, - size_t flip = sizeof(vfloat<N>)) + __forceinline void init(size_t k, const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir, + const Vec3vf<K>& ray_rdir, const Vec3vi<K>& nearXYZ, + size_t flip = sizeof(vfloat<N>)) { - const vfloat<Nx> round_down = 1.0f-3.0f*float(ulp); - const vfloat<Nx> round_up = 1.0f+3.0f*float(ulp); - org = Vec3vf<Nx>(ray_org.x[k], ray_org.y[k], ray_org.z[k]); - dir = Vec3vf<Nx>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]); - rdir_near = round_down*Vec3vf<Nx>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); - rdir_far = round_up *Vec3vf<Nx>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); + const vfloat<N> round_down = 1.0f-3.0f*float(ulp); + const vfloat<N> round_up = 1.0f+3.0f*float(ulp); + org = Vec3vf<N>(ray_org.x[k], ray_org.y[k], ray_org.z[k]); + dir = Vec3vf<N>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]); + rdir_near = round_down*Vec3vf<N>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); + rdir_far = round_up *Vec3vf<N>(ray_rdir.x[k], ray_rdir.y[k], ray_rdir.z[k]); nearX = nearXYZ.x[k]; nearY = nearXYZ.y[k]; @@ -170,47 +114,36 @@ namespace embree farX = nearX ^ flip; farY = nearY ^ flip; farZ = nearZ ^ flip; - -#if defined(__AVX512ER__) // KNL+ - /* optimization works only for 8-wide BVHs with 16-wide SIMD */ - const vint<16> id(step); - const vint<16> id2 = align_shift_right<16/2>(id, id); - permX = select(vfloat<16>(dir.x) >= 0.0f, id, id2); - permY = select(vfloat<16>(dir.y) >= 0.0f, id, id2); - permZ = select(vfloat<16>(dir.z) >= 0.0f, id, id2); -#endif } Vec3fa org_xyz, dir_xyz; - Vec3vf<Nx> org, dir, rdir_near, rdir_far; -#if defined(__AVX512ER__) // KNL+ - vint16 permX, permY, permZ; -#endif - + Vec3vf<N> org, dir, rdir_near, rdir_far; size_t nearX, nearY, nearZ; size_t farX, farY, farZ; }; /* Full (with tnear and tfar) */ - template<int N, int Nx, bool robust> - struct TravRay : TravRayBase<N,Nx,robust> + template<int N, bool robust> + struct TravRay : TravRayBase<N,robust> { __forceinline TravRay() {} __forceinline TravRay(const Vec3fa& ray_org, const Vec3fa& ray_dir, float ray_tnear, float ray_tfar) - : TravRayBase<N,Nx,robust>(ray_org, ray_dir), + : TravRayBase<N,robust>(ray_org, ray_dir), tnear(ray_tnear), tfar(ray_tfar) {} template<int K> - __forceinline TravRay(size_t k, const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir, - const Vec3vf<K>& ray_rdir, const Vec3vi<K>& nearXYZ, - float ray_tnear, float ray_tfar, - size_t flip = sizeof(vfloat<N>)) - : TravRayBase<N,Nx,robust>(k, ray_org, ray_dir, ray_rdir, nearXYZ, flip), - tnear(ray_tnear), tfar(ray_tfar) {} + __forceinline void init(size_t k, const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir, + const Vec3vf<K>& ray_rdir, const Vec3vi<K>& nearXYZ, + float ray_tnear, float ray_tfar, + size_t flip = sizeof(vfloat<N>)) + { + TravRayBase<N,robust>::template init<K>(k, ray_org, ray_dir, ray_rdir, nearXYZ, flip); + tnear = ray_tnear; tfar = ray_tfar; + } - vfloat<Nx> tnear; - vfloat<Nx> tfar; + vfloat<N> tnear; + vfloat<N> tfar; }; ////////////////////////////////////////////////////////////////////////////////////// @@ -465,28 +398,19 @@ namespace embree // Fast AABBNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx, bool robust> - __forceinline size_t intersectNode(const typename BVHN<N>::AABBNode* node, const TravRay<N,Nx,robust>& ray, vfloat<Nx>& dist); + template<int N, bool robust> + __forceinline size_t intersectNode(const typename BVHN<N>::AABBNode* node, const TravRay<N,robust>& ray, vfloat<N>& dist); template<> - __forceinline size_t intersectNode<4,4>(const typename BVH4::AABBNode* node, const TravRay<4,4,false>& ray, vfloat4& dist) + __forceinline size_t intersectNode<4>(const typename BVH4::AABBNode* node, const TravRay<4,false>& ray, vfloat4& dist) { -#if defined(__FMA_X4__) -#if defined(__aarch64__) - const vfloat4 tNearX = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat4 tNearY = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat4 tNearZ = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.neg_org_rdir.z); - const vfloat4 tFarX = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat4 tFarY = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat4 tFarZ = madd(vfloat4::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat4 tNearX = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x); const vfloat4 tNearY = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y); const vfloat4 tNearZ = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z); const vfloat4 tFarX = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x); const vfloat4 tFarY = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y); const vfloat4 tFarZ = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z); -#endif #else const vfloat4 tNearX = (vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x; const vfloat4 tNearY = (vfloat4::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y; @@ -506,7 +430,7 @@ namespace embree const vfloat4 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool4 vmask = asInt(tNear) > asInt(tFar); const size_t mask = movemask(vmask) ^ ((1<<4)-1); -#elif defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#elif defined(__AVX512F__) // SKX const vfloat4 tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat4 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool4 vmask = asInt(tNear) <= asInt(tFar); @@ -524,25 +448,15 @@ namespace embree #if defined(__AVX__) template<> - __forceinline size_t intersectNode<8,8>(const typename BVH8::AABBNode* node, const TravRay<8,8,false>& ray, vfloat8& dist) + __forceinline size_t intersectNode<8>(const typename BVH8::AABBNode* node, const TravRay<8,false>& ray, vfloat8& dist) { -#if defined(__AVX2__) -#if defined(__aarch64__) - const vfloat8 tNearX = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat8 tNearY = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat8 tNearZ = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.neg_org_rdir.z); - const vfloat8 tFarX = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat8 tFarY = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat8 tFarZ = madd(vfloat8::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat8 tNearX = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x); const vfloat8 tNearY = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y); const vfloat8 tNearZ = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z); const vfloat8 tFarX = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x); const vfloat8 tFarY = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y); const vfloat8 tFarZ = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z); -#endif - #else const vfloat8 tNearX = (vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x; const vfloat8 tNearY = (vfloat8::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y; @@ -557,7 +471,7 @@ namespace embree const vfloat8 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool8 vmask = asInt(tNear) > asInt(tFar); const size_t mask = movemask(vmask) ^ ((1<<8)-1); -#elif defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#elif defined(__AVX512F__) // SKX const vfloat8 tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat8 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool8 vmask = asInt(tNear) <= asInt(tFar); @@ -574,52 +488,12 @@ namespace embree #endif -#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL - - template<> - __forceinline size_t intersectNode<4,16>(const typename BVH4::AABBNode* node, const TravRay<4,16,false>& ray, vfloat16& dist) - { - const vfloat16 tNearX = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x); - const vfloat16 tNearY = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y); - const vfloat16 tNearZ = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z); - const vfloat16 tFarX = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x); - const vfloat16 tFarY = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y); - const vfloat16 tFarZ = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z); - const vfloat16 tNear = max(tNearX,tNearY,tNearZ,ray.tnear); - const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,ray.tfar); - const vbool16 vmask = le(vbool16(0xf),tNear,tFar); - const size_t mask = movemask(vmask); - dist = tNear; - return mask; - } - - template<> - __forceinline size_t intersectNode<8,16>(const typename BVH8::AABBNode* node, const TravRay<8,16,false>& ray, vfloat16& dist) - { - const vllong8 invalid((size_t)BVH8::emptyNode); - const vboold8 m_valid(invalid != vllong8::loadu(node->children)); - const vfloat16 bminmaxX = permute(vfloat16::load((const float*)&node->lower_x), ray.permX); - const vfloat16 bminmaxY = permute(vfloat16::load((const float*)&node->lower_y), ray.permY); - const vfloat16 bminmaxZ = permute(vfloat16::load((const float*)&node->lower_z), ray.permZ); - const vfloat16 tNearFarX = msub(bminmaxX, ray.rdir.x, ray.org_rdir.x); - const vfloat16 tNearFarY = msub(bminmaxY, ray.rdir.y, ray.org_rdir.y); - const vfloat16 tNearFarZ = msub(bminmaxZ, ray.rdir.z, ray.org_rdir.z); - const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, ray.tnear); - const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, ray.tfar); - const vbool16 vmask = le(vboolf16(m_valid),tNear,align_shift_right<8>(tFar, tFar)); - const size_t mask = movemask(vmask); - dist = tNear; - return mask; - } - -#endif - ////////////////////////////////////////////////////////////////////////////////////// // Robust AABBNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx> - __forceinline size_t intersectNodeRobust(const typename BVHN<N>::AABBNode* node, const TravRay<N,Nx,true>& ray, vfloat<Nx>& dist) + template<int N> + __forceinline size_t intersectNodeRobust(const typename BVHN<N>::AABBNode* node, const TravRay<N,true>& ray, vfloat<N>& dist) { const vfloat<N> tNearX = (vfloat<N>::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir_near.x; const vfloat<N> tNearY = (vfloat<N>::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir_near.y; @@ -635,50 +509,12 @@ namespace embree return mask; } -#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL - - template<> - __forceinline size_t intersectNodeRobust<4,16>(const typename BVHN<4>::AABBNode* node, const TravRay<4,16,true>& ray, vfloat<16>& dist) - { - const vfloat16 tNearX = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir_near.x; - const vfloat16 tNearY = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir_near.y; - const vfloat16 tNearZ = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearZ)) - ray.org.z) * ray.rdir_near.z; - const vfloat16 tFarX = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.farX )) - ray.org.x) * ray.rdir_far.x; - const vfloat16 tFarY = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.farY )) - ray.org.y) * ray.rdir_far.y; - const vfloat16 tFarZ = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.farZ )) - ray.org.z) * ray.rdir_far.z; - const vfloat16 tNear = max(tNearX,tNearY,tNearZ,ray.tnear); - const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,ray.tfar); - const vbool16 vmask = le((1 << 4)-1,tNear,tFar); - const size_t mask = movemask(vmask); - dist = tNear; - return mask; - } - - template<> - __forceinline size_t intersectNodeRobust<8,16>(const typename BVHN<8>::AABBNode* node, const TravRay<8,16,true>& ray, vfloat<16>& dist) - { - const vfloat16 tNearX = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir_near.x; - const vfloat16 tNearY = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir_near.y; - const vfloat16 tNearZ = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearZ)) - ray.org.z) * ray.rdir_near.z; - const vfloat16 tFarX = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.farX )) - ray.org.x) * ray.rdir_far.x; - const vfloat16 tFarY = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.farY )) - ray.org.y) * ray.rdir_far.y; - const vfloat16 tFarZ = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.farZ )) - ray.org.z) * ray.rdir_far.z; - const vfloat16 tNear = max(tNearX,tNearY,tNearZ,ray.tnear); - const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,ray.tfar); - const vbool16 vmask = le((1 << 8)-1,tNear,tFar); - const size_t mask = movemask(vmask); - dist = tNear; - return mask; - } - -#endif - ////////////////////////////////////////////////////////////////////////////////////// // Fast AABBNodeMB intersection ////////////////////////////////////////////////////////////////////////////////////// template<int N> - __forceinline size_t intersectNode(const typename BVHN<N>::AABBNodeMB* node, const TravRay<N,N,false>& ray, const float time, vfloat<N>& dist) + __forceinline size_t intersectNode(const typename BVHN<N>::AABBNodeMB* node, const TravRay<N,false>& ray, const float time, vfloat<N>& dist) { const vfloat<N>* pNearX = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearX); const vfloat<N>* pNearY = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearY); @@ -686,22 +522,13 @@ namespace embree const vfloat<N>* pFarX = (const vfloat<N>*)((const char*)&node->lower_x+ray.farX); const vfloat<N>* pFarY = (const vfloat<N>*)((const char*)&node->lower_x+ray.farY); const vfloat<N>* pFarZ = (const vfloat<N>*)((const char*)&node->lower_x+ray.farZ); -#if defined(__FMA_X4__) -#if defined(__aarch64__) - const vfloat<N> tNearX = madd(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<N> tNearY = madd(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<N> tNearZ = madd(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<N> tFarX = madd(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<N> tFarY = madd(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<N> tFarZ = madd(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<N> tNearX = msub(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tNearY = msub(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tNearZ = msub(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.org_rdir.z); const vfloat<N> tFarX = msub(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tFarY = msub(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tFarZ = msub(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.org_rdir.z); -#endif #else const vfloat<N> tNearX = (madd(time,pNearX[6],vfloat<N>(pNearX[0])) - ray.org.x) * ray.rdir.x; const vfloat<N> tNearY = (madd(time,pNearY[6],vfloat<N>(pNearY[0])) - ray.org.y) * ray.rdir.y; @@ -710,12 +537,12 @@ namespace embree const vfloat<N> tFarY = (madd(time,pFarY [6],vfloat<N>(pFarY [0])) - ray.org.y) * ray.rdir.y; const vfloat<N> tFarZ = (madd(time,pFarZ [6],vfloat<N>(pFarZ [0])) - ray.org.z) * ray.rdir.z; #endif -#if defined(__FMA_X4__) && !defined(__AVX512F__) // HSW +#if defined(__AVX2__) && !defined(__AVX512F__) // HSW const vfloat<N> tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat<N> tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool<N> vmask = asInt(tNear) > asInt(tFar); const size_t mask = movemask(vmask) ^ ((1<<N)-1); -#elif defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#elif defined(__AVX512F__) // SKX const vfloat<N> tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat<N> tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool<N> vmask = asInt(tNear) <= asInt(tFar); @@ -735,7 +562,7 @@ namespace embree ////////////////////////////////////////////////////////////////////////////////////// template<int N> - __forceinline size_t intersectNodeRobust(const typename BVHN<N>::AABBNodeMB* node, const TravRay<N,N,true>& ray, const float time, vfloat<N>& dist) + __forceinline size_t intersectNodeRobust(const typename BVHN<N>::AABBNodeMB* node, const TravRay<N,true>& ray, const float time, vfloat<N>& dist) { const vfloat<N>* pNearX = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearX); const vfloat<N>* pNearY = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearY); @@ -761,7 +588,7 @@ namespace embree ////////////////////////////////////////////////////////////////////////////////////// template<int N> - __forceinline size_t intersectNodeMB4D(const typename BVHN<N>::NodeRef ref, const TravRay<N,N,false>& ray, const float time, vfloat<N>& dist) + __forceinline size_t intersectNodeMB4D(const typename BVHN<N>::NodeRef ref, const TravRay<N,false>& ray, const float time, vfloat<N>& dist) { const typename BVHN<N>::AABBNodeMB* node = ref.getAABBNodeMB(); @@ -771,22 +598,13 @@ namespace embree const vfloat<N>* pFarX = (const vfloat<N>*)((const char*)&node->lower_x+ray.farX); const vfloat<N>* pFarY = (const vfloat<N>*)((const char*)&node->lower_x+ray.farY); const vfloat<N>* pFarZ = (const vfloat<N>*)((const char*)&node->lower_x+ray.farZ); -#if defined (__FMA_X4__) -#if defined(__aarch64__) - const vfloat<N> tNearX = madd(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<N> tNearY = madd(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<N> tNearZ = madd(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<N> tFarX = madd(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<N> tFarY = madd(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<N> tFarZ = madd(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined (__AVX2__) || defined(__ARM_NEON) const vfloat<N> tNearX = msub(madd(time,pNearX[6],vfloat<N>(pNearX[0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tNearY = msub(madd(time,pNearY[6],vfloat<N>(pNearY[0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tNearZ = msub(madd(time,pNearZ[6],vfloat<N>(pNearZ[0])), ray.rdir.z, ray.org_rdir.z); const vfloat<N> tFarX = msub(madd(time,pFarX [6],vfloat<N>(pFarX [0])), ray.rdir.x, ray.org_rdir.x); const vfloat<N> tFarY = msub(madd(time,pFarY [6],vfloat<N>(pFarY [0])), ray.rdir.y, ray.org_rdir.y); const vfloat<N> tFarZ = msub(madd(time,pFarZ [6],vfloat<N>(pFarZ [0])), ray.rdir.z, ray.org_rdir.z); -#endif #else const vfloat<N> tNearX = (madd(time,pNearX[6],vfloat<N>(pNearX[0])) - ray.org.x) * ray.rdir.x; const vfloat<N> tNearY = (madd(time,pNearY[6],vfloat<N>(pNearY[0])) - ray.org.y) * ray.rdir.y; @@ -795,7 +613,7 @@ namespace embree const vfloat<N> tFarY = (madd(time,pFarY [6],vfloat<N>(pFarY [0])) - ray.org.y) * ray.rdir.y; const vfloat<N> tFarZ = (madd(time,pFarZ [6],vfloat<N>(pFarZ [0])) - ray.org.z) * ray.rdir.z; #endif -#if defined(__FMA_X4__) && !defined(__AVX512F__) +#if defined(__AVX2__) && !defined(__AVX512F__) const vfloat<N> tNear = maxi(maxi(tNearX,tNearY),maxi(tNearZ,ray.tnear)); const vfloat<N> tFar = mini(mini(tFarX ,tFarY ),mini(tFarZ ,ray.tfar )); #else @@ -817,7 +635,7 @@ namespace embree ////////////////////////////////////////////////////////////////////////////////////// template<int N> - __forceinline size_t intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const TravRay<N,N,true>& ray, const float time, vfloat<N>& dist) + __forceinline size_t intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const TravRay<N,true>& ray, const float time, vfloat<N>& dist) { const typename BVHN<N>::AABBNodeMB* node = ref.getAABBNodeMB(); @@ -849,11 +667,11 @@ namespace embree // Fast QuantizedBaseNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx, bool robust> - __forceinline size_t intersectNode(const typename BVHN<N>::QuantizedBaseNode* node, const TravRay<N,Nx,robust>& ray, vfloat<Nx>& dist); + template<int N, bool robust> + __forceinline size_t intersectNode(const typename BVHN<N>::QuantizedBaseNode* node, const TravRay<N,robust>& ray, vfloat<N>& dist); template<> - __forceinline size_t intersectNode<4,4>(const typename BVH4::QuantizedBaseNode* node, const TravRay<4,4,false>& ray, vfloat4& dist) + __forceinline size_t intersectNode<4>(const typename BVH4::QuantizedBaseNode* node, const TravRay<4,false>& ray, vfloat4& dist) { const size_t mvalid = movemask(node->validMask()); const vfloat4 start_x(node->start.x); @@ -869,22 +687,13 @@ namespace embree const vfloat4 lower_z = madd(node->dequantize<4>(ray.nearZ >> 2),scale_z,start_z); const vfloat4 upper_z = madd(node->dequantize<4>(ray.farZ >> 2),scale_z,start_z); -#if defined(__FMA_X4__) -#if defined(__aarch64__) - const vfloat4 tNearX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat4 tNearY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat4 tNearZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat4 tFarX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat4 tFarY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat4 tFarZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat4 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat4 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat4 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); const vfloat4 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); const vfloat4 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); const vfloat4 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); -#endif #else const vfloat4 tNearX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat4 tNearY = (lower_y - ray.org.y) * ray.rdir.y; @@ -894,12 +703,12 @@ namespace embree const vfloat4 tFarZ = (upper_z - ray.org.z) * ray.rdir.z; #endif -#if (defined(__aarch64__) && defined(BUILD_IOS)) || defined(__SSE4_1__) && !defined(__AVX512F__) // up to HSW +#if defined(__SSE4_1__) && !defined(__AVX512F__) // up to HSW const vfloat4 tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat4 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool4 vmask = asInt(tNear) > asInt(tFar); const size_t mask = movemask(vmask) ^ ((1<<4)-1); -#elif defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#elif defined(__AVX512F__) // SKX const vfloat4 tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat4 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool4 vmask = asInt(tNear) <= asInt(tFar); @@ -915,7 +724,7 @@ namespace embree } template<> - __forceinline size_t intersectNode<4,4>(const typename BVH4::QuantizedBaseNode* node, const TravRay<4,4,true>& ray, vfloat4& dist) + __forceinline size_t intersectNode<4>(const typename BVH4::QuantizedBaseNode* node, const TravRay<4,true>& ray, vfloat4& dist) { const size_t mvalid = movemask(node->validMask()); const vfloat4 start_x(node->start.x); @@ -950,7 +759,7 @@ namespace embree #if defined(__AVX__) template<> - __forceinline size_t intersectNode<8,8>(const typename BVH8::QuantizedBaseNode* node, const TravRay<8,8,false>& ray, vfloat8& dist) + __forceinline size_t intersectNode<8>(const typename BVH8::QuantizedBaseNode* node, const TravRay<8,false>& ray, vfloat8& dist) { const size_t mvalid = movemask(node->validMask()); const vfloat8 start_x(node->start.x); @@ -966,22 +775,13 @@ namespace embree const vfloat8 lower_z = madd(node->dequantize<8>(ray.nearZ >> 2),scale_z,start_z); const vfloat8 upper_z = madd(node->dequantize<8>(ray.farZ >> 2),scale_z,start_z); -#if defined(__AVX2__) -#if defined(__aarch64__) - const vfloat8 tNearX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat8 tNearY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat8 tNearZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat8 tFarX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat8 tFarY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat8 tFarZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat8 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat8 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat8 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); const vfloat8 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); const vfloat8 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); const vfloat8 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); -#endif #else const vfloat8 tNearX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat8 tNearY = (lower_y - ray.org.y) * ray.rdir.y; @@ -996,7 +796,7 @@ namespace embree const vfloat8 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool8 vmask = asInt(tNear) > asInt(tFar); const size_t mask = movemask(vmask) ^ ((1<<8)-1); -#elif defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#elif defined(__AVX512F__) // SKX const vfloat8 tNear = maxi(tNearX,tNearY,tNearZ,ray.tnear); const vfloat8 tFar = mini(tFarX ,tFarY ,tFarZ ,ray.tfar); const vbool8 vmask = asInt(tNear) <= asInt(tFar); @@ -1012,7 +812,7 @@ namespace embree } template<> - __forceinline size_t intersectNode<8,8>(const typename BVH8::QuantizedBaseNode* node, const TravRay<8,8,true>& ray, vfloat8& dist) + __forceinline size_t intersectNode<8>(const typename BVH8::QuantizedBaseNode* node, const TravRay<8,true>& ray, vfloat8& dist) { const size_t mvalid = movemask(node->validMask()); const vfloat8 start_x(node->start.x); @@ -1047,113 +847,8 @@ namespace embree #endif -#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL - - template<> - __forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedBaseNode* node, const TravRay<4,16,false>& ray, vfloat16& dist) - { - const size_t mvalid = movemask(node->validMask()); - const vfloat16 start_x(node->start.x); - const vfloat16 scale_x(node->scale.x); - const vfloat16 lower_x = madd(vfloat16(node->dequantize<4>(ray.nearX >> 2)),scale_x,start_x); - const vfloat16 upper_x = madd(vfloat16(node->dequantize<4>(ray.farX >> 2)),scale_x,start_x); - const vfloat16 start_y(node->start.y); - const vfloat16 scale_y(node->scale.y); - const vfloat16 lower_y = madd(vfloat16(node->dequantize<4>(ray.nearY >> 2)),scale_y,start_y); - const vfloat16 upper_y = madd(vfloat16(node->dequantize<4>(ray.farY >> 2)),scale_y,start_y); - const vfloat16 start_z(node->start.z); - const vfloat16 scale_z(node->scale.z); - const vfloat16 lower_z = madd(vfloat16(node->dequantize<4>(ray.nearZ >> 2)),scale_z,start_z); - const vfloat16 upper_z = madd(vfloat16(node->dequantize<4>(ray.farZ >> 2)),scale_z,start_z); - - const vfloat16 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); - const vfloat16 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); - const vfloat16 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); - const vfloat16 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); - const vfloat16 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); - const vfloat16 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); - const vfloat16 tNear = max(tNearX,tNearY,tNearZ,ray.tnear); - const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,ray.tfar); - const vbool16 vmask = le(vbool16(0xf),tNear,tFar); - const size_t mask = movemask(vmask) & mvalid; - dist = tNear; - return mask; - } - - template<> - __forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedBaseNode* node, const TravRay<4,16,true>& ray, vfloat16& dist) - { - const size_t mvalid = movemask(node->validMask()); - const vfloat16 start_x(node->start.x); - const vfloat16 scale_x(node->scale.x); - const vfloat16 lower_x = madd(vfloat16(node->dequantize<4>(ray.nearX >> 2)),scale_x,start_x); - const vfloat16 upper_x = madd(vfloat16(node->dequantize<4>(ray.farX >> 2)),scale_x,start_x); - const vfloat16 start_y(node->start.y); - const vfloat16 scale_y(node->scale.y); - const vfloat16 lower_y = madd(vfloat16(node->dequantize<4>(ray.nearY >> 2)),scale_y,start_y); - const vfloat16 upper_y = madd(vfloat16(node->dequantize<4>(ray.farY >> 2)),scale_y,start_y); - const vfloat16 start_z(node->start.z); - const vfloat16 scale_z(node->scale.z); - const vfloat16 lower_z = madd(vfloat16(node->dequantize<4>(ray.nearZ >> 2)),scale_z,start_z); - const vfloat16 upper_z = madd(vfloat16(node->dequantize<4>(ray.farZ >> 2)),scale_z,start_z); - - const vfloat16 tNearX = (lower_x - ray.org.x) * ray.rdir_near.x; - const vfloat16 tNearY = (lower_y - ray.org.y) * ray.rdir_near.y; - const vfloat16 tNearZ = (lower_z - ray.org.z) * ray.rdir_near.z; - const vfloat16 tFarX = (upper_x - ray.org.x) * ray.rdir_far.x; - const vfloat16 tFarY = (upper_y - ray.org.y) * ray.rdir_far.y; - const vfloat16 tFarZ = (upper_z - ray.org.z) * ray.rdir_far.z; - - const vfloat16 tNear = max(tNearX,tNearY,tNearZ,ray.tnear); - const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,ray.tfar); - const vbool16 vmask = le(vbool16(0xf),tNear,tFar); - const size_t mask = movemask(vmask) & mvalid; - dist = tNear; - return mask; - } - - template<> - __forceinline size_t intersectNode<8,16>(const typename BVH8::QuantizedBaseNode* node, const TravRay<8,16,false>& ray, vfloat16& dist) - { - const vbool16 m_valid(node->validMask16()); - const vfloat16 bminmaxX = node->dequantizeLowerUpperX(ray.permX); - const vfloat16 bminmaxY = node->dequantizeLowerUpperY(ray.permY); - const vfloat16 bminmaxZ = node->dequantizeLowerUpperZ(ray.permZ); - const vfloat16 tNearFarX = msub(bminmaxX, ray.rdir.x, ray.org_rdir.x); - const vfloat16 tNearFarY = msub(bminmaxY, ray.rdir.y, ray.org_rdir.y); - const vfloat16 tNearFarZ = msub(bminmaxZ, ray.rdir.z, ray.org_rdir.z); - const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, ray.tnear); - const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, ray.tfar); - const vbool16 vmask = le(m_valid,tNear,align_shift_right<8>(tFar, tFar)); - const size_t mask = movemask(vmask); - dist = tNear; - return mask; - } - - template<> - __forceinline size_t intersectNode<8,16>(const typename BVH8::QuantizedBaseNode* node, const TravRay<8,16,true>& ray, vfloat16& dist) - { - const vbool16 m_valid(node->validMask16()); - const vfloat16 bminmaxX = node->dequantizeLowerUpperX(ray.permX); - const vfloat16 bminmaxY = node->dequantizeLowerUpperY(ray.permY); - const vfloat16 bminmaxZ = node->dequantizeLowerUpperZ(ray.permZ); - const vfloat16 tNearFarX = (bminmaxX - ray.org.x) * ray.rdir_far.x; // FIXME: this is not conservative !!!!!!!!! - const vfloat16 tNearFarY = (bminmaxY - ray.org.y) * ray.rdir_far.y; - const vfloat16 tNearFarZ = (bminmaxZ - ray.org.z) * ray.rdir_far.z; - const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, ray.tnear); - const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, ray.tfar); - const vbool16 vmask = le(m_valid,tNear,align_shift_right<8>(tFar, tFar)); - const size_t mask = movemask(vmask); - dist = tNear; - return mask; - } - - -#endif - - - template<int N, int Nx> - __forceinline size_t intersectNode(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,Nx,false>& ray, const float time, vfloat<N>& dist) + template<int N> + __forceinline size_t intersectNode(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,false>& ray, const float time, vfloat<N>& dist) { const vboolf<N> mvalid = node->validMask(); const vfloat<N> lower_x = node->dequantizeLowerX(time); @@ -1162,22 +857,13 @@ namespace embree const vfloat<N> upper_y = node->dequantizeUpperY(time); const vfloat<N> lower_z = node->dequantizeLowerZ(time); const vfloat<N> upper_z = node->dequantizeUpperZ(time); -#if defined(__FMA_X4__) -#if defined(__aarch64__) - const vfloat<N> tNearX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<N> tNearY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<N> tNearZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<N> tFarX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<N> tFarY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<N> tFarZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); -#else +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<N> tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<N> tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<N> tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); const vfloat<N> tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); const vfloat<N> tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); const vfloat<N> tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); -#endif #else const vfloat<N> tNearX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat<N> tNearY = (lower_y - ray.org.y) * ray.rdir.y; @@ -1195,7 +881,7 @@ namespace embree const vfloat<N> tmaxZ = maxi(tNearZ,tFarZ); const vfloat<N> tNear = maxi(tminX,tminY,tminZ,ray.tnear); const vfloat<N> tFar = mini(tmaxX,tmaxY,tmaxZ,ray.tfar); -#if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#if defined(__AVX512F__) // SKX const vbool<N> vmask = le(mvalid,asInt(tNear),asInt(tFar)); #else const vbool<N> vmask = (asInt(tNear) <= asInt(tFar)) & mvalid; @@ -1205,8 +891,8 @@ namespace embree return mask; } - template<int N, int Nx> - __forceinline size_t intersectNode(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,Nx,true>& ray, const float time, vfloat<N>& dist) + template<int N> + __forceinline size_t intersectNode(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,true>& ray, const float time, vfloat<N>& dist) { const vboolf<N> mvalid = node->validMask(); const vfloat<N> lower_x = node->dequantizeLowerX(time); @@ -1230,7 +916,7 @@ namespace embree const vfloat<N> tmaxZ = maxi(tNearZ,tFarZ); const vfloat<N> tNear = maxi(tminX,tminY,tminZ,ray.tnear); const vfloat<N> tFar = mini(tmaxX,tmaxY,tmaxZ,ray.tfar); -#if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#if defined(__AVX512F__) // SKX const vbool<N> vmask = le(mvalid,asInt(tNear),asInt(tFar)); #else const vbool<N> vmask = (asInt(tNear) <= asInt(tFar)) & mvalid; @@ -1240,83 +926,12 @@ namespace embree return mask; } - -#if defined(__AVX512ER__) - // for KNL - template<> - __forceinline size_t intersectNode<4,16>(const typename BVHN<4>::QuantizedBaseNodeMB* node, const TravRay<4,16,false>& ray, const float time, vfloat<4>& dist) - { - const size_t mvalid = movemask(node->validMask()); - const vfloat16 lower_x = node->dequantizeLowerX(time); - const vfloat16 upper_x = node->dequantizeUpperX(time); - const vfloat16 lower_y = node->dequantizeLowerY(time); - const vfloat16 upper_y = node->dequantizeUpperY(time); - const vfloat16 lower_z = node->dequantizeLowerZ(time); - const vfloat16 upper_z = node->dequantizeUpperZ(time); - - const vfloat16 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); - const vfloat16 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); - const vfloat16 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); - const vfloat16 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x); - const vfloat16 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y); - const vfloat16 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z); - - const vfloat16 tminX = min(tNearX,tFarX); - const vfloat16 tmaxX = max(tNearX,tFarX); - const vfloat16 tminY = min(tNearY,tFarY); - const vfloat16 tmaxY = max(tNearY,tFarY); - const vfloat16 tminZ = min(tNearZ,tFarZ); - const vfloat16 tmaxZ = max(tNearZ,tFarZ); - const vfloat16 tNear = max(tminX,tminY,tminZ,ray.tnear); - const vfloat16 tFar = min(tmaxX,tmaxY,tmaxZ,ray.tfar ); - const vbool16 vmask = tNear <= tFar; - const size_t mask = movemask(vmask) & mvalid; - dist = extractN<4,0>(tNear); - return mask; - } - - - // for KNL - template<> - __forceinline size_t intersectNode<4,16>(const typename BVHN<4>::QuantizedBaseNodeMB* node, const TravRay<4,16,true>& ray, const float time, vfloat<4>& dist) - { - const size_t mvalid = movemask(node->validMask()); - const vfloat16 lower_x = node->dequantizeLowerX(time); - const vfloat16 upper_x = node->dequantizeUpperX(time); - const vfloat16 lower_y = node->dequantizeLowerY(time); - const vfloat16 upper_y = node->dequantizeUpperY(time); - const vfloat16 lower_z = node->dequantizeLowerZ(time); - const vfloat16 upper_z = node->dequantizeUpperZ(time); - - const vfloat16 tNearX = (lower_x - ray.org.x) * ray.rdir_near.x; - const vfloat16 tNearY = (lower_y - ray.org.y) * ray.rdir_near.y; - const vfloat16 tNearZ = (lower_z - ray.org.z) * ray.rdir_near.z; - const vfloat16 tFarX = (upper_x - ray.org.x) * ray.rdir_far.x; - const vfloat16 tFarY = (upper_y - ray.org.y) * ray.rdir_far.y; - const vfloat16 tFarZ = (upper_z - ray.org.z) * ray.rdir_far.z; - - const vfloat16 tminX = min(tNearX,tFarX); - const vfloat16 tmaxX = max(tNearX,tFarX); - const vfloat16 tminY = min(tNearY,tFarY); - const vfloat16 tmaxY = max(tNearY,tFarY); - const vfloat16 tminZ = min(tNearZ,tFarZ); - const vfloat16 tmaxZ = max(tNearZ,tFarZ); - const vfloat16 tNear = max(tminX,tminY,tminZ,ray.tnear); - const vfloat16 tFar = min(tmaxX,tmaxY,tmaxZ,ray.tfar ); - const vbool16 vmask = tNear <= tFar; - const size_t mask = movemask(vmask) & mvalid; - dist = extractN<4,0>(tNear); - return mask; - } - -#endif - ////////////////////////////////////////////////////////////////////////////////////// // Fast OBBNode intersection ////////////////////////////////////////////////////////////////////////////////////// template<int N, bool robust> - __forceinline size_t intersectNode(const typename BVHN<N>::OBBNode* node, const TravRay<N,N,robust>& ray, vfloat<N>& dist) + __forceinline size_t intersectNode(const typename BVHN<N>::OBBNode* node, const TravRay<N,robust>& ray, vfloat<N>& dist) { const Vec3vf<N> dir = xfmVector(node->naabb,ray.dir); //const Vec3vf<N> nrdir = Vec3vf<N>(vfloat<N>(-1.0f))/dir; @@ -1347,7 +962,7 @@ namespace embree ////////////////////////////////////////////////////////////////////////////////////// template<int N, bool robust> - __forceinline size_t intersectNode(const typename BVHN<N>::OBBNodeMB* node, const TravRay<N,N,robust>& ray, const float time, vfloat<N>& dist) + __forceinline size_t intersectNode(const typename BVHN<N>::OBBNodeMB* node, const TravRay<N,robust>& ray, const float time, vfloat<N>& dist) { const AffineSpace3vf<N> xfm = node->space0; const Vec3vf<N> b0_lower = zero; @@ -1586,13 +1201,13 @@ namespace embree ////////////////////////////////////////////////////////////////////////////////////// /*! Intersects N nodes with 1 ray */ - template<int N, int Nx, int types, bool robust> + template<int N, int types, bool robust> struct BVHNNodeIntersector1; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN1, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN1, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNode(node.getAABBNode(), ray, dist); @@ -1600,10 +1215,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN1, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN1, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNodeRobust(node.getAABBNode(), ray, dist); @@ -1611,10 +1226,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNode(node.getAABBNodeMB(), ray, time, dist); @@ -1622,10 +1237,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNodeRobust(node.getAABBNodeMB(), ray, time, dist); @@ -1633,10 +1248,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2_AN4D, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2_AN4D, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNodeMB4D<N>(node, ray, time, dist); @@ -1644,10 +1259,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2_AN4D, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2_AN4D, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNodeMB4DRobust<N>(node, ray, time, dist); @@ -1655,10 +1270,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN1_UN1, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN1_UN1, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (likely(node.isAABBNode())) mask = intersectNode(node.getAABBNode(), ray, dist); else if (unlikely(node.isOBBNode())) mask = intersectNode(node.ungetAABBNode(), ray, dist); @@ -1667,10 +1282,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN1_UN1, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN1_UN1, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (likely(node.isAABBNode())) mask = intersectNodeRobust(node.getAABBNode(), ray, dist); else if (unlikely(node.isOBBNode())) mask = intersectNode(node.ungetAABBNode(), ray, dist); @@ -1679,10 +1294,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2_UN2, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2_UN2, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (likely(node.isAABBNodeMB())) mask = intersectNode(node.getAABBNodeMB(), ray, time, dist); else if (unlikely(node.isOBBNodeMB())) mask = intersectNode(node.ungetAABBNodeMB(), ray, time, dist); @@ -1691,10 +1306,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2_UN2, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2_UN2, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (likely(node.isAABBNodeMB())) mask = intersectNodeRobust(node.getAABBNodeMB(), ray, time, dist); else if (unlikely(node.isOBBNodeMB())) mask = intersectNode(node.ungetAABBNodeMB(), ray, time, dist); @@ -1703,10 +1318,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2_AN4D_UN2, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2_AN4D_UN2, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; if (unlikely(node.isOBBNodeMB())) mask = intersectNode(node.ungetAABBNodeMB(), ray, time, dist); @@ -1715,10 +1330,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_AN2_AN4D_UN2, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_AN2_AN4D_UN2, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; if (unlikely(node.isOBBNodeMB())) mask = intersectNode(node.ungetAABBNodeMB(), ray, time, dist); @@ -1727,10 +1342,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_QN1, false> + template<int N> + struct BVHNNodeIntersector1<N, BVH_QN1, false> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,false>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,false>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNode((const typename BVHN<N>::QuantizedNode*)node.quantizedNode(), ray, dist); @@ -1738,10 +1353,10 @@ namespace embree } }; - template<int N, int Nx> - struct BVHNNodeIntersector1<N, Nx, BVH_QN1, true> + template<int N> + struct BVHNNodeIntersector1<N, BVH_QN1, true> { - static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx,true>& ray, float time, vfloat<Nx>& dist, size_t& mask) + static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,true>& ray, float time, vfloat<N>& dist, size_t& mask) { if (unlikely(node.isLeaf())) return false; mask = intersectNodeRobust((const typename BVHN<N>::QuantizedNode*)node.quantizedNode(), ray, dist); @@ -1750,33 +1365,33 @@ namespace embree }; /*! Intersects N nodes with K rays */ - template<int N, int Nx, bool robust> + template<int N, bool robust> struct BVHNQuantizedBaseNodeIntersector1; - template<int N, int Nx> - struct BVHNQuantizedBaseNodeIntersector1<N, Nx, false> + template<int N> + struct BVHNQuantizedBaseNodeIntersector1<N, false> { - static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNode* node, const TravRay<N,Nx,false>& ray, vfloat<Nx>& dist) + static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNode* node, const TravRay<N,false>& ray, vfloat<N>& dist) { return intersectNode(node,ray,dist); } - static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,Nx,false>& ray, const float time, vfloat<N>& dist) + static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,false>& ray, const float time, vfloat<N>& dist) { return intersectNode(node,ray,time,dist); } }; - template<int N, int Nx> - struct BVHNQuantizedBaseNodeIntersector1<N, Nx, true> + template<int N> + struct BVHNQuantizedBaseNodeIntersector1<N, true> { - static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNode* node, const TravRay<N,Nx,true>& ray, vfloat<Nx>& dist) + static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNode* node, const TravRay<N,true>& ray, vfloat<N>& dist) { return intersectNode(node,ray,dist); } - static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,Nx,true>& ray, const float time, vfloat<N>& dist) + static __forceinline size_t intersect(const typename BVHN<N>::QuantizedBaseNodeMB* node, const TravRay<N,true>& ray, const float time, vfloat<N>& dist) { return intersectNode(node,ray,time,dist); } diff --git a/thirdparty/embree-aarch64/kernels/bvh/node_intersector_frustum.h b/thirdparty/embree/kernels/bvh/node_intersector_frustum.h index 800ac8b478..1f7215e5df 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/node_intersector_frustum.h +++ b/thirdparty/embree/kernels/bvh/node_intersector_frustum.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -38,12 +38,6 @@ namespace embree __forceinline Frustum() {} template<int K> - __forceinline Frustum(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar, int N) - { - init(valid, org, rdir, ray_tnear, ray_tfar, N); - } - - template<int K> __forceinline void init(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar, int N) { const Vec3fa reduced_min_org(reduce_min(select(valid, org.x, pos_inf)), @@ -81,13 +75,9 @@ namespace embree min_rdir = select(pos_rdir, reduced_min_rdir, reduced_max_rdir); max_rdir = select(pos_rdir, reduced_max_rdir, reduced_min_rdir); -#if defined (__aarch64__) - neg_min_org_rdir = -(min_rdir * select(pos_rdir, reduced_max_org, reduced_min_org)); - neg_max_org_rdir = -(max_rdir * select(pos_rdir, reduced_min_org, reduced_max_org)); -#else min_org_rdir = min_rdir * select(pos_rdir, reduced_max_org, reduced_min_org); max_org_rdir = max_rdir * select(pos_rdir, reduced_min_org, reduced_max_org); -#endif + min_dist = reduced_min_dist; max_dist = reduced_max_dist; @@ -105,13 +95,9 @@ namespace embree Vec3fa min_rdir; Vec3fa max_rdir; -#if defined (__aarch64__) - Vec3fa neg_min_org_rdir; - Vec3fa neg_max_org_rdir; -#else Vec3fa min_org_rdir; Vec3fa max_org_rdir; -#endif + float min_dist; float max_dist; }; @@ -125,12 +111,6 @@ namespace embree __forceinline Frustum() {} template<int K> - __forceinline Frustum(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar, int N) - { - init(valid, org, rdir, ray_tnear, ray_tfar, N); - } - - template<int K> __forceinline void init(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar, int N) { const Vec3fa reduced_min_org(reduce_min(select(valid, org.x, pos_inf)), @@ -200,36 +180,28 @@ namespace embree // Fast AABBNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx> + template<int N> __forceinline size_t intersectNodeFrustum(const typename BVHN<N>::AABBNode* __restrict__ node, - const FrustumFast& frustum, vfloat<Nx>& dist) + const FrustumFast& frustum, vfloat<N>& dist) { - const vfloat<Nx> bminX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearX); - const vfloat<Nx> bminY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearY); - const vfloat<Nx> bminZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearZ); - const vfloat<Nx> bmaxX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farX); - const vfloat<Nx> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farY); - const vfloat<Nx> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farZ); - -#if defined (__aarch64__) - const vfloat<Nx> fminX = madd(bminX, vfloat<Nx>(frustum.min_rdir.x), vfloat<Nx>(frustum.neg_min_org_rdir.x)); - const vfloat<Nx> fminY = madd(bminY, vfloat<Nx>(frustum.min_rdir.y), vfloat<Nx>(frustum.neg_min_org_rdir.y)); - const vfloat<Nx> fminZ = madd(bminZ, vfloat<Nx>(frustum.min_rdir.z), vfloat<Nx>(frustum.neg_min_org_rdir.z)); - const vfloat<Nx> fmaxX = madd(bmaxX, vfloat<Nx>(frustum.max_rdir.x), vfloat<Nx>(frustum.neg_max_org_rdir.x)); - const vfloat<Nx> fmaxY = madd(bmaxY, vfloat<Nx>(frustum.max_rdir.y), vfloat<Nx>(frustum.neg_max_org_rdir.y)); - const vfloat<Nx> fmaxZ = madd(bmaxZ, vfloat<Nx>(frustum.max_rdir.z), vfloat<Nx>(frustum.neg_max_org_rdir.z)); -#else - const vfloat<Nx> fminX = msub(bminX, vfloat<Nx>(frustum.min_rdir.x), vfloat<Nx>(frustum.min_org_rdir.x)); - const vfloat<Nx> fminY = msub(bminY, vfloat<Nx>(frustum.min_rdir.y), vfloat<Nx>(frustum.min_org_rdir.y)); - const vfloat<Nx> fminZ = msub(bminZ, vfloat<Nx>(frustum.min_rdir.z), vfloat<Nx>(frustum.min_org_rdir.z)); - const vfloat<Nx> fmaxX = msub(bmaxX, vfloat<Nx>(frustum.max_rdir.x), vfloat<Nx>(frustum.max_org_rdir.x)); - const vfloat<Nx> fmaxY = msub(bmaxY, vfloat<Nx>(frustum.max_rdir.y), vfloat<Nx>(frustum.max_org_rdir.y)); - const vfloat<Nx> fmaxZ = msub(bmaxZ, vfloat<Nx>(frustum.max_rdir.z), vfloat<Nx>(frustum.max_org_rdir.z)); -#endif - const vfloat<Nx> fmin = maxi(fminX, fminY, fminZ, vfloat<Nx>(frustum.min_dist)); + const vfloat<N> bminX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearX); + const vfloat<N> bminY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearY); + const vfloat<N> bminZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearZ); + const vfloat<N> bmaxX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farX); + const vfloat<N> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farY); + const vfloat<N> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farZ); + + const vfloat<N> fminX = msub(bminX, vfloat<N>(frustum.min_rdir.x), vfloat<N>(frustum.min_org_rdir.x)); + const vfloat<N> fminY = msub(bminY, vfloat<N>(frustum.min_rdir.y), vfloat<N>(frustum.min_org_rdir.y)); + const vfloat<N> fminZ = msub(bminZ, vfloat<N>(frustum.min_rdir.z), vfloat<N>(frustum.min_org_rdir.z)); + const vfloat<N> fmaxX = msub(bmaxX, vfloat<N>(frustum.max_rdir.x), vfloat<N>(frustum.max_org_rdir.x)); + const vfloat<N> fmaxY = msub(bmaxY, vfloat<N>(frustum.max_rdir.y), vfloat<N>(frustum.max_org_rdir.y)); + const vfloat<N> fmaxZ = msub(bmaxZ, vfloat<N>(frustum.max_rdir.z), vfloat<N>(frustum.max_org_rdir.z)); + + const vfloat<N> fmin = maxi(fminX, fminY, fminZ, vfloat<N>(frustum.min_dist)); dist = fmin; - const vfloat<Nx> fmax = mini(fmaxX, fmaxY, fmaxZ, vfloat<Nx>(frustum.max_dist)); - const vbool<Nx> vmask_node_hit = fmin <= fmax; + const vfloat<N> fmax = mini(fmaxX, fmaxY, fmaxZ, vfloat<N>(frustum.max_dist)); + const vbool<N> vmask_node_hit = fmin <= fmax; size_t m_node = movemask(vmask_node_hit) & (((size_t)1 << N)-1); return m_node; } @@ -238,30 +210,30 @@ namespace embree // Robust AABBNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx> + template<int N> __forceinline size_t intersectNodeFrustum(const typename BVHN<N>::AABBNode* __restrict__ node, - const FrustumRobust& frustum, vfloat<Nx>& dist) + const FrustumRobust& frustum, vfloat<N>& dist) { - const vfloat<Nx> bminX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearX); - const vfloat<Nx> bminY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearY); - const vfloat<Nx> bminZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearZ); - const vfloat<Nx> bmaxX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farX); - const vfloat<Nx> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farY); - const vfloat<Nx> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farZ); - - const vfloat<Nx> fminX = (bminX - vfloat<Nx>(frustum.min_org.x)) * vfloat<Nx>(frustum.min_rdir.x); - const vfloat<Nx> fminY = (bminY - vfloat<Nx>(frustum.min_org.y)) * vfloat<Nx>(frustum.min_rdir.y); - const vfloat<Nx> fminZ = (bminZ - vfloat<Nx>(frustum.min_org.z)) * vfloat<Nx>(frustum.min_rdir.z); - const vfloat<Nx> fmaxX = (bmaxX - vfloat<Nx>(frustum.max_org.x)) * vfloat<Nx>(frustum.max_rdir.x); - const vfloat<Nx> fmaxY = (bmaxY - vfloat<Nx>(frustum.max_org.y)) * vfloat<Nx>(frustum.max_rdir.y); - const vfloat<Nx> fmaxZ = (bmaxZ - vfloat<Nx>(frustum.max_org.z)) * vfloat<Nx>(frustum.max_rdir.z); + const vfloat<N> bminX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearX); + const vfloat<N> bminY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearY); + const vfloat<N> bminZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.nearZ); + const vfloat<N> bmaxX = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farX); + const vfloat<N> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farY); + const vfloat<N> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + frustum.nf.farZ); + + const vfloat<N> fminX = (bminX - vfloat<N>(frustum.min_org.x)) * vfloat<N>(frustum.min_rdir.x); + const vfloat<N> fminY = (bminY - vfloat<N>(frustum.min_org.y)) * vfloat<N>(frustum.min_rdir.y); + const vfloat<N> fminZ = (bminZ - vfloat<N>(frustum.min_org.z)) * vfloat<N>(frustum.min_rdir.z); + const vfloat<N> fmaxX = (bmaxX - vfloat<N>(frustum.max_org.x)) * vfloat<N>(frustum.max_rdir.x); + const vfloat<N> fmaxY = (bmaxY - vfloat<N>(frustum.max_org.y)) * vfloat<N>(frustum.max_rdir.y); + const vfloat<N> fmaxZ = (bmaxZ - vfloat<N>(frustum.max_org.z)) * vfloat<N>(frustum.max_rdir.z); const float round_down = 1.0f-2.0f*float(ulp); // FIXME: use per instruction rounding for AVX512 const float round_up = 1.0f+2.0f*float(ulp); - const vfloat<Nx> fmin = max(fminX, fminY, fminZ, vfloat<Nx>(frustum.min_dist)); + const vfloat<N> fmin = max(fminX, fminY, fminZ, vfloat<N>(frustum.min_dist)); dist = fmin; - const vfloat<Nx> fmax = min(fmaxX, fmaxY, fmaxZ, vfloat<Nx>(frustum.max_dist)); - const vbool<Nx> vmask_node_hit = (round_down*fmin <= round_up*fmax); + const vfloat<N> fmax = min(fmaxX, fmaxY, fmaxZ, vfloat<N>(frustum.max_dist)); + const vbool<N> vmask_node_hit = (round_down*fmin <= round_up*fmax); size_t m_node = movemask(vmask_node_hit) & (((size_t)1 << N)-1); return m_node; } diff --git a/thirdparty/embree-aarch64/kernels/bvh/node_intersector_packet.h b/thirdparty/embree/kernels/bvh/node_intersector_packet.h index 0543e56f8e..d5498fc5db 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/node_intersector_packet.h +++ b/thirdparty/embree/kernels/bvh/node_intersector_packet.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -39,11 +39,10 @@ namespace embree org = ray_org; dir = ray_dir; rdir = rcp_safe(ray_dir); -#if defined(__aarch64__) - neg_org_rdir = -(org * rdir); -#elif defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) org_rdir = org * rdir; #endif + if (N) { const int size = sizeof(float)*N; @@ -56,9 +55,7 @@ namespace embree Vec3vf<K> org; Vec3vf<K> dir; Vec3vf<K> rdir; -#if defined(__aarch64__) - Vec3vf<K> neg_org_rdir; -#elif defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) Vec3vf<K> org_rdir; #endif Vec3vi<K> nearXYZ; @@ -122,14 +119,7 @@ namespace embree const TravRayKFast<K>& ray, vfloat<K>& dist) { -#if defined(__aarch64__) - const vfloat<K> lclipMinX = madd(node->lower_x[i], ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMinY = madd(node->lower_y[i], ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMinZ = madd(node->lower_z[i], ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<K> lclipMaxX = madd(node->upper_x[i], ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMaxY = madd(node->upper_y[i], ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMaxZ = madd(node->upper_z[i], ray.rdir.z, ray.neg_org_rdir.z); -#elif defined(__AVX2__) + #if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<K> lclipMinX = msub(node->lower_x[i], ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(node->lower_y[i], ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(node->lower_z[i], ray.rdir.z, ray.org_rdir.z); @@ -145,7 +135,7 @@ namespace embree const vfloat<K> lclipMaxZ = (node->upper_z[i] - ray.org.z) * ray.rdir.z; #endif - #if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX + #if defined(__AVX512F__) // SKX if (K == 16) { /* use mixed float/int min/max */ @@ -160,7 +150,7 @@ namespace embree { const vfloat<K> lnearP = maxi(mini(lclipMinX, lclipMaxX), mini(lclipMinY, lclipMaxY), mini(lclipMinZ, lclipMaxZ)); const vfloat<K> lfarP = mini(maxi(lclipMinX, lclipMaxX), maxi(lclipMinY, lclipMaxY), maxi(lclipMinZ, lclipMaxZ)); - #if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX + #if defined(__AVX512F__) // SKX const vbool<K> lhit = asInt(maxi(lnearP, ray.tnear)) <= asInt(mini(lfarP, ray.tfar)); #else const vbool<K> lhit = maxi(lnearP, ray.tnear) <= mini(lfarP, ray.tfar); @@ -209,14 +199,7 @@ namespace embree const vfloat<K> vupper_y = madd(time, vfloat<K>(node->upper_dy[i]), vfloat<K>(node->upper_y[i])); const vfloat<K> vupper_z = madd(time, vfloat<K>(node->upper_dz[i]), vfloat<K>(node->upper_z[i])); -#if defined(__aarch64__) - const vfloat<K> lclipMinX = madd(vlower_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMinY = madd(vlower_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMinZ = madd(vlower_z, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<K> lclipMaxX = madd(vupper_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMaxY = madd(vupper_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMaxZ = madd(vupper_z, ray.rdir.z, ray.neg_org_rdir.z); -#elif defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<K> lclipMinX = msub(vlower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(vlower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(vlower_z, ray.rdir.z, ray.org_rdir.z); @@ -232,7 +215,7 @@ namespace embree const vfloat<K> lclipMaxZ = (vupper_z - ray.org.z) * ray.rdir.z; #endif -#if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#if defined(__AVX512F__) // SKX if (K == 16) { /* use mixed float/int min/max */ @@ -247,7 +230,7 @@ namespace embree { const vfloat<K> lnearP = maxi(mini(lclipMinX, lclipMaxX), mini(lclipMinY, lclipMaxY), mini(lclipMinZ, lclipMaxZ)); const vfloat<K> lfarP = mini(maxi(lclipMinX, lclipMaxX), maxi(lclipMinY, lclipMaxY), maxi(lclipMinZ, lclipMaxZ)); -#if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#if defined(__AVX512F__) // SKX const vbool<K> lhit = asInt(maxi(lnearP, ray.tnear)) <= asInt(mini(lfarP, ray.tfar)); #else const vbool<K> lhit = maxi(lnearP, ray.tnear) <= mini(lfarP, ray.tfar); @@ -282,7 +265,7 @@ namespace embree const float round_up = 1.0f+3.0f*float(ulp); const float round_down = 1.0f-3.0f*float(ulp); -#if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX +#if defined(__AVX512F__) // SKX if (K == 16) { const vfloat<K> lnearP = round_down*maxi(min(lclipMinX, lclipMaxX), min(lclipMinY, lclipMaxY), min(lclipMinZ, lclipMaxZ)); @@ -319,14 +302,7 @@ namespace embree const vfloat<K> vupper_y = madd(time, vfloat<K>(node->upper_dy[i]), vfloat<K>(node->upper_y[i])); const vfloat<K> vupper_z = madd(time, vfloat<K>(node->upper_dz[i]), vfloat<K>(node->upper_z[i])); -#if defined(__aarch64__) - const vfloat<K> lclipMinX = madd(vlower_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMinY = madd(vlower_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMinZ = madd(vlower_z, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<K> lclipMaxX = madd(vupper_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMaxY = madd(vupper_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMaxZ = madd(vupper_z, ray.rdir.z, ray.neg_org_rdir.z); -#elif defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<K> lclipMinX = msub(vlower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(vlower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(vlower_z, ray.rdir.z, ray.org_rdir.z); @@ -488,14 +464,7 @@ namespace embree const vfloat<N> lower_z = node->dequantizeLowerZ(); const vfloat<N> upper_z = node->dequantizeUpperZ(); - #if defined(__aarch64__) - const vfloat<K> lclipMinX = madd(lower_x[i], ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMinY = madd(lower_y[i], ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMinZ = madd(lower_z[i], ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<K> lclipMaxX = madd(upper_x[i], ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMaxY = madd(upper_y[i], ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMaxZ = madd(upper_z[i], ray.rdir.z, ray.neg_org_rdir.z); - #elif defined(__AVX2__) + #if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<K> lclipMinX = msub(lower_x[i], ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(lower_y[i], ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(lower_z[i], ray.rdir.z, ray.org_rdir.z); @@ -511,7 +480,7 @@ namespace embree const vfloat<K> lclipMaxZ = (upper_z[i] - ray.org.z) * ray.rdir.z; #endif - #if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX + #if defined(__AVX512F__) // SKX if (K == 16) { /* use mixed float/int min/max */ @@ -526,7 +495,7 @@ namespace embree { const vfloat<K> lnearP = maxi(mini(lclipMinX, lclipMaxX), mini(lclipMinY, lclipMaxY), mini(lclipMinZ, lclipMaxZ)); const vfloat<K> lfarP = mini(maxi(lclipMinX, lclipMaxX), maxi(lclipMinY, lclipMaxY), maxi(lclipMinZ, lclipMaxZ)); - #if defined(__AVX512F__) && !defined(__AVX512ER__) // SKX + #if defined(__AVX512F__) // SKX const vbool<K> lhit = asInt(maxi(lnearP, ray.tnear)) <= asInt(mini(lfarP, ray.tfar)); #else const vbool<K> lhit = maxi(lnearP, ray.tnear) <= mini(lfarP, ray.tfar); @@ -573,21 +542,14 @@ namespace embree { assert(movemask(node->validMask()) & ((size_t)1 << i)); - const vfloat<K> lower_x = node->dequantizeLowerX(i,time); - const vfloat<K> upper_x = node->dequantizeUpperX(i,time); - const vfloat<K> lower_y = node->dequantizeLowerY(i,time); - const vfloat<K> upper_y = node->dequantizeUpperY(i,time); - const vfloat<K> lower_z = node->dequantizeLowerZ(i,time); - const vfloat<K> upper_z = node->dequantizeUpperZ(i,time); + const vfloat<K> lower_x = node->template dequantizeLowerX<K>(i,time); + const vfloat<K> upper_x = node->template dequantizeUpperX<K>(i,time); + const vfloat<K> lower_y = node->template dequantizeLowerY<K>(i,time); + const vfloat<K> upper_y = node->template dequantizeUpperY<K>(i,time); + const vfloat<K> lower_z = node->template dequantizeLowerZ<K>(i,time); + const vfloat<K> upper_z = node->template dequantizeUpperZ<K>(i,time); -#if defined(__aarch64__) - const vfloat<K> lclipMinX = madd(lower_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMinY = madd(lower_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMinZ = madd(lower_z, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<K> lclipMaxX = madd(upper_x, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> lclipMaxY = madd(upper_y, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> lclipMaxZ = madd(upper_z, ray.rdir.z, ray.neg_org_rdir.z); -#elif defined(__AVX2__) +#if defined(__AVX2__) || defined(__ARM_NEON) const vfloat<K> lclipMinX = msub(lower_x, ray.rdir.x, ray.org_rdir.x); const vfloat<K> lclipMinY = msub(lower_y, ray.rdir.y, ray.org_rdir.y); const vfloat<K> lclipMinZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z); @@ -617,12 +579,12 @@ namespace embree { assert(movemask(node->validMask()) & ((size_t)1 << i)); - const vfloat<K> lower_x = node->dequantizeLowerX(i,time); - const vfloat<K> upper_x = node->dequantizeUpperX(i,time); - const vfloat<K> lower_y = node->dequantizeLowerY(i,time); - const vfloat<K> upper_y = node->dequantizeUpperY(i,time); - const vfloat<K> lower_z = node->dequantizeLowerZ(i,time); - const vfloat<K> upper_z = node->dequantizeUpperZ(i,time); + const vfloat<K> lower_x = node->template dequantizeLowerX<K>(i,time); + const vfloat<K> upper_x = node->template dequantizeUpperX<K>(i,time); + const vfloat<K> lower_y = node->template dequantizeLowerY<K>(i,time); + const vfloat<K> upper_y = node->template dequantizeUpperY<K>(i,time); + const vfloat<K> lower_z = node->template dequantizeLowerZ<K>(i,time); + const vfloat<K> upper_z = node->template dequantizeUpperZ<K>(i,time); const vfloat<K> lclipMinX = (lower_x - ray.org.x) * ray.rdir.x; const vfloat<K> lclipMinY = (lower_y - ray.org.y) * ray.rdir.y; diff --git a/thirdparty/embree-aarch64/kernels/bvh/node_intersector_packet_stream.h b/thirdparty/embree/kernels/bvh/node_intersector_packet_stream.h index f379b57aea..55b2c27231 100644 --- a/thirdparty/embree-aarch64/kernels/bvh/node_intersector_packet_stream.h +++ b/thirdparty/embree/kernels/bvh/node_intersector_packet_stream.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -32,19 +32,11 @@ namespace embree __forceinline void init(const Vec3vf<K>& ray_org, const Vec3vf<K>& ray_dir) { rdir = rcp_safe(ray_dir); -#if defined(__aarch64__) - neg_org_rdir = -(ray_org * rdir); -#else org_rdir = ray_org * rdir; -#endif } Vec3vf<K> rdir; -#if defined(__aarch64__) - Vec3vf<K> neg_org_rdir; -#else Vec3vf<K> org_rdir; -#endif vfloat<K> tnear; vfloat<K> tfar; }; @@ -84,36 +76,27 @@ namespace embree // Fast AABBNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx, int K> + template<int N, int K> __forceinline size_t intersectNode1(const typename BVHN<N>::AABBNode* __restrict__ node, const TravRayKStreamFast<K>& ray, size_t k, const NearFarPrecalculations& nf) { - const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); - const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); - const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); - const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); - const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); - const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); - -#if defined (__aarch64__) - const vfloat<Nx> rminX = madd(bminX, vfloat<Nx>(ray.rdir.x[k]), vfloat<Nx>(ray.neg_org_rdir.x[k])); - const vfloat<Nx> rminY = madd(bminY, vfloat<Nx>(ray.rdir.y[k]), vfloat<Nx>(ray.neg_org_rdir.y[k])); - const vfloat<Nx> rminZ = madd(bminZ, vfloat<Nx>(ray.rdir.z[k]), vfloat<Nx>(ray.neg_org_rdir.z[k])); - const vfloat<Nx> rmaxX = madd(bmaxX, vfloat<Nx>(ray.rdir.x[k]), vfloat<Nx>(ray.neg_org_rdir.x[k])); - const vfloat<Nx> rmaxY = madd(bmaxY, vfloat<Nx>(ray.rdir.y[k]), vfloat<Nx>(ray.neg_org_rdir.y[k])); - const vfloat<Nx> rmaxZ = madd(bmaxZ, vfloat<Nx>(ray.rdir.z[k]), vfloat<Nx>(ray.neg_org_rdir.z[k])); -#else - const vfloat<Nx> rminX = msub(bminX, vfloat<Nx>(ray.rdir.x[k]), vfloat<Nx>(ray.org_rdir.x[k])); - const vfloat<Nx> rminY = msub(bminY, vfloat<Nx>(ray.rdir.y[k]), vfloat<Nx>(ray.org_rdir.y[k])); - const vfloat<Nx> rminZ = msub(bminZ, vfloat<Nx>(ray.rdir.z[k]), vfloat<Nx>(ray.org_rdir.z[k])); - const vfloat<Nx> rmaxX = msub(bmaxX, vfloat<Nx>(ray.rdir.x[k]), vfloat<Nx>(ray.org_rdir.x[k])); - const vfloat<Nx> rmaxY = msub(bmaxY, vfloat<Nx>(ray.rdir.y[k]), vfloat<Nx>(ray.org_rdir.y[k])); - const vfloat<Nx> rmaxZ = msub(bmaxZ, vfloat<Nx>(ray.rdir.z[k]), vfloat<Nx>(ray.org_rdir.z[k])); -#endif - const vfloat<Nx> rmin = maxi(rminX, rminY, rminZ, vfloat<Nx>(ray.tnear[k])); - const vfloat<Nx> rmax = mini(rmaxX, rmaxY, rmaxZ, vfloat<Nx>(ray.tfar[k])); - - const vbool<Nx> vmask_first_hit = rmin <= rmax; + const vfloat<N> bminX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); + const vfloat<N> bminY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); + const vfloat<N> bminZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); + const vfloat<N> bmaxX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); + const vfloat<N> bmaxY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); + const vfloat<N> bmaxZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); + + const vfloat<N> rminX = msub(bminX, vfloat<N>(ray.rdir.x[k]), vfloat<N>(ray.org_rdir.x[k])); + const vfloat<N> rminY = msub(bminY, vfloat<N>(ray.rdir.y[k]), vfloat<N>(ray.org_rdir.y[k])); + const vfloat<N> rminZ = msub(bminZ, vfloat<N>(ray.rdir.z[k]), vfloat<N>(ray.org_rdir.z[k])); + const vfloat<N> rmaxX = msub(bmaxX, vfloat<N>(ray.rdir.x[k]), vfloat<N>(ray.org_rdir.x[k])); + const vfloat<N> rmaxY = msub(bmaxY, vfloat<N>(ray.rdir.y[k]), vfloat<N>(ray.org_rdir.y[k])); + const vfloat<N> rmaxZ = msub(bmaxZ, vfloat<N>(ray.rdir.z[k]), vfloat<N>(ray.org_rdir.z[k])); + const vfloat<N> rmin = maxi(rminX, rminY, rminZ, vfloat<N>(ray.tnear[k])); + const vfloat<N> rmax = mini(rmaxX, rmaxY, rmaxZ, vfloat<N>(ray.tfar[k])); + + const vbool<N> vmask_first_hit = rmin <= rmax; return movemask(vmask_first_hit) & (((size_t)1 << N)-1); } @@ -130,21 +113,12 @@ namespace embree const vfloat<K> bmaxY = *(const float*)(ptr + nf.farY); const vfloat<K> bmaxZ = *(const float*)(ptr + nf.farZ); -#if defined (__aarch64__) - const vfloat<K> rminX = madd(bminX, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> rminY = madd(bminY, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> rminZ = madd(bminZ, ray.rdir.z, ray.neg_org_rdir.z); - const vfloat<K> rmaxX = madd(bmaxX, ray.rdir.x, ray.neg_org_rdir.x); - const vfloat<K> rmaxY = madd(bmaxY, ray.rdir.y, ray.neg_org_rdir.y); - const vfloat<K> rmaxZ = madd(bmaxZ, ray.rdir.z, ray.neg_org_rdir.z); -#else const vfloat<K> rminX = msub(bminX, ray.rdir.x, ray.org_rdir.x); const vfloat<K> rminY = msub(bminY, ray.rdir.y, ray.org_rdir.y); const vfloat<K> rminZ = msub(bminZ, ray.rdir.z, ray.org_rdir.z); const vfloat<K> rmaxX = msub(bmaxX, ray.rdir.x, ray.org_rdir.x); const vfloat<K> rmaxY = msub(bmaxY, ray.rdir.y, ray.org_rdir.y); const vfloat<K> rmaxZ = msub(bmaxZ, ray.rdir.z, ray.org_rdir.z); -#endif const vfloat<K> rmin = maxi(rminX, rminY, rminZ, ray.tnear); const vfloat<K> rmax = mini(rmaxX, rmaxY, rmaxZ, ray.tfar); @@ -158,28 +132,28 @@ namespace embree // Robust AABBNode intersection ////////////////////////////////////////////////////////////////////////////////////// - template<int N, int Nx, int K> + template<int N, int K> __forceinline size_t intersectNode1(const typename BVHN<N>::AABBNode* __restrict__ node, const TravRayKStreamRobust<K>& ray, size_t k, const NearFarPrecalculations& nf) { - const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); - const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); - const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); - const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); - const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); - const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); - - const vfloat<Nx> rminX = (bminX - vfloat<Nx>(ray.org.x[k])) * vfloat<Nx>(ray.rdir.x[k]); - const vfloat<Nx> rminY = (bminY - vfloat<Nx>(ray.org.y[k])) * vfloat<Nx>(ray.rdir.y[k]); - const vfloat<Nx> rminZ = (bminZ - vfloat<Nx>(ray.org.z[k])) * vfloat<Nx>(ray.rdir.z[k]); - const vfloat<Nx> rmaxX = (bmaxX - vfloat<Nx>(ray.org.x[k])) * vfloat<Nx>(ray.rdir.x[k]); - const vfloat<Nx> rmaxY = (bmaxY - vfloat<Nx>(ray.org.y[k])) * vfloat<Nx>(ray.rdir.y[k]); - const vfloat<Nx> rmaxZ = (bmaxZ - vfloat<Nx>(ray.org.z[k])) * vfloat<Nx>(ray.rdir.z[k]); + const vfloat<N> bminX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX)); + const vfloat<N> bminY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY)); + const vfloat<N> bminZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ)); + const vfloat<N> bmaxX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX)); + const vfloat<N> bmaxY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY)); + const vfloat<N> bmaxZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ)); + + const vfloat<N> rminX = (bminX - vfloat<N>(ray.org.x[k])) * vfloat<N>(ray.rdir.x[k]); + const vfloat<N> rminY = (bminY - vfloat<N>(ray.org.y[k])) * vfloat<N>(ray.rdir.y[k]); + const vfloat<N> rminZ = (bminZ - vfloat<N>(ray.org.z[k])) * vfloat<N>(ray.rdir.z[k]); + const vfloat<N> rmaxX = (bmaxX - vfloat<N>(ray.org.x[k])) * vfloat<N>(ray.rdir.x[k]); + const vfloat<N> rmaxY = (bmaxY - vfloat<N>(ray.org.y[k])) * vfloat<N>(ray.rdir.y[k]); + const vfloat<N> rmaxZ = (bmaxZ - vfloat<N>(ray.org.z[k])) * vfloat<N>(ray.rdir.z[k]); const float round_up = 1.0f+3.0f*float(ulp); // FIXME: use per instruction rounding for AVX512 - const vfloat<Nx> rmin = max(rminX, rminY, rminZ, vfloat<Nx>(ray.tnear[k])); - const vfloat<Nx> rmax = round_up *min(rmaxX, rmaxY, rmaxZ, vfloat<Nx>(ray.tfar[k])); + const vfloat<N> rmin = max(rminX, rminY, rminZ, vfloat<N>(ray.tnear[k])); + const vfloat<N> rmax = round_up *min(rmaxX, rmaxY, rmaxZ, vfloat<N>(ray.tfar[k])); - const vbool<Nx> vmask_first_hit = rmin <= rmax; + const vbool<N> vmask_first_hit = rmin <= rmax; return movemask(vmask_first_hit) & (((size_t)1 << N)-1); } diff --git a/thirdparty/embree-aarch64/kernels/common/accel.h b/thirdparty/embree/kernels/common/accel.h index c038d3cf21..cc4ea1805b 100644 --- a/thirdparty/embree-aarch64/kernels/common/accel.h +++ b/thirdparty/embree/kernels/common/accel.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -332,7 +332,7 @@ namespace embree intersectorN.intersect(this,rayN,N,context); } -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined(__SSE__) __forceinline void intersect(const vbool4& valid, RayHitK<4>& ray, IntersectContext* context) { const vint<4> mask = valid.mask32(); intersect4(&mask,(RTCRayHit4&)ray,context); @@ -388,7 +388,7 @@ namespace embree intersectorN.occluded(this,rayN,N,context); } -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined(__SSE__) __forceinline void occluded(const vbool4& valid, RayK<4>& ray, IntersectContext* context) { const vint<4> mask = valid.mask32(); occluded4(&mask,(RTCRay4&)ray,context); diff --git a/thirdparty/embree-aarch64/kernels/common/accelinstance.h b/thirdparty/embree/kernels/common/accelinstance.h index d74b96df3f..c63ef998bd 100644 --- a/thirdparty/embree-aarch64/kernels/common/accelinstance.h +++ b/thirdparty/embree/kernels/common/accelinstance.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/acceln.cpp b/thirdparty/embree/kernels/common/acceln.cpp index aadb4a64ef..32a27c560a 100644 --- a/thirdparty/embree-aarch64/kernels/common/acceln.cpp +++ b/thirdparty/embree/kernels/common/acceln.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "acceln.h" @@ -97,7 +97,7 @@ namespace embree for (size_t i=0; i<This->accels.size(); i++) { if (This->accels[i]->isEmpty()) continue; This->accels[i]->intersectors.occluded4(valid,ray,context); -#if defined(__SSE2__) || defined(__ARM_NEON) +#if defined(__SSE2__) vbool4 valid0 = asBool(((vint4*)valid)[0]); vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero); if (unlikely(none(valid0 & hit0))) break; @@ -111,7 +111,7 @@ namespace embree for (size_t i=0; i<This->accels.size(); i++) { if (This->accels[i]->isEmpty()) continue; This->accels[i]->intersectors.occluded8(valid,ray,context); -#if defined(__SSE2__) || defined(__ARM_NEON) // FIXME: use higher ISA +#if defined(__SSE2__) // FIXME: use higher ISA vbool4 valid0 = asBool(((vint4*)valid)[0]); vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero); vbool4 valid1 = asBool(((vint4*)valid)[1]); @@ -127,7 +127,7 @@ namespace embree for (size_t i=0; i<This->accels.size(); i++) { if (This->accels[i]->isEmpty()) continue; This->accels[i]->intersectors.occluded16(valid,ray,context); -#if defined(__SSE2__) || defined(__ARM_NEON) // FIXME: use higher ISA +#if defined(__SSE2__) // FIXME: use higher ISA vbool4 valid0 = asBool(((vint4*)valid)[0]); vbool4 hit0 = ((vfloat4*)ray.tfar)[0] >= vfloat4(zero); vbool4 valid1 = asBool(((vint4*)valid)[1]); diff --git a/thirdparty/embree-aarch64/kernels/common/acceln.h b/thirdparty/embree/kernels/common/acceln.h index 2edd98f647..0445b2e811 100644 --- a/thirdparty/embree-aarch64/kernels/common/acceln.h +++ b/thirdparty/embree/kernels/common/acceln.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/accelset.cpp b/thirdparty/embree/kernels/common/accelset.cpp index 79be1c4301..8c18f31776 100644 --- a/thirdparty/embree-aarch64/kernels/common/accelset.cpp +++ b/thirdparty/embree/kernels/common/accelset.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "accelset.h" diff --git a/thirdparty/embree-aarch64/kernels/common/accelset.h b/thirdparty/embree/kernels/common/accelset.h index 3774b2accb..90b184a07b 100644 --- a/thirdparty/embree-aarch64/kernels/common/accelset.h +++ b/thirdparty/embree/kernels/common/accelset.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/alloc.cpp b/thirdparty/embree/kernels/common/alloc.cpp index 6fa406f03a..1a0e1aeed3 100644 --- a/thirdparty/embree-aarch64/kernels/common/alloc.cpp +++ b/thirdparty/embree/kernels/common/alloc.cpp @@ -1,11 +1,8 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "alloc.h" #include "../../common/sys/thread.h" -#if defined(__aarch64__) && defined(BUILD_IOS) -#include "../../common/sys/barrier.h" -#endif namespace embree { diff --git a/thirdparty/embree-aarch64/kernels/common/alloc.h b/thirdparty/embree/kernels/common/alloc.h index 488fa707ef..4458e35c24 100644 --- a/thirdparty/embree-aarch64/kernels/common/alloc.h +++ b/thirdparty/embree/kernels/common/alloc.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -8,10 +8,6 @@ #include "scene.h" #include "primref.h" -#if defined(__aarch64__) && defined(BUILD_IOS) -#include <mutex> -#endif - namespace embree { class FastAllocator @@ -30,7 +26,7 @@ namespace embree public: struct ThreadLocal2; - enum AllocationType { ALIGNED_MALLOC, EMBREE_OS_MALLOC, SHARED, ANY_TYPE }; + enum AllocationType { ALIGNED_MALLOC, OS_MALLOC, SHARED, ANY_TYPE }; /*! Per thread structure holding the current memory block. */ struct __aligned(64) ThreadLocal @@ -136,11 +132,7 @@ namespace embree { assert(alloc_i); if (alloc.load() == alloc_i) return; -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(mutex); -#else Lock<SpinLock> lock(mutex); -#endif //if (alloc.load() == alloc_i) return; // not required as only one thread calls bind if (alloc.load()) { alloc.load()->bytesUsed += alloc0.getUsedBytes() + alloc1.getUsedBytes(); @@ -158,11 +150,7 @@ namespace embree { assert(alloc_i); if (alloc.load() != alloc_i) return; -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(mutex); -#else Lock<SpinLock> lock(mutex); -#endif if (alloc.load() != alloc_i) return; // required as a different thread calls unbind alloc.load()->bytesUsed += alloc0.getUsedBytes() + alloc1.getUsedBytes(); alloc.load()->bytesFree += alloc0.getFreeBytes() + alloc1.getFreeBytes(); @@ -173,11 +161,7 @@ namespace embree } public: -#if defined(__aarch64__) && defined(BUILD_IOS) - std::mutex mutex; -#else SpinLock mutex; //!< required as unbind is called from other threads -#endif std::atomic<FastAllocator*> alloc; //!< parent allocator ThreadLocal alloc0; ThreadLocal alloc1; @@ -185,7 +169,7 @@ namespace embree FastAllocator (Device* device, bool osAllocation) : device(device), slotMask(0), usedBlocks(nullptr), freeBlocks(nullptr), use_single_mode(false), defaultBlockSize(PAGE_SIZE), estimatedSize(0), - growSize(PAGE_SIZE), maxGrowSize(maxAllocationSize), log2_grow_size_scale(0), bytesUsed(0), bytesFree(0), bytesWasted(0), atype(osAllocation ? EMBREE_OS_MALLOC : ALIGNED_MALLOC), + growSize(PAGE_SIZE), maxGrowSize(maxAllocationSize), log2_grow_size_scale(0), bytesUsed(0), bytesFree(0), bytesWasted(0), atype(osAllocation ? OS_MALLOC : ALIGNED_MALLOC), primrefarray(device,0) { for (size_t i=0; i<MAX_THREAD_USED_BLOCK_SLOTS; i++) @@ -222,7 +206,7 @@ namespace embree void setOSallocation(bool flag) { - atype = flag ? EMBREE_OS_MALLOC : ALIGNED_MALLOC; + atype = flag ? OS_MALLOC : ALIGNED_MALLOC; } private: @@ -233,11 +217,7 @@ namespace embree ThreadLocal2* alloc = thread_local_allocator2; if (alloc == nullptr) { thread_local_allocator2 = alloc = new ThreadLocal2; -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(s_thread_local_allocators_lock); -#else Lock<SpinLock> lock(s_thread_local_allocators_lock); -#endif s_thread_local_allocators.push_back(make_unique(alloc)); } return alloc; @@ -247,11 +227,7 @@ namespace embree __forceinline void join(ThreadLocal2* alloc) { -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(s_thread_local_allocators_lock); -#else Lock<SpinLock> lock(thread_local_allocators_lock); -#endif thread_local_allocators.push_back(alloc); } @@ -321,11 +297,7 @@ namespace embree } static const size_t threadLocalAllocOverhead = 20; //! 20 means 5% parallel allocation overhead through unfilled thread local blocks -#if defined(__AVX512ER__) // KNL - static const size_t mainAllocOverheadStatic = 15; //! 15 means 7.5% allocation overhead through unfilled main alloc blocks -#else static const size_t mainAllocOverheadStatic = 20; //! 20 means 5% allocation overhead through unfilled main alloc blocks -#endif static const size_t mainAllocOverheadDynamic = 8; //! 20 means 12.5% allocation overhead through unfilled main alloc blocks /* calculates a single threaded threshold for the builders such @@ -520,11 +492,7 @@ namespace embree /* parallel block creation in case of no freeBlocks, avoids single global mutex */ if (likely(freeBlocks.load() == nullptr)) { -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(slotMutex[slot]); -#else Lock<SpinLock> lock(slotMutex[slot]); -#endif if (myUsedBlocks == threadUsedBlocks[slot]) { const size_t alignedBytes = (bytes+(align-1)) & ~(align-1); const size_t allocSize = max(min(growSize,maxGrowSize),alignedBytes); @@ -537,11 +505,7 @@ namespace embree /* if this fails allocate new block */ { -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(mutex); -#else - Lock<SpinLock> lock(mutex); -#endif + Lock<SpinLock> lock(mutex); if (myUsedBlocks == threadUsedBlocks[slot]) { if (freeBlocks.load() != nullptr) { @@ -563,11 +527,7 @@ namespace embree /*! add new block */ void addBlock(void* ptr, ssize_t bytes) { -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(mutex); -#else Lock<SpinLock> lock(mutex); -#endif const size_t sizeof_Header = offsetof(Block,data[0]); void* aptr = (void*) ((((size_t)ptr)+maxAlignment-1) & ~(maxAlignment-1)); size_t ofs = (size_t) aptr - (size_t) ptr; @@ -653,8 +613,8 @@ namespace embree bytesWasted(alloc->bytesWasted), stat_all(alloc,ANY_TYPE), stat_malloc(alloc,ALIGNED_MALLOC), - stat_4K(alloc,EMBREE_OS_MALLOC,false), - stat_2M(alloc,EMBREE_OS_MALLOC,true), + stat_4K(alloc,OS_MALLOC,false), + stat_2M(alloc,OS_MALLOC,true), stat_shared(alloc,SHARED) {} AllStatistics (size_t bytesUsed, @@ -747,7 +707,7 @@ namespace embree /* We avoid using os_malloc for small blocks as this could * cause a risk of fragmenting the virtual address space and * reach the limit of vm.max_map_count = 65k under Linux. */ - if (atype == EMBREE_OS_MALLOC && bytesAllocate < maxAllocationSize) + if (atype == OS_MALLOC && bytesAllocate < maxAllocationSize) atype = ALIGNED_MALLOC; /* we need to additionally allocate some header */ @@ -756,7 +716,7 @@ namespace embree bytesReserve = sizeof_Header+bytesReserve; /* consume full 4k pages with using os_malloc */ - if (atype == EMBREE_OS_MALLOC) { + if (atype == OS_MALLOC) { bytesAllocate = ((bytesAllocate+PAGE_SIZE-1) & ~(PAGE_SIZE-1)); bytesReserve = ((bytesReserve +PAGE_SIZE-1) & ~(PAGE_SIZE-1)); } @@ -788,11 +748,11 @@ namespace embree return new (ptr) Block(ALIGNED_MALLOC,bytesAllocate-sizeof_Header,bytesAllocate-sizeof_Header,next,alignment); } } - else if (atype == EMBREE_OS_MALLOC) + else if (atype == OS_MALLOC) { if (device) device->memoryMonitor(bytesAllocate,false); bool huge_pages; ptr = os_malloc(bytesReserve,huge_pages); - return new (ptr) Block(EMBREE_OS_MALLOC,bytesAllocate-sizeof_Header,bytesReserve-sizeof_Header,next,0,huge_pages); + return new (ptr) Block(OS_MALLOC,bytesAllocate-sizeof_Header,bytesReserve-sizeof_Header,next,0,huge_pages); } else assert(false); @@ -836,7 +796,7 @@ namespace embree if (device) device->memoryMonitor(-sizeof_Alloced,true); } - else if (atype == EMBREE_OS_MALLOC) { + else if (atype == OS_MALLOC) { size_t sizeof_This = sizeof_Header+reserveEnd; os_free(this,sizeof_This,huge_pages); if (device) device->memoryMonitor(-sizeof_Alloced,true); @@ -897,7 +857,7 @@ namespace embree bool hasType(AllocationType atype_i, bool huge_pages_i) const { if (atype_i == ANY_TYPE ) return true; - else if (atype == EMBREE_OS_MALLOC) return atype_i == atype && huge_pages_i == huge_pages; + else if (atype == OS_MALLOC) return atype_i == atype && huge_pages_i == huge_pages; else return atype_i == atype; } @@ -946,7 +906,7 @@ namespace embree void print_block() const { if (atype == ALIGNED_MALLOC) std::cout << "A"; - else if (atype == EMBREE_OS_MALLOC) std::cout << "O"; + else if (atype == OS_MALLOC) std::cout << "O"; else if (atype == SHARED) std::cout << "S"; if (huge_pages) std::cout << "H"; size_t bytesUsed = getBlockUsedBytes(); @@ -976,11 +936,7 @@ namespace embree std::atomic<Block*> freeBlocks; std::atomic<Block*> threadBlocks[MAX_THREAD_USED_BLOCK_SLOTS]; -#if defined(__aarch64__) && defined(BUILD_IOS) - std::mutex slotMutex[MAX_THREAD_USED_BLOCK_SLOTS]; -#else SpinLock slotMutex[MAX_THREAD_USED_BLOCK_SLOTS]; -#endif bool use_single_mode; size_t defaultBlockSize; @@ -994,11 +950,7 @@ namespace embree static __thread ThreadLocal2* thread_local_allocator2; static SpinLock s_thread_local_allocators_lock; static std::vector<std::unique_ptr<ThreadLocal2>> s_thread_local_allocators; -#if defined(__aarch64__) && defined(BUILD_IOS) - std::mutex thread_local_allocators_lock; -#else SpinLock thread_local_allocators_lock; -#endif std::vector<ThreadLocal2*> thread_local_allocators; AllocationType atype; mvector<PrimRef> primrefarray; //!< primrefarray used to allocate nodes diff --git a/thirdparty/embree-aarch64/kernels/common/buffer.h b/thirdparty/embree/kernels/common/buffer.h index 02d319c59d..793012c04d 100644 --- a/thirdparty/embree-aarch64/kernels/common/buffer.h +++ b/thirdparty/embree/kernels/common/buffer.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/builder.h b/thirdparty/embree/kernels/common/builder.h index d2a1cfe3ce..07fe7b069b 100644 --- a/thirdparty/embree-aarch64/kernels/common/builder.h +++ b/thirdparty/embree/kernels/common/builder.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/context.h b/thirdparty/embree/kernels/common/context.h index d0185a74f2..ccd88bdeac 100644 --- a/thirdparty/embree-aarch64/kernels/common/context.h +++ b/thirdparty/embree/kernels/common/context.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/default.h b/thirdparty/embree/kernels/common/default.h index 709119163b..f15d61b768 100644 --- a/thirdparty/embree-aarch64/kernels/common/default.h +++ b/thirdparty/embree/kernels/common/default.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -55,11 +55,6 @@ #include <utility> #include <sstream> -#if !defined(_DEBUG) && defined(BUILD_IOS) -#undef assert -#define assert(_EXPR) -#endif - namespace embree { //////////////////////////////////////////////////////////////////////////////// diff --git a/thirdparty/embree-aarch64/kernels/common/device.cpp b/thirdparty/embree/kernels/common/device.cpp index 16ec11b892..068e0c2983 100644 --- a/thirdparty/embree-aarch64/kernels/common/device.cpp +++ b/thirdparty/embree/kernels/common/device.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "device.h" @@ -64,6 +64,9 @@ namespace embree case CPU::NEHALEM: frequency_level = FREQUENCY_SIMD128; break; case CPU::CORE2: frequency_level = FREQUENCY_SIMD128; break; case CPU::CORE1: frequency_level = FREQUENCY_SIMD128; break; + case CPU::XEON_PHI_KNIGHTS_MILL : frequency_level = FREQUENCY_SIMD512; break; + case CPU::XEON_PHI_KNIGHTS_LANDING: frequency_level = FREQUENCY_SIMD512; break; + case CPU::ARM: frequency_level = FREQUENCY_SIMD128; break; } /* initialize global state */ @@ -71,10 +74,6 @@ namespace embree State::parseString(EMBREE_CONFIG); #endif State::parseString(cfg); - if (!ignore_config_files && FileName::executableFolder() != FileName("")) - State::parseFile(FileName::executableFolder()+FileName(".embree" TOSTRING(RTC_VERSION_MAJOR))); - if (!ignore_config_files && FileName::homeFolder() != FileName("")) - State::parseFile(FileName::homeFolder()+FileName(".embree" TOSTRING(RTC_VERSION_MAJOR))); State::verify(); /* check whether selected ISA is supported by the HW, as the user could have forced an unsupported ISA */ @@ -127,7 +126,7 @@ namespace embree /* ray stream SOA to AOS conversion */ #if defined(EMBREE_RAY_PACKETS) RayStreamFilterFuncsType rayStreamFilterFuncs; - SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(enabled_cpu_features,rayStreamFilterFuncs); + SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(enabled_cpu_features,rayStreamFilterFuncs); rayStreamFilters = rayStreamFilterFuncs(); #endif } @@ -153,11 +152,8 @@ namespace embree #if defined(EMBREE_TARGET_AVX2) v += "AVX2 "; #endif -#if defined(EMBREE_TARGET_AVX512KNL) - v += "AVX512KNL "; -#endif -#if defined(EMBREE_TARGET_AVX512SKX) - v += "AVX512SKX "; +#if defined(EMBREE_TARGET_AVX512) + v += "AVX512 "; #endif return v; } @@ -221,9 +217,6 @@ namespace embree #if defined(TASKING_INTERNAL) std::cout << "internal_tasking_system "; #endif -#if defined(TASKING_GCD) && defined(BUILD_IOS) - std::cout << "GCD tasking system "; -#endif #if defined(TASKING_PPL) std::cout << "PPL "; #endif @@ -448,7 +441,7 @@ namespace embree #endif #if defined(EMBREE_TARGET_SIMD16) && defined(EMBREE_RAY_PACKETS) - case RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED: return hasISA(AVX512KNL) | hasISA(AVX512SKX); + case RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED: return hasISA(AVX512); #else case RTC_DEVICE_PROPERTY_NATIVE_RAY16_SUPPORTED: return 0; #endif @@ -506,10 +499,6 @@ namespace embree #if defined(TASKING_PPL) case RTC_DEVICE_PROPERTY_TASKING_SYSTEM: return 2; #endif - -#if defined(TASKING_GCD) && defined(BUILD_IOS) - case RTC_DEVICE_PROPERTY_TASKING_SYSTEM: return 3; -#endif #if defined(EMBREE_GEOMETRY_TRIANGLE) case RTC_DEVICE_PROPERTY_TRIANGLE_GEOMETRY_SUPPORTED: return 1; diff --git a/thirdparty/embree-aarch64/kernels/common/device.h b/thirdparty/embree/kernels/common/device.h index e9a81bb109..21c42c654d 100644 --- a/thirdparty/embree-aarch64/kernels/common/device.h +++ b/thirdparty/embree/kernels/common/device.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/geometry.cpp b/thirdparty/embree/kernels/common/geometry.cpp index b3aa8e3396..d8d3f65a5c 100644 --- a/thirdparty/embree-aarch64/kernels/common/geometry.cpp +++ b/thirdparty/embree/kernels/common/geometry.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "geometry.h" diff --git a/thirdparty/embree-aarch64/kernels/common/geometry.h b/thirdparty/embree/kernels/common/geometry.h index 953974bfd2..2f9f2e7c94 100644 --- a/thirdparty/embree-aarch64/kernels/common/geometry.h +++ b/thirdparty/embree/kernels/common/geometry.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -301,7 +301,7 @@ namespace embree template<int N> __forceinline vint<N> timeSegment(const vfloat<N>& time, vfloat<N>& ftime) const { - return getTimeSegment(time,vfloat<N>(time_range.lower),vfloat<N>(time_range.upper),vfloat<N>(fnumTimeSegments),ftime); + return getTimeSegment<N>(time,vfloat<N>(time_range.lower),vfloat<N>(time_range.upper),vfloat<N>(fnumTimeSegments),ftime); } /* calculate overlapping time segment range */ diff --git a/thirdparty/embree-aarch64/kernels/common/hit.h b/thirdparty/embree/kernels/common/hit.h index 32a198cdfe..fd1a9d6391 100644 --- a/thirdparty/embree-aarch64/kernels/common/hit.h +++ b/thirdparty/embree/kernels/common/hit.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -22,7 +22,7 @@ namespace embree { for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) instID[l] = RTC_INVALID_GEOMETRY_ID; - instance_id_stack::copy(context->instID, instID); + instance_id_stack::copy_UV<K>(context->instID, instID); } /* Returns the size of the hit */ @@ -48,7 +48,7 @@ namespace embree __forceinline HitK(const RTCIntersectContext* context, unsigned int geomID, unsigned int primID, float u, float v, const Vec3fa& Ng) : Ng(Ng.x,Ng.y,Ng.z), u(u), v(v), primID(primID), geomID(geomID) { - instance_id_stack::copy(context->instID, instID); + instance_id_stack::copy_UU(context->instID, instID); } /* Returns the size of the hit */ @@ -96,7 +96,7 @@ namespace embree ray.v = hit.v; ray.primID = hit.primID; ray.geomID = hit.geomID; - instance_id_stack::copy(hit.instID, ray.instID); + instance_id_stack::copy_UU(hit.instID, ray.instID); } template<int K> @@ -109,6 +109,6 @@ namespace embree vfloat<K>::storeu(mask,&ray.v, hit.v); vuint<K>::storeu(mask,&ray.primID, hit.primID); vuint<K>::storeu(mask,&ray.geomID, hit.geomID); - instance_id_stack::copy(hit.instID, ray.instID, mask); + instance_id_stack::copy_VV<K>(hit.instID, ray.instID, mask); } } diff --git a/thirdparty/embree/kernels/common/instance_stack.h b/thirdparty/embree/kernels/common/instance_stack.h new file mode 100644 index 0000000000..d3c0a643f1 --- /dev/null +++ b/thirdparty/embree/kernels/common/instance_stack.h @@ -0,0 +1,179 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "rtcore.h" + +namespace embree { +namespace instance_id_stack { + +static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0, + "RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0."); + +/******************************************************************************* + * Instance ID stack manipulation. + * This is used from the instance intersector. + ******************************************************************************/ + +/* + * Push an instance to the stack. + */ +RTC_FORCEINLINE bool push(RTCIntersectContext* context, + unsigned instanceId) +{ +#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1 + const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT; + /* We assert here because instances are silently dropped when the stack is full. + This might be quite hard to find in production. */ + assert(spaceAvailable); + if (likely(spaceAvailable)) + context->instID[context->instStackSize++] = instanceId; + return spaceAvailable; +#else + const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID); + assert(spaceAvailable); + if (likely(spaceAvailable)) + context->instID[0] = instanceId; + return spaceAvailable; +#endif +} + + +/* + * Pop the last instance pushed to the stack. + * Do not call on an empty stack. + */ +RTC_FORCEINLINE void pop(RTCIntersectContext* context) +{ + assert(context); +#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1 + assert(context->instStackSize > 0); + context->instID[--context->instStackSize] = RTC_INVALID_GEOMETRY_ID; +#else + assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID); + context->instID[0] = RTC_INVALID_GEOMETRY_ID; +#endif +} + +/* + * Optimized instance id stack copy. + * The copy() functions will either copy full + * stacks or copy only until the last valid element has been copied, depending + * on RTC_MAX_INSTANCE_LEVEL_COUNT. + */ +RTC_FORCEINLINE void copy_UU(const unsigned* src, unsigned* tgt) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + tgt[0] = src[0]; + +#else + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + tgt[l] = src[l]; + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) + if (src[l] == RTC_INVALID_GEOMETRY_ID) + break; + } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + tgt[0] = src[0]; + +#else + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + tgt[l] = src[l]; + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) + if (src[l] == RTC_INVALID_GEOMETRY_ID) + break; + } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, size_t j) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + tgt[0][j] = src[0]; + +#else + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + tgt[l][j] = src[l]; + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) + if (src[l] == RTC_INVALID_GEOMETRY_ID) + break; + } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, const vbool<K>& mask) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + vuint<K>::store(mask, tgt, src[0]); + +#else + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + vuint<K>::store(mask, tgt + l, src[l]); + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) + if (src[l] == RTC_INVALID_GEOMETRY_ID) + break; + } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_VU(const vuint<K>* src, unsigned* tgt, size_t i) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + tgt[0] = src[0][i]; + +#else + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + tgt[l] = src[l][i]; + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) + if (src[l][i] == RTC_INVALID_GEOMETRY_ID) + break; + } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, size_t i, size_t j) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + tgt[0][j] = src[0][i]; + +#else + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + tgt[l][j] = src[l][i]; + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) + if (src[l][i] == RTC_INVALID_GEOMETRY_ID) + break; + } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) + vuint<K>::store(mask, tgt, src[0]); + +#else + vbool<K> done = !mask; + for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { + vuint<K>::store(mask, tgt + l, src[l]); + if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) { + done |= src[l] == RTC_INVALID_GEOMETRY_ID; + if (all(done)) break; + } + } +#endif +} + +} // namespace instance_id_stack +} // namespace embree diff --git a/thirdparty/embree-aarch64/kernels/common/isa.h b/thirdparty/embree/kernels/common/isa.h index 63fb8d3351..ae6556336c 100644 --- a/thirdparty/embree-aarch64/kernels/common/isa.h +++ b/thirdparty/embree/kernels/common/isa.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -13,23 +13,21 @@ namespace embree name##Func name; #define DECLARE_SYMBOL2(type,name) \ - namespace sse2 { extern type name(); } \ - namespace sse42 { extern type name(); } \ - namespace avx { extern type name(); } \ - namespace avx2 { extern type name(); } \ - namespace avx512knl { extern type name(); } \ - namespace avx512skx { extern type name(); } \ + namespace sse2 { extern type name(); } \ + namespace sse42 { extern type name(); } \ + namespace avx { extern type name(); } \ + namespace avx2 { extern type name(); } \ + namespace avx512 { extern type name(); } \ void name##_error2() { throw_RTCError(RTC_ERROR_UNKNOWN,"internal error in ISA selection for " TOSTRING(name)); } \ type name##_error() { return type(name##_error2); } \ type name##_zero() { return type(nullptr); } #define DECLARE_ISA_FUNCTION(type,symbol,args) \ - namespace sse2 { extern type symbol(args); } \ - namespace sse42 { extern type symbol(args); } \ - namespace avx { extern type symbol(args); } \ - namespace avx2 { extern type symbol(args); } \ - namespace avx512knl { extern type symbol(args); } \ - namespace avx512skx { extern type symbol(args); } \ + namespace sse2 { extern type symbol(args); } \ + namespace sse42 { extern type symbol(args); } \ + namespace avx { extern type symbol(args); } \ + namespace avx2 { extern type symbol(args); } \ + namespace avx512 { extern type symbol(args); } \ inline type symbol##_error(args) { throw_RTCError(RTC_ERROR_UNSUPPORTED_CPU,"function " TOSTRING(symbol) " not supported by your CPU"); } \ typedef type (*symbol##Ty)(args); \ @@ -46,7 +44,7 @@ namespace embree #define SELECT_SYMBOL_DEFAULT(features,intersector) \ intersector = isa::intersector; -#if defined(__SSE__) || defined(__ARM_NEON) +#if defined(__SSE__) #if !defined(EMBREE_TARGET_SIMD4) #define EMBREE_TARGET_SIMD4 #endif @@ -84,24 +82,14 @@ namespace embree #define SELECT_SYMBOL_AVX2(features,intersector) #endif -#if defined(EMBREE_TARGET_AVX512KNL) +#if defined(EMBREE_TARGET_AVX512) #if !defined(EMBREE_TARGET_SIMD16) #define EMBREE_TARGET_SIMD16 #endif -#define SELECT_SYMBOL_AVX512KNL(features,intersector) \ - if ((features & AVX512KNL) == AVX512KNL) intersector = avx512knl::intersector; +#define SELECT_SYMBOL_AVX512(features,intersector) \ + if ((features & AVX512) == AVX512) intersector = avx512::intersector; #else -#define SELECT_SYMBOL_AVX512KNL(features,intersector) -#endif - -#if defined(EMBREE_TARGET_AVX512SKX) -#if !defined(EMBREE_TARGET_SIMD16) -#define EMBREE_TARGET_SIMD16 -#endif -#define SELECT_SYMBOL_AVX512SKX(features,intersector) \ - if ((features & AVX512SKX) == AVX512SKX) intersector = avx512skx::intersector; -#else -#define SELECT_SYMBOL_AVX512SKX(features,intersector) +#define SELECT_SYMBOL_AVX512(features,intersector) #endif #define SELECT_SYMBOL_DEFAULT_SSE42(features,intersector) \ @@ -119,39 +107,37 @@ namespace embree SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); -#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_SSE42(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_SSE42(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_SSE42(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); #define SELECT_SYMBOL_DEFAULT_AVX(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ @@ -162,21 +148,19 @@ namespace embree SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); -#define SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_AVX(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ - SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); - -#define SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL_AVX512SKX(features,intersector) \ + SELECT_SYMBOL_AVX(features,intersector); + +#define SELECT_SYMBOL_DEFAULT_AVX_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_DEFAULT_AVX_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_AVX_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); #define SELECT_SYMBOL_INIT_AVX(features,intersector) \ INIT_SYMBOL(features,intersector); \ @@ -187,11 +171,11 @@ namespace embree SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); -#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,intersector) \ INIT_SYMBOL(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); #define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2(features,intersector) \ INIT_SYMBOL(features,intersector); \ @@ -199,57 +183,49 @@ namespace embree SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); -#define SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,intersector) \ +#define SELECT_SYMBOL_INIT_AVX(features,intersector) \ INIT_SYMBOL(features,intersector); \ - SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); + SELECT_SYMBOL_AVX(features,intersector); -#define SELECT_SYMBOL_INIT_AVX_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_INIT_AVX_AVX512(features,intersector) \ INIT_SYMBOL(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL(features,intersector) \ +#define SELECT_SYMBOL_INIT_AVX_AVX2(features,intersector) \ INIT_SYMBOL(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ - SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); + SELECT_SYMBOL_AVX2(features,intersector); -#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,intersector) \ INIT_SYMBOL(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2_AVX512(features,intersector) \ INIT_SYMBOL(features,intersector); \ SELECT_SYMBOL_SSE42(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_ZERO_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_ZERO_SSE42_AVX_AVX2_AVX512(features,intersector) \ ZERO_SYMBOL(features,intersector); \ SELECT_SYMBOL_SSE42(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,intersector) \ SELECT_SYMBOL_DEFAULT(features,intersector); \ SELECT_SYMBOL_AVX(features,intersector); \ SELECT_SYMBOL_AVX2(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); -#define SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,intersector) \ +#define SELECT_SYMBOL_INIT_AVX512(features,intersector) \ INIT_SYMBOL(features,intersector); \ - SELECT_SYMBOL_AVX512KNL(features,intersector); \ - SELECT_SYMBOL_AVX512SKX(features,intersector); + SELECT_SYMBOL_AVX512(features,intersector); #define SELECT_SYMBOL_SSE42_AVX_AVX2(features,intersector) \ SELECT_SYMBOL_SSE42(features,intersector); \ @@ -262,10 +238,9 @@ namespace embree else return getISA(depth-1); } }; - namespace sse2 { int getISA(); }; - namespace sse42 { int getISA(); }; - namespace avx { int getISA(); }; - namespace avx2 { int getISA(); }; - namespace avx512knl { int getISA(); }; - namespace avx512skx { int getISA(); }; + namespace sse2 { int getISA(); }; + namespace sse42 { int getISA(); }; + namespace avx { int getISA(); }; + namespace avx2 { int getISA(); }; + namespace avx512 { int getISA(); }; } diff --git a/thirdparty/embree-aarch64/kernels/common/motion_derivative.h b/thirdparty/embree/kernels/common/motion_derivative.h index 82953f0e89..c619d6a675 100644 --- a/thirdparty/embree-aarch64/kernels/common/motion_derivative.h +++ b/thirdparty/embree/kernels/common/motion_derivative.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/point_query.h b/thirdparty/embree/kernels/common/point_query.h index 27d158ca3a..7d55c91fff 100644 --- a/thirdparty/embree-aarch64/kernels/common/point_query.h +++ b/thirdparty/embree/kernels/common/point_query.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/primref.h b/thirdparty/embree/kernels/common/primref.h index ce75c982bb..d61763487b 100644 --- a/thirdparty/embree-aarch64/kernels/common/primref.h +++ b/thirdparty/embree/kernels/common/primref.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -29,7 +29,7 @@ namespace embree __forceinline PrimRef (const BBox3fa& bounds, size_t id) { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) lower = Vec3fx(bounds.lower, (unsigned)(id & 0xFFFFFFFF)); upper = Vec3fx(bounds.upper, (unsigned)((id >> 32) & 0xFFFFFFFF)); #else @@ -79,7 +79,7 @@ namespace embree /*! returns an size_t sized ID */ __forceinline size_t ID() const { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) return size_t(lower.u) + (size_t(upper.u) << 32); #else return size_t(lower.u); diff --git a/thirdparty/embree-aarch64/kernels/common/primref_mb.h b/thirdparty/embree/kernels/common/primref_mb.h index b6c1ad5712..fb08a05003 100644 --- a/thirdparty/embree-aarch64/kernels/common/primref_mb.h +++ b/thirdparty/embree/kernels/common/primref_mb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -32,7 +32,7 @@ namespace embree : lbounds((LBBox3fx)lbounds_i), time_range(time_range) { assert(activeTimeSegments > 0); -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) lbounds.bounds0.lower.a = id & 0xFFFFFFFF; lbounds.bounds0.upper.a = (id >> 32) & 0xFFFFFFFF; #else @@ -47,7 +47,7 @@ namespace embree : lbounds((LBBox3fx)lbounds_i), time_range(time_range) { assert(activeTimeSegments > 0); -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) lbounds.bounds0.lower.u = id & 0xFFFFFFFF; lbounds.bounds0.upper.u = (id >> 32) & 0xFFFFFFFF; #else @@ -115,7 +115,7 @@ namespace embree /*! returns an size_t sized ID */ __forceinline size_t ID() const { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) return size_t(lbounds.bounds0.lower.u) + (size_t(lbounds.bounds0.upper.u) << 32); #else return size_t(lbounds.bounds0.lower.u); @@ -163,7 +163,7 @@ namespace embree : bbox(bounds.interpolate(0.5f)), _activeTimeSegments(activeTimeSegments), _totalTimeSegments(totalTimeSegments), time_range(time_range) { assert(activeTimeSegments > 0); -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) bbox.lower.u = id & 0xFFFFFFFF; bbox.upper.u = (id >> 32) & 0xFFFFFFFF; #else @@ -229,7 +229,7 @@ namespace embree /*! returns an size_t sized ID */ __forceinline size_t ID() const { -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) return size_t(bbox.lower.u) + (size_t(bbox.upper.u) << 32); #else return size_t(bbox.lower.u); diff --git a/thirdparty/embree-aarch64/kernels/common/profile.h b/thirdparty/embree/kernels/common/profile.h index a7de36414d..5ef7f6ec0f 100644 --- a/thirdparty/embree-aarch64/kernels/common/profile.h +++ b/thirdparty/embree/kernels/common/profile.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/ray.h b/thirdparty/embree/kernels/common/ray.h index 336d48942c..7b951cc1e8 100644 --- a/thirdparty/embree-aarch64/kernels/common/ray.h +++ b/thirdparty/embree/kernels/common/ray.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -292,7 +292,7 @@ namespace embree ray.u = u[i]; ray.v = v[i]; ray.primID = primID[i]; ray.geomID = geomID[i]; - instance_id_stack::copy(instID, ray.instID, i); + instance_id_stack::copy_VU<K>(instID, ray.instID, i); } /* Converts single rays to ray packet */ @@ -331,7 +331,7 @@ namespace embree u[i] = ray.u; v[i] = ray.v; primID[i] = ray.primID; geomID[i] = ray.geomID; - instance_id_stack::copy(ray.instID, instID, i); + instance_id_stack::copy_UV<K>(ray.instID, instID, i); } /* copies a ray packet element into another element*/ @@ -353,7 +353,7 @@ namespace embree u[dest] = u[source]; v[dest] = v[source]; primID[dest] = primID[source]; geomID[dest] = geomID[source]; - instance_id_stack::copy(instID, instID, source, dest); + instance_id_stack::copy_VV<K>(instID, instID, source, dest); } /* Shortcuts */ @@ -1112,7 +1112,7 @@ namespace embree __forceinline RayK<K> getRayByOffset(const vbool<K>& valid, const vint<K>& offset) { const vint<K> valid_offset = select(valid, offset, vintx(zero)); - return getRayByOffset(valid_offset); + return getRayByOffset<K>(valid_offset); } template<int K> @@ -1153,7 +1153,7 @@ namespace embree ray_k->primID = ray.primID[k]; ray_k->geomID = ray.geomID[k]; - instance_id_stack::copy(ray.instID, ray_k->instID, k); + instance_id_stack::copy_VU<K>(ray.instID, ray_k->instID, k); } #endif } @@ -1185,7 +1185,7 @@ namespace embree }; template<> - __forceinline Ray4 RayStreamAOS::getRayByOffset(const vint4& offset) + __forceinline Ray4 RayStreamAOS::getRayByOffset<4>(const vint4& offset) { Ray4 ray; @@ -1222,7 +1222,7 @@ namespace embree #if defined(__AVX__) template<> - __forceinline Ray8 RayStreamAOS::getRayByOffset(const vint8& offset) + __forceinline Ray8 RayStreamAOS::getRayByOffset<8>(const vint8& offset) { Ray8 ray; @@ -1260,7 +1260,7 @@ namespace embree #if defined(__AVX512F__) template<> - __forceinline Ray16 RayStreamAOS::getRayByOffset(const vint16& offset) + __forceinline Ray16 RayStreamAOS::getRayByOffset<16>(const vint16& offset) { Ray16 ray; @@ -1332,7 +1332,7 @@ namespace embree __forceinline RayK<K> getRayByIndex(const vbool<K>& valid, const vint<K>& index) { const vint<K> valid_index = select(valid, index, vintx(zero)); - return getRayByIndex(valid_index); + return getRayByIndex<K>(valid_index); } template<int K> @@ -1357,7 +1357,7 @@ namespace embree ray_k->v = ray.v[k]; ray_k->primID = ray.primID[k]; ray_k->geomID = ray.geomID[k]; - instance_id_stack::copy(ray.instID, ray_k->instID, k); + instance_id_stack::copy_VU<K>(ray.instID, ray_k->instID, k); } } } @@ -1385,7 +1385,7 @@ namespace embree }; template<> - __forceinline Ray4 RayStreamAOP::getRayByIndex(const vint4& index) + __forceinline Ray4 RayStreamAOP::getRayByIndex<4>(const vint4& index) { Ray4 ray; @@ -1422,7 +1422,7 @@ namespace embree #if defined(__AVX__) template<> - __forceinline Ray8 RayStreamAOP::getRayByIndex(const vint8& index) + __forceinline Ray8 RayStreamAOP::getRayByIndex<8>(const vint8& index) { Ray8 ray; @@ -1460,7 +1460,7 @@ namespace embree #if defined(__AVX512F__) template<> - __forceinline Ray16 RayStreamAOP::getRayByIndex(const vint16& index) + __forceinline Ray16 RayStreamAOP::getRayByIndex<16>(const vint16& index) { Ray16 ray; diff --git a/thirdparty/embree-aarch64/kernels/common/rtcore.cpp b/thirdparty/embree/kernels/common/rtcore.cpp index 625fbf6d4f..94b3819e42 100644 --- a/thirdparty/embree-aarch64/kernels/common/rtcore.cpp +++ b/thirdparty/embree/kernels/common/rtcore.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #define RTC_EXPORT_API @@ -8,31 +8,18 @@ #include "scene.h" #include "context.h" #include "../../include/embree3/rtcore_ray.h" - -#if defined(__aarch64__) && defined(BUILD_IOS) -#include <mutex> -#endif - using namespace embree; RTC_NAMESPACE_BEGIN; /* mutex to make API thread safe */ -#if defined(__aarch64__) && defined(BUILD_IOS) - static std::mutex g_mutex; -#else - static MutexSys g_mutex; -#endif + static MutexSys g_mutex; RTC_API RTCDevice rtcNewDevice(const char* config) { RTC_CATCH_BEGIN; RTC_TRACE(rtcNewDevice); -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(g_mutex); -#else Lock<MutexSys> lock(g_mutex); -#endif Device* device = new Device(config); return (RTCDevice) device->refInc(); RTC_CATCH_END(nullptr); @@ -45,11 +32,7 @@ RTC_NAMESPACE_BEGIN; RTC_CATCH_BEGIN; RTC_TRACE(rtcRetainDevice); RTC_VERIFY_HANDLE(hdevice); -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(g_mutex); -#else Lock<MutexSys> lock(g_mutex); -#endif device->refInc(); RTC_CATCH_END(nullptr); } @@ -60,11 +43,7 @@ RTC_NAMESPACE_BEGIN; RTC_CATCH_BEGIN; RTC_TRACE(rtcReleaseDevice); RTC_VERIFY_HANDLE(hdevice); -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(g_mutex); -#else Lock<MutexSys> lock(g_mutex); -#endif device->refDec(); RTC_CATCH_END(nullptr); } @@ -75,11 +54,7 @@ RTC_NAMESPACE_BEGIN; RTC_CATCH_BEGIN; RTC_TRACE(rtcGetDeviceProperty); RTC_VERIFY_HANDLE(hdevice); -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(g_mutex); -#else Lock<MutexSys> lock(g_mutex); -#endif return device->getProperty(prop); RTC_CATCH_END(device); return 0; @@ -92,11 +67,7 @@ RTC_NAMESPACE_BEGIN; RTC_TRACE(rtcSetDeviceProperty); const bool internal_prop = (size_t)prop >= 1000000 && (size_t)prop < 1000004; if (!internal_prop) RTC_VERIFY_HANDLE(hdevice); // allow NULL device for special internal settings -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(g_mutex); -#else Lock<MutexSys> lock(g_mutex); -#endif device->setProperty(prop,val); RTC_CATCH_END(device); } @@ -212,11 +183,7 @@ RTC_NAMESPACE_BEGIN; RTC_CATCH_BEGIN; RTC_TRACE(rtcSetSceneProgressMonitorFunction); RTC_VERIFY_HANDLE(hscene); -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(g_mutex); -#else Lock<MutexSys> lock(g_mutex); -#endif scene->setProgressMonitorFunction(progress,ptr); RTC_CATCH_END2(scene); } @@ -515,12 +482,12 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - RayHit4* rayhit4 = (RayHit4*)rayhit; + Ray4* ray4 = (Ray4*) rayhit; for (size_t i=0; i<4; i++) { if (!valid[i]) continue; - RayHit ray1; rayhit4->get(i,ray1); + RayHit ray1; ray4->get(i,ray1); scene->intersectors.intersect((RTCRayHit&)ray1,&context); - rayhit4->set(i,ray1); + ray4->set(i,ray1); } #else scene->intersectors.intersect4(valid,*rayhit,&context); @@ -546,12 +513,12 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - RayHit8* rayhit8 = (RayHit8*) rayhit; + Ray8* ray8 = (Ray8*) rayhit; for (size_t i=0; i<8; i++) { if (!valid[i]) continue; - RayHit ray1; rayhit8->get(i,ray1); + RayHit ray1; ray8->get(i,ray1); scene->intersectors.intersect((RTCRayHit&)ray1,&context); - rayhit8->set(i,ray1); + ray8->set(i,ray1); } #else if (likely(scene->intersectors.intersector8)) @@ -579,12 +546,12 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - RayHit16* rayhit16 = (RayHit16*) rayhit; + Ray16* ray16 = (Ray16*) rayhit; for (size_t i=0; i<16; i++) { if (!valid[i]) continue; - RayHit ray1; rayhit16->get(i,ray1); + RayHit ray1; ray16->get(i,ray1); scene->intersectors.intersect((RTCRayHit&)ray1,&context); - rayhit16->set(i,ray1); + ray16->set(i,ray1); } #else if (likely(scene->intersectors.intersector16)) @@ -766,12 +733,12 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - Ray4* ray4 = (Ray4*) ray; + RayHit4* ray4 = (RayHit4*) ray; for (size_t i=0; i<4; i++) { if (!valid[i]) continue; - Ray ray1; ray4->get(i,ray1); + RayHit ray1; ray4->get(i,ray1); scene->intersectors.occluded((RTCRay&)ray1,&context); - ray4->set(i,ray1); + ray4->geomID[i] = ray1.geomID; } #else scene->intersectors.occluded4(valid,*ray,&context); @@ -797,10 +764,10 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - Ray8* ray8 = (Ray8*) ray; + RayHit8* ray8 = (RayHit8*) ray; for (size_t i=0; i<8; i++) { if (!valid[i]) continue; - Ray ray1; ray8->get(i,ray1); + RayHit ray1; ray8->get(i,ray1); scene->intersectors.occluded((RTCRay&)ray1,&context); ray8->set(i,ray1); } @@ -831,10 +798,10 @@ RTC_NAMESPACE_BEGIN; IntersectContext context(scene,user_context); #if !defined(EMBREE_RAY_PACKETS) - Ray16* ray16 = (Ray16*) ray; + RayHit16* ray16 = (RayHit16*) ray; for (size_t i=0; i<16; i++) { if (!valid[i]) continue; - Ray ray1; ray16->get(i,ray1); + RayHit ray1; ray16->get(i,ray1); scene->intersectors.occluded((RTCRay&)ray1,&context); ray16->set(i,ray1); } @@ -1152,7 +1119,7 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_TRIANGLE) createTriangleMeshTy createTriangleMesh = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createTriangleMesh); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createTriangleMesh); Geometry* geom = createTriangleMesh(device); return (RTCGeometry) geom->refInc(); #else @@ -1164,7 +1131,7 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_QUAD) createQuadMeshTy createQuadMesh = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createQuadMesh); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createQuadMesh); Geometry* geom = createQuadMesh(device); return (RTCGeometry) geom->refInc(); #else @@ -1178,7 +1145,7 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_POINT) createPointsTy createPoints = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_builder_cpu_features, createPoints); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_builder_cpu_features, createPoints); Geometry *geom; switch(type) { @@ -1223,9 +1190,9 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_CURVE) createLineSegmentsTy createLineSegments = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createLineSegments); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createLineSegments); createCurvesTy createCurves = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createCurves); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createCurves); Geometry* geom; switch (type) { @@ -1262,7 +1229,7 @@ RTC_NAMESPACE_BEGIN; #if defined(EMBREE_GEOMETRY_SUBDIVISION) createSubdivMeshTy createSubdivMesh = nullptr; SELECT_SYMBOL_DEFAULT_AVX(device->enabled_cpu_features,createSubdivMesh); - //SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createSubdivMesh); // FIXME: this does not work for some reason? + //SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createSubdivMesh); // FIXME: this does not work for some reason? Geometry* geom = createSubdivMesh(device); return (RTCGeometry) geom->refInc(); #else @@ -1274,7 +1241,7 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_USER) createUserGeometryTy createUserGeometry = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createUserGeometry); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createUserGeometry); Geometry* geom = createUserGeometry(device); return (RTCGeometry) geom->refInc(); #else @@ -1286,7 +1253,7 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_INSTANCE) createInstanceTy createInstance = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createInstance); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createInstance); Geometry* geom = createInstance(device); return (RTCGeometry) geom->refInc(); #else @@ -1298,7 +1265,7 @@ RTC_NAMESPACE_BEGIN; { #if defined(EMBREE_GEOMETRY_GRID) createGridMeshTy createGridMesh = nullptr; - SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(device->enabled_cpu_features,createGridMesh); + SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createGridMesh); Geometry* geom = createGridMesh(device); return (RTCGeometry) geom->refInc(); #else diff --git a/thirdparty/embree-aarch64/kernels/common/rtcore.h b/thirdparty/embree/kernels/common/rtcore.h index 4b070e122b..373e49a689 100644 --- a/thirdparty/embree-aarch64/kernels/common/rtcore.h +++ b/thirdparty/embree/kernels/common/rtcore.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/rtcore_builder.cpp b/thirdparty/embree/kernels/common/rtcore_builder.cpp index 6bb96bba07..1f1b6f6ddf 100644 --- a/thirdparty/embree-aarch64/kernels/common/rtcore_builder.cpp +++ b/thirdparty/embree/kernels/common/rtcore_builder.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #define RTC_EXPORT_API diff --git a/thirdparty/embree-aarch64/kernels/common/scene.cpp b/thirdparty/embree/kernels/common/scene.cpp index 1e23aeb415..408d7eae6f 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene.cpp +++ b/thirdparty/embree/kernels/common/scene.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "scene.h" @@ -6,7 +6,7 @@ #include "../bvh/bvh4_factory.h" #include "../bvh/bvh8_factory.h" #include "../../common/algorithms/parallel_reduce.h" - + namespace embree { /* error raising rtcIntersect and rtcOccluded functions */ @@ -40,7 +40,7 @@ namespace embree { device->refDec(); } - + void Scene::printStatistics() { /* calculate maximum number of time segments */ @@ -56,12 +56,12 @@ namespace embree statistics[i].resize(max_time_steps); /* gather statistics */ - for (size_t i=0; i<size(); i++) + for (size_t i=0; i<size(); i++) { if (!get(i)) continue; - int ty = get(i)->getType(); + int ty = get(i)->getType(); assert(ty<Geometry::GTY_END); - int timesegments = get(i)->numTimeSegments(); + int timesegments = get(i)->numTimeSegments(); assert((unsigned int)timesegments < max_time_steps); statistics[ty][timesegments] += get(i)->size(); } @@ -76,7 +76,7 @@ namespace embree for (size_t t=0; t<max_time_steps; t++) std::cout << "----------"; std::cout << std::endl; - + for (size_t p=0; p<Geometry::GTY_END; p++) { if (std::string(Geometry::gtype_names[p]) == "") continue; @@ -90,34 +90,34 @@ namespace embree void Scene::createTriangleAccel() { #if defined(EMBREE_GEOMETRY_TRIANGLE) - if (device->tri_accel == "default") + if (device->tri_accel == "default") { if (quality_flags != RTC_BUILD_QUALITY_LOW) { - int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); + int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); switch (mode) { - case /*0b00*/ 0: + case /*0b00*/ 0: #if defined (EMBREE_TARGET_SIMD8) if (device->canUseAVX()) { - if (quality_flags == RTC_BUILD_QUALITY_HIGH) + if (quality_flags == RTC_BUILD_QUALITY_HIGH) accels_add(device->bvh8_factory->BVH8Triangle4(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST)); else accels_add(device->bvh8_factory->BVH8Triangle4(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST)); } - else + else #endif - { - if (quality_flags == RTC_BUILD_QUALITY_HIGH) + { + if (quality_flags == RTC_BUILD_QUALITY_HIGH) accels_add(device->bvh4_factory->BVH4Triangle4(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST)); - else + else accels_add(device->bvh4_factory->BVH4Triangle4(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST)); } break; - case /*0b01*/ 1: + case /*0b01*/ 1: #if defined (EMBREE_TARGET_SIMD8) - if (device->canUseAVX()) + if (device->canUseAVX()) accels_add(device->bvh8_factory->BVH8Triangle4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST)); else #endif @@ -175,8 +175,8 @@ namespace embree #if defined(EMBREE_GEOMETRY_TRIANGLE) if (device->tri_accel_mb == "default") { - int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); - + int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); + #if defined (EMBREE_TARGET_SIMD8) if (device->canUseAVX2()) // BVH8 reduces performance on AVX only-machines { @@ -211,18 +211,18 @@ namespace embree void Scene::createQuadAccel() { #if defined(EMBREE_GEOMETRY_QUAD) - if (device->quad_accel == "default") + if (device->quad_accel == "default") { if (quality_flags != RTC_BUILD_QUALITY_LOW) { /* static */ - int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); + int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); switch (mode) { case /*0b00*/ 0: #if defined (EMBREE_TARGET_SIMD8) if (device->canUseAVX()) { - if (quality_flags == RTC_BUILD_QUALITY_HIGH) + if (quality_flags == RTC_BUILD_QUALITY_HIGH) accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST)); else accels_add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST)); @@ -230,7 +230,7 @@ namespace embree else #endif { - if (quality_flags == RTC_BUILD_QUALITY_HIGH) + if (quality_flags == RTC_BUILD_QUALITY_HIGH) accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::HIGH_QUALITY,BVHFactory::IntersectVariant::FAST)); else accels_add(device->bvh4_factory->BVH4Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST)); @@ -292,9 +292,9 @@ namespace embree void Scene::createQuadMBAccel() { #if defined(EMBREE_GEOMETRY_QUAD) - if (device->quad_accel_mb == "default") + if (device->quad_accel_mb == "default") { - int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); + int mode = 2*(int)isCompactAccel() + 1*(int)isRobustAccel(); switch (mode) { case /*0b00*/ 0: #if defined (EMBREE_TARGET_SIMD8) @@ -416,7 +416,7 @@ namespace embree void Scene::createUserGeometryAccel() { #if defined(EMBREE_GEOMETRY_USER) - if (device->object_accel == "default") + if (device->object_accel == "default") { #if defined (EMBREE_TARGET_SIMD8) if (device->canUseAVX() && !isCompactAccel()) @@ -554,7 +554,7 @@ namespace embree { BVHFactory::IntersectVariant ivariant = isRobustAccel() ? BVHFactory::IntersectVariant::ROBUST : BVHFactory::IntersectVariant::FAST; #if defined(EMBREE_GEOMETRY_GRID) - if (device->grid_accel == "default") + if (device->grid_accel == "default") { #if defined (EMBREE_TARGET_SIMD8) if (device->canUseAVX() && !isCompactAccel()) @@ -579,7 +579,7 @@ namespace embree void Scene::createGridMBAccel() { #if defined(EMBREE_GEOMETRY_GRID) - if (device->grid_accel_mb == "default") + if (device->grid_accel_mb == "default") { accels_add(device->bvh4_factory->BVH4GridMB(this,BVHFactory::BuildVariant::STATIC)); } @@ -588,17 +588,13 @@ namespace embree #endif } - + void Scene::clear() { } - unsigned Scene::bind(unsigned geomID, Ref<Geometry> geometry) + unsigned Scene::bind(unsigned geomID, Ref<Geometry> geometry) { -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(geometriesMutex); -#else Lock<SpinLock> lock(geometriesMutex); -#endif if (geomID == RTC_INVALID_GEOMETRY_ID) { geomID = id_pool.allocate(); if (geomID == RTC_INVALID_GEOMETRY_ID) @@ -624,19 +620,15 @@ namespace embree void Scene::detachGeometry(size_t geomID) { -#if defined(__aarch64__) && defined(BUILD_IOS) - std::scoped_lock lock(geometriesMutex); -#else Lock<SpinLock> lock(geometriesMutex); -#endif - + if (geomID >= geometries.size()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid geometry ID"); Ref<Geometry>& geometry = geometries[geomID]; if (geometry == null) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid geometry"); - + if (geometry->isEnabled()) { setModified (); } @@ -658,21 +650,21 @@ namespace embree if (!isModified()) { return; } - + /* print scene statistics */ if (device->verbosity(2)) printStatistics(); progress_monitor_counter = 0; - + /* gather scene stats and call preCommit function of each geometry */ - this->world = parallel_reduce (size_t(0), geometries.size(), GeometryCounts (), + this->world = parallel_reduce (size_t(0), geometries.size(), GeometryCounts (), [this](const range<size_t>& r)->GeometryCounts { GeometryCounts c; - for (auto i=r.begin(); i<r.end(); ++i) + for (auto i=r.begin(); i<r.end(); ++i) { - if (geometries[i] && geometries[i]->isEnabled()) + if (geometries[i] && geometries[i]->isEnabled()) { geometries[i]->preCommit(); geometries[i]->addElementsToCount (c); @@ -683,19 +675,19 @@ namespace embree }, std::plus<GeometryCounts>() ); - + /* select acceleration structures to build */ unsigned int new_enabled_geometry_types = world.enabledGeometryTypesMask(); if (flags_modified || new_enabled_geometry_types != enabled_geometry_types) { accels_init(); - /* we need to make all geometries modified, otherwise two level builder will + /* we need to make all geometries modified, otherwise two level builder will not rebuild currently not modified geometries */ parallel_for(geometryModCounters_.size(), [&] ( const size_t i ) { geometryModCounters_[i] = 0; }); - + if (getNumPrimitives(TriangleMesh::geom_type,false)) createTriangleAccel(); if (getNumPrimitives(TriangleMesh::geom_type,true)) createTriangleMBAccel(); if (getNumPrimitives(QuadMesh::geom_type,false)) createQuadAccel(); @@ -712,14 +704,14 @@ namespace embree if (getNumPrimitives(Geometry::MTY_INSTANCE_CHEAP,true)) createInstanceMBAccel(); if (getNumPrimitives(Geometry::MTY_INSTANCE_EXPENSIVE,false)) createInstanceExpensiveAccel(); if (getNumPrimitives(Geometry::MTY_INSTANCE_EXPENSIVE,true)) createInstanceExpensiveMBAccel(); - + flags_modified = false; enabled_geometry_types = new_enabled_geometry_types; } - + /* select fast code path if no filter function is present */ accels_select(hasFilterFunction()); - + /* build all hierarchies of this scene */ accels_build(); @@ -737,7 +729,7 @@ namespace embree geometryModCounters_[i] = geometries[i]->getModCounter(); } }); - + updateInterface(); if (device->verbosity(2)) { @@ -746,7 +738,7 @@ namespace embree std::cout << "selected scene intersector" << std::endl; intersectors.print(2); } - + setModified(false); } @@ -771,16 +763,16 @@ namespace embree RTCSceneFlags Scene::getSceneFlags() const { return scene_flags; } - + #if defined(TASKING_INTERNAL) - void Scene::commit (bool join) + void Scene::commit (bool join) { Lock<MutexSys> buildLock(buildMutex,false); /* allocates own taskscheduler for each build */ Ref<TaskScheduler> scheduler = nullptr; - { + { Lock<MutexSys> lock(schedulerMutex); scheduler = this->scheduler; if (scheduler == null) { @@ -792,9 +784,9 @@ namespace embree /* worker threads join build */ if (!buildLock.isLocked()) { - if (!join) + if (!join) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"use rtcJoinCommitScene to join a build operation"); - + scheduler->join(); return; } @@ -816,9 +808,9 @@ namespace embree #endif -#if defined(TASKING_TBB) || defined(TASKING_GCD) +#if defined(TASKING_TBB) - void Scene::commit (bool join) + void Scene::commit (bool join) { #if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION_MAJOR < 8) if (join) @@ -832,15 +824,12 @@ namespace embree if (!lock.isLocked()) { #if !TASKING_TBB_USE_TASK_ISOLATION - if (!join) + if (!join) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invoking rtcCommitScene from multiple threads is not supported with this TBB version"); #endif - + do { -#if defined(TASKING_GCD) - // Do Nothing -#else #if USE_TASK_ARENA if (join) { device->arena->execute([&]{ group.wait(); }); @@ -850,24 +839,21 @@ namespace embree { group.wait(); } -#endif pause_cpu(); yield(); - } while (!buildMutex.try_lock()); - + buildMutex.unlock(); return; - } + } /* for best performance set FTZ and DAZ flags in the MXCSR control and status register */ const unsigned int mxcsr = _mm_getcsr(); _mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6)); - + try { -#if defined(TASKING_TBB) -#if TBB_INTERFACE_VERSION_MAJOR < 8 +#if TBB_INTERFACE_VERSION_MAJOR < 8 tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits); #else tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits | tbb::task_group_context::fp_settings ); @@ -892,22 +878,15 @@ namespace embree }); group.wait(); } - + /* reset MXCSR register again */ _mm_setcsr(mxcsr); - -#elif defined(TASKING_GCD) - - commit_task(); - -#endif // #if defined(TASKING_TBB) - - } + } catch (...) { /* reset MXCSR register again */ _mm_setcsr(mxcsr); - + accels_clear(); updateInterface(); throw; @@ -917,7 +896,7 @@ namespace embree #if defined(TASKING_PPL) - void Scene::commit (bool join) + void Scene::commit (bool join) { #if defined(TASKING_PPL) if (join) @@ -935,7 +914,7 @@ namespace embree /* for best performance set FTZ and DAZ flags in the MXCSR control and status register */ const unsigned int mxcsr = _mm_getcsr(); _mm_setcsr(mxcsr | /* FTZ */ (1<<15) | /* DAZ */ (1<<6)); - + try { group.run([&]{ @@ -945,12 +924,12 @@ namespace embree /* reset MXCSR register again */ _mm_setcsr(mxcsr); - } + } catch (...) { /* reset MXCSR register again */ _mm_setcsr(mxcsr); - + accels_clear(); updateInterface(); throw; @@ -958,7 +937,7 @@ namespace embree } #endif - void Scene::setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr) + void Scene::setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr) { progress_monitor_function = func; progress_monitor_ptr = ptr; diff --git a/thirdparty/embree-aarch64/kernels/common/scene.h b/thirdparty/embree/kernels/common/scene.h index b41c6cde91..5ed80a63f6 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene.h +++ b/thirdparty/embree/kernels/common/scene.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree/kernels/common/scene_curves.h b/thirdparty/embree/kernels/common/scene_curves.h new file mode 100644 index 0000000000..a5a39e42d4 --- /dev/null +++ b/thirdparty/embree/kernels/common/scene_curves.h @@ -0,0 +1,688 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "default.h" +#include "geometry.h" +#include "buffer.h" + +#include "../subdiv/bezier_curve.h" +#include "../subdiv/hermite_curve.h" +#include "../subdiv/bspline_curve.h" +#include "../subdiv/catmullrom_curve.h" +#include "../subdiv/linear_bezier_patch.h" + +namespace embree +{ + /*! represents an array of bicubic bezier curves */ + struct CurveGeometry : public Geometry + { + /*! type of this geometry */ + static const Geometry::GTypeMask geom_type = Geometry::MTY_CURVE4; + + public: + + /*! bezier curve construction */ + CurveGeometry (Device* device, Geometry::GType gtype); + + public: + void setMask(unsigned mask); + void setNumTimeSteps (unsigned int numTimeSteps); + void setVertexAttributeCount (unsigned int N); + void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num); + void* getBuffer(RTCBufferType type, unsigned int slot); + void updateBuffer(RTCBufferType type, unsigned int slot); + void commit(); + bool verify(); + void setTessellationRate(float N); + void setMaxRadiusScale(float s); + void addElementsToCount (GeometryCounts & counts) const; + + public: + + /*! returns the number of vertices */ + __forceinline size_t numVertices() const { + return vertices[0].size(); + } + + /*! returns the i'th curve */ + __forceinline const unsigned int& curve(size_t i) const { + return curves[i]; + } + + /*! returns i'th vertex of the first time step */ + __forceinline Vec3ff vertex(size_t i) const { + return vertices0[i]; + } + + /*! returns i'th normal of the first time step */ + __forceinline Vec3fa normal(size_t i) const { + return normals0[i]; + } + + /*! returns i'th tangent of the first time step */ + __forceinline Vec3ff tangent(size_t i) const { + return tangents0[i]; + } + + /*! returns i'th normal derivative of the first time step */ + __forceinline Vec3fa dnormal(size_t i) const { + return dnormals0[i]; + } + + /*! returns i'th radius of the first time step */ + __forceinline float radius(size_t i) const { + return vertices0[i].w; + } + + /*! returns i'th vertex of itime'th timestep */ + __forceinline Vec3ff vertex(size_t i, size_t itime) const { + return vertices[itime][i]; + } + + /*! returns i'th normal of itime'th timestep */ + __forceinline Vec3fa normal(size_t i, size_t itime) const { + return normals[itime][i]; + } + + /*! returns i'th tangent of itime'th timestep */ + __forceinline Vec3ff tangent(size_t i, size_t itime) const { + return tangents[itime][i]; + } + + /*! returns i'th normal derivative of itime'th timestep */ + __forceinline Vec3fa dnormal(size_t i, size_t itime) const { + return dnormals[itime][i]; + } + + /*! returns i'th radius of itime'th timestep */ + __forceinline float radius(size_t i, size_t itime) const { + return vertices[itime][i].w; + } + + /*! gathers the curve starting with i'th vertex */ + __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, size_t i) const + { + p0 = vertex(i+0); + p1 = vertex(i+1); + p2 = vertex(i+2); + p3 = vertex(i+3); + } + + /*! gathers the curve starting with i'th vertex of itime'th timestep */ + __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, size_t i, size_t itime) const + { + p0 = vertex(i+0,itime); + p1 = vertex(i+1,itime); + p2 = vertex(i+2,itime); + p3 = vertex(i+3,itime); + } + + /*! gathers the curve starting with i'th vertex */ + __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3, size_t i) const + { + p0 = vertex(i+0); + p1 = vertex(i+1); + p2 = vertex(i+2); + p3 = vertex(i+3); + n0 = normal(i+0); + n1 = normal(i+1); + n2 = normal(i+2); + n3 = normal(i+3); + } + + /*! gathers the curve starting with i'th vertex of itime'th timestep */ + __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3, size_t i, size_t itime) const + { + p0 = vertex(i+0,itime); + p1 = vertex(i+1,itime); + p2 = vertex(i+2,itime); + p3 = vertex(i+3,itime); + n0 = normal(i+0,itime); + n1 = normal(i+1,itime); + n2 = normal(i+2,itime); + n3 = normal(i+3,itime); + } + + /*! prefetches the curve starting with i'th vertex of itime'th timestep */ + __forceinline void prefetchL1_vertices(size_t i) const + { + prefetchL1(vertices0.getPtr(i)+0); + prefetchL1(vertices0.getPtr(i)+64); + } + + /*! prefetches the curve starting with i'th vertex of itime'th timestep */ + __forceinline void prefetchL2_vertices(size_t i) const + { + prefetchL2(vertices0.getPtr(i)+0); + prefetchL2(vertices0.getPtr(i)+64); + } + + /*! loads curve vertices for specified time */ + __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, size_t i, float time) const + { + float ftime; + const size_t itime = timeSegment(time, ftime); + + const float t0 = 1.0f - ftime; + const float t1 = ftime; + Vec3ff a0,a1,a2,a3; + gather(a0,a1,a2,a3,i,itime); + Vec3ff b0,b1,b2,b3; + gather(b0,b1,b2,b3,i,itime+1); + p0 = madd(Vec3ff(t0),a0,t1*b0); + p1 = madd(Vec3ff(t0),a1,t1*b1); + p2 = madd(Vec3ff(t0),a2,t1*b2); + p3 = madd(Vec3ff(t0),a3,t1*b3); + } + + /*! loads curve vertices for specified time */ + __forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, Vec3fa& n0, Vec3fa& n1, Vec3fa& n2, Vec3fa& n3, size_t i, float time) const + { + float ftime; + const size_t itime = timeSegment(time, ftime); + + const float t0 = 1.0f - ftime; + const float t1 = ftime; + Vec3ff a0,a1,a2,a3; Vec3fa an0,an1,an2,an3; + gather(a0,a1,a2,a3,an0,an1,an2,an3,i,itime); + Vec3ff b0,b1,b2,b3; Vec3fa bn0,bn1,bn2,bn3; + gather(b0,b1,b2,b3,bn0,bn1,bn2,bn3,i,itime+1); + p0 = madd(Vec3ff(t0),a0,t1*b0); + p1 = madd(Vec3ff(t0),a1,t1*b1); + p2 = madd(Vec3ff(t0),a2,t1*b2); + p3 = madd(Vec3ff(t0),a3,t1*b3); + n0 = madd(Vec3ff(t0),an0,t1*bn0); + n1 = madd(Vec3ff(t0),an1,t1*bn1); + n2 = madd(Vec3ff(t0),an2,t1*bn2); + n3 = madd(Vec3ff(t0),an3,t1*bn3); + } + + template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> + __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const size_t itime) const + { + Vec3ff v0,v1,v2,v3; Vec3fa n0,n1,n2,n3; + unsigned int vertexID = curve(primID); + gather(v0,v1,v2,v3,n0,n1,n2,n3,vertexID,itime); + SourceCurve3ff ccurve(v0,v1,v2,v3); + SourceCurve3fa ncurve(n0,n1,n2,n3); + ccurve = enlargeRadiusToMinWidth(context,this,ray_org,ccurve); + return TensorLinearCubicBezierSurface3fa::fromCenterAndNormalCurve(ccurve,ncurve); + } + + template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> + __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const float time) const + { + float ftime; + const size_t itime = timeSegment(time, ftime); + const TensorLinearCubicBezierSurface3fa curve0 = getNormalOrientedCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context,ray_org,primID,itime+0); + const TensorLinearCubicBezierSurface3fa curve1 = getNormalOrientedCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context,ray_org,primID,itime+1); + return clerp(curve0,curve1,ftime); + } + + /*! gathers the hermite curve starting with i'th vertex */ + __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3ff& p1, Vec3ff& t1, size_t i) const + { + p0 = vertex (i+0); + p1 = vertex (i+1); + t0 = tangent(i+0); + t1 = tangent(i+1); + } + + /*! gathers the hermite curve starting with i'th vertex of itime'th timestep */ + __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3ff& p1, Vec3ff& t1, size_t i, size_t itime) const + { + p0 = vertex (i+0,itime); + p1 = vertex (i+1,itime); + t0 = tangent(i+0,itime); + t1 = tangent(i+1,itime); + } + + /*! loads curve vertices for specified time */ + __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3ff& p1, Vec3ff& t1, size_t i, float time) const + { + float ftime; + const size_t itime = timeSegment(time, ftime); + const float f0 = 1.0f - ftime, f1 = ftime; + Vec3ff ap0,at0,ap1,at1; + gather_hermite(ap0,at0,ap1,at1,i,itime); + Vec3ff bp0,bt0,bp1,bt1; + gather_hermite(bp0,bt0,bp1,bt1,i,itime+1); + p0 = madd(Vec3ff(f0),ap0,f1*bp0); + t0 = madd(Vec3ff(f0),at0,f1*bt0); + p1 = madd(Vec3ff(f0),ap1,f1*bp1); + t1 = madd(Vec3ff(f0),at1,f1*bt1); + } + + /*! gathers the hermite curve starting with i'th vertex */ + __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3fa& n0, Vec3fa& dn0, Vec3ff& p1, Vec3ff& t1, Vec3fa& n1, Vec3fa& dn1, size_t i) const + { + p0 = vertex (i+0); + p1 = vertex (i+1); + t0 = tangent(i+0); + t1 = tangent(i+1); + n0 = normal(i+0); + n1 = normal(i+1); + dn0 = dnormal(i+0); + dn1 = dnormal(i+1); + } + + /*! gathers the hermite curve starting with i'th vertex of itime'th timestep */ + __forceinline void gather_hermite(Vec3ff& p0, Vec3ff& t0, Vec3fa& n0, Vec3fa& dn0, Vec3ff& p1, Vec3ff& t1, Vec3fa& n1, Vec3fa& dn1, size_t i, size_t itime) const + { + p0 = vertex (i+0,itime); + p1 = vertex (i+1,itime); + t0 = tangent(i+0,itime); + t1 = tangent(i+1,itime); + n0 = normal(i+0,itime); + n1 = normal(i+1,itime); + dn0 = dnormal(i+0,itime); + dn1 = dnormal(i+1,itime); + } + + /*! loads curve vertices for specified time */ + __forceinline void gather_hermite(Vec3ff& p0, Vec3fa& t0, Vec3fa& n0, Vec3fa& dn0, Vec3ff& p1, Vec3fa& t1, Vec3fa& n1, Vec3fa& dn1, size_t i, float time) const + { + float ftime; + const size_t itime = timeSegment(time, ftime); + const float f0 = 1.0f - ftime, f1 = ftime; + Vec3ff ap0,at0,ap1,at1; Vec3fa an0,adn0,an1,adn1; + gather_hermite(ap0,at0,an0,adn0,ap1,at1,an1,adn1,i,itime); + Vec3ff bp0,bt0,bp1,bt1; Vec3fa bn0,bdn0,bn1,bdn1; + gather_hermite(bp0,bt0,bn0,bdn0,bp1,bt1,bn1,bdn1,i,itime+1); + p0 = madd(Vec3ff(f0),ap0,f1*bp0); + t0 = madd(Vec3ff(f0),at0,f1*bt0); + n0 = madd(Vec3ff(f0),an0,f1*bn0); + dn0= madd(Vec3ff(f0),adn0,f1*bdn0); + p1 = madd(Vec3ff(f0),ap1,f1*bp1); + t1 = madd(Vec3ff(f0),at1,f1*bt1); + n1 = madd(Vec3ff(f0),an1,f1*bn1); + dn1= madd(Vec3ff(f0),adn1,f1*bdn1); + } + + template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> + __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedHermiteCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const size_t itime) const + { + Vec3ff v0,t0,v1,t1; Vec3fa n0,dn0,n1,dn1; + unsigned int vertexID = curve(primID); + gather_hermite(v0,t0,n0,dn0,v1,t1,n1,dn1,vertexID,itime); + + SourceCurve3ff ccurve(v0,t0,v1,t1); + SourceCurve3fa ncurve(n0,dn0,n1,dn1); + ccurve = enlargeRadiusToMinWidth(context,this,ray_org,ccurve); + return TensorLinearCubicBezierSurface3fa::fromCenterAndNormalCurve(ccurve,ncurve); + } + + template<typename SourceCurve3ff, typename SourceCurve3fa, typename TensorLinearCubicBezierSurface3fa> + __forceinline TensorLinearCubicBezierSurface3fa getNormalOrientedHermiteCurve(IntersectContext* context, const Vec3fa& ray_org, const unsigned int primID, const float time) const + { + float ftime; + const size_t itime = timeSegment(time, ftime); + const TensorLinearCubicBezierSurface3fa curve0 = getNormalOrientedHermiteCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,itime+0); + const TensorLinearCubicBezierSurface3fa curve1 = getNormalOrientedHermiteCurve<SourceCurve3ff, SourceCurve3fa, TensorLinearCubicBezierSurface3fa>(context, ray_org, primID,itime+1); + return clerp(curve0,curve1,ftime); + } + + private: + void resizeBuffers(unsigned int numSteps); + + public: + BufferView<unsigned int> curves; //!< array of curve indices + BufferView<Vec3ff> vertices0; //!< fast access to first vertex buffer + BufferView<Vec3fa> normals0; //!< fast access to first normal buffer + BufferView<Vec3ff> tangents0; //!< fast access to first tangent buffer + BufferView<Vec3fa> dnormals0; //!< fast access to first normal derivative buffer + vector<BufferView<Vec3ff>> vertices; //!< vertex array for each timestep + vector<BufferView<Vec3fa>> normals; //!< normal array for each timestep + vector<BufferView<Vec3ff>> tangents; //!< tangent array for each timestep + vector<BufferView<Vec3fa>> dnormals; //!< normal derivative array for each timestep + BufferView<char> flags; //!< start, end flag per segment + vector<BufferView<char>> vertexAttribs; //!< user buffers + int tessellationRate; //!< tessellation rate for flat curve + float maxRadiusScale = 1.0; //!< maximal min-width scaling of curve radii + }; + + namespace isa + { + + template<template<typename Ty> class Curve> + struct CurveGeometryInterface : public CurveGeometry + { + typedef Curve<Vec3ff> Curve3ff; + typedef Curve<Vec3fa> Curve3fa; + + CurveGeometryInterface (Device* device, Geometry::GType gtype) + : CurveGeometry(device,gtype) {} + + __forceinline const Curve3ff getCurveScaledRadius(size_t i, size_t itime = 0) const + { + const unsigned int index = curve(i); + Vec3ff v0 = vertex(index+0,itime); + Vec3ff v1 = vertex(index+1,itime); + Vec3ff v2 = vertex(index+2,itime); + Vec3ff v3 = vertex(index+3,itime); + v0.w *= maxRadiusScale; + v1.w *= maxRadiusScale; + v2.w *= maxRadiusScale; + v3.w *= maxRadiusScale; + return Curve3ff (v0,v1,v2,v3); + } + + __forceinline const Curve3ff getCurveScaledRadius(const LinearSpace3fa& space, size_t i, size_t itime = 0) const + { + const unsigned int index = curve(i); + const Vec3ff v0 = vertex(index+0,itime); + const Vec3ff v1 = vertex(index+1,itime); + const Vec3ff v2 = vertex(index+2,itime); + const Vec3ff v3 = vertex(index+3,itime); + const Vec3ff w0(xfmPoint(space,(Vec3fa)v0), maxRadiusScale*v0.w); + const Vec3ff w1(xfmPoint(space,(Vec3fa)v1), maxRadiusScale*v1.w); + const Vec3ff w2(xfmPoint(space,(Vec3fa)v2), maxRadiusScale*v2.w); + const Vec3ff w3(xfmPoint(space,(Vec3fa)v3), maxRadiusScale*v3.w); + return Curve3ff(w0,w1,w2,w3); + } + + __forceinline const Curve3ff getCurveScaledRadius(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const + { + const float r_scale = r_scale0*scale; + const unsigned int index = curve(i); + const Vec3ff v0 = vertex(index+0,itime); + const Vec3ff v1 = vertex(index+1,itime); + const Vec3ff v2 = vertex(index+2,itime); + const Vec3ff v3 = vertex(index+3,itime); + const Vec3ff w0(xfmPoint(space,((Vec3fa)v0-ofs)*Vec3fa(scale)), maxRadiusScale*v0.w*r_scale); + const Vec3ff w1(xfmPoint(space,((Vec3fa)v1-ofs)*Vec3fa(scale)), maxRadiusScale*v1.w*r_scale); + const Vec3ff w2(xfmPoint(space,((Vec3fa)v2-ofs)*Vec3fa(scale)), maxRadiusScale*v2.w*r_scale); + const Vec3ff w3(xfmPoint(space,((Vec3fa)v3-ofs)*Vec3fa(scale)), maxRadiusScale*v3.w*r_scale); + return Curve3ff(w0,w1,w2,w3); + } + + __forceinline const Curve3fa getNormalCurve(size_t i, size_t itime = 0) const + { + const unsigned int index = curve(i); + const Vec3fa n0 = normal(index+0,itime); + const Vec3fa n1 = normal(index+1,itime); + const Vec3fa n2 = normal(index+2,itime); + const Vec3fa n3 = normal(index+3,itime); + return Curve3fa (n0,n1,n2,n3); + } + + __forceinline const TensorLinearCubicBezierSurface3fa getOrientedCurveScaledRadius(size_t i, size_t itime = 0) const + { + const Curve3ff center = getCurveScaledRadius(i,itime); + const Curve3fa normal = getNormalCurve(i,itime); + const TensorLinearCubicBezierSurface3fa ocurve = TensorLinearCubicBezierSurface3fa::fromCenterAndNormalCurve(center,normal); + return ocurve; + } + + __forceinline const TensorLinearCubicBezierSurface3fa getOrientedCurveScaledRadius(const LinearSpace3fa& space, size_t i, size_t itime = 0) const { + return getOrientedCurveScaledRadius(i,itime).xfm(space); + } + + __forceinline const TensorLinearCubicBezierSurface3fa getOrientedCurveScaledRadius(const Vec3fa& ofs, const float scale, const LinearSpace3fa& space, size_t i, size_t itime = 0) const { + return getOrientedCurveScaledRadius(i,itime).xfm(space,ofs,scale); + } + + /*! check if the i'th primitive is valid at the itime'th time step */ + __forceinline bool valid(Geometry::GType ctype, size_t i, const range<size_t>& itime_range) const + { + const unsigned int index = curve(i); + if (index+3 >= numVertices()) return false; + + for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++) + { + const float r0 = radius(index+0,itime); + const float r1 = radius(index+1,itime); + const float r2 = radius(index+2,itime); + const float r3 = radius(index+3,itime); + if (!isvalid(r0) || !isvalid(r1) || !isvalid(r2) || !isvalid(r3)) + return false; + + const Vec3fa v0 = vertex(index+0,itime); + const Vec3fa v1 = vertex(index+1,itime); + const Vec3fa v2 = vertex(index+2,itime); + const Vec3fa v3 = vertex(index+3,itime); + if (!isvalid(v0) || !isvalid(v1) || !isvalid(v2) || !isvalid(v3)) + return false; + + if (ctype == Geometry::GTY_SUBTYPE_ORIENTED_CURVE) + { + const Vec3fa n0 = normal(index+0,itime); + const Vec3fa n1 = normal(index+1,itime); + if (!isvalid(n0) || !isvalid(n1)) + return false; + } + } + + return true; + } + + template<int N> + void interpolate_impl(const RTCInterpolateArguments* const args) + { + unsigned int primID = args->primID; + float u = args->u; + RTCBufferType bufferType = args->bufferType; + unsigned int bufferSlot = args->bufferSlot; + float* P = args->P; + float* dPdu = args->dPdu; + float* ddPdudu = args->ddPdudu; + unsigned int valueCount = args->valueCount; + + /* calculate base pointer and stride */ + assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) || + (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size())); + const char* src = nullptr; + size_t stride = 0; + if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) { + src = vertexAttribs[bufferSlot].getPtr(); + stride = vertexAttribs[bufferSlot].getStride(); + } else { + src = vertices[bufferSlot].getPtr(); + stride = vertices[bufferSlot].getStride(); + } + + for (unsigned int i=0; i<valueCount; i+=N) + { + size_t ofs = i*sizeof(float); + const size_t index = curves[primID]; + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>((int)valueCount); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[(index+0)*stride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[(index+1)*stride+ofs]); + const vfloat<N> p2 = mem<vfloat<N>>::loadu(valid,(float*)&src[(index+2)*stride+ofs]); + const vfloat<N> p3 = mem<vfloat<N>>::loadu(valid,(float*)&src[(index+3)*stride+ofs]); + + const Curve<vfloat<N>> curve(p0,p1,p2,p3); + if (P ) mem<vfloat<N>>::storeu(valid,P+i, curve.eval(u)); + if (dPdu ) mem<vfloat<N>>::storeu(valid,dPdu+i, curve.eval_du(u)); + if (ddPdudu) mem<vfloat<N>>::storeu(valid,ddPdudu+i,curve.eval_dudu(u)); + } + } + + void interpolate(const RTCInterpolateArguments* const args) { + interpolate_impl<4>(args); + } + }; + + template<template<typename Ty> class Curve> + struct HermiteCurveGeometryInterface : public CurveGeometry + { + typedef Curve<Vec3ff> HermiteCurve3ff; + typedef Curve<Vec3fa> HermiteCurve3fa; + + HermiteCurveGeometryInterface (Device* device, Geometry::GType gtype) + : CurveGeometry(device,gtype) {} + + __forceinline const HermiteCurve3ff getCurveScaledRadius(size_t i, size_t itime = 0) const + { + const unsigned int index = curve(i); + Vec3ff v0 = vertex(index+0,itime); + Vec3ff v1 = vertex(index+1,itime); + Vec3ff t0 = tangent(index+0,itime); + Vec3ff t1 = tangent(index+1,itime); + v0.w *= maxRadiusScale; + v1.w *= maxRadiusScale; + t0.w *= maxRadiusScale; + t1.w *= maxRadiusScale; + return HermiteCurve3ff (v0,t0,v1,t1); + } + + __forceinline const HermiteCurve3ff getCurveScaledRadius(const LinearSpace3fa& space, size_t i, size_t itime = 0) const + { + const unsigned int index = curve(i); + const Vec3ff v0 = vertex(index+0,itime); + const Vec3ff v1 = vertex(index+1,itime); + const Vec3ff t0 = tangent(index+0,itime); + const Vec3ff t1 = tangent(index+1,itime); + const Vec3ff V0(xfmPoint(space,(Vec3fa)v0),maxRadiusScale*v0.w); + const Vec3ff V1(xfmPoint(space,(Vec3fa)v1),maxRadiusScale*v1.w); + const Vec3ff T0(xfmVector(space,(Vec3fa)t0),maxRadiusScale*t0.w); + const Vec3ff T1(xfmVector(space,(Vec3fa)t1),maxRadiusScale*t1.w); + return HermiteCurve3ff(V0,T0,V1,T1); + } + + __forceinline const HermiteCurve3ff getCurveScaledRadius(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const + { + const float r_scale = r_scale0*scale; + const unsigned int index = curve(i); + const Vec3ff v0 = vertex(index+0,itime); + const Vec3ff v1 = vertex(index+1,itime); + const Vec3ff t0 = tangent(index+0,itime); + const Vec3ff t1 = tangent(index+1,itime); + const Vec3ff V0(xfmPoint(space,(v0-ofs)*Vec3fa(scale)), maxRadiusScale*v0.w*r_scale); + const Vec3ff V1(xfmPoint(space,(v1-ofs)*Vec3fa(scale)), maxRadiusScale*v1.w*r_scale); + const Vec3ff T0(xfmVector(space,t0*Vec3fa(scale)), maxRadiusScale*t0.w*r_scale); + const Vec3ff T1(xfmVector(space,t1*Vec3fa(scale)), maxRadiusScale*t1.w*r_scale); + return HermiteCurve3ff(V0,T0,V1,T1); + } + + __forceinline const HermiteCurve3fa getNormalCurve(size_t i, size_t itime = 0) const + { + const unsigned int index = curve(i); + const Vec3fa n0 = normal(index+0,itime); + const Vec3fa n1 = normal(index+1,itime); + const Vec3fa dn0 = dnormal(index+0,itime); + const Vec3fa dn1 = dnormal(index+1,itime); + return HermiteCurve3fa (n0,dn0,n1,dn1); + } + + __forceinline const TensorLinearCubicBezierSurface3fa getOrientedCurveScaledRadius(size_t i, size_t itime = 0) const + { + const HermiteCurve3ff center = getCurveScaledRadius(i,itime); + const HermiteCurve3fa normal = getNormalCurve(i,itime); + const TensorLinearCubicBezierSurface3fa ocurve = TensorLinearCubicBezierSurface3fa::fromCenterAndNormalCurve(center,normal); + return ocurve; + } + + __forceinline const TensorLinearCubicBezierSurface3fa getOrientedCurveScaledRadius(const LinearSpace3fa& space, size_t i, size_t itime = 0) const { + return getOrientedCurveScaledRadius(i,itime).xfm(space); + } + + __forceinline const TensorLinearCubicBezierSurface3fa getOrientedCurveScaledRadius(const Vec3fa& ofs, const float scale, const LinearSpace3fa& space, size_t i, size_t itime = 0) const { + return getOrientedCurveScaledRadius(i,itime).xfm(space,ofs,scale); + } + + /*! check if the i'th primitive is valid at the itime'th time step */ + __forceinline bool valid(Geometry::GType ctype, size_t i, const range<size_t>& itime_range) const + { + const unsigned int index = curve(i); + if (index+1 >= numVertices()) return false; + + for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++) + { + const Vec3ff v0 = vertex(index+0,itime); + const Vec3ff v1 = vertex(index+1,itime); + if (!isvalid4(v0) || !isvalid4(v1)) + return false; + + const Vec3ff t0 = tangent(index+0,itime); + const Vec3ff t1 = tangent(index+1,itime); + if (!isvalid4(t0) || !isvalid4(t1)) + return false; + + if (ctype == Geometry::GTY_SUBTYPE_ORIENTED_CURVE) + { + const Vec3fa n0 = normal(index+0,itime); + const Vec3fa n1 = normal(index+1,itime); + if (!isvalid(n0) || !isvalid(n1)) + return false; + + const Vec3fa dn0 = dnormal(index+0,itime); + const Vec3fa dn1 = dnormal(index+1,itime); + if (!isvalid(dn0) || !isvalid(dn1)) + return false; + } + } + + return true; + } + + template<int N> + void interpolate_impl(const RTCInterpolateArguments* const args) + { + unsigned int primID = args->primID; + float u = args->u; + RTCBufferType bufferType = args->bufferType; + unsigned int bufferSlot = args->bufferSlot; + float* P = args->P; + float* dPdu = args->dPdu; + float* ddPdudu = args->ddPdudu; + unsigned int valueCount = args->valueCount; + + /* we interpolate vertex attributes linearly for hermite basis */ + if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) + { + assert(bufferSlot <= vertexAttribs.size()); + const char* vsrc = vertexAttribs[bufferSlot].getPtr(); + const size_t vstride = vertexAttribs[bufferSlot].getStride(); + + for (unsigned int i=0; i<valueCount; i+=N) + { + const size_t ofs = i*sizeof(float); + const size_t index = curves[primID]; + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>((int)valueCount); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&vsrc[(index+0)*vstride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&vsrc[(index+1)*vstride+ofs]); + + if (P ) mem<vfloat<N>>::storeu(valid,P+i, madd(1.0f-u,p0,u*p1)); + if (dPdu ) mem<vfloat<N>>::storeu(valid,dPdu+i, p1-p0); + if (ddPdudu) mem<vfloat<N>>::storeu(valid,ddPdudu+i,vfloat<N>(zero)); + } + } + + /* interpolation for vertex buffers */ + else + { + assert(bufferSlot < numTimeSteps); + const char* vsrc = vertices[bufferSlot].getPtr(); + const char* tsrc = tangents[bufferSlot].getPtr(); + const size_t vstride = vertices[bufferSlot].getStride(); + const size_t tstride = vertices[bufferSlot].getStride(); + + for (unsigned int i=0; i<valueCount; i+=N) + { + const size_t ofs = i*sizeof(float); + const size_t index = curves[primID]; + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>((int)valueCount); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&vsrc[(index+0)*vstride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&vsrc[(index+1)*vstride+ofs]); + const vfloat<N> t0 = mem<vfloat<N>>::loadu(valid,(float*)&tsrc[(index+0)*tstride+ofs]); + const vfloat<N> t1 = mem<vfloat<N>>::loadu(valid,(float*)&tsrc[(index+1)*tstride+ofs]); + + const HermiteCurveT<vfloat<N>> curve(p0,t0,p1,t1); + if (P ) mem<vfloat<N>>::storeu(valid,P+i, curve.eval(u)); + if (dPdu ) mem<vfloat<N>>::storeu(valid,dPdu+i, curve.eval_du(u)); + if (ddPdudu) mem<vfloat<N>>::storeu(valid,ddPdudu+i,curve.eval_dudu(u)); + } + } + } + + void interpolate(const RTCInterpolateArguments* const args) { + interpolate_impl<4>(args); + } + }; + } + + DECLARE_ISA_FUNCTION(CurveGeometry*, createCurves, Device* COMMA Geometry::GType); +} diff --git a/thirdparty/embree-aarch64/kernels/common/scene_grid_mesh.h b/thirdparty/embree/kernels/common/scene_grid_mesh.h index c08658466a..fb6fed445b 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_grid_mesh.h +++ b/thirdparty/embree/kernels/common/scene_grid_mesh.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -55,8 +55,87 @@ namespace embree void commit(); bool verify(); void interpolate(const RTCInterpolateArguments* const args); - void addElementsToCount (GeometryCounts & counts) const; + template<int N> + void interpolate_impl(const RTCInterpolateArguments* const args) + { + unsigned int primID = args->primID; + float U = args->u; + float V = args->v; + + /* clamp input u,v to [0;1] range */ + U = max(min(U,1.0f),0.0f); + V = max(min(V,1.0f),0.0f); + + RTCBufferType bufferType = args->bufferType; + unsigned int bufferSlot = args->bufferSlot; + float* P = args->P; + float* dPdu = args->dPdu; + float* dPdv = args->dPdv; + float* ddPdudu = args->ddPdudu; + float* ddPdvdv = args->ddPdvdv; + float* ddPdudv = args->ddPdudv; + unsigned int valueCount = args->valueCount; + + /* calculate base pointer and stride */ + assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) || + (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size())); + const char* src = nullptr; + size_t stride = 0; + if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) { + src = vertexAttribs[bufferSlot].getPtr(); + stride = vertexAttribs[bufferSlot].getStride(); + } else { + src = vertices[bufferSlot].getPtr(); + stride = vertices[bufferSlot].getStride(); + } + + const Grid& grid = grids[primID]; + const int grid_width = grid.resX-1; + const int grid_height = grid.resY-1; + const float rcp_grid_width = rcp(float(grid_width)); + const float rcp_grid_height = rcp(float(grid_height)); + const int iu = min((int)floor(U*grid_width ),grid_width); + const int iv = min((int)floor(V*grid_height),grid_height); + const float u = U*grid_width-float(iu); + const float v = V*grid_height-float(iv); + + for (unsigned int i=0; i<valueCount; i+=N) + { + const size_t ofs = i*sizeof(float); + const unsigned int idx0 = grid.startVtxID + (iv+0)*grid.lineVtxOffset + iu; + const unsigned int idx1 = grid.startVtxID + (iv+1)*grid.lineVtxOffset + iu; + + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount)); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[(idx0+0)*stride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[(idx0+1)*stride+ofs]); + const vfloat<N> p2 = mem<vfloat<N>>::loadu(valid,(float*)&src[(idx1+1)*stride+ofs]); + const vfloat<N> p3 = mem<vfloat<N>>::loadu(valid,(float*)&src[(idx1+0)*stride+ofs]); + const vbool<N> left = u+v <= 1.0f; + const vfloat<N> Q0 = select(left,p0,p2); + const vfloat<N> Q1 = select(left,p1,p3); + const vfloat<N> Q2 = select(left,p3,p1); + const vfloat<N> U = select(left,u,vfloat<N>(1.0f)-u); + const vfloat<N> V = select(left,v,vfloat<N>(1.0f)-v); + const vfloat<N> W = 1.0f-U-V; + + if (P) { + mem<vfloat<N>>::storeu(valid,P+i,madd(W,Q0,madd(U,Q1,V*Q2))); + } + if (dPdu) { + assert(dPdu); mem<vfloat<N>>::storeu(valid,dPdu+i,select(left,Q1-Q0,Q0-Q1)*rcp_grid_width); + assert(dPdv); mem<vfloat<N>>::storeu(valid,dPdv+i,select(left,Q2-Q0,Q0-Q2)*rcp_grid_height); + } + if (ddPdudu) { + assert(ddPdudu); mem<vfloat<N>>::storeu(valid,ddPdudu+i,vfloat<N>(zero)); + assert(ddPdvdv); mem<vfloat<N>>::storeu(valid,ddPdvdv+i,vfloat<N>(zero)); + assert(ddPdudv); mem<vfloat<N>>::storeu(valid,ddPdudv+i,vfloat<N>(zero)); + } + } + } + + void addElementsToCount (GeometryCounts & counts) const; + __forceinline unsigned int getNumSubGrids(const size_t gridID) { const Grid &g = grid(gridID); diff --git a/thirdparty/embree-aarch64/kernels/common/scene_instance.h b/thirdparty/embree/kernels/common/scene_instance.h index 7ff82a4fb8..773f2b6fec 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_instance.h +++ b/thirdparty/embree/kernels/common/scene_instance.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -150,8 +150,8 @@ namespace embree __forceinline AffineSpace3vf<K> getWorld2Local(const vbool<K>& valid, const vfloat<K>& t) const { if (unlikely(gsubtype == GTY_SUBTYPE_INSTANCE_QUATERNION)) - return getWorld2LocalSlerp(valid, t); - return getWorld2LocalLerp(valid, t); + return getWorld2LocalSlerp<K>(valid, t); + return getWorld2LocalLerp<K>(valid, t); } private: @@ -160,7 +160,7 @@ namespace embree __forceinline AffineSpace3vf<K> getWorld2LocalSlerp(const vbool<K>& valid, const vfloat<K>& t) const { vfloat<K> ftime; - const vint<K> itime_k = timeSegment(t, ftime); + const vint<K> itime_k = timeSegment<K>(t, ftime); assert(any(valid)); const size_t index = bsf(movemask(valid)); const int itime = itime_k[index]; @@ -186,7 +186,7 @@ namespace embree __forceinline AffineSpace3vf<K> getWorld2LocalLerp(const vbool<K>& valid, const vfloat<K>& t) const { vfloat<K> ftime; - const vint<K> itime_k = timeSegment(t, ftime); + const vint<K> itime_k = timeSegment<K>(t, ftime); assert(any(valid)); const size_t index = bsf(movemask(valid)); const int itime = itime_k[index]; diff --git a/thirdparty/embree-aarch64/kernels/common/scene_line_segments.h b/thirdparty/embree/kernels/common/scene_line_segments.h index c0f9ee8f77..3c9fdb39db 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_line_segments.h +++ b/thirdparty/embree/kernels/common/scene_line_segments.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -34,6 +34,44 @@ namespace embree void setMaxRadiusScale(float s); void addElementsToCount (GeometryCounts & counts) const; + template<int N> + void interpolate_impl(const RTCInterpolateArguments* const args) + { + unsigned int primID = args->primID; + float u = args->u; + RTCBufferType bufferType = args->bufferType; + unsigned int bufferSlot = args->bufferSlot; + float* P = args->P; + float* dPdu = args->dPdu; + float* ddPdudu = args->ddPdudu; + unsigned int valueCount = args->valueCount; + + /* calculate base pointer and stride */ + assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) || + (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size())); + const char* src = nullptr; + size_t stride = 0; + if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) { + src = vertexAttribs[bufferSlot].getPtr(); + stride = vertexAttribs[bufferSlot].getStride(); + } else { + src = vertices[bufferSlot].getPtr(); + stride = vertices[bufferSlot].getStride(); + } + + for (unsigned int i=0; i<valueCount; i+=N) + { + const size_t ofs = i*sizeof(float); + const size_t segment = segments[primID]; + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount)); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[(segment+0)*stride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[(segment+1)*stride+ofs]); + if (P ) mem<vfloat<N>>::storeu(valid,P+i,lerp(p0,p1,u)); + if (dPdu ) mem<vfloat<N>>::storeu(valid,dPdu+i,p1-p0); + if (ddPdudu) mem<vfloat<N>>::storeu(valid,dPdu+i,vfloat<N>(zero)); + } + } + public: /*! returns the number of vertices */ diff --git a/thirdparty/embree-aarch64/kernels/common/scene_points.h b/thirdparty/embree/kernels/common/scene_points.h index 1d39ed07ba..017e098a51 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_points.h +++ b/thirdparty/embree/kernels/common/scene_points.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/scene_quad_mesh.h b/thirdparty/embree/kernels/common/scene_quad_mesh.h index d5bb054b14..bd8eeaaeb7 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_quad_mesh.h +++ b/thirdparty/embree/kernels/common/scene_quad_mesh.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,6 +43,66 @@ namespace embree void interpolate(const RTCInterpolateArguments* const args); void addElementsToCount (GeometryCounts & counts) const; + template<int N> + void interpolate_impl(const RTCInterpolateArguments* const args) + { + unsigned int primID = args->primID; + float u = args->u; + float v = args->v; + RTCBufferType bufferType = args->bufferType; + unsigned int bufferSlot = args->bufferSlot; + float* P = args->P; + float* dPdu = args->dPdu; + float* dPdv = args->dPdv; + float* ddPdudu = args->ddPdudu; + float* ddPdvdv = args->ddPdvdv; + float* ddPdudv = args->ddPdudv; + unsigned int valueCount = args->valueCount; + + /* calculate base pointer and stride */ + assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) || + (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size())); + const char* src = nullptr; + size_t stride = 0; + if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) { + src = vertexAttribs[bufferSlot].getPtr(); + stride = vertexAttribs[bufferSlot].getStride(); + } else { + src = vertices[bufferSlot].getPtr(); + stride = vertices[bufferSlot].getStride(); + } + + for (unsigned int i=0; i<valueCount; i+=N) + { + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount)); + const size_t ofs = i*sizeof(float); + const Quad& tri = quad(primID); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]); + const vfloat<N> p2 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]); + const vfloat<N> p3 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[3]*stride+ofs]); + const vbool<N> left = u+v <= 1.0f; + const vfloat<N> Q0 = select(left,p0,p2); + const vfloat<N> Q1 = select(left,p1,p3); + const vfloat<N> Q2 = select(left,p3,p1); + const vfloat<N> U = select(left,u,vfloat<N>(1.0f)-u); + const vfloat<N> V = select(left,v,vfloat<N>(1.0f)-v); + const vfloat<N> W = 1.0f-U-V; + if (P) { + mem<vfloat<N>>::storeu(valid,P+i,madd(W,Q0,madd(U,Q1,V*Q2))); + } + if (dPdu) { + assert(dPdu); mem<vfloat<N>>::storeu(valid,dPdu+i,select(left,Q1-Q0,Q0-Q1)); + assert(dPdv); mem<vfloat<N>>::storeu(valid,dPdv+i,select(left,Q2-Q0,Q0-Q2)); + } + if (ddPdudu) { + assert(ddPdudu); mem<vfloat<N>>::storeu(valid,ddPdudu+i,vfloat<N>(zero)); + assert(ddPdvdv); mem<vfloat<N>>::storeu(valid,ddPdvdv+i,vfloat<N>(zero)); + assert(ddPdudv); mem<vfloat<N>>::storeu(valid,ddPdudv+i,vfloat<N>(zero)); + } + } + } + public: /*! returns number of vertices */ diff --git a/thirdparty/embree-aarch64/kernels/common/scene_subdiv_mesh.h b/thirdparty/embree/kernels/common/scene_subdiv_mesh.h index d0246009db..1db170196d 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_subdiv_mesh.h +++ b/thirdparty/embree/kernels/common/scene_subdiv_mesh.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -275,11 +275,11 @@ namespace embree parallel_set<uint32_t> holeSet; /*! fast lookup table to detect invalid faces */ - mvector<int8_t> invalid_face; + mvector<char> invalid_face; /*! test if face i is invalid in timestep j */ - __forceinline int8_t& invalidFace(size_t i, size_t j = 0) { return invalid_face[i*numTimeSteps+j]; } - __forceinline const int8_t& invalidFace(size_t i, size_t j = 0) const { return invalid_face[i*numTimeSteps+j]; } + __forceinline char& invalidFace(size_t i, size_t j = 0) { return invalid_face[i*numTimeSteps+j]; } + __forceinline const char& invalidFace(size_t i, size_t j = 0) const { return invalid_face[i*numTimeSteps+j]; } /*! interpolation cache */ public: diff --git a/thirdparty/embree-aarch64/kernels/common/scene_triangle_mesh.cpp b/thirdparty/embree/kernels/common/scene_triangle_mesh.cpp index d1c2750f14..3bbd7e51ae 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_triangle_mesh.cpp +++ b/thirdparty/embree/kernels/common/scene_triangle_mesh.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "scene_triangle_mesh.h" @@ -178,62 +178,13 @@ namespace embree return true; } - - void TriangleMesh::interpolate(const RTCInterpolateArguments* const args) - { - unsigned int primID = args->primID; - float u = args->u; - float v = args->v; - RTCBufferType bufferType = args->bufferType; - unsigned int bufferSlot = args->bufferSlot; - float* P = args->P; - float* dPdu = args->dPdu; - float* dPdv = args->dPdv; - float* ddPdudu = args->ddPdudu; - float* ddPdvdv = args->ddPdvdv; - float* ddPdudv = args->ddPdudv; - unsigned int valueCount = args->valueCount; - - /* calculate base pointer and stride */ - assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) || - (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size())); - const char* src = nullptr; - size_t stride = 0; - if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) { - src = vertexAttribs[bufferSlot].getPtr(); - stride = vertexAttribs[bufferSlot].getStride(); - } else { - src = vertices[bufferSlot].getPtr(); - stride = vertices[bufferSlot].getStride(); - } - - for (unsigned int i=0; i<valueCount; i+=4) - { - size_t ofs = i*sizeof(float); - const float w = 1.0f-u-v; - const Triangle& tri = triangle(primID); - const vbool4 valid = vint4((int)i)+vint4(step) < vint4(int(valueCount)); - const vfloat4 p0 = vfloat4::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]); - const vfloat4 p1 = vfloat4::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]); - const vfloat4 p2 = vfloat4::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]); - - if (P) { - vfloat4::storeu(valid,P+i,madd(w,p0,madd(u,p1,v*p2))); - } - if (dPdu) { - assert(dPdu); vfloat4::storeu(valid,dPdu+i,p1-p0); - assert(dPdv); vfloat4::storeu(valid,dPdv+i,p2-p0); - } - if (ddPdudu) { - assert(ddPdudu); vfloat4::storeu(valid,ddPdudu+i,vfloat4(zero)); - assert(ddPdvdv); vfloat4::storeu(valid,ddPdvdv+i,vfloat4(zero)); - assert(ddPdudv); vfloat4::storeu(valid,ddPdudv+i,vfloat4(zero)); - } - } + + void TriangleMesh::interpolate(const RTCInterpolateArguments* const args) { + interpolate_impl<4>(args); } - + #endif - + namespace isa { TriangleMesh* createTriangleMesh(Device* device) { diff --git a/thirdparty/embree-aarch64/kernels/common/scene_triangle_mesh.h b/thirdparty/embree/kernels/common/scene_triangle_mesh.h index eaf2e1799a..ad3f602fde 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_triangle_mesh.h +++ b/thirdparty/embree/kernels/common/scene_triangle_mesh.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,8 +43,62 @@ namespace embree void interpolate(const RTCInterpolateArguments* const args); void addElementsToCount (GeometryCounts & counts) const; + template<int N> + void interpolate_impl(const RTCInterpolateArguments* const args) + { + unsigned int primID = args->primID; + float u = args->u; + float v = args->v; + RTCBufferType bufferType = args->bufferType; + unsigned int bufferSlot = args->bufferSlot; + float* P = args->P; + float* dPdu = args->dPdu; + float* dPdv = args->dPdv; + float* ddPdudu = args->ddPdudu; + float* ddPdvdv = args->ddPdvdv; + float* ddPdudv = args->ddPdudv; + unsigned int valueCount = args->valueCount; + + /* calculate base pointer and stride */ + assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) || + (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size())); + const char* src = nullptr; + size_t stride = 0; + if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) { + src = vertexAttribs[bufferSlot].getPtr(); + stride = vertexAttribs[bufferSlot].getStride(); + } else { + src = vertices[bufferSlot].getPtr(); + stride = vertices[bufferSlot].getStride(); + } + + for (unsigned int i=0; i<valueCount; i+=N) + { + size_t ofs = i*sizeof(float); + const float w = 1.0f-u-v; + const Triangle& tri = triangle(primID); + const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount)); + const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]); + const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]); + const vfloat<N> p2 = mem<vfloat<N>>::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]); + + if (P) { + mem<vfloat<N>>::storeu(valid,P+i,madd(w,p0,madd(u,p1,v*p2))); + } + if (dPdu) { + assert(dPdu); mem<vfloat<N>>::storeu(valid,dPdu+i,p1-p0); + assert(dPdv); mem<vfloat<N>>::storeu(valid,dPdv+i,p2-p0); + } + if (ddPdudu) { + assert(ddPdudu); mem<vfloat<N>>::storeu(valid,ddPdudu+i,vfloat<N>(zero)); + assert(ddPdvdv); mem<vfloat<N>>::storeu(valid,ddPdvdv+i,vfloat<N>(zero)); + assert(ddPdudv); mem<vfloat<N>>::storeu(valid,ddPdudv+i,vfloat<N>(zero)); + } + } + } + public: - + /*! returns number of vertices */ __forceinline size_t numVertices() const { return vertices[0].size(); diff --git a/thirdparty/embree-aarch64/kernels/common/scene_user_geometry.h b/thirdparty/embree/kernels/common/scene_user_geometry.h index 8d11ed6986..2867b18b79 100644 --- a/thirdparty/embree-aarch64/kernels/common/scene_user_geometry.h +++ b/thirdparty/embree/kernels/common/scene_user_geometry.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/stack_item.h b/thirdparty/embree/kernels/common/stack_item.h index 533c385365..c31c64e862 100644 --- a/thirdparty/embree-aarch64/kernels/common/stack_item.h +++ b/thirdparty/embree/kernels/common/stack_item.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/stat.cpp b/thirdparty/embree/kernels/common/stat.cpp index b73c3a8c76..ebb77cd534 100644 --- a/thirdparty/embree-aarch64/kernels/common/stat.cpp +++ b/thirdparty/embree/kernels/common/stat.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "stat.h" diff --git a/thirdparty/embree-aarch64/kernels/common/stat.h b/thirdparty/embree/kernels/common/stat.h index 3cda2bd014..02fc07e67f 100644 --- a/thirdparty/embree-aarch64/kernels/common/stat.h +++ b/thirdparty/embree/kernels/common/stat.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/common/state.cpp b/thirdparty/embree/kernels/common/state.cpp index 51fc9b7826..01c862da0c 100644 --- a/thirdparty/embree-aarch64/kernels/common/state.cpp +++ b/thirdparty/embree/kernels/common/state.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "state.h" @@ -100,7 +100,6 @@ namespace embree instancing_open_max_depth = 32; instancing_open_max = 50000000; - ignore_config_files = false; float_exceptions = false; quality_flags = -1; scene_flags = -1; @@ -115,8 +114,6 @@ namespace embree #else set_affinity = false; #endif - /* per default enable affinity on KNL */ - if (hasISA(AVX512KNL)) set_affinity = true; start_threads = false; enable_selockmemoryprivilege = false; @@ -147,20 +144,7 @@ namespace embree } bool State::checkISASupport() { -#if defined(__ARM_NEON) - /* - * NEON CPU type is a mixture of NEON and SSE2 - */ - - bool hasSSE2 = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_SSE2; - - /* this will be true when explicitly initialize Device with `isa=neon` config */ - bool hasNEON = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_NEON; - - return hasSSE2 || hasNEON; -#else return (getCPUFeatures() & enabled_cpu_features) == enabled_cpu_features; -#endif } void State::verify() @@ -173,10 +157,8 @@ namespace embree * functions */ #if defined(DEBUG) #if defined(EMBREE_TARGET_SSE2) -#if !defined(__ARM_NEON) assert(sse2::getISA() <= SSE2); #endif -#endif #if defined(EMBREE_TARGET_SSE42) assert(sse42::getISA() <= SSE42); #endif @@ -186,11 +168,8 @@ namespace embree #if defined(EMBREE_TARGET_AVX2) assert(avx2::getISA() <= AVX2); #endif -#if defined (EMBREE_TARGET_AVX512KNL) - assert(avx512knl::getISA() <= AVX512KNL); -#endif -#if defined (EMBREE_TARGET_AVX512SKX) - assert(avx512skx::getISA() <= AVX512SKX); +#if defined (EMBREE_TARGET_AVX512) + assert(avx512::getISA() <= AVX512); #endif #endif } @@ -241,8 +220,7 @@ namespace embree else if (isa == "avx") return AVX; else if (isa == "avxi") return AVXI; else if (isa == "avx2") return AVX2; - else if (isa == "avx512knl") return AVX512KNL; - else if (isa == "avx512skx") return AVX512SKX; + else if (isa == "avx512") return AVX512; else return SSE2; } @@ -269,20 +247,20 @@ namespace embree start_threads = cin->get().Int(); else if (tok == Token::Id("isa") && cin->trySymbol("=")) { - std::string isa = toLowerCase(cin->get().Identifier()); - enabled_cpu_features = string_to_cpufeatures(isa); + std::string isa_str = toLowerCase(cin->get().Identifier()); + enabled_cpu_features = string_to_cpufeatures(isa_str); enabled_builder_cpu_features = enabled_cpu_features; } else if (tok == Token::Id("max_isa") && cin->trySymbol("=")) { - std::string isa = toLowerCase(cin->get().Identifier()); - enabled_cpu_features &= string_to_cpufeatures(isa); + std::string isa_str = toLowerCase(cin->get().Identifier()); + enabled_cpu_features &= string_to_cpufeatures(isa_str); enabled_builder_cpu_features &= enabled_cpu_features; } else if (tok == Token::Id("max_builder_isa") && cin->trySymbol("=")) { - std::string isa = toLowerCase(cin->get().Identifier()); - enabled_builder_cpu_features &= string_to_cpufeatures(isa); + std::string isa_str = toLowerCase(cin->get().Identifier()); + enabled_builder_cpu_features &= string_to_cpufeatures(isa_str); } else if (tok == Token::Id("frequency_level") && cin->trySymbol("=")) { @@ -299,8 +277,6 @@ namespace embree hugepages = cin->get().Int(); } - else if (tok == Token::Id("ignore_config_files") && cin->trySymbol("=")) - ignore_config_files = cin->get().Int(); else if (tok == Token::Id("float_exceptions") && cin->trySymbol("=")) float_exceptions = cin->get().Int(); diff --git a/thirdparty/embree-aarch64/kernels/common/state.h b/thirdparty/embree/kernels/common/state.h index d0fccc023f..33bcc843b2 100644 --- a/thirdparty/embree-aarch64/kernels/common/state.h +++ b/thirdparty/embree/kernels/common/state.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -118,7 +118,6 @@ namespace embree size_t instancing_open_max; //!< instancing opens tree to maximally that number of subtrees public: - bool ignore_config_files; //!< if true no more config files get parse bool float_exceptions; //!< enable floating point exceptions int quality_flags; int scene_flags; diff --git a/thirdparty/embree-aarch64/kernels/common/vector.h b/thirdparty/embree/kernels/common/vector.h index b478762240..4b08275f3b 100644 --- a/thirdparty/embree-aarch64/kernels/common/vector.h +++ b/thirdparty/embree/kernels/common/vector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "default.h" diff --git a/thirdparty/embree-aarch64/kernels/config.h b/thirdparty/embree/kernels/config.h index 80a8ab2a56..80a8ab2a56 100644 --- a/thirdparty/embree-aarch64/kernels/config.h +++ b/thirdparty/embree/kernels/config.h diff --git a/thirdparty/embree-aarch64/kernels/geometry/cone.h b/thirdparty/embree/kernels/geometry/cone.h index 961ef86160..17429bab32 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/cone.h +++ b/thirdparty/embree/kernels/geometry/cone.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/coneline_intersector.h b/thirdparty/embree/kernels/geometry/coneline_intersector.h index 0902baff7d..90f3792eff 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/coneline_intersector.h +++ b/thirdparty/embree/kernels/geometry/coneline_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -169,9 +169,9 @@ namespace embree const Vec3vf<M> ray_org(ray.org.x, ray.org.y, ray.org.z); const Vec3vf<M> ray_dir(ray.dir.x, ray.dir.y, ray.dir.z); const vfloat<M> ray_tnear(ray.tnear()); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); - const Vec4vf<M> v1 = enlargeRadiusToMinWidth(context,geom,ray_org,v1i); - return __coneline_internal::intersectCone(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray),v0,v1,cL,cR,epilog); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); + const Vec4vf<M> v1 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v1i); + return __coneline_internal::intersectCone<M>(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray),v0,v1,cL,cR,epilog); } }; @@ -200,9 +200,9 @@ namespace embree const Vec3vf<M> ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]); const Vec3vf<M> ray_dir(ray.dir.x[k], ray.dir.y[k], ray.dir.z[k]); const vfloat<M> ray_tnear = ray.tnear()[k]; - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); - const Vec4vf<M> v1 = enlargeRadiusToMinWidth(context,geom,ray_org,v1i); - return __coneline_internal::intersectCone(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray,k),v0,v1,cL,cR,epilog); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); + const Vec4vf<M> v1 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v1i); + return __coneline_internal::intersectCone<M>(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray,k),v0,v1,cL,cR,epilog); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/conelinei_intersector.h b/thirdparty/embree/kernels/geometry/conelinei_intersector.h index d47218eb8b..6a985ebcad 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/conelinei_intersector.h +++ b/thirdparty/embree/kernels/geometry/conelinei_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -10,7 +10,7 @@ namespace embree { namespace isa { - template<int M, int Mx, bool filter> + template<int M, bool filter> struct ConeCurveMiIntersector1 { typedef LineMi<M> Primitive; @@ -23,8 +23,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - ConeCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Intersect1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + ConeCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Intersect1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& line) @@ -34,8 +34,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - return ConeCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Occluded1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return ConeCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Occluded1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); return false; } @@ -45,7 +45,7 @@ namespace embree } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct ConeCurveMiMBIntersector1 { typedef LineMi<M> Primitive; @@ -58,8 +58,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom,ray.time()); - const vbool<Mx> valid = line.template valid<Mx>(); - ConeCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Intersect1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + ConeCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Intersect1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& line) @@ -69,8 +69,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom,ray.time()); - const vbool<Mx> valid = line.template valid<Mx>(); - return ConeCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Occluded1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return ConeCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,cL,cR,Occluded1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); return false; } @@ -80,7 +80,7 @@ namespace embree } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct ConeCurveMiIntersectorK { typedef LineMi<M> Primitive; @@ -93,8 +93,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - ConeCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + ConeCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Intersect1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& line) @@ -104,12 +104,12 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - return ConeCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return ConeCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Occluded1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct ConeCurveMiMBIntersectorK { typedef LineMi<M> Primitive; @@ -122,8 +122,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom,ray.time()[k]); - const vbool<Mx> valid = line.template valid<Mx>(); - ConeCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + ConeCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Intersect1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& line) @@ -133,8 +133,8 @@ namespace embree Vec4vf<M> v0,v1; vbool<M> cL,cR; line.gather(v0,v1,cL,cR,geom,ray.time()[k]); - const vbool<Mx> valid = line.template valid<Mx>(); - return ConeCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return ConeCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,cL,cR,Occluded1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/curveNi.h b/thirdparty/embree/kernels/geometry/curveNi.h index 51384f1959..6366a6fb9c 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curveNi.h +++ b/thirdparty/embree/kernels/geometry/curveNi.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,10 +43,10 @@ namespace embree __forceinline void fill(const PrimRef* prims, size_t& begin, size_t _end, Scene* scene) { size_t end = min(begin+M,_end); - N = (uint8_t)(end-begin); + N = (unsigned char)(end-begin); const unsigned int geomID0 = prims[begin].geomID(); this->geomID(N) = geomID0; - ty = (uint8_t) scene->get(geomID0)->getType(); + ty = (unsigned char) scene->get(geomID0)->getType(); /* encode all primitives */ BBox3fa bounds = empty; @@ -76,25 +76,25 @@ namespace embree const LinearSpace3fa space3(trunc(126.0f*space2.vx),trunc(126.0f*space2.vy),trunc(126.0f*space2.vz)); const BBox3fa bounds = scene->get(geomID)->vbounds(loffset,lscale,max(length(space3.vx),length(space3.vy),length(space3.vz)),space3.transposed(),primID); - bounds_vx_x(N)[i] = (int8_t) space3.vx.x; - bounds_vx_y(N)[i] = (int8_t) space3.vx.y; - bounds_vx_z(N)[i] = (int8_t) space3.vx.z; + bounds_vx_x(N)[i] = (char) space3.vx.x; + bounds_vx_y(N)[i] = (char) space3.vx.y; + bounds_vx_z(N)[i] = (char) space3.vx.z; bounds_vx_lower(N)[i] = (short) clamp(floor(bounds.lower.x),-32767.0f,32767.0f); bounds_vx_upper(N)[i] = (short) clamp(ceil (bounds.upper.x),-32767.0f,32767.0f); assert(-32767.0f <= floor(bounds.lower.x) && floor(bounds.lower.x) <= 32767.0f); assert(-32767.0f <= ceil (bounds.upper.x) && ceil (bounds.upper.x) <= 32767.0f); - bounds_vy_x(N)[i] = (int8_t) space3.vy.x; - bounds_vy_y(N)[i] = (int8_t) space3.vy.y; - bounds_vy_z(N)[i] = (int8_t) space3.vy.z; + bounds_vy_x(N)[i] = (char) space3.vy.x; + bounds_vy_y(N)[i] = (char) space3.vy.y; + bounds_vy_z(N)[i] = (char) space3.vy.z; bounds_vy_lower(N)[i] = (short) clamp(floor(bounds.lower.y),-32767.0f,32767.0f); bounds_vy_upper(N)[i] = (short) clamp(ceil (bounds.upper.y),-32767.0f,32767.0f); assert(-32767.0f <= floor(bounds.lower.y) && floor(bounds.lower.y) <= 32767.0f); assert(-32767.0f <= ceil (bounds.upper.y) && ceil (bounds.upper.y) <= 32767.0f); - bounds_vz_x(N)[i] = (int8_t) space3.vz.x; - bounds_vz_y(N)[i] = (int8_t) space3.vz.y; - bounds_vz_z(N)[i] = (int8_t) space3.vz.z; + bounds_vz_x(N)[i] = (char) space3.vz.x; + bounds_vz_y(N)[i] = (char) space3.vz.y; + bounds_vz_z(N)[i] = (char) space3.vz.z; bounds_vz_lower(N)[i] = (short) clamp(floor(bounds.lower.z),-32767.0f,32767.0f); bounds_vz_upper(N)[i] = (short) clamp(ceil (bounds.upper.z),-32767.0f,32767.0f); assert(-32767.0f <= floor(bounds.lower.z) && floor(bounds.lower.z) <= 32767.0f); @@ -114,15 +114,15 @@ namespace embree for (size_t i=0; i<items; i++) { accel[i].fill(prims,start,set.end(),bvh->scene); } - return bvh->encodeLeaf((int8_t*)accel,items); + return bvh->encodeLeaf((char*)accel,items); }; public: // 27.6 - 46 bytes per primitive - uint8_t ty; - uint8_t N; - uint8_t data[4+25*M+16]; + unsigned char ty; + unsigned char N; + unsigned char data[4+25*M+16]; /* struct Layout @@ -130,21 +130,21 @@ namespace embree unsigned int geomID; unsigned int primID[N]; - int8_t bounds_vx_x[N]; - int8_t bounds_vx_y[N]; - int8_t bounds_vx_z[N]; + char bounds_vx_x[N]; + char bounds_vx_y[N]; + char bounds_vx_z[N]; short bounds_vx_lower[N]; short bounds_vx_upper[N]; - int8_t bounds_vy_x[N]; - int8_t bounds_vy_y[N]; - int8_t bounds_vy_z[N]; + char bounds_vy_x[N]; + char bounds_vy_y[N]; + char bounds_vy_z[N]; short bounds_vy_lower[N]; short bounds_vy_upper[N]; - int8_t bounds_vz_x[N]; - int8_t bounds_vz_y[N]; - int8_t bounds_vz_z[N]; + char bounds_vz_x[N]; + char bounds_vz_y[N]; + char bounds_vz_z[N]; short bounds_vz_lower[N]; short bounds_vz_upper[N]; @@ -153,65 +153,65 @@ namespace embree }; */ - __forceinline unsigned int& geomID(size_t N) { return *(unsigned int*)((int8_t*)this+2); } - __forceinline const unsigned int& geomID(size_t N) const { return *(unsigned int*)((int8_t*)this+2); } + __forceinline unsigned int& geomID(size_t N) { return *(unsigned int*)((char*)this+2); } + __forceinline const unsigned int& geomID(size_t N) const { return *(unsigned int*)((char*)this+2); } - __forceinline unsigned int* primID(size_t N) { return (unsigned int*)((int8_t*)this+6); } - __forceinline const unsigned int* primID(size_t N) const { return (unsigned int*)((int8_t*)this+6); } + __forceinline unsigned int* primID(size_t N) { return (unsigned int*)((char*)this+6); } + __forceinline const unsigned int* primID(size_t N) const { return (unsigned int*)((char*)this+6); } - __forceinline int8_t* bounds_vx_x(size_t N) { return (int8_t*)((int8_t*)this+6+4*N); } - __forceinline const int8_t* bounds_vx_x(size_t N) const { return (int8_t*)((int8_t*)this+6+4*N); } + __forceinline char* bounds_vx_x(size_t N) { return (char*)((char*)this+6+4*N); } + __forceinline const char* bounds_vx_x(size_t N) const { return (char*)((char*)this+6+4*N); } - __forceinline int8_t* bounds_vx_y(size_t N) { return (int8_t*)((int8_t*)this+6+5*N); } - __forceinline const int8_t* bounds_vx_y(size_t N) const { return (int8_t*)((int8_t*)this+6+5*N); } + __forceinline char* bounds_vx_y(size_t N) { return (char*)((char*)this+6+5*N); } + __forceinline const char* bounds_vx_y(size_t N) const { return (char*)((char*)this+6+5*N); } - __forceinline int8_t* bounds_vx_z(size_t N) { return (int8_t*)((int8_t*)this+6+6*N); } - __forceinline const int8_t* bounds_vx_z(size_t N) const { return (int8_t*)((int8_t*)this+6+6*N); } + __forceinline char* bounds_vx_z(size_t N) { return (char*)((char*)this+6+6*N); } + __forceinline const char* bounds_vx_z(size_t N) const { return (char*)((char*)this+6+6*N); } - __forceinline short* bounds_vx_lower(size_t N) { return (short*)((int8_t*)this+6+7*N); } - __forceinline const short* bounds_vx_lower(size_t N) const { return (short*)((int8_t*)this+6+7*N); } + __forceinline short* bounds_vx_lower(size_t N) { return (short*)((char*)this+6+7*N); } + __forceinline const short* bounds_vx_lower(size_t N) const { return (short*)((char*)this+6+7*N); } - __forceinline short* bounds_vx_upper(size_t N) { return (short*)((int8_t*)this+6+9*N); } - __forceinline const short* bounds_vx_upper(size_t N) const { return (short*)((int8_t*)this+6+9*N); } + __forceinline short* bounds_vx_upper(size_t N) { return (short*)((char*)this+6+9*N); } + __forceinline const short* bounds_vx_upper(size_t N) const { return (short*)((char*)this+6+9*N); } - __forceinline int8_t* bounds_vy_x(size_t N) { return (int8_t*)((int8_t*)this+6+11*N); } - __forceinline const int8_t* bounds_vy_x(size_t N) const { return (int8_t*)((int8_t*)this+6+11*N); } + __forceinline char* bounds_vy_x(size_t N) { return (char*)((char*)this+6+11*N); } + __forceinline const char* bounds_vy_x(size_t N) const { return (char*)((char*)this+6+11*N); } - __forceinline int8_t* bounds_vy_y(size_t N) { return (int8_t*)((int8_t*)this+6+12*N); } - __forceinline const int8_t* bounds_vy_y(size_t N) const { return (int8_t*)((int8_t*)this+6+12*N); } + __forceinline char* bounds_vy_y(size_t N) { return (char*)((char*)this+6+12*N); } + __forceinline const char* bounds_vy_y(size_t N) const { return (char*)((char*)this+6+12*N); } - __forceinline int8_t* bounds_vy_z(size_t N) { return (int8_t*)((int8_t*)this+6+13*N); } - __forceinline const int8_t* bounds_vy_z(size_t N) const { return (int8_t*)((int8_t*)this+6+13*N); } + __forceinline char* bounds_vy_z(size_t N) { return (char*)((char*)this+6+13*N); } + __forceinline const char* bounds_vy_z(size_t N) const { return (char*)((char*)this+6+13*N); } - __forceinline short* bounds_vy_lower(size_t N) { return (short*)((int8_t*)this+6+14*N); } - __forceinline const short* bounds_vy_lower(size_t N) const { return (short*)((int8_t*)this+6+14*N); } + __forceinline short* bounds_vy_lower(size_t N) { return (short*)((char*)this+6+14*N); } + __forceinline const short* bounds_vy_lower(size_t N) const { return (short*)((char*)this+6+14*N); } - __forceinline short* bounds_vy_upper(size_t N) { return (short*)((int8_t*)this+6+16*N); } - __forceinline const short* bounds_vy_upper(size_t N) const { return (short*)((int8_t*)this+6+16*N); } + __forceinline short* bounds_vy_upper(size_t N) { return (short*)((char*)this+6+16*N); } + __forceinline const short* bounds_vy_upper(size_t N) const { return (short*)((char*)this+6+16*N); } - __forceinline int8_t* bounds_vz_x(size_t N) { return (int8_t*)((int8_t*)this+6+18*N); } - __forceinline const int8_t* bounds_vz_x(size_t N) const { return (int8_t*)((int8_t*)this+6+18*N); } + __forceinline char* bounds_vz_x(size_t N) { return (char*)((char*)this+6+18*N); } + __forceinline const char* bounds_vz_x(size_t N) const { return (char*)((char*)this+6+18*N); } - __forceinline int8_t* bounds_vz_y(size_t N) { return (int8_t*)((int8_t*)this+6+19*N); } - __forceinline const int8_t* bounds_vz_y(size_t N) const { return (int8_t*)((int8_t*)this+6+19*N); } + __forceinline char* bounds_vz_y(size_t N) { return (char*)((char*)this+6+19*N); } + __forceinline const char* bounds_vz_y(size_t N) const { return (char*)((char*)this+6+19*N); } - __forceinline int8_t* bounds_vz_z(size_t N) { return (int8_t*)((int8_t*)this+6+20*N); } - __forceinline const int8_t* bounds_vz_z(size_t N) const { return (int8_t*)((int8_t*)this+6+20*N); } + __forceinline char* bounds_vz_z(size_t N) { return (char*)((char*)this+6+20*N); } + __forceinline const char* bounds_vz_z(size_t N) const { return (char*)((char*)this+6+20*N); } - __forceinline short* bounds_vz_lower(size_t N) { return (short*)((int8_t*)this+6+21*N); } - __forceinline const short* bounds_vz_lower(size_t N) const { return (short*)((int8_t*)this+6+21*N); } + __forceinline short* bounds_vz_lower(size_t N) { return (short*)((char*)this+6+21*N); } + __forceinline const short* bounds_vz_lower(size_t N) const { return (short*)((char*)this+6+21*N); } - __forceinline short* bounds_vz_upper(size_t N) { return (short*)((int8_t*)this+6+23*N); } - __forceinline const short* bounds_vz_upper(size_t N) const { return (short*)((int8_t*)this+6+23*N); } + __forceinline short* bounds_vz_upper(size_t N) { return (short*)((char*)this+6+23*N); } + __forceinline const short* bounds_vz_upper(size_t N) const { return (short*)((char*)this+6+23*N); } - __forceinline Vec3f* offset(size_t N) { return (Vec3f*)((int8_t*)this+6+25*N); } - __forceinline const Vec3f* offset(size_t N) const { return (Vec3f*)((int8_t*)this+6+25*N); } + __forceinline Vec3f* offset(size_t N) { return (Vec3f*)((char*)this+6+25*N); } + __forceinline const Vec3f* offset(size_t N) const { return (Vec3f*)((char*)this+6+25*N); } - __forceinline float* scale(size_t N) { return (float*)((int8_t*)this+6+25*N+12); } - __forceinline const float* scale(size_t N) const { return (float*)((int8_t*)this+6+25*N+12); } + __forceinline float* scale(size_t N) { return (float*)((char*)this+6+25*N+12); } + __forceinline const float* scale(size_t N) const { return (float*)((char*)this+6+25*N+12); } - __forceinline int8_t* end(size_t N) { return (int8_t*)this+6+25*N+16; } - __forceinline const int8_t* end(size_t N) const { return (int8_t*)this+6+25*N+16; } + __forceinline char* end(size_t N) { return (char*)this+6+25*N+16; } + __forceinline const char* end(size_t N) const { return (char*)this+6+25*N+16; } }; template<int M> diff --git a/thirdparty/embree-aarch64/kernels/geometry/curveNi_intersector.h b/thirdparty/embree/kernels/geometry/curveNi_intersector.h index 0f9038c9fc..c0b66515c1 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curveNi_intersector.h +++ b/thirdparty/embree/kernels/geometry/curveNi_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curveNi_mb.h b/thirdparty/embree/kernels/geometry/curveNi_mb.h index 0cd8f833fd..5d972b43a0 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curveNi_mb.h +++ b/thirdparty/embree/kernels/geometry/curveNi_mb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,10 +43,10 @@ namespace embree __forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t _end, Scene* scene, const BBox1f time_range) { size_t end = min(begin+M,_end); - N = (uint8_t)(end-begin); + N = (unsigned char)(end-begin); const unsigned int geomID0 = prims[begin].geomID(); this->geomID(N) = geomID0; - ty = (uint8_t) scene->get(geomID0)->getType(); + ty = (unsigned char) scene->get(geomID0)->getType(); /* encode all primitives */ LBBox3fa lbounds = empty; @@ -79,10 +79,10 @@ namespace embree const LinearSpace3fa space3(trunc(126.0f*space2.vx),trunc(126.0f*space2.vy),trunc(126.0f*space2.vz)); const LBBox3fa bounds = scene->get(geomID)->vlinearBounds(loffset,lscale,max(length(space3.vx),length(space3.vy),length(space3.vz)),space3.transposed(),primID,time_range); - // NOTE: this weird (int8_t) (short) cast works around VS2015 Win32 compiler bug - bounds_vx_x(N)[i] = (int8_t) (short) space3.vx.x; - bounds_vx_y(N)[i] = (int8_t) (short) space3.vx.y; - bounds_vx_z(N)[i] = (int8_t) (short) space3.vx.z; + // NOTE: this weird (char) (short) cast works around VS2015 Win32 compiler bug + bounds_vx_x(N)[i] = (char) (short) space3.vx.x; + bounds_vx_y(N)[i] = (char) (short) space3.vx.y; + bounds_vx_z(N)[i] = (char) (short) space3.vx.z; bounds_vx_lower0(N)[i] = (short) clamp(floor(bounds.bounds0.lower.x),-32767.0f,32767.0f); bounds_vx_upper0(N)[i] = (short) clamp(ceil (bounds.bounds0.upper.x),-32767.0f,32767.0f); bounds_vx_lower1(N)[i] = (short) clamp(floor(bounds.bounds1.lower.x),-32767.0f,32767.0f); @@ -92,9 +92,9 @@ namespace embree assert(-32767.0f <= floor(bounds.bounds1.lower.x) && floor(bounds.bounds1.lower.x) <= 32767.0f); assert(-32767.0f <= ceil (bounds.bounds1.upper.x) && ceil (bounds.bounds1.upper.x) <= 32767.0f); - bounds_vy_x(N)[i] = (int8_t) (short) space3.vy.x; - bounds_vy_y(N)[i] = (int8_t) (short) space3.vy.y; - bounds_vy_z(N)[i] = (int8_t) (short) space3.vy.z; + bounds_vy_x(N)[i] = (char) (short) space3.vy.x; + bounds_vy_y(N)[i] = (char) (short) space3.vy.y; + bounds_vy_z(N)[i] = (char) (short) space3.vy.z; bounds_vy_lower0(N)[i] = (short) clamp(floor(bounds.bounds0.lower.y),-32767.0f,32767.0f); bounds_vy_upper0(N)[i] = (short) clamp(ceil (bounds.bounds0.upper.y),-32767.0f,32767.0f); bounds_vy_lower1(N)[i] = (short) clamp(floor(bounds.bounds1.lower.y),-32767.0f,32767.0f); @@ -104,9 +104,9 @@ namespace embree assert(-32767.0f <= floor(bounds.bounds1.lower.y) && floor(bounds.bounds1.lower.y) <= 32767.0f); assert(-32767.0f <= ceil (bounds.bounds1.upper.y) && ceil (bounds.bounds1.upper.y) <= 32767.0f); - bounds_vz_x(N)[i] = (int8_t) (short) space3.vz.x; - bounds_vz_y(N)[i] = (int8_t) (short) space3.vz.y; - bounds_vz_z(N)[i] = (int8_t) (short) space3.vz.z; + bounds_vz_x(N)[i] = (char) (short) space3.vz.x; + bounds_vz_y(N)[i] = (char) (short) space3.vz.y; + bounds_vz_z(N)[i] = (char) (short) space3.vz.z; bounds_vz_lower0(N)[i] = (short) clamp(floor(bounds.bounds0.lower.z),-32767.0f,32767.0f); bounds_vz_upper0(N)[i] = (short) clamp(ceil (bounds.bounds0.upper.z),-32767.0f,32767.0f); bounds_vz_lower1(N)[i] = (short) clamp(floor(bounds.bounds1.lower.z),-32767.0f,32767.0f); @@ -130,7 +130,7 @@ namespace embree size_t items = CurveNiMB::blocks(prims.size()); size_t numbytes = CurveNiMB::bytes(prims.size()); CurveNiMB* accel = (CurveNiMB*) alloc.malloc1(numbytes,BVH::byteAlignment); - const typename BVH::NodeRef node = bvh->encodeLeaf((int8_t*)accel,items); + const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel,items); LBBox3fa bounds = empty; for (size_t i=0; i<items; i++) @@ -143,9 +143,9 @@ namespace embree public: // 27.6 - 46 bytes per primitive - uint8_t ty; - uint8_t N; - uint8_t data[4+37*M+24]; + unsigned char ty; + unsigned char N; + unsigned char data[4+37*M+24]; /* struct Layout @@ -153,25 +153,25 @@ namespace embree unsigned int geomID; unsigned int primID[N]; - int8_t bounds_vx_x[N]; - int8_t bounds_vx_y[N]; - int8_t bounds_vx_z[N]; + char bounds_vx_x[N]; + char bounds_vx_y[N]; + char bounds_vx_z[N]; short bounds_vx_lower0[N]; short bounds_vx_upper0[N]; short bounds_vx_lower1[N]; short bounds_vx_upper1[N]; - int8_t bounds_vy_x[N]; - int8_t bounds_vy_y[N]; - int8_t bounds_vy_z[N]; + char bounds_vy_x[N]; + char bounds_vy_y[N]; + char bounds_vy_z[N]; short bounds_vy_lower0[N]; short bounds_vy_upper0[N]; short bounds_vy_lower1[N]; short bounds_vy_upper1[N]; - int8_t bounds_vz_x[N]; - int8_t bounds_vz_y[N]; - int8_t bounds_vz_z[N]; + char bounds_vz_x[N]; + char bounds_vz_y[N]; + char bounds_vz_z[N]; short bounds_vz_lower0[N]; short bounds_vz_upper0[N]; short bounds_vz_lower1[N]; @@ -185,89 +185,89 @@ namespace embree }; */ - __forceinline unsigned int& geomID(size_t N) { return *(unsigned int*)((int8_t*)this+2); } - __forceinline const unsigned int& geomID(size_t N) const { return *(unsigned int*)((int8_t*)this+2); } + __forceinline unsigned int& geomID(size_t N) { return *(unsigned int*)((char*)this+2); } + __forceinline const unsigned int& geomID(size_t N) const { return *(unsigned int*)((char*)this+2); } - __forceinline unsigned int* primID(size_t N) { return (unsigned int*)((int8_t*)this+6); } - __forceinline const unsigned int* primID(size_t N) const { return (unsigned int*)((int8_t*)this+6); } + __forceinline unsigned int* primID(size_t N) { return (unsigned int*)((char*)this+6); } + __forceinline const unsigned int* primID(size_t N) const { return (unsigned int*)((char*)this+6); } - __forceinline int8_t* bounds_vx_x(size_t N) { return (int8_t*)((int8_t*)this+6+4*N); } - __forceinline const int8_t* bounds_vx_x(size_t N) const { return (int8_t*)((int8_t*)this+6+4*N); } + __forceinline char* bounds_vx_x(size_t N) { return (char*)((char*)this+6+4*N); } + __forceinline const char* bounds_vx_x(size_t N) const { return (char*)((char*)this+6+4*N); } - __forceinline int8_t* bounds_vx_y(size_t N) { return (int8_t*)((int8_t*)this+6+5*N); } - __forceinline const int8_t* bounds_vx_y(size_t N) const { return (int8_t*)((int8_t*)this+6+5*N); } + __forceinline char* bounds_vx_y(size_t N) { return (char*)((char*)this+6+5*N); } + __forceinline const char* bounds_vx_y(size_t N) const { return (char*)((char*)this+6+5*N); } - __forceinline int8_t* bounds_vx_z(size_t N) { return (int8_t*)((int8_t*)this+6+6*N); } - __forceinline const int8_t* bounds_vx_z(size_t N) const { return (int8_t*)((int8_t*)this+6+6*N); } + __forceinline char* bounds_vx_z(size_t N) { return (char*)((char*)this+6+6*N); } + __forceinline const char* bounds_vx_z(size_t N) const { return (char*)((char*)this+6+6*N); } - __forceinline short* bounds_vx_lower0(size_t N) { return (short*)((int8_t*)this+6+7*N); } - __forceinline const short* bounds_vx_lower0(size_t N) const { return (short*)((int8_t*)this+6+7*N); } + __forceinline short* bounds_vx_lower0(size_t N) { return (short*)((char*)this+6+7*N); } + __forceinline const short* bounds_vx_lower0(size_t N) const { return (short*)((char*)this+6+7*N); } - __forceinline short* bounds_vx_upper0(size_t N) { return (short*)((int8_t*)this+6+9*N); } - __forceinline const short* bounds_vx_upper0(size_t N) const { return (short*)((int8_t*)this+6+9*N); } + __forceinline short* bounds_vx_upper0(size_t N) { return (short*)((char*)this+6+9*N); } + __forceinline const short* bounds_vx_upper0(size_t N) const { return (short*)((char*)this+6+9*N); } - __forceinline short* bounds_vx_lower1(size_t N) { return (short*)((int8_t*)this+6+11*N); } - __forceinline const short* bounds_vx_lower1(size_t N) const { return (short*)((int8_t*)this+6+11*N); } + __forceinline short* bounds_vx_lower1(size_t N) { return (short*)((char*)this+6+11*N); } + __forceinline const short* bounds_vx_lower1(size_t N) const { return (short*)((char*)this+6+11*N); } - __forceinline short* bounds_vx_upper1(size_t N) { return (short*)((int8_t*)this+6+13*N); } - __forceinline const short* bounds_vx_upper1(size_t N) const { return (short*)((int8_t*)this+6+13*N); } + __forceinline short* bounds_vx_upper1(size_t N) { return (short*)((char*)this+6+13*N); } + __forceinline const short* bounds_vx_upper1(size_t N) const { return (short*)((char*)this+6+13*N); } - __forceinline int8_t* bounds_vy_x(size_t N) { return (int8_t*)((int8_t*)this+6+15*N); } - __forceinline const int8_t* bounds_vy_x(size_t N) const { return (int8_t*)((int8_t*)this+6+15*N); } + __forceinline char* bounds_vy_x(size_t N) { return (char*)((char*)this+6+15*N); } + __forceinline const char* bounds_vy_x(size_t N) const { return (char*)((char*)this+6+15*N); } - __forceinline int8_t* bounds_vy_y(size_t N) { return (int8_t*)((int8_t*)this+6+16*N); } - __forceinline const int8_t* bounds_vy_y(size_t N) const { return (int8_t*)((int8_t*)this+6+16*N); } + __forceinline char* bounds_vy_y(size_t N) { return (char*)((char*)this+6+16*N); } + __forceinline const char* bounds_vy_y(size_t N) const { return (char*)((char*)this+6+16*N); } - __forceinline int8_t* bounds_vy_z(size_t N) { return (int8_t*)((int8_t*)this+6+17*N); } - __forceinline const int8_t* bounds_vy_z(size_t N) const { return (int8_t*)((int8_t*)this+6+17*N); } + __forceinline char* bounds_vy_z(size_t N) { return (char*)((char*)this+6+17*N); } + __forceinline const char* bounds_vy_z(size_t N) const { return (char*)((char*)this+6+17*N); } - __forceinline short* bounds_vy_lower0(size_t N) { return (short*)((int8_t*)this+6+18*N); } - __forceinline const short* bounds_vy_lower0(size_t N) const { return (short*)((int8_t*)this+6+18*N); } + __forceinline short* bounds_vy_lower0(size_t N) { return (short*)((char*)this+6+18*N); } + __forceinline const short* bounds_vy_lower0(size_t N) const { return (short*)((char*)this+6+18*N); } - __forceinline short* bounds_vy_upper0(size_t N) { return (short*)((int8_t*)this+6+20*N); } - __forceinline const short* bounds_vy_upper0(size_t N) const { return (short*)((int8_t*)this+6+20*N); } + __forceinline short* bounds_vy_upper0(size_t N) { return (short*)((char*)this+6+20*N); } + __forceinline const short* bounds_vy_upper0(size_t N) const { return (short*)((char*)this+6+20*N); } - __forceinline short* bounds_vy_lower1(size_t N) { return (short*)((int8_t*)this+6+22*N); } - __forceinline const short* bounds_vy_lower1(size_t N) const { return (short*)((int8_t*)this+6+22*N); } + __forceinline short* bounds_vy_lower1(size_t N) { return (short*)((char*)this+6+22*N); } + __forceinline const short* bounds_vy_lower1(size_t N) const { return (short*)((char*)this+6+22*N); } - __forceinline short* bounds_vy_upper1(size_t N) { return (short*)((int8_t*)this+6+24*N); } - __forceinline const short* bounds_vy_upper1(size_t N) const { return (short*)((int8_t*)this+6+24*N); } + __forceinline short* bounds_vy_upper1(size_t N) { return (short*)((char*)this+6+24*N); } + __forceinline const short* bounds_vy_upper1(size_t N) const { return (short*)((char*)this+6+24*N); } - __forceinline int8_t* bounds_vz_x(size_t N) { return (int8_t*)((int8_t*)this+6+26*N); } - __forceinline const int8_t* bounds_vz_x(size_t N) const { return (int8_t*)((int8_t*)this+6+26*N); } + __forceinline char* bounds_vz_x(size_t N) { return (char*)((char*)this+6+26*N); } + __forceinline const char* bounds_vz_x(size_t N) const { return (char*)((char*)this+6+26*N); } - __forceinline int8_t* bounds_vz_y(size_t N) { return (int8_t*)((int8_t*)this+6+27*N); } - __forceinline const int8_t* bounds_vz_y(size_t N) const { return (int8_t*)((int8_t*)this+6+27*N); } + __forceinline char* bounds_vz_y(size_t N) { return (char*)((char*)this+6+27*N); } + __forceinline const char* bounds_vz_y(size_t N) const { return (char*)((char*)this+6+27*N); } - __forceinline int8_t* bounds_vz_z(size_t N) { return (int8_t*)((int8_t*)this+6+28*N); } - __forceinline const int8_t* bounds_vz_z(size_t N) const { return (int8_t*)((int8_t*)this+6+28*N); } + __forceinline char* bounds_vz_z(size_t N) { return (char*)((char*)this+6+28*N); } + __forceinline const char* bounds_vz_z(size_t N) const { return (char*)((char*)this+6+28*N); } - __forceinline short* bounds_vz_lower0(size_t N) { return (short*)((int8_t*)this+6+29*N); } - __forceinline const short* bounds_vz_lower0(size_t N) const { return (short*)((int8_t*)this+6+29*N); } + __forceinline short* bounds_vz_lower0(size_t N) { return (short*)((char*)this+6+29*N); } + __forceinline const short* bounds_vz_lower0(size_t N) const { return (short*)((char*)this+6+29*N); } - __forceinline short* bounds_vz_upper0(size_t N) { return (short*)((int8_t*)this+6+31*N); } - __forceinline const short* bounds_vz_upper0(size_t N) const { return (short*)((int8_t*)this+6+31*N); } + __forceinline short* bounds_vz_upper0(size_t N) { return (short*)((char*)this+6+31*N); } + __forceinline const short* bounds_vz_upper0(size_t N) const { return (short*)((char*)this+6+31*N); } - __forceinline short* bounds_vz_lower1(size_t N) { return (short*)((int8_t*)this+6+33*N); } - __forceinline const short* bounds_vz_lower1(size_t N) const { return (short*)((int8_t*)this+6+33*N); } + __forceinline short* bounds_vz_lower1(size_t N) { return (short*)((char*)this+6+33*N); } + __forceinline const short* bounds_vz_lower1(size_t N) const { return (short*)((char*)this+6+33*N); } - __forceinline short* bounds_vz_upper1(size_t N) { return (short*)((int8_t*)this+6+35*N); } - __forceinline const short* bounds_vz_upper1(size_t N) const { return (short*)((int8_t*)this+6+35*N); } + __forceinline short* bounds_vz_upper1(size_t N) { return (short*)((char*)this+6+35*N); } + __forceinline const short* bounds_vz_upper1(size_t N) const { return (short*)((char*)this+6+35*N); } - __forceinline Vec3f* offset(size_t N) { return (Vec3f*)((int8_t*)this+6+37*N); } - __forceinline const Vec3f* offset(size_t N) const { return (Vec3f*)((int8_t*)this+6+37*N); } + __forceinline Vec3f* offset(size_t N) { return (Vec3f*)((char*)this+6+37*N); } + __forceinline const Vec3f* offset(size_t N) const { return (Vec3f*)((char*)this+6+37*N); } - __forceinline float* scale(size_t N) { return (float*)((int8_t*)this+6+37*N+12); } - __forceinline const float* scale(size_t N) const { return (float*)((int8_t*)this+6+37*N+12); } + __forceinline float* scale(size_t N) { return (float*)((char*)this+6+37*N+12); } + __forceinline const float* scale(size_t N) const { return (float*)((char*)this+6+37*N+12); } - __forceinline float& time_offset(size_t N) { return *(float*)((int8_t*)this+6+37*N+16); } - __forceinline const float& time_offset(size_t N) const { return *(float*)((int8_t*)this+6+37*N+16); } + __forceinline float& time_offset(size_t N) { return *(float*)((char*)this+6+37*N+16); } + __forceinline const float& time_offset(size_t N) const { return *(float*)((char*)this+6+37*N+16); } - __forceinline float& time_scale(size_t N) { return *(float*)((int8_t*)this+6+37*N+20); } - __forceinline const float& time_scale(size_t N) const { return *(float*)((int8_t*)this+6+37*N+20); } + __forceinline float& time_scale(size_t N) { return *(float*)((char*)this+6+37*N+20); } + __forceinline const float& time_scale(size_t N) const { return *(float*)((char*)this+6+37*N+20); } - __forceinline int8_t* end(size_t N) { return (int8_t*)this+6+37*N+24; } - __forceinline const int8_t* end(size_t N) const { return (int8_t*)this+6+37*N+24; } + __forceinline char* end(size_t N) { return (char*)this+6+37*N+24; } + __forceinline const char* end(size_t N) const { return (char*)this+6+37*N+24; } }; template<int M> diff --git a/thirdparty/embree-aarch64/kernels/geometry/curveNi_mb_intersector.h b/thirdparty/embree/kernels/geometry/curveNi_mb_intersector.h index 0cbc764668..bab796b33b 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curveNi_mb_intersector.h +++ b/thirdparty/embree/kernels/geometry/curveNi_mb_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curveNv.h b/thirdparty/embree/kernels/geometry/curveNv.h index 6eb5e30b39..e41a381706 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curveNv.h +++ b/thirdparty/embree/kernels/geometry/curveNv.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curveNv_intersector.h b/thirdparty/embree/kernels/geometry/curveNv_intersector.h index e20da2882e..2742725aec 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curveNv_intersector.h +++ b/thirdparty/embree/kernels/geometry/curveNv_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector.h b/thirdparty/embree/kernels/geometry/curve_intersector.h index 204958f7cc..1e8ac26125 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -23,8 +23,8 @@ namespace embree typedef unsigned char Primitive; typedef CurvePrecalculations1 Precalculations; - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { assert(num == 1); RTCGeometryType ty = (RTCGeometryType)(*prim); @@ -33,8 +33,8 @@ namespace embree leafIntersector.intersect<1>(&pre,&ray,context,prim); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { assert(num == 1); RTCGeometryType ty = (RTCGeometryType)(*prim); diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_distance.h b/thirdparty/embree/kernels/geometry/curve_intersector_distance.h index 343cc8ff28..748a9511a5 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_distance.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_distance.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_oriented.h b/thirdparty/embree/kernels/geometry/curve_intersector_oriented.h index 47531027fc..3d8900c2aa 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_oriented.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_oriented.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_precalculations.h b/thirdparty/embree/kernels/geometry/curve_intersector_precalculations.h index 6e9fc91925..de6b70be1b 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_precalculations.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_precalculations.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_ribbon.h b/thirdparty/embree/kernels/geometry/curve_intersector_ribbon.h index a99cf99d56..c3272e99fd 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_ribbon.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_ribbon.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -32,9 +32,11 @@ namespace embree __forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); } __forceinline float t (const size_t i) const { return vt[i]; } - __forceinline Vec3fa Ng(const size_t i) const { - return curve3D.eval_du(vu[i]); - } + __forceinline Vec3fa Ng(const size_t i) const { return curve3D.eval_du(vu[i]); } + + __forceinline Vec2vf<M> uv() const { return Vec2vf<M>(vu,vv); } + __forceinline vfloat<M> t () const { return vt; } + __forceinline Vec3vf<M> Ng() const { return (Vec3vf<M>) curve3D.template veval_du<M>(vu); } public: vfloat<M> U; @@ -98,7 +100,7 @@ namespace embree const Vec3vfx up1 = nmadd(p1.w,nn1,Vec3vfx(p1)); vfloatx vu,vv,vt; - vboolx valid0 = intersect_quad_backface_culling(valid,zero,Vec3fa(0,0,1),ray_tnear,ray_tfar,lp0,lp1,up1,up0,vu,vv,vt); + vboolx valid0 = intersect_quad_backface_culling<VSIZEX>(valid,zero,Vec3fa(0,0,1),ray_tnear,ray_tfar,lp0,lp1,up1,up0,vu,vv,vt); if (any(valid0)) { @@ -143,7 +145,7 @@ namespace embree const Vec3vfx up1 = nmadd(p1.w,nn1,Vec3vfx(p1)); vfloatx vu,vv,vt; - vboolx valid0 = intersect_quad_backface_culling(valid,zero,Vec3fa(0,0,1),ray_tnear,ray_tfar,lp0,lp1,up1,up0,vu,vv,vt); + vboolx valid0 = intersect_quad_backface_culling<VSIZEX>(valid,zero,Vec3fa(0,0,1),ray_tnear,ray_tfar,lp0,lp1,up1,up0,vu,vv,vt); if (any(valid0)) { diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_sweep.h b/thirdparty/embree/kernels/geometry/curve_intersector_sweep.h index 883cedc3d2..2d4abd73ac 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_sweep.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_sweep.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -137,10 +137,12 @@ namespace embree float u0, float u1, unsigned int depth, const Epilog& epilog) { #if defined(__AVX__) + enum { VSIZEX_ = 8 }; typedef vbool8 vboolx; // maximally 8-wide to work around KNL issues typedef vint8 vintx; typedef vfloat8 vfloatx; #else + enum { VSIZEX_ = 4 }; typedef vbool4 vboolx; typedef vint4 vintx; typedef vfloat4 vfloatx; @@ -192,7 +194,7 @@ namespace embree /* subdivide curve */ const float dscale = (u1-u0)*(1.0f/(3.0f*(vfloatx::size-1))); const vfloatx vu0 = lerp(u0,u1,vfloatx(step)*(1.0f/(vfloatx::size-1))); - Vec4vfx P0, dP0du; curve.veval(vu0,P0,dP0du); dP0du = dP0du * Vec4vfx(dscale); + Vec4vfx P0, dP0du; curve.template veval<VSIZEX_>(vu0,P0,dP0du); dP0du = dP0du * Vec4vfx(dscale); const Vec4vfx P3 = shift_right_1(P0); const Vec4vfx dP3du = shift_right_1(dP0du); const Vec4vfx P1 = P0 + dP0du; diff --git a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual.h b/thirdparty/embree/kernels/geometry/curve_intersector_virtual.h index e1f4238130..cffa8e46ad 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/curve_intersector_virtual.h +++ b/thirdparty/embree/kernels/geometry/curve_intersector_virtual.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -97,8 +97,8 @@ namespace embree typedef unsigned char Primitive; typedef CurvePrecalculations1 Precalculations; - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { assert(num == 1); RTCGeometryType ty = (RTCGeometryType)(*prim); @@ -107,8 +107,8 @@ namespace embree leafIntersector.intersect<1>(&pre,&ray,context,prim); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { assert(num == 1); RTCGeometryType ty = (RTCGeometryType)(*prim); @@ -152,8 +152,8 @@ namespace embree return valid_o; } - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { assert(num == 1); RTCGeometryType ty = (RTCGeometryType)(*prim); @@ -162,8 +162,8 @@ namespace embree leafIntersector.intersect<K>(&pre,&ray,k,context,prim); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { assert(num == 1); RTCGeometryType ty = (RTCGeometryType)(*prim); @@ -177,17 +177,17 @@ namespace embree static VirtualCurveIntersector::Intersectors LinearRoundConeNiIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &RoundLinearCurveMiIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &RoundLinearCurveMiIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &RoundLinearCurveMiIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &RoundLinearCurveMiIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &RoundLinearCurveMiIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &RoundLinearCurveMiIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &RoundLinearCurveMiIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &RoundLinearCurveMiIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&RoundLinearCurveMiIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &RoundLinearCurveMiIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&RoundLinearCurveMiIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &RoundLinearCurveMiIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&RoundLinearCurveMiIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &RoundLinearCurveMiIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&RoundLinearCurveMiIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &RoundLinearCurveMiIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -196,17 +196,17 @@ namespace embree static VirtualCurveIntersector::Intersectors LinearConeNiIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &ConeCurveMiIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &ConeCurveMiIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &ConeCurveMiIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &ConeCurveMiIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &ConeCurveMiIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &ConeCurveMiIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &ConeCurveMiIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &ConeCurveMiIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&ConeCurveMiIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &ConeCurveMiIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&ConeCurveMiIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &ConeCurveMiIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&ConeCurveMiIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &ConeCurveMiIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&ConeCurveMiIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &ConeCurveMiIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -215,17 +215,17 @@ namespace embree static VirtualCurveIntersector::Intersectors LinearRoundConeNiMBIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &RoundLinearCurveMiMBIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &RoundLinearCurveMiMBIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &RoundLinearCurveMiMBIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &RoundLinearCurveMiMBIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &RoundLinearCurveMiMBIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &RoundLinearCurveMiMBIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &RoundLinearCurveMiMBIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &RoundLinearCurveMiMBIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&RoundLinearCurveMiMBIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &RoundLinearCurveMiMBIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&RoundLinearCurveMiMBIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &RoundLinearCurveMiMBIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&RoundLinearCurveMiMBIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &RoundLinearCurveMiMBIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&RoundLinearCurveMiMBIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &RoundLinearCurveMiMBIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -234,17 +234,17 @@ namespace embree static VirtualCurveIntersector::Intersectors LinearConeNiMBIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &ConeCurveMiMBIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &ConeCurveMiMBIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &ConeCurveMiMBIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &ConeCurveMiMBIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &ConeCurveMiMBIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &ConeCurveMiMBIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &ConeCurveMiMBIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &ConeCurveMiMBIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&ConeCurveMiMBIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &ConeCurveMiMBIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&ConeCurveMiMBIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &ConeCurveMiMBIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&ConeCurveMiMBIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &ConeCurveMiMBIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&ConeCurveMiMBIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &ConeCurveMiMBIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -254,17 +254,17 @@ namespace embree static VirtualCurveIntersector::Intersectors LinearRibbonNiIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &FlatLinearCurveMiIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &FlatLinearCurveMiIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &FlatLinearCurveMiIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &FlatLinearCurveMiIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &FlatLinearCurveMiIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &FlatLinearCurveMiIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &FlatLinearCurveMiIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &FlatLinearCurveMiIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&FlatLinearCurveMiIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &FlatLinearCurveMiIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&FlatLinearCurveMiIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &FlatLinearCurveMiIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&FlatLinearCurveMiIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &FlatLinearCurveMiIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&FlatLinearCurveMiIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &FlatLinearCurveMiIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -273,17 +273,17 @@ namespace embree static VirtualCurveIntersector::Intersectors LinearRibbonNiMBIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &FlatLinearCurveMiMBIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &FlatLinearCurveMiMBIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &FlatLinearCurveMiMBIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &FlatLinearCurveMiMBIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &FlatLinearCurveMiMBIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &FlatLinearCurveMiMBIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &FlatLinearCurveMiMBIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &FlatLinearCurveMiMBIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&FlatLinearCurveMiMBIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &FlatLinearCurveMiMBIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&FlatLinearCurveMiMBIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &FlatLinearCurveMiMBIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&FlatLinearCurveMiMBIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &FlatLinearCurveMiMBIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&FlatLinearCurveMiMBIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &FlatLinearCurveMiMBIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -292,17 +292,17 @@ namespace embree static VirtualCurveIntersector::Intersectors SphereNiIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &SphereMiIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &SphereMiIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &SphereMiIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &SphereMiIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &SphereMiIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &SphereMiIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &SphereMiIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &SphereMiIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&SphereMiIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &SphereMiIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&SphereMiIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &SphereMiIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&SphereMiIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &SphereMiIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&SphereMiIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &SphereMiIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -311,17 +311,17 @@ namespace embree static VirtualCurveIntersector::Intersectors SphereNiMBIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &SphereMiMBIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &SphereMiMBIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &SphereMiMBIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &SphereMiMBIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &SphereMiMBIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &SphereMiMBIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &SphereMiMBIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &SphereMiMBIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&SphereMiMBIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &SphereMiMBIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&SphereMiMBIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &SphereMiMBIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&SphereMiMBIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &SphereMiMBIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&SphereMiMBIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &SphereMiMBIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -330,17 +330,17 @@ namespace embree static VirtualCurveIntersector::Intersectors DiscNiIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &DiscMiIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &DiscMiIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &DiscMiIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &DiscMiIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &DiscMiIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &DiscMiIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &DiscMiIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &DiscMiIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&DiscMiIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &DiscMiIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&DiscMiIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &DiscMiIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&DiscMiIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &DiscMiIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&DiscMiIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &DiscMiIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -349,17 +349,17 @@ namespace embree static VirtualCurveIntersector::Intersectors DiscNiMBIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &DiscMiMBIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &DiscMiMBIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &DiscMiMBIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &DiscMiMBIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &DiscMiMBIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &DiscMiMBIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &DiscMiMBIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &DiscMiMBIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&DiscMiMBIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &DiscMiMBIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&DiscMiMBIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &DiscMiMBIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&DiscMiMBIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &DiscMiMBIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&DiscMiMBIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &DiscMiMBIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -368,17 +368,17 @@ namespace embree static VirtualCurveIntersector::Intersectors OrientedDiscNiIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &OrientedDiscMiIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &OrientedDiscMiIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &OrientedDiscMiIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &OrientedDiscMiIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &OrientedDiscMiIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &OrientedDiscMiIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &OrientedDiscMiIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &OrientedDiscMiIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&OrientedDiscMiIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &OrientedDiscMiIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&OrientedDiscMiIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &OrientedDiscMiIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&OrientedDiscMiIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &OrientedDiscMiIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&OrientedDiscMiIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &OrientedDiscMiIntersectorK<N,16,true>::occluded; #endif return intersectors; } @@ -387,17 +387,17 @@ namespace embree static VirtualCurveIntersector::Intersectors OrientedDiscNiMBIntersectors() { VirtualCurveIntersector::Intersectors intersectors; - intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &OrientedDiscMiMBIntersector1<N,N,true>::intersect; - intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &OrientedDiscMiMBIntersector1<N,N,true>::occluded; - intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &OrientedDiscMiMBIntersectorK<N,N,4,true>::intersect; - intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &OrientedDiscMiMBIntersectorK<N,N,4,true>::occluded; + intersectors.intersect1 = (VirtualCurveIntersector::Intersect1Ty) &OrientedDiscMiMBIntersector1<N,true>::intersect; + intersectors.occluded1 = (VirtualCurveIntersector::Occluded1Ty) &OrientedDiscMiMBIntersector1<N,true>::occluded; + intersectors.intersect4 = (VirtualCurveIntersector::Intersect4Ty) &OrientedDiscMiMBIntersectorK<N,4,true>::intersect; + intersectors.occluded4 = (VirtualCurveIntersector::Occluded4Ty) &OrientedDiscMiMBIntersectorK<N,4,true>::occluded; #if defined(__AVX__) - intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&OrientedDiscMiMBIntersectorK<N,N,8,true>::intersect; - intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &OrientedDiscMiMBIntersectorK<N,N,8,true>::occluded; + intersectors.intersect8 = (VirtualCurveIntersector::Intersect8Ty)&OrientedDiscMiMBIntersectorK<N,8,true>::intersect; + intersectors.occluded8 = (VirtualCurveIntersector::Occluded8Ty) &OrientedDiscMiMBIntersectorK<N,8,true>::occluded; #endif #if defined(__AVX512F__) - intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&OrientedDiscMiMBIntersectorK<N,N,16,true>::intersect; - intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &OrientedDiscMiMBIntersectorK<N,N,16,true>::occluded; + intersectors.intersect16 = (VirtualCurveIntersector::Intersect16Ty)&OrientedDiscMiMBIntersectorK<N,16,true>::intersect; + intersectors.occluded16 = (VirtualCurveIntersector::Occluded16Ty) &OrientedDiscMiMBIntersectorK<N,16,true>::occluded; #endif return intersectors; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/cylinder.h b/thirdparty/embree/kernels/geometry/cylinder.h index 39a582864c..dab02989ce 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/cylinder.h +++ b/thirdparty/embree/kernels/geometry/cylinder.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/disc_intersector.h b/thirdparty/embree/kernels/geometry/disc_intersector.h index e8305780e5..816c066899 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/disc_intersector.h +++ b/thirdparty/embree/kernels/geometry/disc_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -64,7 +64,7 @@ namespace embree const Vec3vf<M> ray_dir(ray.dir.x, ray.dir.y, ray.dir.z); const vfloat<M> rd2 = rcp(dot(ray_dir, ray_dir)); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; @@ -101,7 +101,7 @@ namespace embree vbool<M> valid = valid_i; const Vec3vf<M> ray_org(ray.org.x, ray.org.y, ray.org.z); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; @@ -148,7 +148,7 @@ namespace embree const Vec3vf<M> ray_dir(ray.dir.x[k], ray.dir.y[k], ray.dir.z[k]); const vfloat<M> rd2 = rcp(dot(ray_dir, ray_dir)); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; @@ -187,7 +187,7 @@ namespace embree const Vec3vf<M> ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]); const Vec3vf<M> ray_dir(ray.dir.x[k], ray.dir.y[k], ray.dir.z[k]); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; diff --git a/thirdparty/embree-aarch64/kernels/geometry/disci_intersector.h b/thirdparty/embree/kernels/geometry/disci_intersector.h index e1dc3aa98e..bb9d396f6e 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/disci_intersector.h +++ b/thirdparty/embree/kernels/geometry/disci_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,7 +11,7 @@ namespace embree { namespace isa { - template<int M, int Mx, bool filter> + template<int M, bool filter> struct DiscMiIntersector1 { typedef PointMi<M> Primitive; @@ -25,9 +25,9 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded(const Precalculations& pre, @@ -38,13 +38,13 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + return DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct DiscMiMBIntersector1 { typedef PointMi<M> Primitive; @@ -58,9 +58,9 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom, ray.time()); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded(const Precalculations& pre, @@ -71,13 +71,13 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom, ray.time()); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + return DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct DiscMiIntersectorK { typedef PointMi<M> Primitive; @@ -89,10 +89,10 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Intersect1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Intersect1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded( @@ -101,14 +101,14 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + return DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Occluded1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Occluded1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct DiscMiMBIntersectorK { typedef PointMi<M> Primitive; @@ -120,10 +120,10 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom, ray.time()[k]); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Intersect1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Intersect1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded( @@ -132,13 +132,13 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Disc.gather(v0, geom, ray.time()[k]); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersectorK<Mx, K>::intersect( - valid, ray, k, context, geom, pre, v0, Occluded1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + return DiscIntersectorK<M, K>::intersect( + valid, ray, k, context, geom, pre, v0, Occluded1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct OrientedDiscMiIntersector1 { typedef PointMi<M> Primitive; @@ -153,9 +153,9 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, n0, Intersect1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, n0, Intersect1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded(const Precalculations& pre, @@ -167,13 +167,13 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, n0, Occluded1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + return DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, n0, Occluded1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct OrientedDiscMiMBIntersector1 { typedef PointMi<M> Primitive; @@ -188,9 +188,9 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom, ray.time()); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, n0, Intersect1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, n0, Intersect1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded(const Precalculations& pre, @@ -202,13 +202,13 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom, ray.time()); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, n0, Occluded1EpilogM<M, Mx, filter>(ray, context, Disc.geomID(), Disc.primID())); + const vbool<M> valid = Disc.valid(); + return DiscIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, n0, Occluded1EpilogM<M, filter>(ray, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct OrientedDiscMiIntersectorK { typedef PointMi<M> Primitive; @@ -221,10 +221,10 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, n0, - Intersect1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Intersect1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded( @@ -234,14 +234,14 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + return DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, n0, - Occluded1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Occluded1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct OrientedDiscMiMBIntersectorK { typedef PointMi<M> Primitive; @@ -254,10 +254,10 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom, ray.time()[k]); - const vbool<Mx> valid = Disc.template valid<Mx>(); - DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, n0, - Intersect1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Intersect1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } static __forceinline bool occluded( @@ -267,10 +267,10 @@ namespace embree const Points* geom = context->scene->get<Points>(Disc.geomID()); Vec4vf<M> v0; Vec3vf<M> n0; Disc.gather(v0, n0, geom, ray.time()[k]); - const vbool<Mx> valid = Disc.template valid<Mx>(); - return DiscIntersectorK<Mx, K>::intersect( + const vbool<M> valid = Disc.valid(); + return DiscIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, n0, - Occluded1KEpilogM<M, Mx, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); + Occluded1KEpilogM<M, K, filter>(ray, k, context, Disc.geomID(), Disc.primID())); } }; } // namespace isa diff --git a/thirdparty/embree-aarch64/kernels/geometry/filter.h b/thirdparty/embree/kernels/geometry/filter.h index 4cdf7a395a..3b4d924ea7 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/filter.h +++ b/thirdparty/embree/kernels/geometry/filter.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/grid_intersector.h b/thirdparty/embree/kernels/geometry/grid_intersector.h index 46a0af0827..9c59cef119 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/grid_intersector.h +++ b/thirdparty/embree/kernels/geometry/grid_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/grid_soa.h b/thirdparty/embree/kernels/geometry/grid_soa.h index d3b275586c..cea90aedf6 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/grid_soa.h +++ b/thirdparty/embree/kernels/geometry/grid_soa.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -41,7 +41,7 @@ namespace embree } const size_t gridBytes = 4*size_t(width)*size_t(height)*sizeof(float); size_t rootBytes = time_steps*sizeof(BVH4::NodeRef); -#if !defined(__X86_64__) && !defined(__aarch64__) +#if !defined(__64BIT__) rootBytes += 4; // We read 2 elements behind the grid. As we store at least 8 root bytes after the grid we are fine in 64 bit mode. But in 32 bit mode we have to do additional padding. #endif void* data = alloc(offsetof(GridSOA,data)+bvhBytes+time_steps*gridBytes+rootBytes); @@ -62,8 +62,8 @@ namespace embree __forceinline const BVH4::NodeRef& root(size_t t = 0) const { return (BVH4::NodeRef&)data[rootOffset + t*sizeof(BVH4::NodeRef)]; } /*! returns pointer to BVH array */ - __forceinline int8_t* bvhData() { return &data[0]; } - __forceinline const int8_t* bvhData() const { return &data[0]; } + __forceinline char* bvhData() { return &data[0]; } + __forceinline const char* bvhData() const { return &data[0]; } /*! returns pointer to Grid array */ __forceinline float* gridData(size_t t = 0) { return (float*) &data[gridOffset + t*gridBytes]; } @@ -132,7 +132,7 @@ namespace embree __forceinline MapUV(const float* const grid_uv, size_t line_offset, const size_t lines) : grid_uv(grid_uv), line_offset(line_offset), lines(lines) {} - __forceinline void operator() (vfloat& u, vfloat& v) const { + __forceinline void operator() (vfloat& u, vfloat& v, Vec3<vfloat>& Ng) const { const Vec3<vfloat> tri_v012_uv = Loader::gather(grid_uv,line_offset,lines); const Vec2<vfloat> uv0 = GridSOA::decodeUV(tri_v012_uv[0]); const Vec2<vfloat> uv1 = GridSOA::decodeUV(tri_v012_uv[1]); @@ -253,7 +253,7 @@ namespace embree public: BVH4::NodeRef troot; -#if !defined(__X86_64__) && !defined(__aarch64__) +#if !defined(__64BIT__) unsigned align1; #endif unsigned time_steps; @@ -269,7 +269,7 @@ namespace embree unsigned gridBytes; unsigned rootOffset; - int8_t data[1]; //!< after the struct we first store the BVH, then the grid, and finally the roots + char data[1]; //!< after the struct we first store the BVH, then the grid, and finally the roots }; } } diff --git a/thirdparty/embree-aarch64/kernels/geometry/grid_soa_intersector1.h b/thirdparty/embree/kernels/geometry/grid_soa_intersector1.h index 2ed922a5ae..8fbf0d4bdf 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/grid_soa_intersector1.h +++ b/thirdparty/embree/kernels/geometry/grid_soa_intersector1.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/grid_soa_intersector_packet.h b/thirdparty/embree/kernels/geometry/grid_soa_intersector_packet.h index 41d66e1e28..14cacab5fe 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/grid_soa_intersector_packet.h +++ b/thirdparty/embree/kernels/geometry/grid_soa_intersector_packet.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -20,7 +20,7 @@ namespace embree __forceinline MapUV0(const float* const grid_uv, size_t ofs00, size_t ofs01, size_t ofs10, size_t ofs11) : grid_uv(grid_uv), ofs00(ofs00), ofs01(ofs01), ofs10(ofs10), ofs11(ofs11) {} - __forceinline void operator() (vfloat<K>& u, vfloat<K>& v) const { + __forceinline void operator() (vfloat<K>& u, vfloat<K>& v, Vec3vf<K>& Ng) const { const vfloat<K> uv00(grid_uv[ofs00]); const vfloat<K> uv01(grid_uv[ofs01]); const vfloat<K> uv10(grid_uv[ofs10]); @@ -42,7 +42,7 @@ namespace embree __forceinline MapUV1(const float* const grid_uv, size_t ofs00, size_t ofs01, size_t ofs10, size_t ofs11) : grid_uv(grid_uv), ofs00(ofs00), ofs01(ofs01), ofs10(ofs10), ofs11(ofs11) {} - __forceinline void operator() (vfloat<K>& u, vfloat<K>& v) const { + __forceinline void operator() (vfloat<K>& u, vfloat<K>& v, Vec3vf<K>& Ng) const { const vfloat<K> uv00(grid_uv[ofs00]); const vfloat<K> uv01(grid_uv[ofs01]); const vfloat<K> uv10(grid_uv[ofs10]); @@ -222,7 +222,7 @@ namespace embree static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node) { vfloat<K> vftime; - vint<K> vitime = getTimeSegment(ray.time(), vfloat<K>((float)(pre.grid->time_steps-1)), vftime); + vint<K> vitime = getTimeSegment<K>(ray.time(), vfloat<K>((float)(pre.grid->time_steps-1)), vftime); vbool<K> valid1 = valid_i; while (any(valid1)) { @@ -282,7 +282,7 @@ namespace embree static __forceinline vbool<K> occluded(const vbool<K>& valid_i, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t& lazy_node) { vfloat<K> vftime; - vint<K> vitime = getTimeSegment(ray.time(), vfloat<K>((float)(pre.grid->time_steps-1)), vftime); + vint<K> vitime = getTimeSegment<K>(ray.time(), vfloat<K>((float)(pre.grid->time_steps-1)), vftime); vbool<K> valid_o = valid_i; vbool<K> valid1 = valid_i; diff --git a/thirdparty/embree-aarch64/kernels/geometry/instance.h b/thirdparty/embree/kernels/geometry/instance.h index 66893d581f..7c0e7e0f49 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/instance.h +++ b/thirdparty/embree/kernels/geometry/instance.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/instance_intersector.h b/thirdparty/embree/kernels/geometry/instance_intersector.h index 91731a39c5..28a7b728e5 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/instance_intersector.h +++ b/thirdparty/embree/kernels/geometry/instance_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/intersector_epilog.h b/thirdparty/embree/kernels/geometry/intersector_epilog.h index 0df49dd6e9..7bf134cc54 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/intersector_epilog.h +++ b/thirdparty/embree/kernels/geometry/intersector_epilog.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -13,7 +13,7 @@ namespace embree { template<int M> struct UVIdentity { - __forceinline void operator() (vfloat<M>& u, vfloat<M>& v) const {} + __forceinline void operator() (vfloat<M>& u, vfloat<M>& v, Vec3vf<M>& Ng) const {} }; @@ -63,7 +63,7 @@ namespace embree ray.v = hit.v; ray.primID = primID; ray.geomID = geomID; - instance_id_stack::copy(context->user->instID, ray.instID); + instance_id_stack::copy_UU(context->user->instID, ray.instID); return true; } }; @@ -162,7 +162,7 @@ namespace embree ray.v[k] = hit.v; ray.primID[k] = primID; ray.geomID[k] = geomID; - instance_id_stack::copy<const unsigned*, vuint<K>*, const size_t&>(context->user->instID, ray.instID, k); + instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, k); return true; } }; @@ -211,7 +211,7 @@ namespace embree } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct Intersect1EpilogM { RayHit& ray; @@ -226,11 +226,10 @@ namespace embree : ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs) {} template<typename Hit> - __forceinline bool operator() (const vbool<Mx>& valid_i, Hit& hit) const + __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const { Scene* scene MAYBE_UNUSED = context->scene; - vbool<Mx> valid = valid_i; - if (Mx > M) valid &= (1<<M)-1; + vbool<M> valid = valid_i; hit.finalize(); size_t i = select_min(valid,hit.vt); unsigned int geomID = geomIDs[i]; @@ -287,94 +286,13 @@ namespace embree ray.v = uv.y; ray.primID = primIDs[i]; ray.geomID = geomID; - instance_id_stack::copy(context->user->instID, ray.instID); + instance_id_stack::copy_UU(context->user->instID, ray.instID); return true; } }; -#if 0 && defined(__AVX512F__) // do not enable, this reduced frequency for BVH4 template<int M, bool filter> - struct Intersect1EpilogM<M,16,filter> - { - static const size_t Mx = 16; - RayHit& ray; - IntersectContext* context; - const vuint<M>& geomIDs; - const vuint<M>& primIDs; - - __forceinline Intersect1EpilogM(RayHit& ray, - IntersectContext* context, - const vuint<M>& geomIDs, - const vuint<M>& primIDs) - : ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs) {} - - template<typename Hit> - __forceinline bool operator() (const vbool<Mx>& valid_i, Hit& hit) const - { - Scene* MAYBE_UNUSED scene = context->scene; - vbool<Mx> valid = valid_i; - if (Mx > M) valid &= (1<<M)-1; - hit.finalize(); - size_t i = select_min(valid,hit.vt); - unsigned int geomID = geomIDs[i]; - - /* intersection filter test */ -#if defined(EMBREE_FILTER_FUNCTION) || defined(EMBREE_RAY_MASK) - bool foundhit = false; - goto entry; - while (true) - { - if (unlikely(none(valid))) return foundhit; - i = select_min(valid,hit.vt); - - geomID = geomIDs[i]; - entry: - Geometry* geometry MAYBE_UNUSED = scene->get(geomID); - -#if defined(EMBREE_RAY_MASK) - /* goto next hit if mask test fails */ - if ((geometry->mask & ray.mask) == 0) { - clear(valid,i); - continue; - } -#endif - -#if defined(EMBREE_FILTER_FUNCTION) - /* call intersection filter function */ - if (filter) { - if (unlikely(context->hasContextFilter() || geometry->hasIntersectionFilter())) { - const Vec2f uv = hit.uv(i); - HitK<1> h(context->user,geomID,primIDs[i],uv.x,uv.y,hit.Ng(i)); - const float old_t = ray.tfar; - ray.tfar = hit.t(i); - const bool found = runIntersectionFilter1(geometry,ray,context,h); - if (!found) ray.tfar = old_t; - foundhit |= found; - clear(valid,i); - valid &= hit.vt <= ray.tfar; // intersection filters may modify tfar value - continue; - } - } -#endif - break; - } -#endif - - vbool<Mx> finalMask(((unsigned int)1 << i)); - ray.update(finalMask,hit.vt,hit.vu,hit.vv,hit.vNg.x,hit.vNg.y,hit.vNg.z,geomID,primIDs); - instance_id_stack::foreach([&](unsigned level) - { - ray.instID[level] = context->user->instID[level]; - return (context->user->instID[level] != RTC_INVALID_GEOMETRY_ID); - }); - return true; - - } - }; -#endif - - template<int M, int Mx, bool filter> struct Occluded1EpilogM { Ray& ray; @@ -389,7 +307,7 @@ namespace embree : ray(ray), context(context), geomIDs(geomIDs), primIDs(primIDs) {} template<typename Hit> - __forceinline bool operator() (const vbool<Mx>& valid_i, Hit& hit) const + __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const { Scene* scene MAYBE_UNUSED = context->scene; /* intersection filter test */ @@ -397,8 +315,7 @@ namespace embree if (unlikely(filter)) hit.finalize(); /* called only once */ - vbool<Mx> valid = valid_i; - if (Mx > M) valid &= (1<<M)-1; + vbool<M> valid = valid_i; size_t m=movemask(valid); goto entry; while (true) @@ -506,7 +423,7 @@ namespace embree ray.v = uv.y; ray.primID = primID; ray.geomID = geomID; - instance_id_stack::copy(context->user->instID, ray.instID); + instance_id_stack::copy_UU(context->user->instID, ray.instID); return true; } }; @@ -616,7 +533,7 @@ namespace embree vfloat<K>::store(valid,&ray.v,v); vuint<K>::store(valid,&ray.primID,primID); vuint<K>::store(valid,&ray.geomID,geomID); - instance_id_stack::copy<const unsigned*, vuint<K>*, const vbool<K>&>(context->user->instID, ray.instID, valid); + instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, valid); return valid; } }; @@ -646,8 +563,8 @@ namespace embree /* ray masking test */ Scene* scene MAYBE_UNUSED = context->scene; - const unsigned int geomID = geomIDs[i]; - const unsigned int primID = primIDs[i]; + const unsigned int geomID MAYBE_UNUSED = geomIDs[i]; + const unsigned int primID MAYBE_UNUSED = primIDs[i]; Geometry* geometry MAYBE_UNUSED = scene->get(geomID); #if defined(EMBREE_RAY_MASK) valid &= (geometry->mask & ray.mask) != 0; @@ -731,8 +648,7 @@ namespace embree vfloat<K>::store(valid,&ray.v,v); vuint<K>::store(valid,&ray.primID,primID); vuint<K>::store(valid,&ray.geomID,geomID); - instance_id_stack::copy<const unsigned*, vuint<K>*, const vbool<K>&>(context->user->instID, ray.instID, valid); - + instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, valid); return valid; } }; @@ -788,7 +704,7 @@ namespace embree } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct Intersect1KEpilogM { RayHitK<K>& ray; @@ -804,12 +720,11 @@ namespace embree : ray(ray), k(k), context(context), geomIDs(geomIDs), primIDs(primIDs) {} template<typename Hit> - __forceinline bool operator() (const vbool<Mx>& valid_i, Hit& hit) const + __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const { Scene* scene MAYBE_UNUSED = context->scene; - vbool<Mx> valid = valid_i; + vbool<M> valid = valid_i; hit.finalize(); - if (Mx > M) valid &= (1<<M)-1; size_t i = select_min(valid,hit.vt); assert(i<M); unsigned int geomID = geomIDs[i]; @@ -858,9 +773,6 @@ namespace embree #endif assert(i<M); /* update hit information */ -#if 0 && defined(__AVX512F__) // do not enable, this reduced frequency for BVH4 - ray.updateK(i,k,hit.vt,hit.vu,hit.vv,vfloat<Mx>(hit.vNg.x),vfloat<Mx>(hit.vNg.y),vfloat<Mx>(hit.vNg.z),geomID,vuint<Mx>(primIDs)); -#else const Vec2f uv = hit.uv(i); ray.tfar[k] = hit.t(i); ray.Ng.x[k] = hit.vNg.x[i]; @@ -870,13 +782,12 @@ namespace embree ray.v[k] = uv.y; ray.primID[k] = primIDs[i]; ray.geomID[k] = geomID; - instance_id_stack::copy<const unsigned*, vuint<K>*, const size_t&>(context->user->instID, ray.instID, k); -#endif + instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, k); return true; } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct Occluded1KEpilogM { RayK<K>& ray; @@ -892,7 +803,7 @@ namespace embree : ray(ray), k(k), context(context), geomIDs(geomIDs), primIDs(primIDs) {} template<typename Hit> - __forceinline bool operator() (const vbool<Mx>& valid_i, Hit& hit) const + __forceinline bool operator() (const vbool<M>& valid_i, Hit& hit) const { Scene* scene MAYBE_UNUSED = context->scene; @@ -901,8 +812,7 @@ namespace embree if (unlikely(filter)) hit.finalize(); /* called only once */ - vbool<Mx> valid = valid_i; - if (Mx > M) valid &= (1<<M)-1; + vbool<M> valid = valid_i; size_t m=movemask(valid); goto entry; while (true) @@ -1002,10 +912,6 @@ namespace embree #endif /* update hit information */ -#if 0 && defined(__AVX512F__) // do not enable, this reduced frequency for BVH4 - const Vec3fa Ng = hit.Ng(i); - ray.updateK(i,k,hit.vt,hit.vu,hit.vv,vfloat<M>(Ng.x),vfloat<M>(Ng.y),vfloat<M>(Ng.z),geomID,vuint<M>(primID)); -#else const Vec2f uv = hit.uv(i); const Vec3fa Ng = hit.Ng(i); ray.tfar[k] = hit.t(i); @@ -1016,8 +922,7 @@ namespace embree ray.v[k] = uv.y; ray.primID[k] = primID; ray.geomID[k] = geomID; - instance_id_stack::copy<const unsigned*, vuint<K>*, const size_t&>(context->user->instID, ray.instID, k); -#endif + instance_id_stack::copy_UV<K>(context->user->instID, ray.instID, k); return true; } }; diff --git a/thirdparty/embree-aarch64/kernels/geometry/intersector_iterators.h b/thirdparty/embree/kernels/geometry/intersector_iterators.h index 5c1ba5cb61..9cac1cd25c 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/intersector_iterators.h +++ b/thirdparty/embree/kernels/geometry/intersector_iterators.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -19,15 +19,15 @@ namespace embree typedef typename Intersector::Primitive Primitive; typedef typename Intersector::Precalculations Precalculations; - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { for (size_t i=0; i<num; i++) Intersector::intersect(pre,ray,context,prim[i]); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { for (size_t i=0; i<num; i++) { if (Intersector::occluded(pre,ray,context,prim[i])) @@ -82,16 +82,16 @@ namespace embree return !valid0; } - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { for (size_t i=0; i<num; i++) { Intersector::intersect(pre,ray,k,context,prim[i]); } } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { for (size_t i=0; i<num; i++) { if (Intersector::occluded(pre,ray,k,context,prim[i])) diff --git a/thirdparty/embree-aarch64/kernels/geometry/line_intersector.h b/thirdparty/embree/kernels/geometry/line_intersector.h index eef5b0b1fd..41096d8794 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/line_intersector.h +++ b/thirdparty/embree/kernels/geometry/line_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -23,6 +23,10 @@ namespace embree __forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); } __forceinline float t (const size_t i) const { return vt[i]; } __forceinline Vec3fa Ng(const size_t i) const { return Vec3fa(vNg.x[i],vNg.y[i],vNg.z[i]); } + + __forceinline Vec2vf<M> uv() const { return Vec2vf<M>(vu,vv); } + __forceinline vfloat<M> t () const { return vt; } + __forceinline Vec3vf<M> Ng() const { return vNg; } public: vfloat<M> vu; @@ -36,7 +40,7 @@ namespace embree { typedef CurvePrecalculations1 Precalculations; - template<typename Epilog> + template<typename Ray, typename Epilog> static __forceinline bool intersect(const vbool<M>& valid_i, Ray& ray, IntersectContext* context, @@ -51,8 +55,8 @@ namespace embree LinearSpace3<Vec3vf<M>> ray_space = pre.ray_space; const Vec3vf<M> ray_org ((Vec3fa)ray.org); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); - const Vec4vf<M> v1 = enlargeRadiusToMinWidth(context,geom,ray_org,v1i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); + const Vec4vf<M> v1 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v1i); Vec4vf<M> p0(xfmVector(ray_space,v0.xyz()-ray_org), v0.w); Vec4vf<M> p1(xfmVector(ray_space,v1.xyz()-ray_org), v1.w); @@ -105,8 +109,8 @@ namespace embree const Vec3vf<M> ray_org(ray.org.x[k],ray.org.y[k],ray.org.z[k]); const Vec3vf<M> ray_dir(ray.dir.x[k],ray.dir.y[k],ray.dir.z[k]); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); - const Vec4vf<M> v1 = enlargeRadiusToMinWidth(context,geom,ray_org,v1i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); + const Vec4vf<M> v1 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v1i); Vec4vf<M> p0(xfmVector(ray_space,v0.xyz()-ray_org), v0.w); Vec4vf<M> p1(xfmVector(ray_space,v1.xyz()-ray_org), v1.w); diff --git a/thirdparty/embree-aarch64/kernels/geometry/linei.h b/thirdparty/embree/kernels/geometry/linei.h index a72029ca53..3ee70ac012 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/linei.h +++ b/thirdparty/embree/kernels/geometry/linei.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -49,10 +49,6 @@ namespace embree /* Returns a mask that tells which line segments are valid */ __forceinline vbool<M> valid() const { return primIDs != vuint<M>(-1); } - /* Returns a mask that tells which line segments are valid */ - template<int Mx> - __forceinline vbool<Mx> valid() const { return vuint<Mx>(primIDs) != vuint<Mx>(-1); } - /* Returns if the specified line segment is valid */ __forceinline bool valid(const size_t i) const { assert(i<M); return primIDs[i] != -1; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/linei_intersector.h b/thirdparty/embree/kernels/geometry/linei_intersector.h index a431796a88..5992827f5b 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/linei_intersector.h +++ b/thirdparty/embree/kernels/geometry/linei_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,7 +11,7 @@ namespace embree { namespace isa { - template<int M, int Mx, bool filter> + template<int M, bool filter> struct FlatLinearCurveMiIntersector1 { typedef LineMi<M> Primitive; @@ -22,8 +22,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - FlatLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,Intersect1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + FlatLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,Intersect1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& line) @@ -31,8 +31,8 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - return FlatLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,Occluded1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return FlatLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,Occluded1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& line) @@ -41,7 +41,7 @@ namespace embree } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct FlatLinearCurveMiMBIntersector1 { typedef LineMi<M> Primitive; @@ -52,8 +52,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom,ray.time()); - const vbool<Mx> valid = line.template valid<Mx>(); - FlatLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,Intersect1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + FlatLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,Intersect1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& line) @@ -61,8 +61,8 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom,ray.time()); - const vbool<Mx> valid = line.template valid<Mx>(); - return FlatLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,Occluded1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return FlatLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,Occluded1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& line) @@ -71,7 +71,7 @@ namespace embree } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct FlatLinearCurveMiIntersectorK { typedef LineMi<M> Primitive; @@ -82,8 +82,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - FlatLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + FlatLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Intersect1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& line) @@ -91,12 +91,12 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - return FlatLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return FlatLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Occluded1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct FlatLinearCurveMiMBIntersectorK { typedef LineMi<M> Primitive; @@ -107,8 +107,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom,ray.time()[k]); - const vbool<Mx> valid = line.template valid<Mx>(); - FlatLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + FlatLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Intersect1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& line) @@ -116,8 +116,8 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1; line.gather(v0,v1,geom,ray.time()[k]); - const vbool<Mx> valid = line.template valid<Mx>(); - return FlatLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return FlatLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,Occluded1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/object.h b/thirdparty/embree/kernels/geometry/object.h index f26391de52..2a61829ffd 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/object.h +++ b/thirdparty/embree/kernels/geometry/object.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/object_intersector.h b/thirdparty/embree/kernels/geometry/object_intersector.h index 97882e0e59..11ceb2f7fe 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/object_intersector.h +++ b/thirdparty/embree/kernels/geometry/object_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/plane.h b/thirdparty/embree/kernels/geometry/plane.h index ebe45db558..e447122eab 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/plane.h +++ b/thirdparty/embree/kernels/geometry/plane.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/pointi.h b/thirdparty/embree/kernels/geometry/pointi.h index 4ba298e86b..bed04116b0 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/pointi.h +++ b/thirdparty/embree/kernels/geometry/pointi.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -61,11 +61,6 @@ namespace embree return vint<M>(step) < vint<M>(numPrimitives); } - /* Returns a mask that tells which line segments are valid */ - template<int Mx> __forceinline vbool<Mx> valid() const { - return vint<Mx>(step) < vint<Mx>(numPrimitives); - } - /* Returns if the specified line segment is valid */ __forceinline bool valid(const size_t i) const { diff --git a/thirdparty/embree-aarch64/kernels/geometry/primitive.h b/thirdparty/embree/kernels/geometry/primitive.h index 41e5b2b304..608d981dd7 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/primitive.h +++ b/thirdparty/embree/kernels/geometry/primitive.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/primitive4.cpp b/thirdparty/embree/kernels/geometry/primitive4.cpp index f93574c9c8..9c953c5d35 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/primitive4.cpp +++ b/thirdparty/embree/kernels/geometry/primitive4.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "primitive.h" diff --git a/thirdparty/embree-aarch64/kernels/geometry/quad_intersector.h b/thirdparty/embree/kernels/geometry/quad_intersector.h index 57ff4e60e5..93c9526912 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quad_intersector.h +++ b/thirdparty/embree/kernels/geometry/quad_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/quad_intersector_moeller.h b/thirdparty/embree/kernels/geometry/quad_intersector_moeller.h index 74e8c7720c..3abc9d6f70 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quad_intersector_moeller.h +++ b/thirdparty/embree/kernels/geometry/quad_intersector_moeller.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -126,16 +126,17 @@ namespace embree const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - MoellerTrumboreHitM<M> hit; + UVIdentity<M> mapUV; + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); MoellerTrumboreIntersector1<M> intersector(ray,nullptr); - Intersect1EpilogM<M,M,filter> epilog(ray,context,geomID,primID); + Intersect1EpilogM<M,filter> epilog(ray,context,geomID,primID); /* intersect first triangle */ - if (intersector.intersect(ray,v0,v1,v3,hit)) + if (intersector.intersect(ray,v0,v1,v3,mapUV,hit)) epilog(hit.valid,hit); /* intersect second triangle */ - if (intersector.intersect(ray,v2,v3,v1,hit)) + if (intersector.intersect(ray,v2,v3,v1,mapUV,hit)) { hit.U = hit.absDen - hit.U; hit.V = hit.absDen - hit.V; @@ -147,19 +148,20 @@ namespace embree const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - MoellerTrumboreHitM<M> hit; + UVIdentity<M> mapUV; + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); MoellerTrumboreIntersector1<M> intersector(ray,nullptr); - Occluded1EpilogM<M,M,filter> epilog(ray,context,geomID,primID); + Occluded1EpilogM<M,filter> epilog(ray,context,geomID,primID); /* intersect first triangle */ - if (intersector.intersect(ray,v0,v1,v3,hit)) + if (intersector.intersect(ray,v0,v1,v3,mapUV,hit)) { if (epilog(hit.valid,hit)) return true; } /* intersect second triangle */ - if (intersector.intersect(ray,v2,v3,v1,hit)) + if (intersector.intersect(ray,v2,v3,v1,mapUV,hit)) { hit.U = hit.absDen - hit.U; hit.V = hit.absDen - hit.V; @@ -170,70 +172,7 @@ namespace embree } }; -#if defined(__AVX512ER__) // KNL - - /*! Intersects 4 quads with 1 ray using AVX512 */ - template<bool filter> - struct QuadMIntersector1MoellerTrumbore<4,filter> - { - __forceinline QuadMIntersector1MoellerTrumbore() {} - - __forceinline QuadMIntersector1MoellerTrumbore(const Ray& ray, const void* ptr) {} - - template<typename Epilog> - __forceinline bool intersect(Ray& ray, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const Epilog& epilog) const - { - const Vec3vf16 vtx0(select(0x0f0f,vfloat16(v0.x),vfloat16(v2.x)), - select(0x0f0f,vfloat16(v0.y),vfloat16(v2.y)), - select(0x0f0f,vfloat16(v0.z),vfloat16(v2.z))); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf16 vtx1(vfloat16(v1.x),vfloat16(v1.y),vfloat16(v1.z)); - const Vec3vf16 vtx2(vfloat16(v3.x),vfloat16(v3.y),vfloat16(v3.z)); -#else - const Vec3vf16 vtx1(select(0x0f0f,vfloat16(v1.x),vfloat16(v3.x)), - select(0x0f0f,vfloat16(v1.y),vfloat16(v3.y)), - select(0x0f0f,vfloat16(v1.z),vfloat16(v3.z))); - const Vec3vf16 vtx2(select(0x0f0f,vfloat16(v3.x),vfloat16(v1.x)), - select(0x0f0f,vfloat16(v3.y),vfloat16(v1.y)), - select(0x0f0f,vfloat16(v3.z),vfloat16(v1.z))); -#endif - const vbool16 flags(0xf0f0); - - MoellerTrumboreHitM<16> hit; - MoellerTrumboreIntersector1<16> intersector(ray,nullptr); - if (unlikely(intersector.intersect(ray,vtx0,vtx1,vtx2,hit))) - { - vfloat16 U = hit.U, V = hit.V, absDen = hit.absDen; -#if !defined(EMBREE_BACKFACE_CULLING) - hit.U = select(flags,absDen-V,U); - hit.V = select(flags,absDen-U,V); - hit.vNg *= select(flags,vfloat16(-1.0f),vfloat16(1.0f)); // FIXME: use XOR -#else - hit.U = select(flags,absDen-U,U); - hit.V = select(flags,absDen-V,V); -#endif - if (likely(epilog(hit.valid,hit))) - return true; - } - return false; - } - - __forceinline bool intersect(RayHit& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect(ray,v0,v1,v2,v3,Intersect1EpilogM<8,16,filter>(ray,context,vuint8(geomID),vuint8(primID))); - } - - __forceinline bool occluded(Ray& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect(ray,v0,v1,v2,v3,Occluded1EpilogM<8,16,filter>(ray,context,vuint8(geomID),vuint8(primID))); - } - }; - -#elif defined(__AVX__) +#if defined(__AVX__) /*! Intersects 4 quads with 1 ray using AVX */ template<bool filter> @@ -254,10 +193,11 @@ namespace embree const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); #endif - MoellerTrumboreHitM<8> hit; + UVIdentity<8> mapUV; + MoellerTrumboreHitM<8,UVIdentity<8>> hit(mapUV); MoellerTrumboreIntersector1<8> intersector(ray,nullptr); const vbool8 flags(0,0,0,0,1,1,1,1); - if (unlikely(intersector.intersect(ray,vtx0,vtx1,vtx2,hit))) + if (unlikely(intersector.intersect(ray,vtx0,vtx1,vtx2,mapUV,hit))) { vfloat8 U = hit.U, V = hit.V, absDen = hit.absDen; @@ -279,14 +219,14 @@ namespace embree const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect(ray,v0,v1,v2,v3,Intersect1EpilogM<8,8,filter>(ray,context,vuint8(geomID),vuint8(primID))); + return intersect(ray,v0,v1,v2,v3,Intersect1EpilogM<8,filter>(ray,context,vuint8(geomID),vuint8(primID))); } __forceinline bool occluded(Ray& ray, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect(ray,v0,v1,v2,v3,Occluded1EpilogM<8,8,filter>(ray,context,vuint8(geomID),vuint8(primID))); + return intersect(ray,v0,v1,v2,v3,Occluded1EpilogM<8,filter>(ray,context,vuint8(geomID),vuint8(primID))); } }; @@ -353,7 +293,7 @@ namespace embree const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v2-v0; const Vec3vf<M> Ng = cross(e2,e1); - return intersect(ray,k,v0,e1,e2,Ng,flags,epilog); + return intersect<M,K>(ray,k,v0,e1,e2,Ng,flags,epilog); } }; @@ -458,70 +398,24 @@ namespace embree const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - Intersect1KEpilogM<M,M,K,filter> epilog(ray,k,context,geomID,primID); - MoellerTrumboreIntersector1KTriangleM::intersect1(ray,k,v0,v1,v3,vbool<M>(false),epilog); - MoellerTrumboreIntersector1KTriangleM::intersect1(ray,k,v2,v3,v1,vbool<M>(true ),epilog); + Intersect1KEpilogM<M,K,filter> epilog(ray,k,context,geomID,primID); + MoellerTrumboreIntersector1KTriangleM::intersect1<M,K>(ray,k,v0,v1,v3,vbool<M>(false),epilog); + MoellerTrumboreIntersector1KTriangleM::intersect1<M,K>(ray,k,v2,v3,v1,vbool<M>(true ),epilog); } __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - Occluded1KEpilogM<M,M,K,filter> epilog(ray,k,context,geomID,primID); - if (MoellerTrumboreIntersector1KTriangleM::intersect1(ray,k,v0,v1,v3,vbool<M>(false),epilog)) return true; - if (MoellerTrumboreIntersector1KTriangleM::intersect1(ray,k,v2,v3,v1,vbool<M>(true ),epilog)) return true; + Occluded1KEpilogM<M,K,filter> epilog(ray,k,context,geomID,primID); + if (MoellerTrumboreIntersector1KTriangleM::intersect1<M,K>(ray,k,v0,v1,v3,vbool<M>(false),epilog)) return true; + if (MoellerTrumboreIntersector1KTriangleM::intersect1<M,K>(ray,k,v2,v3,v1,vbool<M>(true ),epilog)) return true; return false; } }; -#if defined(__AVX512ER__) // KNL - - /*! Intersects 4 quads with 1 ray using AVX512 */ - template<int K, bool filter> - struct QuadMIntersectorKMoellerTrumbore<4,K,filter> : public QuadMIntersectorKMoellerTrumboreBase<4,K,filter> - { - __forceinline QuadMIntersectorKMoellerTrumbore(const vbool<K>& valid, const RayK<K>& ray) - : QuadMIntersectorKMoellerTrumboreBase<4,K,filter>(valid,ray) {} - - template<typename Epilog> - __forceinline bool intersect1(RayK<K>& ray, size_t k, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const Epilog& epilog) const - { - const Vec3vf16 vtx0(select(0x0f0f,vfloat16(v0.x),vfloat16(v2.x)), - select(0x0f0f,vfloat16(v0.y),vfloat16(v2.y)), - select(0x0f0f,vfloat16(v0.z),vfloat16(v2.z))); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf16 vtx1(vfloat16(v1.x),vfloat16(v1.y),vfloat16(v1.z)); - const Vec3vf16 vtx2(vfloat16(v3.x),vfloat16(v3.y),vfloat16(v3.z)); -#else - const Vec3vf16 vtx1(select(0x0f0f,vfloat16(v1.x),vfloat16(v3.x)), - select(0x0f0f,vfloat16(v1.y),vfloat16(v3.y)), - select(0x0f0f,vfloat16(v1.z),vfloat16(v3.z))); - const Vec3vf16 vtx2(select(0x0f0f,vfloat16(v3.x),vfloat16(v1.x)), - select(0x0f0f,vfloat16(v3.y),vfloat16(v1.y)), - select(0x0f0f,vfloat16(v3.z),vfloat16(v1.z))); -#endif - const vbool16 flags(0xf0f0); - return MoellerTrumboreIntersector1KTriangleM::intersect1(ray,k,vtx0,vtx1,vtx2,flags,epilog); - } - - __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect1(ray,k,v0,v1,v2,v3,Intersect1KEpilogM<8,16,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); - } - - __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect1(ray,k,v0,v1,v2,v3,Occluded1KEpilogM<8,16,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); - } - }; - -#elif defined(__AVX__) +#if defined(__AVX__) /*! Intersects 4 quads with 1 ray using AVX */ template<int K, bool filter> @@ -543,21 +437,21 @@ namespace embree const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); #endif const vbool8 flags(0,0,0,0,1,1,1,1); - return MoellerTrumboreIntersector1KTriangleM::intersect1(ray,k,vtx0,vtx1,vtx2,flags,epilog); + return MoellerTrumboreIntersector1KTriangleM::intersect1<8,K>(ray,k,vtx0,vtx1,vtx2,flags,epilog); } __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect1(ray,k,v0,v1,v2,v3,Intersect1KEpilogM<8,8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); + return intersect1(ray,k,v0,v1,v2,v3,Intersect1KEpilogM<8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); } __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect1(ray,k,v0,v1,v2,v3,Occluded1KEpilogM<8,8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); + return intersect1(ray,k,v0,v1,v2,v3,Occluded1KEpilogM<8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); } }; diff --git a/thirdparty/embree-aarch64/kernels/geometry/quad_intersector_pluecker.h b/thirdparty/embree/kernels/geometry/quad_intersector_pluecker.h index 7ca3aed0a0..9873ff76ac 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quad_intersector_pluecker.h +++ b/thirdparty/embree/kernels/geometry/quad_intersector_pluecker.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -175,69 +175,23 @@ namespace embree const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - Intersect1EpilogM<M,M,filter> epilog(ray,context,geomID,primID); - PlueckerIntersectorTriangle1::intersect(ray,v0,v1,v3,vbool<M>(false),epilog); - PlueckerIntersectorTriangle1::intersect(ray,v2,v3,v1,vbool<M>(true),epilog); + Intersect1EpilogM<M,filter> epilog(ray,context,geomID,primID); + PlueckerIntersectorTriangle1::intersect<M>(ray,v0,v1,v3,vbool<M>(false),epilog); + PlueckerIntersectorTriangle1::intersect<M>(ray,v2,v3,v1,vbool<M>(true),epilog); } __forceinline bool occluded(Ray& ray, IntersectContext* context, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - Occluded1EpilogM<M,M,filter> epilog(ray,context,geomID,primID); - if (PlueckerIntersectorTriangle1::intersect(ray,v0,v1,v3,vbool<M>(false),epilog)) return true; - if (PlueckerIntersectorTriangle1::intersect(ray,v2,v3,v1,vbool<M>(true ),epilog)) return true; + Occluded1EpilogM<M,filter> epilog(ray,context,geomID,primID); + if (PlueckerIntersectorTriangle1::intersect<M>(ray,v0,v1,v3,vbool<M>(false),epilog)) return true; + if (PlueckerIntersectorTriangle1::intersect<M>(ray,v2,v3,v1,vbool<M>(true ),epilog)) return true; return false; } }; -#if defined(__AVX512ER__) // KNL - - /*! Intersects 4 quads with 1 ray using AVX512 */ - template<bool filter> - struct QuadMIntersector1Pluecker<4,filter> - { - __forceinline QuadMIntersector1Pluecker() {} - - __forceinline QuadMIntersector1Pluecker(const Ray& ray, const void* ptr) {} - - template<typename Epilog> - __forceinline bool intersect(Ray& ray, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const Epilog& epilog) const - { - const Vec3vf16 vtx0(select(0x0f0f,vfloat16(v0.x),vfloat16(v2.x)), - select(0x0f0f,vfloat16(v0.y),vfloat16(v2.y)), - select(0x0f0f,vfloat16(v0.z),vfloat16(v2.z))); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf16 vtx1(vfloat16(v1.x),vfloat16(v1.y),vfloat16(v1.z)); - const Vec3vf16 vtx2(vfloat16(v3.x),vfloat16(v3.y),vfloat16(v3.z)); -#else - const Vec3vf16 vtx1(select(0x0f0f,vfloat16(v1.x),vfloat16(v3.x)), - select(0x0f0f,vfloat16(v1.y),vfloat16(v3.y)), - select(0x0f0f,vfloat16(v1.z),vfloat16(v3.z))); - const Vec3vf16 vtx2(select(0x0f0f,vfloat16(v3.x),vfloat16(v1.x)), - select(0x0f0f,vfloat16(v3.y),vfloat16(v1.y)), - select(0x0f0f,vfloat16(v3.z),vfloat16(v1.z))); -#endif - const vbool16 flags(0xf0f0); - return PlueckerIntersectorTriangle1::intersect(ray,vtx0,vtx1,vtx2,flags,epilog); - } - - __forceinline bool intersect(RayHit& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect(ray,v0,v1,v2,v3,Intersect1EpilogM<8,16,filter>(ray,context,vuint8(geomID),vuint8(primID))); - } - - __forceinline bool occluded(Ray& ray, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect(ray,v0,v1,v2,v3,Occluded1EpilogM<8,16,filter>(ray,context,vuint8(geomID),vuint8(primID))); - } - }; - -#elif defined(__AVX__) +#if defined(__AVX__) /*! Intersects 4 quads with 1 ray using AVX */ template<bool filter> @@ -259,19 +213,19 @@ namespace embree const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); #endif const vbool8 flags(0,0,0,0,1,1,1,1); - return PlueckerIntersectorTriangle1::intersect(ray,vtx0,vtx1,vtx2,flags,epilog); + return PlueckerIntersectorTriangle1::intersect<8>(ray,vtx0,vtx1,vtx2,flags,epilog); } __forceinline bool intersect(RayHit& ray, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect(ray,v0,v1,v2,v3,Intersect1EpilogM<8,8,filter>(ray,context,vuint8(geomID),vuint8(primID))); + return intersect(ray,v0,v1,v2,v3,Intersect1EpilogM<8,filter>(ray,context,vuint8(geomID),vuint8(primID))); } __forceinline bool occluded(Ray& ray, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect(ray,v0,v1,v2,v3,Occluded1EpilogM<8,8,filter>(ray,context,vuint8(geomID),vuint8(primID))); + return intersect(ray,v0,v1,v2,v3,Occluded1EpilogM<8,filter>(ray,context,vuint8(geomID),vuint8(primID))); } }; @@ -305,18 +259,19 @@ namespace embree const Vec3vf<M> e0 = v2-v0; const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v1-v2; - + /* perform edge tests */ const vfloat<M> U = dot(cross(e0,v2+v0),D); const vfloat<M> V = dot(cross(e1,v0+v1),D); const vfloat<M> W = dot(cross(e2,v1+v2),D); + const vfloat<M> UVW = U+V+W; const vfloat<M> eps = float(ulp)*abs(UVW); #if defined(EMBREE_BACKFACE_CULLING) vbool<M> valid = max(U,V,W) <= eps; #else vbool<M> valid = (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); -#endif +#endif if (unlikely(none(valid))) return false; /* calculate geometry normal and denominator */ @@ -423,69 +378,23 @@ namespace embree const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - Intersect1KEpilogM<M,M,K,filter> epilog(ray,k,context,geomID,primID); - PlueckerIntersector1KTriangleM::intersect1(ray,k,v0,v1,v3,vbool<M>(false),epilog); - PlueckerIntersector1KTriangleM::intersect1(ray,k,v2,v3,v1,vbool<M>(true ),epilog); + Intersect1KEpilogM<M,K,filter> epilog(ray,k,context,geomID,primID); + PlueckerIntersector1KTriangleM::intersect1<M,K>(ray,k,v0,v1,v3,vbool<M>(false),epilog); + PlueckerIntersector1KTriangleM::intersect1<M,K>(ray,k,v2,v3,v1,vbool<M>(true ),epilog); } __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vuint<M>& geomID, const vuint<M>& primID) const { - Occluded1KEpilogM<M,M,K,filter> epilog(ray,k,context,geomID,primID); - if (PlueckerIntersector1KTriangleM::intersect1(ray,k,v0,v1,v3,vbool<M>(false),epilog)) return true; - if (PlueckerIntersector1KTriangleM::intersect1(ray,k,v2,v3,v1,vbool<M>(true ),epilog)) return true; + Occluded1KEpilogM<M,K,filter> epilog(ray,k,context,geomID,primID); + if (PlueckerIntersector1KTriangleM::intersect1<M,K>(ray,k,v0,v1,v3,vbool<M>(false),epilog)) return true; + if (PlueckerIntersector1KTriangleM::intersect1<M,K>(ray,k,v2,v3,v1,vbool<M>(true ),epilog)) return true; return false; } }; -#if defined(__AVX512ER__) // KNL - - /*! Intersects 4 quads with 1 ray using AVX512 */ - template<int K, bool filter> - struct QuadMIntersectorKPluecker<4,K,filter> : public QuadMIntersectorKPlueckerBase<4,K,filter> - { - __forceinline QuadMIntersectorKPluecker(const vbool<K>& valid, const RayK<K>& ray) - : QuadMIntersectorKPlueckerBase<4,K,filter>(valid,ray) {} - - template<typename Epilog> - __forceinline bool intersect1(RayK<K>& ray, size_t k, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const Epilog& epilog) const - { - const Vec3vf16 vtx0(select(0x0f0f,vfloat16(v0.x),vfloat16(v2.x)), - select(0x0f0f,vfloat16(v0.y),vfloat16(v2.y)), - select(0x0f0f,vfloat16(v0.z),vfloat16(v2.z))); -#if !defined(EMBREE_BACKFACE_CULLING) - const Vec3vf16 vtx1(vfloat16(v1.x),vfloat16(v1.y),vfloat16(v1.z)); - const Vec3vf16 vtx2(vfloat16(v3.x),vfloat16(v3.y),vfloat16(v3.z)); -#else - const Vec3vf16 vtx1(select(0x0f0f,vfloat16(v1.x),vfloat16(v3.x)), - select(0x0f0f,vfloat16(v1.y),vfloat16(v3.y)), - select(0x0f0f,vfloat16(v1.z),vfloat16(v3.z))); - const Vec3vf16 vtx2(select(0x0f0f,vfloat16(v3.x),vfloat16(v1.x)), - select(0x0f0f,vfloat16(v3.y),vfloat16(v1.y)), - select(0x0f0f,vfloat16(v3.z),vfloat16(v1.z))); -#endif - - const vbool16 flags(0xf0f0); - return PlueckerIntersector1KTriangleM::intersect1(ray,k,vtx0,vtx1,vtx2,flags,epilog); - } - - __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect1(ray,k,v0,v1,v2,v3,Intersect1KEpilogM<8,16,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); - } - - __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, - const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, - const vuint4& geomID, const vuint4& primID) const - { - return intersect1(ray,k,v0,v1,v2,v3,Occluded1KEpilogM<8,16,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); - } - }; - -#elif defined(__AVX__) +#if defined(__AVX__) /*! Intersects 4 quads with 1 ray using AVX */ template<int K, bool filter> @@ -506,21 +415,21 @@ namespace embree const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); #endif - return PlueckerIntersector1KTriangleM::intersect1(ray,k,vtx0,vtx1,vtx2,flags,epilog); + return PlueckerIntersector1KTriangleM::intersect1<8,K>(ray,k,vtx0,vtx1,vtx2,flags,epilog); } __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect1(ray,k,v0,v1,v2,v3,Intersect1KEpilogM<8,8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); + return intersect1(ray,k,v0,v1,v2,v3,Intersect1KEpilogM<8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); } __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const vuint4& geomID, const vuint4& primID) const { - return intersect1(ray,k,v0,v1,v2,v3,Occluded1KEpilogM<8,8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); + return intersect1(ray,k,v0,v1,v2,v3,Occluded1KEpilogM<8,K,filter>(ray,k,context,vuint8(geomID),vuint8(primID))); } }; diff --git a/thirdparty/embree-aarch64/kernels/geometry/quadi.h b/thirdparty/embree/kernels/geometry/quadi.h index 741ec519ab..70a7bdf158 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quadi.h +++ b/thirdparty/embree/kernels/geometry/quadi.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -349,7 +349,7 @@ namespace embree const QuadMesh* mesh = scene->get<QuadMesh>(geomID(index)); vfloat<K> ftime; - const vint<K> itime = mesh->timeSegment(time, ftime); + const vint<K> itime = mesh->timeSegment<K>(time, ftime); const size_t first = bsf(movemask(valid)); if (likely(all(valid,itime[first] == itime))) @@ -361,10 +361,10 @@ namespace embree } else { - p0 = getVertex<0>(valid, index, scene, itime, ftime); - p1 = getVertex<1>(valid, index, scene, itime, ftime); - p2 = getVertex<2>(valid, index, scene, itime, ftime); - p3 = getVertex<3>(valid, index, scene, itime, ftime); + p0 = getVertex<0,K>(valid, index, scene, itime, ftime); + p1 = getVertex<1,K>(valid, index, scene, itime, ftime); + p2 = getVertex<2,K>(valid, index, scene, itime, ftime); + p3 = getVertex<3,K>(valid, index, scene, itime, ftime); } } diff --git a/thirdparty/embree-aarch64/kernels/geometry/quadi_intersector.h b/thirdparty/embree/kernels/geometry/quadi_intersector.h index 96cf7f1ca2..20a98c3406 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quadi_intersector.h +++ b/thirdparty/embree/kernels/geometry/quadi_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -230,7 +230,7 @@ namespace embree { if (!quad.valid(i)) break; STAT3(normal.trav_prims,1,popcnt(valid_i),K); - Vec3vf<K> v0,v1,v2,v3; quad.gather(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); + Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); pre.intersectK(valid_i,ray,v0,v1,v2,v3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i)); } } @@ -243,7 +243,7 @@ namespace embree { if (!quad.valid(i)) break; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - Vec3vf<K> v0,v1,v2,v3; quad.gather(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); + Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); if (pre.intersectK(valid0,ray,v0,v1,v2,v3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i))) break; } @@ -310,7 +310,7 @@ namespace embree { if (!quad.valid(i)) break; STAT3(normal.trav_prims,1,popcnt(valid_i),K); - Vec3vf<K> v0,v1,v2,v3; quad.gather(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); + Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); pre.intersectK(valid_i,ray,v0,v1,v2,v3,IntersectKEpilogM<M,K,filter>(ray,context,quad.geomID(),quad.primID(),i)); } } @@ -323,7 +323,7 @@ namespace embree { if (!quad.valid(i)) break; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - Vec3vf<K> v0,v1,v2,v3; quad.gather(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); + Vec3vf<K> v0,v1,v2,v3; quad.template gather<K>(valid_i,v0,v1,v2,v3,i,context->scene,ray.time()); if (pre.intersectK(valid0,ray,v0,v1,v2,v3,OccludedKEpilogM<M,K,filter>(valid0,ray,context,quad.geomID(),quad.primID(),i))) break; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/quadv.h b/thirdparty/embree/kernels/geometry/quadv.h index 0a1fe4d128..2137356ff2 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quadv.h +++ b/thirdparty/embree/kernels/geometry/quadv.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/quadv_intersector.h b/thirdparty/embree/kernels/geometry/quadv_intersector.h index 30a24b291a..9b28e05614 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/quadv_intersector.h +++ b/thirdparty/embree/kernels/geometry/quadv_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/roundline_intersector.h b/thirdparty/embree/kernels/geometry/roundline_intersector.h index cdf68f486b..0e9393442b 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/roundline_intersector.h +++ b/thirdparty/embree/kernels/geometry/roundline_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -81,7 +81,11 @@ namespace embree __forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); } __forceinline float t (const size_t i) const { return vt[i]; } __forceinline Vec3fa Ng(const size_t i) const { return Vec3fa(vNg.x[i],vNg.y[i],vNg.z[i]); } - + + __forceinline Vec2vf<M> uv() const { return Vec2vf<M>(vu,vv); } + __forceinline vfloat<M> t () const { return vt; } + __forceinline Vec3vf<M> Ng() const { return vNg; } + public: vfloat<M> vu; vfloat<M> vv; @@ -646,14 +650,15 @@ namespace embree struct RoundLinearCurveIntersector1 { typedef CurvePrecalculations1 Precalculations; - + + template<typename Ray> struct ray_tfar { Ray& ray; __forceinline ray_tfar(Ray& ray) : ray(ray) {} __forceinline vfloat<M> operator() () const { return ray.tfar; }; }; - - template<typename Epilog> + + template<typename Ray, typename Epilog> static __forceinline bool intersect(const vbool<M>& valid_i, Ray& ray, IntersectContext* context, @@ -666,11 +671,11 @@ namespace embree const Vec3vf<M> ray_org(ray.org.x, ray.org.y, ray.org.z); const Vec3vf<M> ray_dir(ray.dir.x, ray.dir.y, ray.dir.z); const vfloat<M> ray_tnear(ray.tnear()); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); - const Vec4vf<M> v1 = enlargeRadiusToMinWidth(context,geom,ray_org,v1i); - const Vec4vf<M> vL = enlargeRadiusToMinWidth(context,geom,ray_org,vLi); - const Vec4vf<M> vR = enlargeRadiusToMinWidth(context,geom,ray_org,vRi); - return __roundline_internal::intersectConeSphere(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray),v0,v1,vL,vR,epilog); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); + const Vec4vf<M> v1 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v1i); + const Vec4vf<M> vL = enlargeRadiusToMinWidth<M>(context,geom,ray_org,vLi); + const Vec4vf<M> vR = enlargeRadiusToMinWidth<M>(context,geom,ray_org,vRi); + return __roundline_internal::intersectConeSphere<M>(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar<Ray>(ray),v0,v1,vL,vR,epilog); } }; @@ -699,11 +704,11 @@ namespace embree const Vec3vf<M> ray_org(ray.org.x[k], ray.org.y[k], ray.org.z[k]); const Vec3vf<M> ray_dir(ray.dir.x[k], ray.dir.y[k], ray.dir.z[k]); const vfloat<M> ray_tnear = ray.tnear()[k]; - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); - const Vec4vf<M> v1 = enlargeRadiusToMinWidth(context,geom,ray_org,v1i); - const Vec4vf<M> vL = enlargeRadiusToMinWidth(context,geom,ray_org,vLi); - const Vec4vf<M> vR = enlargeRadiusToMinWidth(context,geom,ray_org,vRi); - return __roundline_internal::intersectConeSphere(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray,k),v0,v1,vL,vR,epilog); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); + const Vec4vf<M> v1 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v1i); + const Vec4vf<M> vL = enlargeRadiusToMinWidth<M>(context,geom,ray_org,vLi); + const Vec4vf<M> vR = enlargeRadiusToMinWidth<M>(context,geom,ray_org,vRi); + return __roundline_internal::intersectConeSphere<M>(valid_i,ray_org,ray_dir,ray_tnear,ray_tfar(ray,k),v0,v1,vL,vR,epilog); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/roundlinei_intersector.h b/thirdparty/embree/kernels/geometry/roundlinei_intersector.h index 079817335e..29061d6475 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/roundlinei_intersector.h +++ b/thirdparty/embree/kernels/geometry/roundlinei_intersector.h @@ -1,18 +1,5 @@ -// ======================================================================== // -// Copyright 2009-2020 Intel Corporation // -// // -// Licensed under the Apache License, Version 2.0 (the "License"); // -// you may not use this file except in compliance with the License. // -// You may obtain a copy of the License at // -// // -// http://www.apache.org/licenses/LICENSE-2.0 // -// // -// Unless required by applicable law or agreed to in writing, software // -// distributed under the License is distributed on an "AS IS" BASIS, // -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // -// See the License for the specific language governing permissions and // -// limitations under the License. // -// ======================================================================== // +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 #pragma once @@ -23,7 +10,7 @@ namespace embree { namespace isa { - template<int M, int Mx, bool filter> + template<int M, bool filter> struct RoundLinearCurveMiIntersector1 { typedef LineMi<M> Primitive; @@ -34,8 +21,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - RoundLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Intersect1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + RoundLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Intersect1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& line) @@ -43,8 +30,8 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - return RoundLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Occluded1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return RoundLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Occluded1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& line) @@ -53,7 +40,7 @@ namespace embree } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct RoundLinearCurveMiMBIntersector1 { typedef LineMi<M> Primitive; @@ -64,8 +51,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom,ray.time()); - const vbool<Mx> valid = line.template valid<Mx>(); - RoundLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Intersect1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + RoundLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Intersect1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& line) @@ -73,8 +60,8 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom,ray.time()); - const vbool<Mx> valid = line.template valid<Mx>(); - return RoundLinearCurveIntersector1<Mx>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Occluded1EpilogM<M,Mx,filter>(ray,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return RoundLinearCurveIntersector1<M>::intersect(valid,ray,context,geom,pre,v0,v1,vL,vR,Occluded1EpilogM<M,filter>(ray,context,line.geomID(),line.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& line) @@ -83,7 +70,7 @@ namespace embree } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct RoundLinearCurveMiIntersectorK { typedef LineMi<M> Primitive; @@ -94,8 +81,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - RoundLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + RoundLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Intersect1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& line) @@ -103,12 +90,12 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom); - const vbool<Mx> valid = line.template valid<Mx>(); - return RoundLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return RoundLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Occluded1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct RoundLinearCurveMiMBIntersectorK { typedef LineMi<M> Primitive; @@ -119,8 +106,8 @@ namespace embree STAT3(normal.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom,ray.time()[k]); - const vbool<Mx> valid = line.template valid<Mx>(); - RoundLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + RoundLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Intersect1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } static __forceinline bool occluded(const Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& line) @@ -128,8 +115,8 @@ namespace embree STAT3(shadow.trav_prims,1,1,1); const LineSegments* geom = context->scene->get<LineSegments>(line.geomID()); Vec4vf<M> v0,v1,vL,vR; line.gather(v0,v1,vL,vR,geom,ray.time()[k]); - const vbool<Mx> valid = line.template valid<Mx>(); - return RoundLinearCurveIntersectorK<Mx,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,line.geomID(),line.primID())); + const vbool<M> valid = line.valid(); + return RoundLinearCurveIntersectorK<M,K>::intersect(valid,ray,k,context,geom,pre,v0,v1,vL,vR,Occluded1KEpilogM<M,K,filter>(ray,k,context,line.geomID(),line.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/sphere_intersector.h b/thirdparty/embree/kernels/geometry/sphere_intersector.h index 3ab90c29ef..2670f9762d 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/sphere_intersector.h +++ b/thirdparty/embree/kernels/geometry/sphere_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -105,7 +105,7 @@ namespace embree const Precalculations& pre, const Vec4vf<M>& v0i, const Epilog& epilog) { const Vec3vf<M> ray_org(ray.org.x, ray.org.y, ray.org.z); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); return intersect(valid_i,ray,pre,v0,epilog); } }; @@ -130,7 +130,7 @@ namespace embree const Vec3vf<M> ray_dir(ray.dir.x[k], ray.dir.y[k], ray.dir.z[k]); const vfloat<M> rd2 = rcp(dot(ray_dir, ray_dir)); - const Vec4vf<M> v0 = enlargeRadiusToMinWidth(context,geom,ray_org,v0i); + const Vec4vf<M> v0 = enlargeRadiusToMinWidth<M>(context,geom,ray_org,v0i); const Vec3vf<M> center = v0.xyz(); const vfloat<M> radius = v0.w; diff --git a/thirdparty/embree-aarch64/kernels/geometry/spherei_intersector.h b/thirdparty/embree/kernels/geometry/spherei_intersector.h index 1146847602..7a0b428117 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/spherei_intersector.h +++ b/thirdparty/embree/kernels/geometry/spherei_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,7 +11,7 @@ namespace embree { namespace isa { - template<int M, int Mx, bool filter> + template<int M, bool filter> struct SphereMiIntersector1 { typedef PointMi<M> Primitive; @@ -25,9 +25,9 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom); - const vbool<Mx> valid = sphere.template valid<Mx>(); - SphereIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, Mx, filter>(ray, context, sphere.geomID(), sphere.primID())); + const vbool<M> valid = sphere.valid(); + SphereIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, filter>(ray, context, sphere.geomID(), sphere.primID())); } static __forceinline bool occluded(const Precalculations& pre, @@ -38,9 +38,9 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom); - const vbool<Mx> valid = sphere.template valid<Mx>(); - return SphereIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, Mx, filter>(ray, context, sphere.geomID(), sphere.primID())); + const vbool<M> valid = sphere.valid(); + return SphereIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, filter>(ray, context, sphere.geomID(), sphere.primID())); } static __forceinline bool pointQuery(PointQuery* query, @@ -51,7 +51,7 @@ namespace embree } }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct SphereMiMBIntersector1 { typedef PointMi<M> Primitive; @@ -65,9 +65,9 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom, ray.time()); - const vbool<Mx> valid = sphere.template valid<Mx>(); - SphereIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, Mx, filter>(ray, context, sphere.geomID(), sphere.primID())); + const vbool<M> valid = sphere.valid(); + SphereIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Intersect1EpilogM<M, filter>(ray, context, sphere.geomID(), sphere.primID())); } static __forceinline bool occluded(const Precalculations& pre, @@ -78,9 +78,9 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom, ray.time()); - const vbool<Mx> valid = sphere.template valid<Mx>(); - return SphereIntersector1<Mx>::intersect( - valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, Mx, filter>(ray, context, sphere.geomID(), sphere.primID())); + const vbool<M> valid = sphere.valid(); + return SphereIntersector1<M>::intersect( + valid, ray, context, geom, pre, v0, Occluded1EpilogM<M, filter>(ray, context, sphere.geomID(), sphere.primID())); } static __forceinline bool pointQuery(PointQuery* query, @@ -91,7 +91,7 @@ namespace embree } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct SphereMiIntersectorK { typedef PointMi<M> Primitive; @@ -103,10 +103,10 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom); - const vbool<Mx> valid = sphere.template valid<Mx>(); - SphereIntersectorK<Mx, K>::intersect( + const vbool<M> valid = sphere.valid(); + SphereIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Intersect1KEpilogM<M, Mx, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); + Intersect1KEpilogM<M, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); } static __forceinline bool occluded( @@ -115,14 +115,14 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom); - const vbool<Mx> valid = sphere.template valid<Mx>(); - return SphereIntersectorK<Mx, K>::intersect( + const vbool<M> valid = sphere.valid(); + return SphereIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Occluded1KEpilogM<M, Mx, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); + Occluded1KEpilogM<M, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); } }; - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct SphereMiMBIntersectorK { typedef PointMi<M> Primitive; @@ -134,10 +134,10 @@ namespace embree STAT3(normal.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom, ray.time()[k]); - const vbool<Mx> valid = sphere.template valid<Mx>(); - SphereIntersectorK<Mx, K>::intersect( + const vbool<M> valid = sphere.valid(); + SphereIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Intersect1KEpilogM<M, Mx, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); + Intersect1KEpilogM<M, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); } static __forceinline bool occluded( @@ -146,10 +146,10 @@ namespace embree STAT3(shadow.trav_prims, 1, 1, 1); const Points* geom = context->scene->get<Points>(sphere.geomID()); Vec4vf<M> v0; sphere.gather(v0, geom, ray.time()[k]); - const vbool<Mx> valid = sphere.template valid<Mx>(); - return SphereIntersectorK<Mx, K>::intersect( + const vbool<M> valid = sphere.valid(); + return SphereIntersectorK<M, K>::intersect( valid, ray, k, context, geom, pre, v0, - Occluded1KEpilogM<M, Mx, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); + Occluded1KEpilogM<M, K, filter>(ray, k, context, sphere.geomID(), sphere.primID())); } }; } // namespace isa diff --git a/thirdparty/embree-aarch64/kernels/geometry/subdivpatch1.h b/thirdparty/embree/kernels/geometry/subdivpatch1.h index 94ad46ad87..ae0d4e2616 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/subdivpatch1.h +++ b/thirdparty/embree/kernels/geometry/subdivpatch1.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/subdivpatch1_intersector.h b/thirdparty/embree/kernels/geometry/subdivpatch1_intersector.h index 74ec1de258..b4b15a1210 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/subdivpatch1_intersector.h +++ b/thirdparty/embree/kernels/geometry/subdivpatch1_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -43,28 +43,28 @@ namespace embree } /*! Intersect a ray with the primitive. */ - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) GridSOAIntersector1::intersect(pre,ray,context,prim,lazy_node); else processLazyNode(pre,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) { + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { intersect(This,pre,ray,context,prim,ty,tray,lazy_node); } /*! Test if the ray is occluded by the primitive */ - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) return GridSOAIntersector1::occluded(pre,ray,context,prim,lazy_node); else return processLazyNode(pre,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) { + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { return occluded(This,pre,ray,context,prim,ty,tray,lazy_node); } @@ -100,28 +100,28 @@ namespace embree } /*! Intersect a ray with the primitive. */ - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) GridSOAMBIntersector1::intersect(pre,ray,context,prim,lazy_node); else processLazyNode(pre,ray,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) { + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { intersect(This,pre,ray,context,prim,ty,tray,lazy_node); } /*! Test if the ray is occluded by the primitive */ - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) return GridSOAMBIntersector1::occluded(pre,ray,context,prim,lazy_node); else return processLazyNode(pre,ray,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) { + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { return occluded(This,pre,ray,context,prim,ty,tray,lazy_node); } @@ -133,7 +133,7 @@ namespace embree return false; } - template<int N, int Nx, bool robust> + template<int N, bool robust> static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravPointQuery<N> &tquery, size_t& lazy_node) { return pointQuery(This,query,context,prim,ty,tquery,lazy_node); } @@ -166,15 +166,15 @@ namespace embree else return processLazyNode(pre,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) GridSOAIntersectorK<K>::intersect(pre,ray,k,context,prim,lazy_node); else processLazyNode(pre,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) return GridSOAIntersectorK<K>::occluded(pre,ray,k,context,prim,lazy_node); else return processLazyNode(pre,context,prim,lazy_node); @@ -215,15 +215,15 @@ namespace embree else return processLazyNode(pre,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) GridSOAMBIntersectorK<K>::intersect(pre,ray,k,context,prim,lazy_node); else processLazyNode(pre,context,prim,lazy_node); } - template<int N, int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<int N, bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { if (likely(ty == 0)) return GridSOAMBIntersectorK<K>::occluded(pre,ray,k,context,prim,lazy_node); else return processLazyNode(pre,context,prim,lazy_node); diff --git a/thirdparty/embree-aarch64/kernels/geometry/subgrid.h b/thirdparty/embree/kernels/geometry/subgrid.h index 39fa6fb0f0..ce54421cab 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/subgrid.h +++ b/thirdparty/embree/kernels/geometry/subgrid.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector.h b/thirdparty/embree/kernels/geometry/subgrid_intersector.h index 045eee4329..ad5fee2e4e 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/subgrid_intersector.h +++ b/thirdparty/embree/kernels/geometry/subgrid_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -53,14 +53,14 @@ namespace embree return accel->pointQuery(query, context); } - template<int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); #if defined(__AVX__) STAT3(normal.trav_hit_boxes[popcnt(mask)],1,1,1); @@ -75,15 +75,15 @@ namespace embree } } } - template<int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); while(mask != 0) { @@ -155,14 +155,14 @@ namespace embree return accel->pointQuery(query, context); } - template<int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); #if defined(__AVX__) STAT3(normal.trav_hit_boxes[popcnt(mask)],1,1,1); @@ -178,14 +178,14 @@ namespace embree } } - template<int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); while(mask != 0) { @@ -326,14 +326,14 @@ namespace embree return !valid0; } - template<int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); while(mask != 0) { @@ -346,14 +346,14 @@ namespace embree } } - template<int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); while(mask != 0) { @@ -408,7 +408,9 @@ namespace embree const Vec3vf<K> p2 = vtx[i*4+2]; const Vec3vf<K> p3 = vtx[i*4+3]; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - if (pre.intersectK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i))) + //if (pre.intersectK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i))) + if (pre.occludedK(valid0,ray,p0,p1,p2,p3,g,subgrid,i,OccludedKEpilogM<4,K,filter>(valid0,ray,context,subgrid.geomID(),subgrid.primID(),i))) + break; } return !valid0; @@ -470,14 +472,14 @@ namespace embree return !valid0; } - template<int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); while(mask != 0) { @@ -490,14 +492,14 @@ namespace embree } } - template<int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,dist); while(mask != 0) { @@ -511,8 +513,5 @@ namespace embree return false; } }; - - - } } diff --git a/thirdparty/embree/kernels/geometry/subgrid_intersector_moeller.h b/thirdparty/embree/kernels/geometry/subgrid_intersector_moeller.h new file mode 100644 index 0000000000..64937d34fe --- /dev/null +++ b/thirdparty/embree/kernels/geometry/subgrid_intersector_moeller.h @@ -0,0 +1,382 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "subgrid.h" +#include "quad_intersector_moeller.h" + +namespace embree +{ + namespace isa + { + + /* ----------------------------- */ + /* -- single ray intersectors -- */ + /* ----------------------------- */ + + template<int M> + __forceinline void interpolateUV(MoellerTrumboreHitM<M,UVIdentity<M>> &hit,const GridMesh::Grid &g, const SubGrid& subgrid, const vint<M> &stepX, const vint<M> &stepY) + { + /* correct U,V interpolation across the entire grid */ + const vint<M> sx((int)subgrid.x()); + const vint<M> sy((int)subgrid.y()); + const vint<M> sxM(sx + stepX); + const vint<M> syM(sy + stepY); + const float inv_resX = rcp((float)((int)g.resX-1)); + const float inv_resY = rcp((float)((int)g.resY-1)); + hit.U = (hit.U + (vfloat<M>)sxM * hit.absDen) * inv_resX; + hit.V = (hit.V + (vfloat<M>)syM * hit.absDen) * inv_resY; + } + + template<int M, bool filter> + struct SubGridQuadMIntersector1MoellerTrumbore; + + template<int M, bool filter> + struct SubGridQuadMIntersector1MoellerTrumbore + { + __forceinline SubGridQuadMIntersector1MoellerTrumbore() {} + + __forceinline SubGridQuadMIntersector1MoellerTrumbore(const Ray& ray, const void* ptr) {} + + __forceinline void intersect(RayHit& ray, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + UVIdentity<M> mapUV; + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); + MoellerTrumboreIntersector1<M> intersector(ray,nullptr); + Intersect1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); + + /* intersect first triangle */ + if (intersector.intersect(ray,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + + /* intersect second triangle */ + if (intersector.intersect(ray,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.absDen - hit.U; + hit.V = hit.absDen - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + } + + __forceinline bool occluded(Ray& ray, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + UVIdentity<M> mapUV; + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); + MoellerTrumboreIntersector1<M> intersector(ray,nullptr); + Occluded1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); + + /* intersect first triangle */ + if (intersector.intersect(ray,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) + return true; + } + + /* intersect second triangle */ + if (intersector.intersect(ray,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.absDen - hit.U; + hit.V = hit.absDen - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) + return true; + } + return false; + } + }; + +#if defined (__AVX__) + + /*! Intersects 4 quads with 1 ray using AVX */ + template<bool filter> + struct SubGridQuadMIntersector1MoellerTrumbore<4,filter> + { + __forceinline SubGridQuadMIntersector1MoellerTrumbore() {} + + __forceinline SubGridQuadMIntersector1MoellerTrumbore(const Ray& ray, const void* ptr) {} + + template<typename Epilog> + __forceinline bool intersect(Ray& ray, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid& subgrid, const Epilog& epilog) const + { + const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); +#if !defined(EMBREE_BACKFACE_CULLING) + const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); + const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); +#else + const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); + const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); +#endif + UVIdentity<8> mapUV; + MoellerTrumboreHitM<8,UVIdentity<8>> hit(mapUV); + MoellerTrumboreIntersector1<8> intersector(ray,nullptr); + const vbool8 flags(0,0,0,0,1,1,1,1); + if (unlikely(intersector.intersect(ray,vtx0,vtx1,vtx2,mapUV,hit))) + { + /* correct U,V interpolation across the entire grid */ + const vfloat8 U = select(flags,hit.absDen - hit.V,hit.U); + const vfloat8 V = select(flags,hit.absDen - hit.U,hit.V); + hit.U = U; + hit.V = V; + hit.vNg *= select(flags,vfloat8(-1.0f),vfloat8(1.0f)); + interpolateUV<8>(hit,g,subgrid,vint<8>(0,1,1,0,0,1,1,0),vint<8>(0,0,1,1,0,0,1,1)); + if (unlikely(epilog(hit.valid,hit))) + return true; + } + return false; + } + + __forceinline bool intersect(RayHit& ray, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + return intersect(ray,v0,v1,v2,v3,g,subgrid,Intersect1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); + } + + __forceinline bool occluded(Ray& ray, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + return intersect(ray,v0,v1,v2,v3,g,subgrid,Occluded1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); + } + }; + +#endif + + // ============================================================================================================================ + // ============================================================================================================================ + // ============================================================================================================================ + + + /* ----------------------------- */ + /* -- ray packet intersectors -- */ + /* ----------------------------- */ + + template<int K> + __forceinline void interpolateUV(const vbool<K>& valid, MoellerTrumboreHitK<K,UVIdentity<K>> &hit,const GridMesh::Grid &g, const SubGrid& subgrid, const unsigned int i) + { + /* correct U,V interpolation across the entire grid */ + const unsigned int sx = subgrid.x() + (unsigned int)(i % 2); + const unsigned int sy = subgrid.y() + (unsigned int)(i >>1); + const float inv_resX = rcp((float)(int)(g.resX-1)); + const float inv_resY = rcp((float)(int)(g.resY-1)); + hit.U = select(valid,(hit.U + vfloat<K>((float)sx) * hit.absDen) * inv_resX,hit.U); + hit.V = select(valid,(hit.V + vfloat<K>((float)sy) * hit.absDen) * inv_resY,hit.V); + } + + template<int M, int K, bool filter> + struct SubGridQuadMIntersectorKMoellerTrumboreBase + { + __forceinline SubGridQuadMIntersectorKMoellerTrumboreBase(const vbool<K>& valid, const RayK<K>& ray) {} + + template<typename Epilog> + __forceinline bool intersectK(const vbool<K>& valid, + RayK<K>& ray, + const Vec3vf<K>& v0, + const Vec3vf<K>& v1, + const Vec3vf<K>& v2, + const Vec3vf<K>& v3, + const GridMesh::Grid &g, + const SubGrid &subgrid, + const unsigned int i, + const Epilog& epilog) const + { + UVIdentity<K> mapUV; + MoellerTrumboreHitK<K,UVIdentity<K>> hit(mapUV); + MoellerTrumboreIntersectorK<M,K> intersector; + + const vbool<K> valid0 = intersector.intersectK(valid,ray,v0,v1,v3,mapUV,hit); + if (any(valid0)) + { + interpolateUV(valid0,hit,g,subgrid,i); + epilog(valid0,hit); + } + const vbool<K> valid1 = intersector.intersectK(valid,ray,v2,v3,v1,mapUV,hit); + if (any(valid1)) + { + hit.U = hit.absDen - hit.U; + hit.V = hit.absDen - hit.V; + interpolateUV(valid1,hit,g,subgrid,i); + epilog(valid1,hit); + } + return any(valid0|valid1); + } + + template<typename Epilog> + __forceinline bool occludedK(const vbool<K>& valid, + RayK<K>& ray, + const Vec3vf<K>& v0, + const Vec3vf<K>& v1, + const Vec3vf<K>& v2, + const Vec3vf<K>& v3, + const GridMesh::Grid &g, + const SubGrid &subgrid, + const unsigned int i, + const Epilog& epilog) const + { + UVIdentity<K> mapUV; + MoellerTrumboreHitK<K,UVIdentity<K>> hit(mapUV); + MoellerTrumboreIntersectorK<M,K> intersector; + + vbool<K> valid_final = valid; + const vbool<K> valid0 = intersector.intersectK(valid,ray,v0,v1,v3,mapUV,hit); + if (any(valid0)) + { + interpolateUV(valid0,hit,g,subgrid,i); + epilog(valid0,hit); + valid_final &= !valid0; + } + if (none(valid_final)) return true; + const vbool<K> valid1 = intersector.intersectK(valid,ray,v2,v3,v1,mapUV,hit); + if (any(valid1)) + { + hit.U = hit.absDen - hit.U; + hit.V = hit.absDen - hit.V; + interpolateUV(valid1,hit,g,subgrid,i); + epilog(valid1,hit); + valid_final &= !valid1; + } + return none(valid_final); + } + + static __forceinline bool intersect1(RayK<K>& ray, + size_t k, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + MoellerTrumboreHitM<M,UVIdentity<M>> &hit) + { + const Vec3vf<M> e1 = v0-v1; + const Vec3vf<M> e2 = v2-v0; + MoellerTrumboreIntersectorK<8,K> intersector; + UVIdentity<M> mapUV; + return intersector.intersectEdge(ray,k,v0,e1,e2,mapUV,hit); + } + + }; + + template<int M, int K, bool filter> + struct SubGridQuadMIntersectorKMoellerTrumbore : public SubGridQuadMIntersectorKMoellerTrumboreBase<M,K,filter> + { + __forceinline SubGridQuadMIntersectorKMoellerTrumbore(const vbool<K>& valid, const RayK<K>& ray) + : SubGridQuadMIntersectorKMoellerTrumboreBase<M,K,filter>(valid,ray) {} + + __forceinline void intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + UVIdentity<M> mapUV; + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); + Intersect1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); + MoellerTrumboreIntersectorK<M,K> intersector; + /* intersect first triangle */ + if (intersector.intersect(ray,k,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + + /* intersect second triangle */ + if (intersector.intersect(ray,k,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.absDen - hit.U; + hit.V = hit.absDen - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + } + + __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + UVIdentity<M> mapUV; + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); + Occluded1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); + MoellerTrumboreIntersectorK<M,K> intersector; + /* intersect first triangle */ + if (intersector.intersect(ray,k,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) return true; + } + + /* intersect second triangle */ + if (intersector.intersect(ray,k,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.absDen - hit.U; + hit.V = hit.absDen - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) return true; + } + return false; + } + }; + + +#if defined (__AVX__) + + /*! Intersects 4 quads with 1 ray using AVX */ + template<int K, bool filter> + struct SubGridQuadMIntersectorKMoellerTrumbore<4,K,filter> : public SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter> + { + __forceinline SubGridQuadMIntersectorKMoellerTrumbore(const vbool<K>& valid, const RayK<K>& ray) + : SubGridQuadMIntersectorKMoellerTrumboreBase<4,K,filter>(valid,ray) {} + + template<typename Epilog> + __forceinline bool intersect1(RayK<K>& ray, size_t k,const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, + const GridMesh::Grid &g, const SubGrid &subgrid, const Epilog& epilog) const + { + const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); +#if !defined(EMBREE_BACKFACE_CULLING) + const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); + const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); +#else + const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); + const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); +#endif + const vbool8 flags(0,0,0,0,1,1,1,1); + + UVIdentity<8> mapUV; + MoellerTrumboreHitM<8,UVIdentity<8>> hit(mapUV); + if (SubGridQuadMIntersectorKMoellerTrumboreBase<8,K,filter>::intersect1(ray,k,vtx0,vtx1,vtx2,hit)) + { + const vfloat8 U = select(flags,hit.absDen - hit.V,hit.U); + const vfloat8 V = select(flags,hit.absDen - hit.U,hit.V); + hit.U = U; + hit.V = V; + hit.vNg *= select(flags,vfloat8(-1.0f),vfloat8(1.0f)); + interpolateUV<8>(hit,g,subgrid,vint<8>(0,1,1,0,0,1,1,0),vint<8>(0,0,1,1,0,0,1,1)); + if (unlikely(epilog(hit.valid,hit))) + return true; + + } + return false; + } + + __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + return intersect1(ray,k,v0,v1,v2,v3,g,subgrid,Intersect1KEpilogMU<8,K,filter>(ray,k,context,subgrid.geomID(),subgrid.primID())); + } + + __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + return intersect1(ray,k,v0,v1,v2,v3,g,subgrid,Occluded1KEpilogMU<8,K,filter>(ray,k,context,subgrid.geomID(),subgrid.primID())); + } + }; + +#endif + + + + } +} diff --git a/thirdparty/embree/kernels/geometry/subgrid_intersector_pluecker.h b/thirdparty/embree/kernels/geometry/subgrid_intersector_pluecker.h new file mode 100644 index 0000000000..5ded56e1f7 --- /dev/null +++ b/thirdparty/embree/kernels/geometry/subgrid_intersector_pluecker.h @@ -0,0 +1,367 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "subgrid.h" +#include "quad_intersector_moeller.h" +#include "quad_intersector_pluecker.h" + +namespace embree +{ + namespace isa + { + + template<int M> + __forceinline void interpolateUV(PlueckerHitM<M,UVIdentity<M>> &hit,const GridMesh::Grid &g, const SubGrid& subgrid, const vint<M> &stepX, const vint<M> &stepY) + { + /* correct U,V interpolation across the entire grid */ + const vint<M> sx((int)subgrid.x()); + const vint<M> sy((int)subgrid.y()); + const vint<M> sxM(sx + stepX); + const vint<M> syM(sy + stepY); + const float inv_resX = rcp((float)((int)g.resX-1)); + const float inv_resY = rcp((float)((int)g.resY-1)); + hit.U = (hit.U + vfloat<M>(sxM) * hit.UVW) * inv_resX; + hit.V = (hit.V + vfloat<M>(syM) * hit.UVW) * inv_resY; + } + + template<int M, bool filter> + struct SubGridQuadMIntersector1Pluecker; + + template<int M, bool filter> + struct SubGridQuadMIntersector1Pluecker + { + __forceinline SubGridQuadMIntersector1Pluecker() {} + + __forceinline SubGridQuadMIntersector1Pluecker(const Ray& ray, const void* ptr) {} + + __forceinline void intersect(RayHit& ray, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + UVIdentity<M> mapUV; + PlueckerHitM<M,UVIdentity<M>> hit(mapUV); + PlueckerIntersector1<M> intersector(ray,nullptr); + + Intersect1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); + + /* intersect first triangle */ + if (intersector.intersect(ray,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + + /* intersect second triangle */ + if (intersector.intersect(ray,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.UVW - hit.U; + hit.V = hit.UVW - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + } + + __forceinline bool occluded(Ray& ray, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + UVIdentity<M> mapUV; + PlueckerHitM<M,UVIdentity<M>> hit(mapUV); + PlueckerIntersector1<M> intersector(ray,nullptr); + Occluded1EpilogMU<M,filter> epilog(ray,context,subgrid.geomID(),subgrid.primID()); + + /* intersect first triangle */ + if (intersector.intersect(ray,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) + return true; + } + + /* intersect second triangle */ + if (intersector.intersect(ray,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.UVW - hit.U; + hit.V = hit.UVW - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) + return true; + } + return false; + } + }; + +#if defined (__AVX__) + + /*! Intersects 4 quads with 1 ray using AVX */ + template<bool filter> + struct SubGridQuadMIntersector1Pluecker<4,filter> + { + __forceinline SubGridQuadMIntersector1Pluecker() {} + + __forceinline SubGridQuadMIntersector1Pluecker(const Ray& ray, const void* ptr) {} + + template<typename Epilog> + __forceinline bool intersect(Ray& ray, const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid& subgrid, const Epilog& epilog) const + { + const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); +#if !defined(EMBREE_BACKFACE_CULLING) + const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); + const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); +#else + const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); + const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); +#endif + + UVIdentity<8> mapUV; + PlueckerHitM<8,UVIdentity<8>> hit(mapUV); + PlueckerIntersector1<8> intersector(ray,nullptr); + const vbool8 flags(0,0,0,0,1,1,1,1); + if (unlikely(intersector.intersect(ray,vtx0,vtx1,vtx2,mapUV,hit))) + { + /* correct U,V interpolation across the entire grid */ + const vfloat8 U = select(flags,hit.UVW - hit.V,hit.U); + const vfloat8 V = select(flags,hit.UVW - hit.U,hit.V); + hit.U = U; + hit.V = V; + hit.vNg *= select(flags,vfloat8(-1.0f),vfloat8(1.0f)); + interpolateUV<8>(hit,g,subgrid,vint<8>(0,1,1,0,0,1,1,0),vint<8>(0,0,1,1,0,0,1,1)); + if (unlikely(epilog(hit.valid,hit))) + return true; + } + return false; + } + + __forceinline bool intersect(RayHit& ray, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + return intersect(ray,v0,v1,v2,v3,g,subgrid,Intersect1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); + } + + __forceinline bool occluded(Ray& ray, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, + const GridMesh::Grid &g, const SubGrid& subgrid) const + { + return intersect(ray,v0,v1,v2,v3,g,subgrid,Occluded1EpilogMU<8,filter>(ray,context,subgrid.geomID(),subgrid.primID())); + } + }; + +#endif + + + /* ----------------------------- */ + /* -- ray packet intersectors -- */ + /* ----------------------------- */ + + template<int K> + __forceinline void interpolateUV(const vbool<K>& valid, PlueckerHitK<K,UVIdentity<K>> &hit,const GridMesh::Grid &g, const SubGrid& subgrid, const unsigned int i) + { + /* correct U,V interpolation across the entire grid */ + const unsigned int sx = subgrid.x() + (unsigned int)(i % 2); + const unsigned int sy = subgrid.y() + (unsigned int)(i >>1); + const float inv_resX = rcp((float)(int)(g.resX-1)); + const float inv_resY = rcp((float)(int)(g.resY-1)); + hit.U = select(valid,(hit.U + vfloat<K>((float)sx) * hit.UVW) * inv_resX,hit.U); + hit.V = select(valid,(hit.V + vfloat<K>((float)sy) * hit.UVW) * inv_resY,hit.V); + } + + template<int M, int K, bool filter> + struct SubGridQuadMIntersectorKPlueckerBase + { + __forceinline SubGridQuadMIntersectorKPlueckerBase(const vbool<K>& valid, const RayK<K>& ray) {} + + template<typename Epilog> + __forceinline bool intersectK(const vbool<K>& valid, + RayK<K>& ray, + const Vec3vf<K>& v0, + const Vec3vf<K>& v1, + const Vec3vf<K>& v2, + const Vec3vf<K>& v3, + const GridMesh::Grid &g, + const SubGrid &subgrid, + const unsigned int i, + const Epilog& epilog) const + { + UVIdentity<K> mapUV; + PlueckerHitK<K,UVIdentity<K>> hit(mapUV); + PlueckerIntersectorK<M,K> intersector; + + const vbool<K> valid0 = intersector.intersectK(valid,ray,v0,v1,v3,mapUV,hit); + if (any(valid0)) + { + interpolateUV(valid0,hit,g,subgrid,i); + epilog(valid0,hit); + } + const vbool<K> valid1 = intersector.intersectK(valid,ray,v2,v3,v1,mapUV,hit); + if (any(valid1)) + { + hit.U = hit.UVW - hit.U; + hit.V = hit.UVW - hit.V; + interpolateUV(valid1,hit,g,subgrid,i); + epilog(valid1,hit); + } + return any(valid0|valid1); + } + + template<typename Epilog> + __forceinline bool occludedK(const vbool<K>& valid, + RayK<K>& ray, + const Vec3vf<K>& v0, + const Vec3vf<K>& v1, + const Vec3vf<K>& v2, + const Vec3vf<K>& v3, + const GridMesh::Grid &g, + const SubGrid &subgrid, + const unsigned int i, + const Epilog& epilog) const + { + UVIdentity<K> mapUV; + PlueckerHitK<K,UVIdentity<K>> hit(mapUV); + PlueckerIntersectorK<M,K> intersector; + + vbool<K> valid_final = valid; + const vbool<K> valid0 = intersector.intersectK(valid,ray,v0,v1,v3,mapUV,hit); + if (any(valid0)) + { + interpolateUV(valid0,hit,g,subgrid,i); + epilog(valid0,hit); + valid_final &= !valid0; + } + if (none(valid_final)) return true; + const vbool<K> valid1 = intersector.intersectK(valid,ray,v2,v3,v1,mapUV,hit); + if (any(valid1)) + { + hit.U = hit.UVW - hit.U; + hit.V = hit.UVW - hit.V; + interpolateUV(valid1,hit,g,subgrid,i); + epilog(valid1,hit); + valid_final &= !valid1; + } + return none(valid_final); + } + + + }; + + + + + template<int M, int K, bool filter> + struct SubGridQuadMIntersectorKPluecker : public SubGridQuadMIntersectorKPlueckerBase<M,K,filter> + { + __forceinline SubGridQuadMIntersectorKPluecker(const vbool<K>& valid, const RayK<K>& ray) + : SubGridQuadMIntersectorKPlueckerBase<M,K,filter>(valid,ray) {} + + __forceinline void intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + UVIdentity<M> mapUV; + PlueckerHitM<M,UVIdentity<M>> hit(mapUV); + Intersect1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); + PlueckerIntersectorK<M,K> intersector; + + /* intersect first triangle */ + if (intersector.intersect(ray,k,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + + /* intersect second triangle */ + if (intersector.intersect(ray,k,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.UVW - hit.U; + hit.V = hit.UVW - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + epilog(hit.valid,hit); + } + } + + __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + UVIdentity<M> mapUV; + PlueckerHitM<M,UVIdentity<M>> hit(mapUV); + Occluded1KEpilogMU<M,K,filter> epilog(ray,k,context,subgrid.geomID(),subgrid.primID()); + PlueckerIntersectorK<M,K> intersector; + + /* intersect first triangle */ + if (intersector.intersect(ray,k,v0,v1,v3,mapUV,hit)) + { + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) return true; + } + + /* intersect second triangle */ + if (intersector.intersect(ray,k,v2,v3,v1,mapUV,hit)) + { + hit.U = hit.UVW - hit.U; + hit.V = hit.UVW - hit.V; + interpolateUV<M>(hit,g,subgrid,vint<M>(0,1,1,0),vint<M>(0,0,1,1)); + if (epilog(hit.valid,hit)) return true; + } + return false; + } + }; + + +#if defined (__AVX__) + + /*! Intersects 4 quads with 1 ray using AVX */ + template<int K, bool filter> + struct SubGridQuadMIntersectorKPluecker<4,K,filter> : public SubGridQuadMIntersectorKPlueckerBase<4,K,filter> + { + __forceinline SubGridQuadMIntersectorKPluecker(const vbool<K>& valid, const RayK<K>& ray) + : SubGridQuadMIntersectorKPlueckerBase<4,K,filter>(valid,ray) {} + + template<typename Epilog> + __forceinline bool intersect1(RayK<K>& ray, size_t k,const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, + const GridMesh::Grid &g, const SubGrid &subgrid, const Epilog& epilog) const + { + const Vec3vf8 vtx0(vfloat8(v0.x,v2.x),vfloat8(v0.y,v2.y),vfloat8(v0.z,v2.z)); +#if !defined(EMBREE_BACKFACE_CULLING) + const Vec3vf8 vtx1(vfloat8(v1.x),vfloat8(v1.y),vfloat8(v1.z)); + const Vec3vf8 vtx2(vfloat8(v3.x),vfloat8(v3.y),vfloat8(v3.z)); +#else + const Vec3vf8 vtx1(vfloat8(v1.x,v3.x),vfloat8(v1.y,v3.y),vfloat8(v1.z,v3.z)); + const Vec3vf8 vtx2(vfloat8(v3.x,v1.x),vfloat8(v3.y,v1.y),vfloat8(v3.z,v1.z)); +#endif + UVIdentity<8> mapUV; + PlueckerHitM<8,UVIdentity<8>> hit(mapUV); + PlueckerIntersectorK<8,K> intersector; + const vbool8 flags(0,0,0,0,1,1,1,1); + if (unlikely(intersector.intersect(ray,k,vtx0,vtx1,vtx2,mapUV,hit))) + { + /* correct U,V interpolation across the entire grid */ + const vfloat8 U = select(flags,hit.UVW - hit.V,hit.U); + const vfloat8 V = select(flags,hit.UVW - hit.U,hit.V); + hit.U = U; + hit.V = V; + hit.vNg *= select(flags,vfloat8(-1.0f),vfloat8(1.0f)); + interpolateUV<8>(hit,g,subgrid,vint<8>(0,1,1,0,0,1,1,0),vint<8>(0,0,1,1,0,0,1,1)); + if (unlikely(epilog(hit.valid,hit))) + return true; + } + return false; + } + + __forceinline bool intersect1(RayHitK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + return intersect1(ray,k,v0,v1,v2,v3,g,subgrid,Intersect1KEpilogMU<8,K,filter>(ray,k,context,subgrid.geomID(),subgrid.primID())); + } + + __forceinline bool occluded1(RayK<K>& ray, size_t k, IntersectContext* context, + const Vec3vf4& v0, const Vec3vf4& v1, const Vec3vf4& v2, const Vec3vf4& v3, const GridMesh::Grid &g, const SubGrid &subgrid) const + { + return intersect1(ray,k,v0,v1,v2,v3,g,subgrid,Occluded1KEpilogMU<8,K,filter>(ray,k,context,subgrid.geomID(),subgrid.primID())); + } + }; +#endif + + + } +} diff --git a/thirdparty/embree-aarch64/kernels/geometry/subgrid_mb_intersector.h b/thirdparty/embree/kernels/geometry/subgrid_mb_intersector.h index 400a88b985..473d656e24 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/subgrid_mb_intersector.h +++ b/thirdparty/embree/kernels/geometry/subgrid_mb_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -45,13 +45,13 @@ namespace embree return PrimitivePointQuery1<Primitive>::pointQuery(query, context, subgrid); } - template<int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { - vfloat<Nx> dist; + vfloat<N> dist; const float time = prim[i].adjustTime(ray.time()); assert(time <= 1.0f); @@ -68,15 +68,15 @@ namespace embree } } - template<int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { const float time = prim[i].adjustTime(ray.time()); assert(time <= 1.0f); - vfloat<Nx> dist; + vfloat<N> dist; size_t mask = isec1.intersect(&prim[i].qnode,tray,time,dist); while(mask != 0) { @@ -132,7 +132,7 @@ namespace embree const GridMesh::Grid &g = mesh->grid(subgrid.primID()); vfloat<K> ftime; - const vint<K> itime = mesh->timeSegment(ray.time(), ftime); + const vint<K> itime = mesh->timeSegment<K>(ray.time(), ftime); Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime[k],ftime[k]); pre.intersect1(ray,k,context,v0,v1,v2,v3,g,subgrid); } @@ -144,7 +144,7 @@ namespace embree const GridMesh::Grid &g = mesh->grid(subgrid.primID()); vfloat<K> ftime; - const vint<K> itime = mesh->timeSegment(ray.time(), ftime); + const vint<K> itime = mesh->timeSegment<K>(ray.time(), ftime); Vec3vf4 v0,v1,v2,v3; subgrid.gatherMB(v0,v1,v2,v3,context->scene,itime[k],ftime[k]); return pre.occluded1(ray,k,context,v0,v1,v2,v3,g,subgrid); } @@ -156,7 +156,7 @@ namespace embree for (size_t j=0;j<num;j++) { size_t m_valid = movemask(prim[j].qnode.validMask()); - const vfloat<K> time = prim[j].adjustTime(ray.time()); + const vfloat<K> time = prim[j].template adjustTime<K>(ray.time()); vfloat<K> dist; while(m_valid) @@ -177,7 +177,7 @@ namespace embree for (size_t j=0;j<num;j++) { size_t m_valid = movemask(prim[j].qnode.validMask()); - const vfloat<K> time = prim[j].adjustTime(ray.time()); + const vfloat<K> time = prim[j].template adjustTime<K>(ray.time()); vfloat<K> dist; while(m_valid) { @@ -190,10 +190,10 @@ namespace embree return !valid0; } - template<int Nx, bool robust> - static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { vfloat<N> dist; @@ -210,10 +210,10 @@ namespace embree } } - template<int Nx, bool robust> - static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,Nx,robust> &tray, size_t& lazy_node) + template<bool robust> + static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node) { - BVHNQuantizedBaseNodeIntersector1<N,Nx,robust> isec1; + BVHNQuantizedBaseNodeIntersector1<N,robust> isec1; for (size_t i=0;i<num;i++) { diff --git a/thirdparty/embree-aarch64/kernels/geometry/triangle.h b/thirdparty/embree/kernels/geometry/triangle.h index 0dedf6dc4c..24b758ae48 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/triangle.h +++ b/thirdparty/embree/kernels/geometry/triangle.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector.h b/thirdparty/embree/kernels/geometry/triangle_intersector.h index 125a42c5fe..2cdff78ec8 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector.h +++ b/thirdparty/embree/kernels/geometry/triangle_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,24 +11,24 @@ namespace embree namespace isa { /*! Intersects M triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMIntersector1Moeller { typedef TriangleM<M> Primitive; - typedef MoellerTrumboreIntersector1<Mx> Precalculations; + typedef MoellerTrumboreIntersector1<M> Precalculations; /*! Intersect a ray with the M triangles and updates the hit. */ static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const TriangleM<M>& tri) { STAT3(normal.trav_prims,1,1,1); - pre.intersectEdge(ray,tri.v0,tri.e1,tri.e2,Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersectEdge(ray,tri.v0,tri.e1,tri.e2,UVIdentity<M>(),Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of M triangles. */ static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleM<M>& tri) { STAT3(shadow.trav_prims,1,1,1); - return pre.intersectEdge(ray,tri.v0,tri.e1,tri.e2,Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersectEdge(ray,tri.v0,tri.e1,tri.e2,UVIdentity<M>(),Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -39,11 +39,11 @@ namespace embree }; /*! Intersects M triangles with K rays. */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMIntersectorKMoeller { typedef TriangleM<M> Primitive; - typedef MoellerTrumboreIntersectorK<Mx,K> Precalculations; + typedef MoellerTrumboreIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleM<M>& tri) @@ -56,7 +56,7 @@ namespace embree const Vec3vf<K> p0 = broadcast<vfloat<K>>(tri.v0,i); const Vec3vf<K> e1 = broadcast<vfloat<K>>(tri.e1,i); const Vec3vf<K> e2 = broadcast<vfloat<K>>(tri.e2,i); - pre.intersectEdgeK(valid_i,ray,p0,e1,e2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); + pre.intersectEdgeK(valid_i,ray,p0,e1,e2,UVIdentity<K>(),IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); } } @@ -72,7 +72,7 @@ namespace embree const Vec3vf<K> p0 = broadcast<vfloat<K>>(tri.v0,i); const Vec3vf<K> e1 = broadcast<vfloat<K>>(tri.e1,i); const Vec3vf<K> e2 = broadcast<vfloat<K>>(tri.e2,i); - pre.intersectEdgeK(valid0,ray,p0,e1,e2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); + pre.intersectEdgeK(valid0,ray,p0,e1,e2,UVIdentity<K>(),OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); if (none(valid0)) break; } return !valid0; @@ -82,14 +82,14 @@ namespace embree static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const TriangleM<M>& tri) { STAT3(normal.trav_prims,1,1,1); - pre.intersectEdge(ray,k,tri.v0,tri.e1,tri.e2,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + pre.intersectEdge(ray,k,tri.v0,tri.e1,tri.e2,UVIdentity<M>(),Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleM<M>& tri) { STAT3(shadow.trav_prims,1,1,1); - return pre.intersectEdge(ray,k,tri.v0,tri.e1,tri.e2,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + return pre.intersectEdge(ray,k,tri.v0,tri.e1,tri.e2,UVIdentity<M>(),Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector_moeller.h b/thirdparty/embree/kernels/geometry/triangle_intersector_moeller.h index b5a8519236..0a42d8f08b 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector_moeller.h +++ b/thirdparty/embree/kernels/geometry/triangle_intersector_moeller.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -18,13 +18,13 @@ namespace embree { namespace isa { - template<int M> + template<int M, typename UVMapper> struct MoellerTrumboreHitM { - __forceinline MoellerTrumboreHitM() {} + __forceinline MoellerTrumboreHitM(const UVMapper& mapUV) : mapUV(mapUV) {} - __forceinline MoellerTrumboreHitM(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& T, const vfloat<M>& absDen, const Vec3vf<M>& Ng) - : U(U), V(V), T(T), absDen(absDen), valid(valid), vNg(Ng) {} + __forceinline MoellerTrumboreHitM(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& T, const vfloat<M>& absDen, const Vec3vf<M>& Ng, const UVMapper& mapUV) + : U(U), V(V), T(T), absDen(absDen), mapUV(mapUV), valid(valid), vNg(Ng) {} __forceinline void finalize() { @@ -32,8 +32,13 @@ namespace embree vt = T * rcpAbsDen; vu = U * rcpAbsDen; vv = V * rcpAbsDen; + mapUV(vu,vv,vNg); } + __forceinline Vec2vf<M> uv() const { return Vec2vf<M>(vu,vv); } + __forceinline vfloat<M> t () const { return vt; } + __forceinline Vec3vf<M> Ng() const { return vNg; } + __forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); } __forceinline float t (const size_t i) const { return vt[i]; } __forceinline Vec3fa Ng(const size_t i) const { return Vec3fa(vNg.x[i],vNg.y[i],vNg.z[i]); } @@ -43,6 +48,7 @@ namespace embree vfloat<M> V; vfloat<M> T; vfloat<M> absDen; + UVMapper mapUV; public: vbool<M> valid; @@ -52,20 +58,22 @@ namespace embree Vec3vf<M> vNg; }; - template<int M> + template<int M, bool early_out = true> struct MoellerTrumboreIntersector1 { __forceinline MoellerTrumboreIntersector1() {} __forceinline MoellerTrumboreIntersector1(const Ray& ray, const void* ptr) {} + template<typename UVMapper> __forceinline bool intersect(const vbool<M>& valid0, Ray& ray, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_e1, const Vec3vf<M>& tri_e2, const Vec3vf<M>& tri_Ng, - MoellerTrumboreHitM<M>& hit) const + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const { /* calculate denominator */ vbool<M> valid = valid0; @@ -88,122 +96,160 @@ namespace embree #else valid &= (den != vfloat<M>(zero)) & (U >= 0.0f) & (V >= 0.0f) & (U+V<=absDen); #endif - if (likely(none(valid))) return false; + if (likely(early_out && none(valid))) return false; /* perform depth test */ const vfloat<M> T = dot(Vec3vf<M>(tri_Ng),C) ^ sgnDen; valid &= (absDen*vfloat<M>(ray.tnear()) < T) & (T <= absDen*vfloat<M>(ray.tfar)); - if (likely(none(valid))) return false; - - + if (likely(early_out && none(valid))) return false; + /* update hit information */ - new (&hit) MoellerTrumboreHitM<M>(valid,U,V,T,absDen,tri_Ng); + new (&hit) MoellerTrumboreHitM<M,UVMapper>(valid,U,V,T,absDen,tri_Ng,mapUV); return true; } + template<typename UVMapper> + __forceinline bool intersectEdge(const vbool<M>& valid, + Ray& ray, + const Vec3vf<M>& tri_v0, + const Vec3vf<M>& tri_e1, + const Vec3vf<M>& tri_e2, + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const + { + const Vec3<vfloat<M>> tri_Ng = cross(tri_e2,tri_e1); + return intersect(valid,ray,tri_v0,tri_e1,tri_e2,tri_Ng,mapUV,hit); + } + + template<typename UVMapper> __forceinline bool intersectEdge(Ray& ray, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_e1, const Vec3vf<M>& tri_e2, - MoellerTrumboreHitM<M>& hit) const + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const { vbool<M> valid = true; const Vec3<vfloat<M>> tri_Ng = cross(tri_e2,tri_e1); - return intersect(valid,ray,tri_v0,tri_e1,tri_e2,tri_Ng,hit); + return intersect(valid,ray,tri_v0,tri_e1,tri_e2,tri_Ng,mapUV,hit); } - + + template<typename UVMapper> __forceinline bool intersect(Ray& ray, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, - MoellerTrumboreHitM<M>& hit) const + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const { const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v2-v0; - return intersectEdge(ray,v0,e1,e2,hit); + return intersectEdge(ray,v0,e1,e2,mapUV,hit); } + template<typename UVMapper> __forceinline bool intersect(const vbool<M>& valid, Ray& ray, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, - MoellerTrumboreHitM<M>& hit) const + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const { const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v2-v0; - return intersectEdge(valid,ray,v0,e1,e2,hit); + return intersectEdge(valid,ray,v0,e1,e2,mapUV,hit); } - template<typename Epilog> + template<typename UVMapper, typename Epilog> __forceinline bool intersectEdge(Ray& ray, const Vec3vf<M>& v0, const Vec3vf<M>& e1, const Vec3vf<M>& e2, + const UVMapper& mapUV, const Epilog& epilog) const { - MoellerTrumboreHitM<M> hit; - if (likely(intersectEdge(ray,v0,e1,e2,hit))) return epilog(hit.valid,hit); + MoellerTrumboreHitM<M,UVMapper> hit(mapUV); + if (likely(intersectEdge(ray,v0,e1,e2,mapUV,hit))) return epilog(hit.valid,hit); return false; } - template<typename Epilog> + template<typename UVMapper, typename Epilog> __forceinline bool intersect(Ray& ray, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, + const UVMapper& mapUV, const Epilog& epilog) const { - MoellerTrumboreHitM<M> hit; - if (likely(intersect(ray,v0,v1,v2,hit))) return epilog(hit.valid,hit); + MoellerTrumboreHitM<M,UVMapper> hit(mapUV); + if (likely(intersect(ray,v0,v1,v2,mapUV,hit))) return epilog(hit.valid,hit); return false; } template<typename Epilog> + __forceinline bool intersect(Ray& ray, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + const Epilog& epilog) const + { + auto mapUV = UVIdentity<M>(); + MoellerTrumboreHitM<M,UVIdentity<M>> hit(mapUV); + if (likely(intersect(ray,v0,v1,v2,mapUV,hit))) return epilog(hit.valid,hit); + return false; + } + + template<typename UVMapper, typename Epilog> __forceinline bool intersect(const vbool<M>& valid, Ray& ray, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, + const UVMapper& mapUV, const Epilog& epilog) const { - MoellerTrumboreHitM<M> hit; - if (likely(intersect(valid,ray,v0,v1,v2,hit))) return epilog(hit.valid,hit); + MoellerTrumboreHitM<M,UVMapper> hit(mapUV); + if (likely(intersect(valid,ray,v0,v1,v2,mapUV,hit))) return epilog(hit.valid,hit); return false; } }; - template<int K> + template<int K, typename UVMapper> struct MoellerTrumboreHitK { - __forceinline MoellerTrumboreHitK(const vfloat<K>& U, const vfloat<K>& V, const vfloat<K>& T, const vfloat<K>& absDen, const Vec3vf<K>& Ng) - : U(U), V(V), T(T), absDen(absDen), Ng(Ng) {} + __forceinline MoellerTrumboreHitK(const UVMapper& mapUV) : mapUV(mapUV) {} + __forceinline MoellerTrumboreHitK(const vfloat<K>& U, const vfloat<K>& V, const vfloat<K>& T, const vfloat<K>& absDen, const Vec3vf<K>& Ng, const UVMapper& mapUV) + : U(U), V(V), T(T), absDen(absDen), Ng(Ng), mapUV(mapUV) {} __forceinline std::tuple<vfloat<K>,vfloat<K>,vfloat<K>,Vec3vf<K>> operator() () const { const vfloat<K> rcpAbsDen = rcp(absDen); const vfloat<K> t = T * rcpAbsDen; - const vfloat<K> u = U * rcpAbsDen; - const vfloat<K> v = V * rcpAbsDen; - return std::make_tuple(u,v,t,Ng); + vfloat<K> u = U * rcpAbsDen; + vfloat<K> v = V * rcpAbsDen; + Vec3vf<K> vNg = Ng; + mapUV(u,v,vNg); + return std::make_tuple(u,v,t,vNg); } - private: - const vfloat<K> U; - const vfloat<K> V; + vfloat<K> U; + vfloat<K> V; const vfloat<K> T; const vfloat<K> absDen; const Vec3vf<K> Ng; + const UVMapper& mapUV; }; template<int M, int K> struct MoellerTrumboreIntersectorK { + __forceinline MoellerTrumboreIntersectorK() {} __forceinline MoellerTrumboreIntersectorK(const vbool<K>& valid, const RayK<K>& ray) {} /*! Intersects K rays with one of M triangles. */ - template<typename Epilog> + template<typename UVMapper> __forceinline vbool<K> intersectK(const vbool<K>& valid0, //RayK<K>& ray, const Vec3vf<K>& ray_org, @@ -214,7 +260,8 @@ namespace embree const Vec3vf<K>& tri_e1, const Vec3vf<K>& tri_e2, const Vec3vf<K>& tri_Ng, - const Epilog& epilog) const + const UVMapper& mapUV, + MoellerTrumboreHitK<K,UVMapper> &hit) const { /* calculate denominator */ vbool<K> valid = valid0; @@ -254,11 +301,47 @@ namespace embree #endif /* calculate hit information */ - MoellerTrumboreHitK<K> hit(U,V,T,absDen,tri_Ng); - return epilog(valid,hit); + new (&hit) MoellerTrumboreHitK<K,UVMapper>(U,V,T,absDen,tri_Ng,mapUV); + return valid; + } + + /*! Intersects K rays with one of M triangles. */ + template<typename UVMapper> + __forceinline vbool<K> intersectK(const vbool<K>& valid0, + RayK<K>& ray, + const Vec3vf<K>& tri_v0, + const Vec3vf<K>& tri_v1, + const Vec3vf<K>& tri_v2, + const UVMapper& mapUV, + MoellerTrumboreHitK<K,UVMapper> &hit) const + { + const Vec3vf<K> e1 = tri_v0-tri_v1; + const Vec3vf<K> e2 = tri_v2-tri_v0; + const Vec3vf<K> Ng = cross(e2,e1); + return intersectK(valid0,ray.org,ray.dir,ray.tnear(),ray.tfar,tri_v0,e1,e2,Ng,mapUV,hit); } + /*! Intersects K rays with one of M triangles. */ + template<typename UVMapper, typename Epilog> + __forceinline vbool<K> intersectK(const vbool<K>& valid0, + RayK<K>& ray, + const Vec3vf<K>& tri_v0, + const Vec3vf<K>& tri_v1, + const Vec3vf<K>& tri_v2, + const UVMapper& mapUV, + const Epilog& epilog) const + { + MoellerTrumboreHitK<K,UVIdentity<K>> hit(mapUV); + const Vec3vf<K> e1 = tri_v0-tri_v1; + const Vec3vf<K> e2 = tri_v2-tri_v0; + const Vec3vf<K> Ng = cross(e2,e1); + const vbool<K> valid = intersectK(valid0,ray.org,ray.dir,ray.tnear(),ray.tfar,tri_v0,e1,e2,Ng,mapUV,hit); + return epilog(valid,hit); + } + + + template<typename Epilog> __forceinline vbool<K> intersectK(const vbool<K>& valid0, RayK<K>& ray, @@ -267,32 +350,40 @@ namespace embree const Vec3vf<K>& tri_v2, const Epilog& epilog) const { + UVIdentity<K> mapUV; + MoellerTrumboreHitK<K,UVIdentity<K>> hit(mapUV); const Vec3vf<K> e1 = tri_v0-tri_v1; const Vec3vf<K> e2 = tri_v2-tri_v0; const Vec3vf<K> Ng = cross(e2,e1); - return intersectK(valid0,ray.org,ray.dir,ray.tnear(),ray.tfar,tri_v0,e1,e2,Ng,epilog); + const vbool<K> valid = intersectK(valid0,ray.org,ray.dir,ray.tnear(),ray.tfar,tri_v0,e1,e2,Ng,mapUV,hit); + return epilog(valid,hit); } /*! Intersects K rays with one of M triangles. */ - template<typename Epilog> + template<typename UVMapper, typename Epilog> __forceinline vbool<K> intersectEdgeK(const vbool<K>& valid0, RayK<K>& ray, const Vec3vf<K>& tri_v0, const Vec3vf<K>& tri_e1, - const Vec3vf<K>& tri_e2, + const Vec3vf<K>& tri_e2, + const UVMapper& mapUV, const Epilog& epilog) const { + MoellerTrumboreHitK<K,UVIdentity<K>> hit(mapUV); const Vec3vf<K> tri_Ng = cross(tri_e2,tri_e1); - return intersectK(valid0,ray.org,ray.dir,ray.tnear(),ray.tfar,tri_v0,tri_e1,tri_e2,tri_Ng,epilog); + const vbool<K> valid = intersectK(valid0,ray.org,ray.dir,ray.tnear(),ray.tfar,tri_v0,tri_e1,tri_e2,tri_Ng,mapUV,hit); + return epilog(valid,hit); } /*! Intersect k'th ray from ray packet of size K with M triangles. */ + template<typename UVMapper> __forceinline bool intersectEdge(RayK<K>& ray, size_t k, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_e1, const Vec3vf<M>& tri_e2, - MoellerTrumboreHitM<M>& hit) const + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const { /* calculate denominator */ typedef Vec3vf<M> Vec3vfM; @@ -324,19 +415,21 @@ namespace embree if (likely(none(valid))) return false; /* calculate hit information */ - new (&hit) MoellerTrumboreHitM<M>(valid,U,V,T,absDen,tri_Ng); + new (&hit) MoellerTrumboreHitM<M,UVMapper>(valid,U,V,T,absDen,tri_Ng,mapUV); return true; } + template<typename UVMapper> __forceinline bool intersectEdge(RayK<K>& ray, size_t k, const BBox<vfloat<M>>& time_range, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_e1, - const Vec3vf<M>& tri_e2, - MoellerTrumboreHitM<M>& hit) const + const Vec3vf<M>& tri_e2, + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const { - if (likely(intersect(ray,k,tri_v0,tri_e1,tri_e2,hit))) + if (likely(intersect(ray,k,tri_v0,tri_e1,tri_e2,mapUV,hit))) { hit.valid &= time_range.lower <= vfloat<M>(ray.time[k]); hit.valid &= vfloat<M>(ray.time[k]) < time_range.upper; @@ -345,58 +438,87 @@ namespace embree return false; } - template<typename Epilog> + template<typename UVMapper> + __forceinline bool intersect(RayK<K>& ray, + size_t k, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + const UVMapper& mapUV, + MoellerTrumboreHitM<M,UVMapper>& hit) const + { + const Vec3vf<M> e1 = v0-v1; + const Vec3vf<M> e2 = v2-v0; + return intersectEdge(ray,k,v0,e1,e2,mapUV,hit); + } + + template<typename UVMapper, typename Epilog> __forceinline bool intersectEdge(RayK<K>& ray, size_t k, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_e1, - const Vec3vf<M>& tri_e2, + const Vec3vf<M>& tri_e2, + const UVMapper& mapUV, const Epilog& epilog) const { - MoellerTrumboreHitM<M> hit; - if (likely(intersectEdge(ray,k,tri_v0,tri_e1,tri_e2,hit))) return epilog(hit.valid,hit); + MoellerTrumboreHitM<M,UVMapper> hit(mapUV); + if (likely(intersectEdge(ray,k,tri_v0,tri_e1,tri_e2,mapUV,hit))) return epilog(hit.valid,hit); return false; } - template<typename Epilog> + template<typename UVMapper, typename Epilog> __forceinline bool intersectEdge(RayK<K>& ray, size_t k, const BBox<vfloat<M>>& time_range, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_e1, - const Vec3vf<M>& tri_e2, + const Vec3vf<M>& tri_e2, + const UVMapper& mapUV, const Epilog& epilog) const { - MoellerTrumboreHitM<M> hit; - if (likely(intersectEdge(ray,k,time_range,tri_v0,tri_e1,tri_e2,hit))) return epilog(hit.valid,hit); + MoellerTrumboreHitM<M,UVMapper> hit(mapUV); + if (likely(intersectEdge(ray,k,time_range,tri_v0,tri_e1,tri_e2,mapUV,hit))) return epilog(hit.valid,hit); return false; } - template<typename Epilog> + template<typename UVMapper, typename Epilog> __forceinline bool intersect(RayK<K>& ray, size_t k, const Vec3vf<M>& v0, const Vec3vf<M>& v1, - const Vec3vf<M>& v2, + const Vec3vf<M>& v2, + const UVMapper& mapUV, const Epilog& epilog) const { const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v2-v0; - return intersectEdge(ray,k,v0,e1,e2,epilog); + return intersectEdge(ray,k,v0,e1,e2,mapUV,epilog); } template<typename Epilog> __forceinline bool intersect(RayK<K>& ray, size_t k, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + const Epilog& epilog) const + { + return intersect(ray,k,v0,v1,v2,UVIdentity<M>(),epilog); + } + + template<typename UVMapper, typename Epilog> + __forceinline bool intersect(RayK<K>& ray, + size_t k, const BBox<vfloat<M>>& time_range, const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, + const UVMapper& mapUV, const Epilog& epilog) const { const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v2-v0; - return intersectEdge(ray,k,time_range,v0,e1,e2,epilog); + return intersectEdge(ray,k,time_range,v0,e1,e2,mapUV,epilog); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector_pluecker.h b/thirdparty/embree/kernels/geometry/triangle_intersector_pluecker.h index f1de99d208..8fbefcea88 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector_pluecker.h +++ b/thirdparty/embree/kernels/geometry/triangle_intersector_pluecker.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -22,50 +22,60 @@ namespace embree template<int M, typename UVMapper> struct PlueckerHitM { - __forceinline PlueckerHitM(const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& UVW, const vfloat<M>& t, const Vec3vf<M>& Ng, const UVMapper& mapUV) - : U(U), V(V), UVW(UVW), mapUV(mapUV), vt(t), vNg(Ng) {} + __forceinline PlueckerHitM(const UVMapper& mapUV) : mapUV(mapUV) {} + + __forceinline PlueckerHitM(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& UVW, const vfloat<M>& t, const Vec3vf<M>& Ng, const UVMapper& mapUV) + : U(U), V(V), UVW(UVW), mapUV(mapUV), valid(valid), vt(t), vNg(Ng) {} __forceinline void finalize() { const vbool<M> invalid = abs(UVW) < min_rcp_input; const vfloat<M> rcpUVW = select(invalid,vfloat<M>(0.0f),rcp(UVW)); - vu = U * rcpUVW; - vv = V * rcpUVW; - mapUV(vu,vv); + vu = min(U * rcpUVW,1.0f); + vv = min(V * rcpUVW,1.0f); + mapUV(vu,vv,vNg); } - + + __forceinline Vec2vf<M> uv() const { return Vec2vf<M>(vu,vv); } + __forceinline vfloat<M> t () const { return vt; } + __forceinline Vec3vf<M> Ng() const { return vNg; } + __forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); } __forceinline float t (const size_t i) const { return vt[i]; } __forceinline Vec3fa Ng(const size_t i) const { return Vec3fa(vNg.x[i],vNg.y[i],vNg.z[i]); } - private: - const vfloat<M> U; - const vfloat<M> V; - const vfloat<M> UVW; + public: + vfloat<M> U; + vfloat<M> V; + vfloat<M> UVW; const UVMapper& mapUV; public: + vbool<M> valid; vfloat<M> vu; vfloat<M> vv; vfloat<M> vt; Vec3vf<M> vNg; }; - template<int M> + template<int M, bool early_out = true> struct PlueckerIntersector1 { __forceinline PlueckerIntersector1() {} __forceinline PlueckerIntersector1(const Ray& ray, const void* ptr) {} - template<typename UVMapper, typename Epilog> - __forceinline bool intersect(Ray& ray, + template<typename UVMapper> + __forceinline bool intersect(const vbool<M>& valid0, + Ray& ray, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_v1, const Vec3vf<M>& tri_v2, const UVMapper& mapUV, - const Epilog& epilog) const + PlueckerHitM<M,UVMapper>& hit) const { + vbool<M> valid = valid0; + /* calculate vertices relative to ray origin */ const Vec3vf<M> O = Vec3vf<M>((Vec3fa)ray.org); const Vec3vf<M> D = Vec3vf<M>((Vec3fa)ray.dir); @@ -85,11 +95,11 @@ namespace embree const vfloat<M> UVW = U+V+W; const vfloat<M> eps = float(ulp)*abs(UVW); #if defined(EMBREE_BACKFACE_CULLING) - vbool<M> valid = max(U,V,W) <= eps; + valid &= max(U,V,W) <= eps; #else - vbool<M> valid = (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); + valid &= (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); #endif - if (unlikely(none(valid))) return false; + if (unlikely(early_out && none(valid))) return false; /* calculate geometry normal and denominator */ const Vec3vf<M> Ng = stable_triangle_normal(e0,e1,e2); @@ -100,33 +110,123 @@ namespace embree const vfloat<M> t = rcp(den)*T; valid &= vfloat<M>(ray.tnear()) <= t & t <= vfloat<M>(ray.tfar); valid &= den != vfloat<M>(zero); - if (unlikely(none(valid))) return false; + if (unlikely(early_out && none(valid))) return false; /* update hit information */ - PlueckerHitM<M,UVMapper> hit(U,V,UVW,t,Ng,mapUV); - return epilog(valid,hit); + new (&hit) PlueckerHitM<M,UVMapper>(valid,U,V,UVW,t,Ng,mapUV); + return true; + } + + template<typename UVMapper> + __forceinline bool intersectEdge(const vbool<M>& valid, + Ray& ray, + const Vec3vf<M>& tri_v0, + const Vec3vf<M>& tri_v1, + const Vec3vf<M>& tri_v2, + const UVMapper& mapUV, + PlueckerHitM<M,UVMapper>& hit) const + { + return intersect(valid,ray,tri_v0,tri_v1,tri_v2,mapUV,hit); + } + + template<typename UVMapper> + __forceinline bool intersectEdge(Ray& ray, + const Vec3vf<M>& tri_v0, + const Vec3vf<M>& tri_v1, + const Vec3vf<M>& tri_v2, + const UVMapper& mapUV, + PlueckerHitM<M,UVMapper>& hit) const + { + vbool<M> valid = true; + return intersect(valid,ray,tri_v0,tri_v1,tri_v2,mapUV,hit); + } + + template<typename UVMapper> + __forceinline bool intersect(Ray& ray, + const Vec3vf<M>& tri_v0, + const Vec3vf<M>& tri_v1, + const Vec3vf<M>& tri_v2, + const UVMapper& mapUV, + PlueckerHitM<M,UVMapper>& hit) const + { + return intersectEdge(ray,tri_v0,tri_v1,tri_v2,mapUV,hit); + } + + template<typename UVMapper, typename Epilog> + __forceinline bool intersectEdge(Ray& ray, + const Vec3vf<M>& v0, + const Vec3vf<M>& e1, + const Vec3vf<M>& e2, + const UVMapper& mapUV, + const Epilog& epilog) const + { + PlueckerHitM<M,UVMapper> hit(mapUV); + if (likely(intersectEdge(ray,v0,e1,e2,mapUV,hit))) return epilog(hit.valid,hit); + return false; + } + + template<typename UVMapper, typename Epilog> + __forceinline bool intersect(Ray& ray, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + const UVMapper& mapUV, + const Epilog& epilog) const + { + PlueckerHitM<M,UVMapper> hit(mapUV); + if (likely(intersect(ray,v0,v1,v2,mapUV,hit))) return epilog(hit.valid,hit); + return false; } + + template<typename Epilog> + __forceinline bool intersect(Ray& ray, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + const Epilog& epilog) const + { + auto mapUV = UVIdentity<M>(); + PlueckerHitM<M,UVIdentity<M>> hit(mapUV); + if (likely(intersect(ray,v0,v1,v2,mapUV,hit))) return epilog(hit.valid,hit); + return false; + } + + template<typename UVMapper, typename Epilog> + __forceinline bool intersect(const vbool<M>& valid, + Ray& ray, + const Vec3vf<M>& v0, + const Vec3vf<M>& v1, + const Vec3vf<M>& v2, + const UVMapper& mapUV, + const Epilog& epilog) const + { + PlueckerHitM<M,UVMapper> hit(mapUV); + if (likely(intersect(valid,ray,v0,v1,v2,mapUV,hit))) return epilog(hit.valid,hit); + return false; + } + }; template<int K, typename UVMapper> struct PlueckerHitK { + __forceinline PlueckerHitK(const UVMapper& mapUV) : mapUV(mapUV) {} + __forceinline PlueckerHitK(const vfloat<K>& U, const vfloat<K>& V, const vfloat<K>& UVW, const vfloat<K>& t, const Vec3vf<K>& Ng, const UVMapper& mapUV) - : U(U), V(V), UVW(UVW), t(t), Ng(Ng), mapUV(mapUV) {} + : U(U), V(V), UVW(UVW), t(t), Ng(Ng), mapUV(mapUV) {} __forceinline std::tuple<vfloat<K>,vfloat<K>,vfloat<K>,Vec3vf<K>> operator() () const { const vbool<K> invalid = abs(UVW) < min_rcp_input; const vfloat<K> rcpUVW = select(invalid,vfloat<K>(0.0f),rcp(UVW)); - vfloat<K> u = U * rcpUVW; - vfloat<K> v = V * rcpUVW; - mapUV(u,v); - return std::make_tuple(u,v,t,Ng); + vfloat<K> u = min(U * rcpUVW,1.0f); + vfloat<K> v = min(V * rcpUVW,1.0f); + Vec3vf<K> vNg = Ng; + mapUV(u,v,vNg); + return std::make_tuple(u,v,t,vNg); } - - private: - const vfloat<K> U; - const vfloat<K> V; + vfloat<K> U; + vfloat<K> V; const vfloat<K> UVW; const vfloat<K> t; const Vec3vf<K> Ng; @@ -136,17 +236,18 @@ namespace embree template<int M, int K> struct PlueckerIntersectorK { + __forceinline PlueckerIntersectorK() {} __forceinline PlueckerIntersectorK(const vbool<K>& valid, const RayK<K>& ray) {} /*! Intersects K rays with one of M triangles. */ - template<typename UVMapper, typename Epilog> + template<typename UVMapper> __forceinline vbool<K> intersectK(const vbool<K>& valid0, - RayK<K>& ray, - const Vec3vf<K>& tri_v0, - const Vec3vf<K>& tri_v1, - const Vec3vf<K>& tri_v2, - const UVMapper& mapUV, - const Epilog& epilog) const + RayK<K>& ray, + const Vec3vf<K>& tri_v0, + const Vec3vf<K>& tri_v1, + const Vec3vf<K>& tri_v2, + const UVMapper& mapUV, + PlueckerHitK<K,UVMapper> &hit) const { /* calculate vertices relative to ray origin */ vbool<K> valid = valid0; @@ -172,7 +273,7 @@ namespace embree #else valid &= (min(U,V,W) >= -eps) | (max(U,V,W) <= eps); #endif - if (unlikely(none(valid))) return false; + if (unlikely(none(valid))) return valid; /* calculate geometry normal and denominator */ const Vec3vf<K> Ng = stable_triangle_normal(e0,e1,e2); @@ -183,21 +284,49 @@ namespace embree const vfloat<K> t = rcp(den)*T; valid &= ray.tnear() <= t & t <= ray.tfar; valid &= den != vfloat<K>(zero); - if (unlikely(none(valid))) return false; + if (unlikely(none(valid))) return valid; /* calculate hit information */ - PlueckerHitK<K,UVMapper> hit(U,V,UVW,t,Ng,mapUV); - return epilog(valid,hit); + new (&hit) PlueckerHitK<K,UVMapper>(U,V,UVW,t,Ng,mapUV); + return valid; + } + + template<typename Epilog> + __forceinline vbool<K> intersectK(const vbool<K>& valid0, + RayK<K>& ray, + const Vec3vf<K>& tri_v0, + const Vec3vf<K>& tri_v1, + const Vec3vf<K>& tri_v2, + const Epilog& epilog) const + { + UVIdentity<K> mapUV; + PlueckerHitK<K,UVIdentity<K>> hit(mapUV); + const vbool<K> valid = intersectK(valid0,ray,tri_v0,tri_v1,tri_v2,mapUV,hit); + return epilog(valid,hit); } - /*! Intersect k'th ray from ray packet of size K with M triangles. */ template<typename UVMapper, typename Epilog> + __forceinline vbool<K> intersectK(const vbool<K>& valid0, + RayK<K>& ray, + const Vec3vf<K>& tri_v0, + const Vec3vf<K>& tri_v1, + const Vec3vf<K>& tri_v2, + const UVMapper& mapUV, + const Epilog& epilog) const + { + PlueckerHitK<K,UVMapper> hit(mapUV); + const vbool<K> valid = intersectK(valid0,ray,tri_v0,tri_v1,tri_v2,mapUV,hit); + return epilog(valid,hit); + } + + /*! Intersect k'th ray from ray packet of size K with M triangles. */ + template<typename UVMapper> __forceinline bool intersect(RayK<K>& ray, size_t k, const Vec3vf<M>& tri_v0, const Vec3vf<M>& tri_v1, const Vec3vf<M>& tri_v2, const UVMapper& mapUV, - const Epilog& epilog) const + PlueckerHitM<M,UVMapper> &hit) const { /* calculate vertices relative to ray origin */ const Vec3vf<M> O = broadcast<vfloat<M>>(ray.org,k); @@ -211,10 +340,12 @@ namespace embree const Vec3vf<M> e1 = v0-v1; const Vec3vf<M> e2 = v1-v2; + /* perform edge tests */ const vfloat<M> U = dot(cross(e0,v2+v0),D); const vfloat<M> V = dot(cross(e1,v0+v1),D); const vfloat<M> W = dot(cross(e2,v1+v2),D); + const vfloat<M> UVW = U+V+W; const vfloat<M> eps = float(ulp)*abs(UVW); #if defined(EMBREE_BACKFACE_CULLING) @@ -239,9 +370,38 @@ namespace embree if (unlikely(none(valid))) return false; /* update hit information */ - PlueckerHitM<M,UVMapper> hit(U,V,UVW,t,Ng,mapUV); - return epilog(valid,hit); + new (&hit) PlueckerHitM<M,UVMapper>(valid,U,V,UVW,t,Ng,mapUV); + return true; } + + template<typename UVMapper, typename Epilog> + __forceinline bool intersect(RayK<K>& ray, size_t k, + const Vec3vf<M>& tri_v0, + const Vec3vf<M>& tri_v1, + const Vec3vf<M>& tri_v2, + const UVMapper& mapUV, + const Epilog& epilog) const + { + PlueckerHitM<M,UVMapper> hit(mapUV); + if (intersect(ray,k,tri_v0,tri_v1,tri_v2,mapUV,hit)) + return epilog(hit.valid,hit); + return false; + } + + template<typename Epilog> + __forceinline bool intersect(RayK<K>& ray, size_t k, + const Vec3vf<M>& tri_v0, + const Vec3vf<M>& tri_v1, + const Vec3vf<M>& tri_v2, + const Epilog& epilog) const + { + UVIdentity<M> mapUV; + PlueckerHitM<M,UVIdentity<M>> hit(mapUV); + if (intersect(ray,k,tri_v0,tri_v1,tri_v2,mapUV,hit)) + return epilog(hit.valid,hit); + return false; + } + }; } } diff --git a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector_woop.h b/thirdparty/embree/kernels/geometry/triangle_intersector_woop.h index 63e649d8fb..f05dcc4537 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/triangle_intersector_woop.h +++ b/thirdparty/embree/kernels/geometry/triangle_intersector_woop.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/triangle_triangle_intersector.h b/thirdparty/embree/kernels/geometry/triangle_triangle_intersector.h index 91b35c36f3..50106bcc16 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/triangle_triangle_intersector.h +++ b/thirdparty/embree/kernels/geometry/triangle_triangle_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "primitive.h" diff --git a/thirdparty/embree-aarch64/kernels/geometry/trianglei.h b/thirdparty/embree/kernels/geometry/trianglei.h index 4f3118cc0c..6aad48a5ef 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/trianglei.h +++ b/thirdparty/embree/kernels/geometry/trianglei.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -343,7 +343,7 @@ namespace embree const TriangleMesh* mesh = scene->get<TriangleMesh>(geomID(index)); vfloat<K> ftime; - const vint<K> itime = mesh->timeSegment(time, ftime); + const vint<K> itime = mesh->timeSegment<K>(time, ftime); const size_t first = bsf(movemask(valid)); if (likely(all(valid,itime[first] == itime))) @@ -352,9 +352,9 @@ namespace embree p1 = getVertex<1>(index, scene, itime[first], ftime); p2 = getVertex<2>(index, scene, itime[first], ftime); } else { - p0 = getVertex<0>(valid, index, scene, itime, ftime); - p1 = getVertex<1>(valid, index, scene, itime, ftime); - p2 = getVertex<2>(valid, index, scene, itime, ftime); + p0 = getVertex<0,K>(valid, index, scene, itime, ftime); + p1 = getVertex<1,K>(valid, index, scene, itime, ftime); + p2 = getVertex<2,K>(valid, index, scene, itime, ftime); } } diff --git a/thirdparty/embree-aarch64/kernels/geometry/trianglei_intersector.h b/thirdparty/embree/kernels/geometry/trianglei_intersector.h index e2f106a62c..f7deb9e72d 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/trianglei_intersector.h +++ b/thirdparty/embree/kernels/geometry/trianglei_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -12,24 +12,24 @@ namespace embree namespace isa { /*! Intersects M triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMiIntersector1Moeller { typedef TriangleMi<M> Primitive; - typedef MoellerTrumboreIntersector1<Mx> Precalculations; + typedef MoellerTrumboreIntersector1<M> Precalculations; static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - pre.intersect(ray,v0,v1,v2,/*UVIdentity<Mx>(),*/Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - return pre.intersect(ray,v0,v1,v2,/*UVIdentity<Mx>(),*/Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -39,11 +39,11 @@ namespace embree }; /*! Intersects M triangles with K rays */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMiIntersectorKMoeller { typedef TriangleMi<M> Primitive; - typedef MoellerTrumboreIntersectorK<Mx,K> Precalculations; + typedef MoellerTrumboreIntersectorK<M,K> Precalculations; static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri) { @@ -55,7 +55,7 @@ namespace embree const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene); const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene); const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene); - pre.intersectK(valid_i,ray,v0,v1,v2,/*UVIdentity<K>(),*/IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); + pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); } } @@ -71,7 +71,7 @@ namespace embree const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene); const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene); const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene); - pre.intersectK(valid0,ray,v0,v1,v2,/*UVIdentity<K>(),*/OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); + pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); if (none(valid0)) break; } return !valid0; @@ -81,36 +81,36 @@ namespace embree { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - pre.intersect(ray,k,v0,v1,v2,/*UVIdentity<Mx>(),*/Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - return pre.intersect(ray,k,v0,v1,v2,/*UVIdentity<Mx>(),*/Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; /*! Intersects M triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMiIntersector1Pluecker { typedef TriangleMi<M> Primitive; - typedef PlueckerIntersector1<Mx> Precalculations; + typedef PlueckerIntersector1<M> Precalculations; static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - pre.intersect(ray,v0,v1,v2,UVIdentity<Mx>(),Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - return pre.intersect(ray,v0,v1,v2,UVIdentity<Mx>(),Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -120,11 +120,11 @@ namespace embree }; /*! Intersects M triangles with K rays */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMiIntersectorKPluecker { typedef TriangleMi<M> Primitive; - typedef PlueckerIntersectorK<Mx,K> Precalculations; + typedef PlueckerIntersectorK<M,K> Precalculations; static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri) { @@ -136,7 +136,7 @@ namespace embree const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene); const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene); const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene); - pre.intersectK(valid_i,ray,v0,v1,v2,UVIdentity<K>(),IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); + pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); } } @@ -152,7 +152,7 @@ namespace embree const Vec3vf<K> v0 = tri.template getVertex<0>(i,scene); const Vec3vf<K> v1 = tri.template getVertex<1>(i,scene); const Vec3vf<K> v2 = tri.template getVertex<2>(i,scene); - pre.intersectK(valid0,ray,v0,v1,v2,UVIdentity<K>(),OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); + pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); if (none(valid0)) break; } return !valid0; @@ -162,30 +162,30 @@ namespace embree { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - pre.intersect(ray,k,v0,v1,v2,UVIdentity<Mx>(),Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0, v1, v2; tri.gather(v0,v1,v2,context->scene); - return pre.intersect(ray,k,v0,v1,v2,UVIdentity<Mx>(),Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; /*! Intersects M motion blur triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMiMBIntersector1Moeller { typedef TriangleMi<M> Primitive; - typedef MoellerTrumboreIntersector1<Mx> Precalculations; + typedef MoellerTrumboreIntersector1<M> Precalculations; /*! Intersect a ray with the M triangles and updates the hit. */ static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()); - pre.intersect(ray,v0,v1,v2,/*UVIdentity<Mx>(),*/Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of M triangles. */ @@ -193,7 +193,7 @@ namespace embree { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()); - return pre.intersect(ray,v0,v1,v2,/*UVIdentity<Mx>(),*/Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -203,11 +203,11 @@ namespace embree }; /*! Intersects M motion blur triangles with K rays. */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMiMBIntersectorKMoeller { typedef TriangleMi<M> Primitive; - typedef MoellerTrumboreIntersectorK<Mx,K> Precalculations; + typedef MoellerTrumboreIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleMi<M>& tri) @@ -216,8 +216,8 @@ namespace embree { if (!tri.valid(i)) break; STAT3(normal.trav_prims,1,popcnt(valid_i),K); - Vec3vf<K> v0,v1,v2; tri.gather(valid_i,v0,v1,v2,i,context->scene,ray.time()); - pre.intersectK(valid_i,ray,v0,v1,v2,/*UVIdentity<K>(),*/IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); + Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time()); + pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); } } @@ -229,8 +229,8 @@ namespace embree { if (!tri.valid(i)) break; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - Vec3vf<K> v0,v1,v2; tri.gather(valid_i,v0,v1,v2,i,context->scene,ray.time()); - pre.intersectK(valid0,ray,v0,v1,v2,/*UVIdentity<K>(),*/OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); + Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time()); + pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); if (none(valid0)) break; } return !valid0; @@ -241,7 +241,7 @@ namespace embree { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]); - pre.intersect(ray,k,v0,v1,v2,/*UVIdentity<Mx>(),*/Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ @@ -249,23 +249,23 @@ namespace embree { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]); - return pre.intersect(ray,k,v0,v1,v2,/*UVIdentity<Mx>(),*/Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; /*! Intersects M motion blur triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMiMBIntersector1Pluecker { typedef TriangleMi<M> Primitive; - typedef PlueckerIntersector1<Mx> Precalculations; + typedef PlueckerIntersector1<M> Precalculations; /*! Intersect a ray with the M triangles and updates the hit. */ static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()); - pre.intersect(ray,v0,v1,v2,UVIdentity<Mx>(),Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of M triangles. */ @@ -273,7 +273,7 @@ namespace embree { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()); - return pre.intersect(ray,v0,v1,v2,UVIdentity<Mx>(),Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -283,11 +283,11 @@ namespace embree }; /*! Intersects M motion blur triangles with K rays. */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMiMBIntersectorKPluecker { typedef TriangleMi<M> Primitive; - typedef PlueckerIntersectorK<Mx,K> Precalculations; + typedef PlueckerIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleMi<M>& tri) @@ -296,8 +296,8 @@ namespace embree { if (!tri.valid(i)) break; STAT3(normal.trav_prims,1,popcnt(valid_i),K); - Vec3vf<K> v0,v1,v2; tri.gather(valid_i,v0,v1,v2,i,context->scene,ray.time()); - pre.intersectK(valid_i,ray,v0,v1,v2,UVIdentity<K>(),IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); + Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time()); + pre.intersectK(valid_i,ray,v0,v1,v2,IntersectKEpilogM<M,K,filter>(ray,context,tri.geomID(),tri.primID(),i)); } } @@ -309,8 +309,8 @@ namespace embree { if (!tri.valid(i)) break; STAT3(shadow.trav_prims,1,popcnt(valid0),K); - Vec3vf<K> v0,v1,v2; tri.gather(valid_i,v0,v1,v2,i,context->scene,ray.time()); - pre.intersectK(valid0,ray,v0,v1,v2,UVIdentity<K>(),OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); + Vec3vf<K> v0,v1,v2; tri.template gather<K>(valid_i,v0,v1,v2,i,context->scene,ray.time()); + pre.intersectK(valid0,ray,v0,v1,v2,OccludedKEpilogM<M,K,filter>(valid0,ray,context,tri.geomID(),tri.primID(),i)); if (none(valid0)) break; } return !valid0; @@ -321,7 +321,7 @@ namespace embree { STAT3(normal.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]); - pre.intersect(ray,k,v0,v1,v2,UVIdentity<Mx>(),Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ @@ -329,7 +329,7 @@ namespace embree { STAT3(shadow.trav_prims,1,1,1); Vec3vf<M> v0,v1,v2; tri.gather(v0,v1,v2,context->scene,ray.time()[k]); - return pre.intersect(ray,k,v0,v1,v2,UVIdentity<Mx>(),Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/trianglev.h b/thirdparty/embree/kernels/geometry/trianglev.h index 19af389e73..cd94756b9e 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/trianglev.h +++ b/thirdparty/embree/kernels/geometry/trianglev.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/trianglev_intersector.h b/thirdparty/embree/kernels/geometry/trianglev_intersector.h index 6af0d5a11c..3abb7f8e32 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/trianglev_intersector.h +++ b/thirdparty/embree/kernels/geometry/trianglev_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -13,24 +13,24 @@ namespace embree namespace isa { /*! Intersects M triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMvIntersector1Moeller { typedef TriangleMv<M> Primitive; - typedef MoellerTrumboreIntersector1<Mx> Precalculations; + typedef MoellerTrumboreIntersector1<M> Precalculations; /*! Intersect a ray with M triangles and updates the hit. */ static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); - pre.intersect(ray,tri.v0,tri.v1,tri.v2,/*UVIdentity<Mx>(),*/Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersect(ray,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); - return pre.intersect(ray,tri.v0,tri.v1,tri.v2,/*UVIdentity<Mx>(),*/Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -40,25 +40,25 @@ namespace embree }; - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMvIntersector1Woop { typedef TriangleMv<M> Primitive; - typedef WoopIntersector1<Mx> intersec; + typedef WoopIntersector1<M> intersec; typedef WoopPrecalculations1<M> Precalculations; /*! Intersect a ray with M triangles and updates the hit. */ static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); - intersec::intersect(ray,pre,tri.v0,tri.v1,tri.v2,Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + intersec::intersect(ray,pre,tri.v0,tri.v1,tri.v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); - return intersec::intersect(ray,pre,tri.v0,tri.v1,tri.v2,Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return intersec::intersect(ray,pre,tri.v0,tri.v1,tri.v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -69,11 +69,11 @@ namespace embree /*! Intersects M triangles with K rays */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMvIntersectorKMoeller { typedef TriangleMv<M> Primitive; - typedef MoellerTrumboreIntersectorK<Mx,K> Precalculations; + typedef MoellerTrumboreIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri) @@ -111,36 +111,36 @@ namespace embree static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); - pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,/*UVIdentity<Mx>(),*/Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M,Mx + pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); - return pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,/*UVIdentity<Mx>(),*/Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M,Mx + return pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,/*UVIdentity<M>(),*/Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M } }; /*! Intersects M triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMvIntersector1Pluecker { typedef TriangleMv<M> Primitive; - typedef PlueckerIntersector1<Mx> Precalculations; + typedef PlueckerIntersector1<M> Precalculations; /*! Intersect a ray with M triangles and updates the hit. */ static __forceinline void intersect(Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); - pre.intersect(ray,tri.v0,tri.v1,tri.v2,UVIdentity<Mx>(),Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + pre.intersect(ray,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); - return pre.intersect(ray,tri.v0,tri.v1,tri.v2,UVIdentity<Mx>(),Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + return pre.intersect(ray,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -150,11 +150,11 @@ namespace embree }; /*! Intersects M triangles with K rays */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMvIntersectorKPluecker { typedef TriangleMv<M> Primitive; - typedef PlueckerIntersectorK<Mx,K> Precalculations; + typedef PlueckerIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive& tri) @@ -192,14 +192,14 @@ namespace embree static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri) { STAT3(normal.trav_prims,1,1,1); - pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,UVIdentity<Mx>(),Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M,Mx + pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive& tri) { STAT3(shadow.trav_prims,1,1,1); - return pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,UVIdentity<Mx>(),Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); //FIXME: M,Mx + return pre.intersect(ray,k,tri.v0,tri.v1,tri.v2,UVIdentity<M>(),Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/geometry/trianglev_mb.h b/thirdparty/embree/kernels/geometry/trianglev_mb.h index 63137aee16..b550a29fd5 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/trianglev_mb.h +++ b/thirdparty/embree/kernels/geometry/trianglev_mb.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/geometry/trianglev_mb_intersector.h b/thirdparty/embree/kernels/geometry/trianglev_mb_intersector.h index 35a260d826..38cd52e85d 100644 --- a/thirdparty/embree-aarch64/kernels/geometry/trianglev_mb_intersector.h +++ b/thirdparty/embree/kernels/geometry/trianglev_mb_intersector.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,32 +11,32 @@ namespace embree namespace isa { /*! Intersects M motion blur triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMvMBIntersector1Moeller { typedef TriangleMvMB<M> Primitive; - typedef MoellerTrumboreIntersector1<Mx> Precalculations; + typedef MoellerTrumboreIntersector1<M> Precalculations; /*! Intersect a ray with the M triangles and updates the hit. */ static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(normal.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + pre.intersect(ray,v0,v1,v2,Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of M triangles. */ static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(shadow.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + return pre.intersect(ray,v0,v1,v2,Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -46,11 +46,11 @@ namespace embree }; /*! Intersects M motion blur triangles with K rays. */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMvMBIntersectorKMoeller { typedef TriangleMvMB<M> Primitive; - typedef MoellerTrumboreIntersectorK<Mx,K> Precalculations; + typedef MoellerTrumboreIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleMvMB<M>& tri) @@ -90,52 +90,52 @@ namespace embree static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(normal.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()[k]); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()[k]); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + pre.intersect(ray,k,v0,v1,v2,Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(shadow.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()[k]); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()[k]); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + return pre.intersect(ray,k,v0,v1,v2,Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; /*! Intersects M motion blur triangles with 1 ray */ - template<int M, int Mx, bool filter> + template<int M, bool filter> struct TriangleMvMBIntersector1Pluecker { typedef TriangleMvMB<M> Primitive; - typedef PlueckerIntersector1<Mx> Precalculations; + typedef PlueckerIntersector1<M> Precalculations; /*! Intersect a ray with the M triangles and updates the hit. */ static __forceinline void intersect(const Precalculations& pre, RayHit& ray, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(normal.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - pre.intersect(ray,v0,v1,v2,UVIdentity<Mx>(),Intersect1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + pre.intersect(ray,v0,v1,v2,UVIdentity<M>(),Intersect1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of M triangles. */ static __forceinline bool occluded(const Precalculations& pre, Ray& ray, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(shadow.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - return pre.intersect(ray,v0,v1,v2,UVIdentity<Mx>(),Occluded1EpilogM<M,Mx,filter>(ray,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + return pre.intersect(ray,v0,v1,v2,UVIdentity<M>(),Occluded1EpilogM<M,filter>(ray,context,tri.geomID(),tri.primID())); } static __forceinline bool pointQuery(PointQuery* query, PointQueryContext* context, const Primitive& tri) @@ -145,11 +145,11 @@ namespace embree }; /*! Intersects M motion blur triangles with K rays. */ - template<int M, int Mx, int K, bool filter> + template<int M, int K, bool filter> struct TriangleMvMBIntersectorKPluecker { typedef TriangleMvMB<M> Primitive; - typedef PlueckerIntersectorK<Mx,K> Precalculations; + typedef PlueckerIntersectorK<M,K> Precalculations; /*! Intersects K rays with M triangles. */ static __forceinline void intersect(const vbool<K>& valid_i, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const TriangleMvMB<M>& tri) @@ -189,22 +189,22 @@ namespace embree static __forceinline void intersect(Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(normal.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()[k]); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - pre.intersect(ray,k,v0,v1,v2,UVIdentity<Mx>(),Intersect1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()[k]); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + pre.intersect(ray,k,v0,v1,v2,UVIdentity<M>(),Intersect1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } /*! Test if the ray is occluded by one of the M triangles. */ static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const TriangleMvMB<M>& tri) { STAT3(shadow.trav_prims,1,1,1); - const Vec3vf<Mx> time(ray.time()[k]); - const Vec3vf<Mx> v0 = madd(time,Vec3vf<Mx>(tri.dv0),Vec3vf<Mx>(tri.v0)); - const Vec3vf<Mx> v1 = madd(time,Vec3vf<Mx>(tri.dv1),Vec3vf<Mx>(tri.v1)); - const Vec3vf<Mx> v2 = madd(time,Vec3vf<Mx>(tri.dv2),Vec3vf<Mx>(tri.v2)); - return pre.intersect(ray,k,v0,v1,v2,UVIdentity<Mx>(),Occluded1KEpilogM<M,Mx,K,filter>(ray,k,context,tri.geomID(),tri.primID())); + const Vec3vf<M> time(ray.time()[k]); + const Vec3vf<M> v0 = madd(time,Vec3vf<M>(tri.dv0),Vec3vf<M>(tri.v0)); + const Vec3vf<M> v1 = madd(time,Vec3vf<M>(tri.dv1),Vec3vf<M>(tri.v1)); + const Vec3vf<M> v2 = madd(time,Vec3vf<M>(tri.dv2),Vec3vf<M>(tri.v2)); + return pre.intersect(ray,k,v0,v1,v2,UVIdentity<M>(),Occluded1KEpilogM<M,K,filter>(ray,k,context,tri.geomID(),tri.primID())); } }; } diff --git a/thirdparty/embree-aarch64/kernels/hash.h b/thirdparty/embree/kernels/hash.h index 4abbe203d6..10f315cee7 100644 --- a/thirdparty/embree-aarch64/kernels/hash.h +++ b/thirdparty/embree/kernels/hash.h @@ -2,4 +2,4 @@ // Copyright 2009-2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 -#define RTC_HASH "6ef362f99af80c9dfe8dd2bfc582d9067897edc6" +#define RTC_HASH "7c53133eb21424f7f0ae1e25bf357e358feaf6ab" diff --git a/thirdparty/embree-aarch64/kernels/subdiv/bezier_curve.h b/thirdparty/embree/kernels/subdiv/bezier_curve.h index c0e78820f8..a5adad5cc9 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/bezier_curve.h +++ b/thirdparty/embree/kernels/subdiv/bezier_curve.h @@ -1,10 +1,11 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../common/default.h" -#include "../common/scene_curves.h" +//#include "../common/scene_curves.h" +#include "../common/context.h" namespace embree { @@ -659,6 +660,7 @@ namespace embree return numRoots(v0,v1) + numRoots(v1,v2) + numRoots(v2,v3); } + template<typename CurveGeometry> __forceinline CubicBezierCurve<Vec3ff> enlargeRadiusToMinWidth(const IntersectContext* context, const CurveGeometry* geom, const Vec3fa& ray_org, const CubicBezierCurve<Vec3ff>& curve) { return CubicBezierCurve<Vec3ff>(enlargeRadiusToMinWidth(context,geom,ray_org,curve.v0), diff --git a/thirdparty/embree-aarch64/kernels/subdiv/bezier_patch.h b/thirdparty/embree/kernels/subdiv/bezier_patch.h index d87ed41ccb..2ff03902a7 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/bezier_patch.h +++ b/thirdparty/embree/kernels/subdiv/bezier_patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/bilinear_patch.h b/thirdparty/embree/kernels/subdiv/bilinear_patch.h index 35748754bd..cade104a6c 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/bilinear_patch.h +++ b/thirdparty/embree/kernels/subdiv/bilinear_patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/bspline_curve.h b/thirdparty/embree/kernels/subdiv/bspline_curve.h index a325667328..51489ef37c 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/bspline_curve.h +++ b/thirdparty/embree/kernels/subdiv/bspline_curve.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -161,8 +161,8 @@ namespace embree template<int M> __forceinline void veval(const vfloat<M>& t, Vec4vf<M>& p, Vec4vf<M>& dp) const { - p = veval(t); - dp = veval_du(t); + p = veval<M>(t); + dp = veval_du<M>(t); } template<int M> @@ -306,6 +306,7 @@ namespace embree ocurve = BezierCurveT<Vertex>(v0,v1,v2,v3); } + template<typename CurveGeometry> __forceinline BSplineCurveT<Vec3ff> enlargeRadiusToMinWidth(const IntersectContext* context, const CurveGeometry* geom, const Vec3fa& ray_org, const BSplineCurveT<Vec3ff>& curve) { return BSplineCurveT<Vec3ff>(enlargeRadiusToMinWidth(context,geom,ray_org,curve.v0), diff --git a/thirdparty/embree-aarch64/kernels/subdiv/bspline_patch.h b/thirdparty/embree/kernels/subdiv/bspline_patch.h index 9769bc17bd..ff47f01c7a 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/bspline_patch.h +++ b/thirdparty/embree/kernels/subdiv/bspline_patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/catmullclark_coefficients.h b/thirdparty/embree/kernels/subdiv/catmullclark_coefficients.h index 05031cf6b9..46959797bf 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/catmullclark_coefficients.h +++ b/thirdparty/embree/kernels/subdiv/catmullclark_coefficients.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/catmullclark_patch.h b/thirdparty/embree/kernels/subdiv/catmullclark_patch.h index ab1d63594a..91772d94ed 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/catmullclark_patch.h +++ b/thirdparty/embree/kernels/subdiv/catmullclark_patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/catmullclark_ring.h b/thirdparty/embree/kernels/subdiv/catmullclark_ring.h index 73b41fd4ff..e5ad5dadfe 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/catmullclark_ring.h +++ b/thirdparty/embree/kernels/subdiv/catmullclark_ring.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/catmullrom_curve.h b/thirdparty/embree/kernels/subdiv/catmullrom_curve.h index b244af481c..74fc4c1230 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/catmullrom_curve.h +++ b/thirdparty/embree/kernels/subdiv/catmullrom_curve.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -168,8 +168,8 @@ namespace embree template<int M> __forceinline void veval(const vfloat<M>& t, Vec4vf<M>& p, Vec4vf<M>& dp) const { - p = veval(t); - dp = veval_du(t); + p = veval<M>(t); + dp = veval_du<M>(t); } template<int M> @@ -283,6 +283,7 @@ namespace embree } }; + template<typename CurveGeometry> __forceinline CatmullRomCurveT<Vec3ff> enlargeRadiusToMinWidth(const IntersectContext* context, const CurveGeometry* geom, const Vec3fa& ray_org, const CatmullRomCurveT<Vec3ff>& curve) { return CatmullRomCurveT<Vec3ff>(enlargeRadiusToMinWidth(context,geom,ray_org,curve.v0), diff --git a/thirdparty/embree-aarch64/kernels/subdiv/feature_adaptive_eval.h b/thirdparty/embree/kernels/subdiv/feature_adaptive_eval.h index 23f24c360c..58c0b63e62 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/feature_adaptive_eval.h +++ b/thirdparty/embree/kernels/subdiv/feature_adaptive_eval.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/feature_adaptive_eval_grid.h b/thirdparty/embree/kernels/subdiv/feature_adaptive_eval_grid.h index 76583b2e5d..4755aba28d 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/feature_adaptive_eval_grid.h +++ b/thirdparty/embree/kernels/subdiv/feature_adaptive_eval_grid.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/feature_adaptive_eval_simd.h b/thirdparty/embree/kernels/subdiv/feature_adaptive_eval_simd.h index fa3216730f..edab0db12f 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/feature_adaptive_eval_simd.h +++ b/thirdparty/embree/kernels/subdiv/feature_adaptive_eval_simd.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/gregory_patch.h b/thirdparty/embree/kernels/subdiv/gregory_patch.h index 2a7c4b1f2c..9026d5c407 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/gregory_patch.h +++ b/thirdparty/embree/kernels/subdiv/gregory_patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/gregory_patch_dense.h b/thirdparty/embree/kernels/subdiv/gregory_patch_dense.h index 85effd02cf..4cf9a7e98f 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/gregory_patch_dense.h +++ b/thirdparty/embree/kernels/subdiv/gregory_patch_dense.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/gridrange.h b/thirdparty/embree/kernels/subdiv/gridrange.h index 4fd741c879..4f2b90d7bd 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/gridrange.h +++ b/thirdparty/embree/kernels/subdiv/gridrange.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/half_edge.h b/thirdparty/embree/kernels/subdiv/half_edge.h index fb350ca71f..baf019cd79 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/half_edge.h +++ b/thirdparty/embree/kernels/subdiv/half_edge.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -186,7 +186,7 @@ namespace embree { const HalfEdge* p = this; do { - if (p->vertexHasBorder()) return true; + if (p->vertexHasBorder() && (p->vertex_type != HalfEdge::NON_MANIFOLD_EDGE_VERTEX)) return true; p = p->next(); } while (p != this); return false; diff --git a/thirdparty/embree-aarch64/kernels/subdiv/hermite_curve.h b/thirdparty/embree/kernels/subdiv/hermite_curve.h index 9fab79cf0c..ffef5a4315 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/hermite_curve.h +++ b/thirdparty/embree/kernels/subdiv/hermite_curve.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -29,6 +29,7 @@ namespace embree } }; + template<typename CurveGeometry> __forceinline HermiteCurveT<Vec3ff> enlargeRadiusToMinWidth(const IntersectContext* context, const CurveGeometry* geom, const Vec3fa& ray_org, const HermiteCurveT<Vec3ff>& curve) { return HermiteCurveT<Vec3ff>(enlargeRadiusToMinWidth(context,geom,ray_org,BezierCurveT<Vec3ff>(curve))); } diff --git a/thirdparty/embree-aarch64/kernels/subdiv/linear_bezier_patch.h b/thirdparty/embree/kernels/subdiv/linear_bezier_patch.h index f4a854af7f..f8e8a25f35 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/linear_bezier_patch.h +++ b/thirdparty/embree/kernels/subdiv/linear_bezier_patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/patch.h b/thirdparty/embree/kernels/subdiv/patch.h index d58241b96d..c4340ea9b6 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/patch.h +++ b/thirdparty/embree/kernels/subdiv/patch.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/patch_eval.h b/thirdparty/embree/kernels/subdiv/patch_eval.h index 482d015fa3..a3fafa72f4 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/patch_eval.h +++ b/thirdparty/embree/kernels/subdiv/patch_eval.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/patch_eval_grid.h b/thirdparty/embree/kernels/subdiv/patch_eval_grid.h index c05db55f4c..167e1ebe1c 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/patch_eval_grid.h +++ b/thirdparty/embree/kernels/subdiv/patch_eval_grid.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/patch_eval_simd.h b/thirdparty/embree/kernels/subdiv/patch_eval_simd.h index 28016d9e20..fef88a4492 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/patch_eval_simd.h +++ b/thirdparty/embree/kernels/subdiv/patch_eval_simd.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/subdivpatch1base.h b/thirdparty/embree/kernels/subdiv/subdivpatch1base.h index d5bc403cca..c3069dadee 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/subdivpatch1base.h +++ b/thirdparty/embree/kernels/subdiv/subdivpatch1base.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/tessellation.h b/thirdparty/embree/kernels/subdiv/tessellation.h index bda1e2d559..abde4f2bde 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/tessellation.h +++ b/thirdparty/embree/kernels/subdiv/tessellation.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once diff --git a/thirdparty/embree-aarch64/kernels/subdiv/tessellation_cache.h b/thirdparty/embree/kernels/subdiv/tessellation_cache.h index 5c215288b6..99edf49be4 100644 --- a/thirdparty/embree-aarch64/kernels/subdiv/tessellation_cache.h +++ b/thirdparty/embree/kernels/subdiv/tessellation_cache.h @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -63,7 +63,7 @@ namespace embree static const size_t NUM_CACHE_SEGMENTS = 8; static const size_t NUM_PREALLOC_THREAD_WORK_STATES = 512; static const size_t COMMIT_INDEX_SHIFT = 32+8; -#if defined(__X86_64__) || defined(__aarch64__) +#if defined(__64BIT__) static const size_t REF_TAG_MASK = 0xffffffffff; #else static const size_t REF_TAG_MASK = 0x7FFFFFFF; diff --git a/thirdparty/embree/patches/godot-changes-android.patch b/thirdparty/embree/patches/godot-changes-android.patch new file mode 100644 index 0000000000..a27f924bde --- /dev/null +++ b/thirdparty/embree/patches/godot-changes-android.patch @@ -0,0 +1,103 @@ +diff --git a/thirdparty/embree/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp +index ba97dc227b..1679599608 100644 +--- a/thirdparty/embree/common/sys/sysinfo.cpp ++++ b/thirdparty/embree/common/sys/sysinfo.cpp +@@ -618,7 +618,10 @@ namespace embree + static int nThreads = -1; + if (nThreads != -1) return nThreads; + +-#if defined(__MACOSX__) ++// -- GODOT start -- ++// #if defined(__MACOSX__) ++#if defined(__MACOSX__) || defined(__ANDROID__) ++// -- GODOT end -- + nThreads = sysconf(_SC_NPROCESSORS_ONLN); // does not work in Linux LXC container + assert(nThreads); + #else +diff --git a/thirdparty/embree/common/sys/thread.cpp b/thirdparty/embree/common/sys/thread.cpp +index a7827e18f7..f4014be89b 100644 +--- a/thirdparty/embree/common/sys/thread.cpp ++++ b/thirdparty/embree/common/sys/thread.cpp +@@ -158,7 +158,9 @@ namespace embree + /// Linux Platform + //////////////////////////////////////////////////////////////////////////////// + +-#if defined(__LINUX__) ++// -- GODOT start -- ++#if defined(__LINUX__) && !defined(__ANDROID__) ++// -- GODOT end -- + + #include <fstream> + #include <sstream> +@@ -247,6 +249,28 @@ namespace embree + } + #endif + ++// -- GODOT start -- ++//////////////////////////////////////////////////////////////////////////////// ++/// Android Platform ++//////////////////////////////////////////////////////////////////////////////// ++ ++#if defined(__ANDROID__) ++ ++namespace embree ++{ ++ /*! set affinity of the calling thread */ ++ void setAffinity(ssize_t affinity) ++ { ++ cpu_set_t cset; ++ CPU_ZERO(&cset); ++ CPU_SET(affinity, &cset); ++ ++ sched_setaffinity(0, sizeof(cset), &cset); ++ } ++} ++#endif ++// -- GODOT end -- ++ + //////////////////////////////////////////////////////////////////////////////// + /// FreeBSD Platform + //////////////////////////////////////////////////////////////////////////////// +@@ -355,7 +379,9 @@ namespace embree + pthread_attr_destroy(&attr); + + /* set affinity */ +-#if defined(__LINUX__) ++// -- GODOT start -- ++#if defined(__LINUX__) && !defined(__ANDROID__) ++// -- GODOT end -- + if (threadID >= 0) { + cpu_set_t cset; + CPU_ZERO(&cset); +@@ -370,7 +396,16 @@ namespace embree + CPU_SET(threadID, &cset); + pthread_setaffinity_np(*tid, sizeof(cset), &cset); + } ++// -- GODOT start -- ++#elif defined(__ANDROID__) ++ if (threadID >= 0) { ++ cpu_set_t cset; ++ CPU_ZERO(&cset); ++ CPU_SET(threadID, &cset); ++ sched_setaffinity(pthread_gettid_np(*tid), sizeof(cset), &cset); ++ } + #endif ++// -- GODOT end -- + + return thread_t(tid); + } +@@ -389,8 +424,14 @@ namespace embree + + /*! destroy a hardware thread by its handle */ + void destroyThread(thread_t tid) { ++// -- GODOT start -- ++#if defined(__ANDROID__) ++ FATAL("Can't destroy threads on Android."); ++#else + pthread_cancel(*(pthread_t*)tid); + delete (pthread_t*)tid; ++#endif ++// -- GODOT end -- + } + + /*! creates thread local storage */ diff --git a/thirdparty/embree/patches/godot-changes-misc.patch b/thirdparty/embree/patches/godot-changes-misc.patch new file mode 100644 index 0000000000..8bf0d9fa97 --- /dev/null +++ b/thirdparty/embree/patches/godot-changes-misc.patch @@ -0,0 +1,105 @@ +diff --git a/thirdparty/embree/common/sys/intrinsics.h b/thirdparty/embree/common/sys/intrinsics.h +index 79729c87ab..ed8dd7d40a 100644 +--- a/thirdparty/embree/common/sys/intrinsics.h ++++ b/thirdparty/embree/common/sys/intrinsics.h +@@ -34,8 +34,14 @@ + #endif + + #if defined(__WIN32__) +-# define NOMINMAX +-# include <windows.h> ++// -- GODOT start -- ++#if !defined(NOMINMAX) ++// -- GODOT end -- ++#define NOMINMAX ++// -- GODOT start -- ++#endif ++#include "windows.h" ++// -- GODOT end -- + #endif + + /* normally defined in pmmintrin.h, but we always need this */ +diff --git a/thirdparty/embree/common/sys/platform.h b/thirdparty/embree/common/sys/platform.h +index 3fc5e99b8d..697e07bb86 100644 +--- a/thirdparty/embree/common/sys/platform.h ++++ b/thirdparty/embree/common/sys/platform.h +@@ -99,7 +99,9 @@ + #define dll_import + #endif + +-#ifdef __WIN32__ ++// -- GODOT start -- ++#if defined(__WIN32__) && !defined(__MINGW32__) ++// -- GODOT end -- + #if !defined(__noinline) + #define __noinline __declspec(noinline) + #endif +@@ -149,6 +151,9 @@ + #define DELETED = delete + #endif + ++// -- GODOT start -- ++#if !defined(likely) ++// -- GODOT end -- + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #define likely(expr) (expr) + #define unlikely(expr) (expr) +@@ -156,6 +161,9 @@ + #define likely(expr) __builtin_expect((bool)(expr),true ) + #define unlikely(expr) __builtin_expect((bool)(expr),false) + #endif ++// -- GODOT start -- ++#endif ++// -- GODOT end -- + + //////////////////////////////////////////////////////////////////////////////// + /// Error handling and debugging +diff --git a/thirdparty/embree/common/sys/sysinfo.cpp b/thirdparty/embree/common/sys/sysinfo.cpp +index ba97dc227b..f1a59e511e 100644 +--- a/thirdparty/embree/common/sys/sysinfo.cpp ++++ b/thirdparty/embree/common/sys/sysinfo.cpp +@@ -248,7 +248,9 @@ namespace embree + #if defined(__X86_ASM__) + __noinline int64_t get_xcr0() + { +-#if defined (__WIN32__) ++// -- GODOT start -- ++#if defined (__WIN32__) && !defined (__MINGW32__) ++// -- GODOT end -- + int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 + xcr0 = _xgetbv(0); + return xcr0; +diff --git a/thirdparty/embree/include/embree3/rtcore_common.h b/thirdparty/embree/include/embree3/rtcore_common.h +index 9c14b28745..4857e1e05e 100644 +--- a/thirdparty/embree/include/embree3/rtcore_common.h ++++ b/thirdparty/embree/include/embree3/rtcore_common.h +@@ -19,7 +19,9 @@ typedef int ssize_t; + #endif + #endif + +-#ifdef _WIN32 ++// -- GODOT start -- ++#if defined(_WIN32) && defined(_MSC_VER) ++// -- GODOT end -- + # define RTC_ALIGN(...) __declspec(align(__VA_ARGS__)) + #else + # define RTC_ALIGN(...) __attribute__((aligned(__VA_ARGS__))) +diff --git a/thirdparty/embree/common/tasking/taskschedulertbb.h b/thirdparty/embree/common/tasking/taskschedulertbb.h +index 3fd15816e9..35bd49849f 100644 +--- a/thirdparty/embree/common/tasking/taskschedulertbb.h ++++ b/thirdparty/embree/common/tasking/taskschedulertbb.h +@@ -12,7 +12,13 @@ + #include "../sys/ref.h" + + #if defined(__WIN32__) ++// -- GODOT start -- ++#if !defined(NOMINMAX) ++// -- GODOT end -- + # define NOMINMAX ++// -- GODOT start -- ++#endif ++// -- GODOT end -- + #endif + + // We need to define these to avoid implicit linkage against +
\ No newline at end of file diff --git a/thirdparty/embree-aarch64/patches/godot-changes.patch b/thirdparty/embree/patches/godot-changes-noexcept.patch index 86fbf226d2..c587a0e2be 100644 --- a/thirdparty/embree-aarch64/patches/godot-changes.patch +++ b/thirdparty/embree/patches/godot-changes-noexcept.patch @@ -1,27 +1,27 @@ -diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_for.h b/thirdparty/embree-aarch64/common/algorithms/parallel_for.h -index 76c6b740aa..51d296fb16 100644 ---- a/thirdparty/embree-aarch64/common/algorithms/parallel_for.h -+++ b/thirdparty/embree-aarch64/common/algorithms/parallel_for.h -@@ -27,7 +27,10 @@ namespace embree +diff --git a/thirdparty/embree/common/algorithms/parallel_for.h b/thirdparty/embree/common/algorithms/parallel_for.h +index f052d8b468..645681ac63 100644 +--- a/thirdparty/embree/common/algorithms/parallel_for.h ++++ b/thirdparty/embree/common/algorithms/parallel_for.h +@@ -21,7 +21,10 @@ namespace embree func(r.begin()); }); if (!TaskScheduler::wait()) - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- } - #elif defined(TASKING_GCD) && defined(BUILD_IOS) - -@@ -55,13 +58,19 @@ namespace embree + + #elif defined(TASKING_TBB) +@@ -31,13 +34,19 @@ namespace embree func(i); },context); if (context.is_group_execution_cancelled()) - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { @@ -31,31 +31,31 @@ index 76c6b740aa..51d296fb16 100644 - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #endif #elif defined(TASKING_PPL) -@@ -81,7 +90,10 @@ namespace embree +@@ -57,7 +66,10 @@ namespace embree #if defined(TASKING_INTERNAL) TaskScheduler::spawn(first,last,minStepSize,func); if (!TaskScheduler::wait()) - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- - #elif defined(TASKING_GCD) && defined(BUILD_IOS) - -@@ -109,13 +121,19 @@ namespace embree + #elif defined(TASKING_TBB) + #if TBB_INTERFACE_VERSION >= 12002 +@@ -66,13 +78,19 @@ namespace embree func(range<Index>(r.begin(),r.end())); },context); if (context.is_group_execution_cancelled()) - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #else tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) { @@ -65,19 +65,19 @@ index 76c6b740aa..51d296fb16 100644 - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #endif #elif defined(TASKING_PPL) -@@ -147,13 +165,19 @@ namespace embree +@@ -104,13 +122,19 @@ namespace embree func(i); },tbb::simple_partitioner(),context); if (context.is_group_execution_cancelled()) - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { @@ -87,20 +87,20 @@ index 76c6b740aa..51d296fb16 100644 - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #endif } -@@ -168,13 +192,19 @@ namespace embree +@@ -125,13 +149,19 @@ namespace embree func(i); },ap,context); if (context.is_group_execution_cancelled()) - throw std::runtime_error("task cancelled"); -+ // -- GODOT start -- -+ // throw std::runtime_error("task cancelled"); -+ abort(); -+ // -- GODOT end -- ++ // -- GODOT start -- ++ // throw std::runtime_error("task cancelled"); ++ abort(); ++ // -- GODOT end -- #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); @@ -109,15 +109,15 @@ index 76c6b740aa..51d296fb16 100644 - throw std::runtime_error("task cancelled"); + // -- GODOT start -- + // throw std::runtime_error("task cancelled"); -+ abort(); ++ abort(); + // -- GODOT end -- #endif } -diff --git a/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.h b/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.h -index d444b6a2e4..0daf94e50e 100644 ---- a/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.h -+++ b/thirdparty/embree-aarch64/common/algorithms/parallel_reduce.h +diff --git a/thirdparty/embree/common/algorithms/parallel_reduce.h b/thirdparty/embree/common/algorithms/parallel_reduce.h +index f42ae2ec50..8271372ea4 100644 +--- a/thirdparty/embree/common/algorithms/parallel_reduce.h ++++ b/thirdparty/embree/common/algorithms/parallel_reduce.h @@ -58,15 +58,19 @@ namespace embree const Value v = tbb::parallel_reduce(tbb::blocked_range<Index>(first,last,minStepSize),identity, [&](const tbb::blocked_range<Index>& r, const Value& start) { return reduction(start,func(range<Index>(r.begin(),r.end()))); }, @@ -142,10 +142,10 @@ index d444b6a2e4..0daf94e50e 100644 return v; #endif #else // TASKING_PPL -diff --git a/thirdparty/embree-aarch64/common/lexers/stringstream.cpp b/thirdparty/embree-aarch64/common/lexers/stringstream.cpp -index 7e7b9faef8..98dc80ad59 100644 ---- a/thirdparty/embree-aarch64/common/lexers/stringstream.cpp -+++ b/thirdparty/embree-aarch64/common/lexers/stringstream.cpp +diff --git a/thirdparty/embree/common/lexers/stringstream.cpp b/thirdparty/embree/common/lexers/stringstream.cpp +index 42ffb10176..a037869506 100644 +--- a/thirdparty/embree/common/lexers/stringstream.cpp ++++ b/thirdparty/embree/common/lexers/stringstream.cpp @@ -39,7 +39,10 @@ namespace embree std::vector<char> str; str.reserve(64); while (cin->peek() != EOF && !isSeparator(cin->peek())) { @@ -158,10 +158,10 @@ index 7e7b9faef8..98dc80ad59 100644 str.push_back((char)c); } str.push_back(0); -diff --git a/thirdparty/embree-aarch64/common/sys/alloc.cpp b/thirdparty/embree-aarch64/common/sys/alloc.cpp -index 4e8928242e..12f143f131 100644 ---- a/thirdparty/embree-aarch64/common/sys/alloc.cpp -+++ b/thirdparty/embree-aarch64/common/sys/alloc.cpp +diff --git a/thirdparty/embree/common/sys/alloc.cpp b/thirdparty/embree/common/sys/alloc.cpp +index 1bc30fe9a5..abdd269069 100644 +--- a/thirdparty/embree/common/sys/alloc.cpp ++++ b/thirdparty/embree/common/sys/alloc.cpp @@ -21,7 +21,10 @@ namespace embree void* ptr = _mm_malloc(size,align); @@ -169,7 +169,7 @@ index 4e8928242e..12f143f131 100644 - throw std::bad_alloc(); + // -- GODOT start -- + // throw std::bad_alloc(); -+ abort(); ++ abort(); + // -- GODOT end -- return ptr; @@ -246,11 +246,11 @@ index 4e8928242e..12f143f131 100644 } /* hint for transparent huge pages (THP) */ -diff --git a/thirdparty/embree-aarch64/common/sys/platform.h b/thirdparty/embree-aarch64/common/sys/platform.h -index 7914eb7a52..737f14aa6e 100644 ---- a/thirdparty/embree-aarch64/common/sys/platform.h -+++ b/thirdparty/embree-aarch64/common/sys/platform.h -@@ -174,11 +174,19 @@ +diff --git a/thirdparty/embree/common/sys/platform.h b/thirdparty/embree/common/sys/platform.h +index 8a6d9fa0a9..697e07bb86 100644 +--- a/thirdparty/embree/common/sys/platform.h ++++ b/thirdparty/embree/common/sys/platform.h +@@ -179,11 +179,19 @@ #define PRINT4(x,y,z,w) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl #if defined(DEBUG) // only report file and line in debug mode @@ -272,10 +272,10 @@ index 7914eb7a52..737f14aa6e 100644 #endif #define FATAL(x) THROW_RUNTIME_ERROR(x) -diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.cpp b/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.cpp -index 98d7fb9249..ebf656d1a0 100644 ---- a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.cpp -+++ b/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.cpp +diff --git a/thirdparty/embree/common/tasking/taskschedulerinternal.cpp b/thirdparty/embree/common/tasking/taskschedulerinternal.cpp +index dca835a716..ad438588a3 100644 +--- a/thirdparty/embree/common/tasking/taskschedulerinternal.cpp ++++ b/thirdparty/embree/common/tasking/taskschedulerinternal.cpp @@ -48,13 +48,15 @@ namespace embree { Task* prevTask = thread.task; @@ -298,7 +298,7 @@ index 98d7fb9249..ebf656d1a0 100644 thread.task = prevTask; add_dependencies(-1); } -@@ -297,8 +299,11 @@ namespace embree +@@ -291,8 +293,11 @@ namespace embree size_t threadIndex = allocThreadIndex(); condition.wait(mutex, [&] () { return hasRootTask.load(); }); mutex.unlock(); @@ -312,7 +312,7 @@ index 98d7fb9249..ebf656d1a0 100644 } void TaskScheduler::reset() { -@@ -330,7 +335,10 @@ namespace embree +@@ -324,7 +329,10 @@ namespace embree return thread->scheduler->cancellingException == nullptr; } @@ -324,7 +324,7 @@ index 98d7fb9249..ebf656d1a0 100644 { /* allocate thread structure */ std::unique_ptr<Thread> mthread(new Thread(threadIndex,this)); // too large for stack allocation -@@ -353,9 +361,10 @@ namespace embree +@@ -347,9 +355,10 @@ namespace embree swapThread(oldThread); /* remember exception to throw */ @@ -338,22 +338,22 @@ index 98d7fb9249..ebf656d1a0 100644 /* wait for all threads to terminate */ threadCounter--; #if defined(__WIN32__) -@@ -373,7 +382,10 @@ namespace embree +@@ -367,7 +376,10 @@ namespace embree yield(); #endif } - return except; -+ // -- GODOT start -- -+ // return except; -+ return; -+ // -- GODOT end -- ++ // -- GODOT start -- ++ // return except; ++ return; ++ // -- GODOT end -- } bool TaskScheduler::steal_from_other_threads(Thread& thread) -diff --git a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.h b/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.h -index c2a9391aea..8bd70b2b8c 100644 ---- a/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.h -+++ b/thirdparty/embree-aarch64/common/tasking/taskschedulerinternal.h +diff --git a/thirdparty/embree/common/tasking/taskschedulerinternal.h b/thirdparty/embree/common/tasking/taskschedulerinternal.h +index c766a0bb6a..8fa6bb12fa 100644 +--- a/thirdparty/embree/common/tasking/taskschedulerinternal.h ++++ b/thirdparty/embree/common/tasking/taskschedulerinternal.h @@ -123,7 +123,10 @@ namespace embree { size_t ofs = bytes + ((align - stackPtr) & (align-1)); @@ -371,14 +371,14 @@ index c2a9391aea..8bd70b2b8c 100644 { if (right >= TASK_STACK_SIZE) - throw std::runtime_error("task stack overflow"); -+ // -- GODOT start -- -+ // throw std::runtime_error("task stack overflow"); -+ abort(); -+ // -- GODOT end -- ++ // -- GODOT start -- ++ // throw std::runtime_error("task stack overflow"); ++ abort(); ++ // -- GODOT end -- /* allocate new task on right side of stack */ size_t oldStackPtr = stackPtr; -@@ -239,7 +245,10 @@ namespace embree +@@ -238,7 +244,10 @@ namespace embree void wait_for_threads(size_t threadCount); /*! thread loop for all worker threads */ @@ -390,10 +390,10 @@ index c2a9391aea..8bd70b2b8c 100644 /*! steals a task from a different thread */ bool steal_from_other_threads(Thread& thread); -diff --git a/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.cpp b/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.cpp -index 20cdd2d320..aa56035026 100644 ---- a/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.cpp -+++ b/thirdparty/embree-aarch64/kernels/bvh/bvh_statistics.cpp +diff --git a/thirdparty/embree/kernels/bvh/bvh_statistics.cpp b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp +index d8da78eed7..d857ff7d95 100644 +--- a/thirdparty/embree/kernels/bvh/bvh_statistics.cpp ++++ b/thirdparty/embree/kernels/bvh/bvh_statistics.cpp @@ -150,7 +150,10 @@ namespace embree } } @@ -406,11 +406,11 @@ index 20cdd2d320..aa56035026 100644 } return s; } -diff --git a/thirdparty/embree-aarch64/kernels/common/rtcore.cpp b/thirdparty/embree-aarch64/kernels/common/rtcore.cpp -index ee5c37b238..625fbf6d4f 100644 ---- a/thirdparty/embree-aarch64/kernels/common/rtcore.cpp -+++ b/thirdparty/embree-aarch64/kernels/common/rtcore.cpp -@@ -230,7 +230,10 @@ RTC_NAMESPACE_BEGIN; +diff --git a/thirdparty/embree/kernels/common/rtcore.cpp b/thirdparty/embree/kernels/common/rtcore.cpp +index 74e9fb335c..94b3819e42 100644 +--- a/thirdparty/embree/kernels/common/rtcore.cpp ++++ b/thirdparty/embree/kernels/common/rtcore.cpp +@@ -197,7 +197,10 @@ RTC_NAMESPACE_BEGIN; if (quality != RTC_BUILD_QUALITY_LOW && quality != RTC_BUILD_QUALITY_MEDIUM && quality != RTC_BUILD_QUALITY_HIGH) @@ -422,7 +422,7 @@ index ee5c37b238..625fbf6d4f 100644 scene->setBuildQuality(quality); RTC_CATCH_END2(scene); } -@@ -1383,7 +1386,10 @@ RTC_NAMESPACE_BEGIN; +@@ -1350,7 +1353,10 @@ RTC_NAMESPACE_BEGIN; quality != RTC_BUILD_QUALITY_MEDIUM && quality != RTC_BUILD_QUALITY_HIGH && quality != RTC_BUILD_QUALITY_REFIT) @@ -434,10 +434,10 @@ index ee5c37b238..625fbf6d4f 100644 geometry->setBuildQuality(quality); RTC_CATCH_END2(geometry); } -diff --git a/thirdparty/embree-aarch64/kernels/common/rtcore.h b/thirdparty/embree-aarch64/kernels/common/rtcore.h -index 6583d12d57..4b070e122b 100644 ---- a/thirdparty/embree-aarch64/kernels/common/rtcore.h -+++ b/thirdparty/embree-aarch64/kernels/common/rtcore.h +diff --git a/thirdparty/embree/kernels/common/rtcore.h b/thirdparty/embree/kernels/common/rtcore.h +index 4e4b24e9c2..373e49a689 100644 +--- a/thirdparty/embree/kernels/common/rtcore.h ++++ b/thirdparty/embree/kernels/common/rtcore.h @@ -25,52 +25,58 @@ namespace embree #endif @@ -596,11 +596,11 @@ index 6583d12d57..4b070e122b 100644 #endif #define RTC_BUILD_ARGUMENTS_HAS(settings,member) \ -diff --git a/thirdparty/embree-aarch64/kernels/common/scene.cpp b/thirdparty/embree-aarch64/kernels/common/scene.cpp -index e75aa968f9..1e23aeb415 100644 ---- a/thirdparty/embree-aarch64/kernels/common/scene.cpp -+++ b/thirdparty/embree-aarch64/kernels/common/scene.cpp -@@ -800,16 +800,18 @@ namespace embree +diff --git a/thirdparty/embree/kernels/common/scene.cpp b/thirdparty/embree/kernels/common/scene.cpp +index 0149055f2c..408d7eae6f 100644 +--- a/thirdparty/embree/kernels/common/scene.cpp ++++ b/thirdparty/embree/kernels/common/scene.cpp +@@ -792,16 +792,18 @@ namespace embree } /* initiate build */ diff --git a/thirdparty/embree/patches/godot-changes-ubsan.patch b/thirdparty/embree/patches/godot-changes-ubsan.patch new file mode 100644 index 0000000000..1336246f0d --- /dev/null +++ b/thirdparty/embree/patches/godot-changes-ubsan.patch @@ -0,0 +1,24 @@ +diff --git a/thirdparty/embree/kernels/builders/primrefgen.cpp b/thirdparty/embree/kernels/builders/primrefgen.cpp +index bb4fc81dfe..d279dc4993 100644 +--- a/thirdparty/embree/kernels/builders/primrefgen.cpp ++++ b/thirdparty/embree/kernels/builders/primrefgen.cpp +@@ -184,6 +184,9 @@ namespace embree + + // special variants for grid meshes + ++// -- GODOT start -- ++#if defined(EMBREE_GEOMETRY_GRID) ++// -- GODOT end -- + PrimInfo createPrimRefArrayGrids(Scene* scene, mvector<PrimRef>& prims, mvector<SubGridBuildData>& sgrids) + { + PrimInfo pinfo(empty); +@@ -293,6 +296,9 @@ namespace embree + + return pinfo; + } ++// -- GODOT start -- ++#endif ++// -- GODOT end -- + + // ==================================================================================================== + // ==================================================================================================== diff --git a/thirdparty/fonts/OpenSans_SemiBold.ttf b/thirdparty/fonts/OpenSans_SemiBold.ttf Binary files differnew file mode 100644 index 0000000000..54e7059cf3 --- /dev/null +++ b/thirdparty/fonts/OpenSans_SemiBold.ttf diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h index fe8d349731..e44b99ce52 100644 --- a/thirdparty/meshoptimizer/meshoptimizer.h +++ b/thirdparty/meshoptimizer/meshoptimizer.h @@ -299,6 +299,11 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t ver MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error); /** + * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex) + */ +MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count); + +/** * Experimental: Mesh simplifier (sloppy) * Reduces the number of triangles in the mesh, sacrificing mesh apperance for simplification performance * The algorithm doesn't preserve mesh topology but can stop short of the target goal based on target error. diff --git a/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch b/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch new file mode 100644 index 0000000000..cf648b0da3 --- /dev/null +++ b/thirdparty/meshoptimizer/patches/attribute-aware-simplify.patch @@ -0,0 +1,262 @@ +diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h +index fe8d349731..e44b99ce52 100644 +--- a/thirdparty/meshoptimizer/meshoptimizer.h ++++ b/thirdparty/meshoptimizer/meshoptimizer.h +@@ -298,6 +298,11 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t ver + */ + MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error); + ++/** ++ * Experimental: Mesh simplifier with attribute metric; attributes follow xyz position data atm (vertex data must contain 3 + attribute_count floats per vertex) ++ */ ++MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* result_error, const float* attributes, const float* attribute_weights, size_t attribute_count); ++ + /** + * Experimental: Mesh simplifier (sloppy) + * Reduces the number of triangles in the mesh, sacrificing mesh apperance for simplification performance +diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp +index b2cb589462..059cabb055 100644 +--- a/thirdparty/meshoptimizer/simplifier.cpp ++++ b/thirdparty/meshoptimizer/simplifier.cpp +@@ -20,6 +20,8 @@ + #define TRACESTATS(i) (void)0 + #endif + ++#define ATTRIBUTES 8 ++ + // This work is based on: + // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997 + // Michael Garland. Quadric-based polygonal surface simplification. 1999 +@@ -358,6 +360,10 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned + struct Vector3 + { + float x, y, z; ++ ++#if ATTRIBUTES ++ float a[ATTRIBUTES]; ++#endif + }; + + static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride) +@@ -414,6 +420,13 @@ struct Quadric + float a10, a20, a21; + float b0, b1, b2, c; + float w; ++ ++#if ATTRIBUTES ++ float gx[ATTRIBUTES]; ++ float gy[ATTRIBUTES]; ++ float gz[ATTRIBUTES]; ++ float gw[ATTRIBUTES]; ++#endif + }; + + struct Collapse +@@ -456,6 +469,16 @@ static void quadricAdd(Quadric& Q, const Quadric& R) + Q.b2 += R.b2; + Q.c += R.c; + Q.w += R.w; ++ ++#if ATTRIBUTES ++ for (int k = 0; k < ATTRIBUTES; ++k) ++ { ++ Q.gx[k] += R.gx[k]; ++ Q.gy[k] += R.gy[k]; ++ Q.gz[k] += R.gz[k]; ++ Q.gw[k] += R.gw[k]; ++ } ++#endif + } + + static float quadricError(const Quadric& Q, const Vector3& v) +@@ -481,6 +504,17 @@ static float quadricError(const Quadric& Q, const Vector3& v) + r += ry * v.y; + r += rz * v.z; + ++#if ATTRIBUTES ++ // see quadricUpdateAttributes for general derivation; here we need to add the parts of (eval(pos) - attr)^2 that depend on attr ++ for (int k = 0; k < ATTRIBUTES; ++k) ++ { ++ float a = v.a[k]; ++ ++ r += a * a * Q.w; ++ r -= 2 * a * (v.x * Q.gx[k] + v.y * Q.gy[k] + v.z * Q.gz[k] + Q.gw[k]); ++ } ++#endif ++ + float s = Q.w == 0.f ? 0.f : 1.f / Q.w; + + return fabsf(r) * s; +@@ -504,6 +538,13 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo + Q.b2 = c * dw; + Q.c = d * dw; + Q.w = w; ++ ++#if ATTRIBUTES ++ memset(Q.gx, 0, sizeof(Q.gx)); ++ memset(Q.gy, 0, sizeof(Q.gy)); ++ memset(Q.gz, 0, sizeof(Q.gz)); ++ memset(Q.gw, 0, sizeof(Q.gw)); ++#endif + } + + static void quadricFromPoint(Quadric& Q, float x, float y, float z, float w) +@@ -556,6 +597,84 @@ static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3 + quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance, length * weight); + } + ++#if ATTRIBUTES ++static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float w) ++{ ++ // for each attribute we want to encode the following function into the quadric: ++ // (eval(pos) - attr)^2 ++ // where eval(pos) interpolates attribute across the triangle like so: ++ // eval(pos) = pos.x * gx + pos.y * gy + pos.z * gz + gw ++ // where gx/gy/gz/gw are gradients ++ Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z}; ++ Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z}; ++ ++ // we compute gradients using barycentric coordinates; barycentric coordinates can be computed as follows: ++ // v = (d11 * d20 - d01 * d21) / denom ++ // w = (d00 * d21 - d01 * d20) / denom ++ // u = 1 - v - w ++ // here v0, v1 are triangle edge vectors, v2 is a vector from point to triangle corner, and dij = dot(vi, vj) ++ const Vector3& v0 = p10; ++ const Vector3& v1 = p20; ++ float d00 = v0.x * v0.x + v0.y * v0.y + v0.z * v0.z; ++ float d01 = v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; ++ float d11 = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z; ++ float denom = d00 * d11 - d01 * d01; ++ float denomr = denom == 0 ? 0.f : 1.f / denom; ++ ++ // precompute gradient factors ++ // these are derived by directly computing derivative of eval(pos) = a0 * u + a1 * v + a2 * w and factoring out common factors that are shared between attributes ++ float gx1 = (d11 * v0.x - d01 * v1.x) * denomr; ++ float gx2 = (d00 * v1.x - d01 * v0.x) * denomr; ++ float gy1 = (d11 * v0.y - d01 * v1.y) * denomr; ++ float gy2 = (d00 * v1.y - d01 * v0.y) * denomr; ++ float gz1 = (d11 * v0.z - d01 * v1.z) * denomr; ++ float gz2 = (d00 * v1.z - d01 * v0.z) * denomr; ++ ++ for (int k = 0; k < ATTRIBUTES; ++k) ++ { ++ float a0 = p0.a[k], a1 = p1.a[k], a2 = p2.a[k]; ++ ++ // compute gradient of eval(pos) for x/y/z/w ++ // the formulas below are obtained by directly computing derivative of eval(pos) = a0 * u + a1 * v + a2 * w ++ float gx = gx1 * (a1 - a0) + gx2 * (a2 - a0); ++ float gy = gy1 * (a1 - a0) + gy2 * (a2 - a0); ++ float gz = gz1 * (a1 - a0) + gz2 * (a2 - a0); ++ float gw = a0 - p0.x * gx - p0.y * gy - p0.z * gz; ++ ++ // quadric encodes (eval(pos)-attr)^2; this means that the resulting expansion needs to compute, for example, pos.x * pos.y * K ++ // since quadrics already encode factors for pos.x * pos.y, we can accumulate almost everything in basic quadric fields ++ Q.a00 += w * (gx * gx); ++ Q.a11 += w * (gy * gy); ++ Q.a22 += w * (gz * gz); ++ ++ Q.a10 += w * (gy * gx); ++ Q.a20 += w * (gz * gx); ++ Q.a21 += w * (gz * gy); ++ ++ Q.b0 += w * (gx * gw); ++ Q.b1 += w * (gy * gw); ++ Q.b2 += w * (gz * gw); ++ ++ Q.c += w * (gw * gw); ++ ++ // the only remaining sum components are ones that depend on attr; these will be addded during error evaluation, see quadricError ++ Q.gx[k] = w * gx; ++ Q.gy[k] = w * gy; ++ Q.gz[k] = w * gz; ++ Q.gw[k] = w * gw; ++ ++#if TRACE > 2 ++ printf("attr%d: %e %e %e\n", ++ k, ++ (gx * p0.x + gy * p0.y + gz * p0.z + gw - a0), ++ (gx * p1.x + gy * p1.y + gz * p1.z + gw - a1), ++ (gx * p2.x + gy * p2.y + gz * p2.z + gw - a2) ++ ); ++#endif ++ } ++} ++#endif ++ + static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) + { + for (size_t i = 0; i < index_count; i += 3) +@@ -567,6 +686,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic + Quadric Q; + quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f); + ++#if ATTRIBUTES ++ quadricUpdateAttributes(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], Q.w); ++#endif + quadricAdd(vertex_quadrics[remap[i0]], Q); + quadricAdd(vertex_quadrics[remap[i1]], Q); + quadricAdd(vertex_quadrics[remap[i2]], Q); +@@ -1259,13 +1381,19 @@ unsigned int* meshopt_simplifyDebugLoopBack = 0; + #endif + + size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) ++{ ++ return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, out_result_error, 0, 0, 0); ++} ++ ++size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count) + { + using namespace meshopt; + + assert(index_count % 3 == 0); +- assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); +- assert(vertex_positions_stride % sizeof(float) == 0); ++ assert(vertex_stride > 0 && vertex_stride <= 256); ++ assert(vertex_stride % sizeof(float) == 0); + assert(target_index_count <= index_count); ++ assert(attribute_count <= ATTRIBUTES); + + meshopt_Allocator allocator; + +@@ -1279,7 +1407,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, + // build position remap that maps each vertex to the one with identical position + unsigned int* remap = allocator.allocate<unsigned int>(vertex_count); + unsigned int* wedge = allocator.allocate<unsigned int>(vertex_count); +- buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, allocator); ++ buildPositionRemap(remap, wedge, vertex_data, vertex_count, vertex_stride, allocator); + + // classify vertices; vertex kind determines collapse rules, see kCanCollapse + unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count); +@@ -1303,7 +1431,21 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, + #endif + + Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count); +- rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride); ++ rescalePositions(vertex_positions, vertex_data, vertex_count, vertex_stride); ++ ++#if ATTRIBUTES ++ for (size_t i = 0; i < vertex_count; ++i) ++ { ++ memset(vertex_positions[i].a, 0, sizeof(vertex_positions[i].a)); ++ ++ for (size_t k = 0; k < attribute_count; ++k) ++ { ++ float a = attributes[i * attribute_count + k]; ++ ++ vertex_positions[i].a[k] = a * attribute_weights[k]; ++ } ++ } ++#endif + + Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count); + memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric)); +@@ -1395,7 +1537,9 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, + + // result_error is quadratic; we need to remap it back to linear + if (out_result_error) ++ { + *out_result_error = sqrtf(result_error); ++ } + + return result_count; + } diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp index b2cb589462..0f10ebef4b 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -20,6 +20,8 @@ #define TRACESTATS(i) (void)0 #endif +#define ATTRIBUTES 8 + // This work is based on: // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997 // Michael Garland. Quadric-based polygonal surface simplification. 1999 @@ -118,8 +120,13 @@ struct PositionHasher { const unsigned int* key = reinterpret_cast<const unsigned int*>(vertex_positions + index * vertex_stride_float); + // scramble bits to make sure that integer coordinates have entropy in lower bits + unsigned int x = key[0] ^ (key[0] >> 17); + unsigned int y = key[1] ^ (key[1] >> 17); + unsigned int z = key[2] ^ (key[2] >> 17); + // Optimized Spatial Hashing for Collision Detection of Deformable Objects - return (key[0] * 73856093) ^ (key[1] * 19349663) ^ (key[2] * 83492791); + return (x * 73856093) ^ (y * 19349663) ^ (z * 83492791); } bool equal(unsigned int lhs, unsigned int rhs) const @@ -358,6 +365,10 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned struct Vector3 { float x, y, z; + +#if ATTRIBUTES + float a[ATTRIBUTES]; +#endif }; static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride) @@ -414,6 +425,13 @@ struct Quadric float a10, a20, a21; float b0, b1, b2, c; float w; + +#if ATTRIBUTES + float gx[ATTRIBUTES]; + float gy[ATTRIBUTES]; + float gz[ATTRIBUTES]; + float gw[ATTRIBUTES]; +#endif }; struct Collapse @@ -456,6 +474,16 @@ static void quadricAdd(Quadric& Q, const Quadric& R) Q.b2 += R.b2; Q.c += R.c; Q.w += R.w; + +#if ATTRIBUTES + for (int k = 0; k < ATTRIBUTES; ++k) + { + Q.gx[k] += R.gx[k]; + Q.gy[k] += R.gy[k]; + Q.gz[k] += R.gz[k]; + Q.gw[k] += R.gw[k]; + } +#endif } static float quadricError(const Quadric& Q, const Vector3& v) @@ -481,6 +509,17 @@ static float quadricError(const Quadric& Q, const Vector3& v) r += ry * v.y; r += rz * v.z; +#if ATTRIBUTES + // see quadricUpdateAttributes for general derivation; here we need to add the parts of (eval(pos) - attr)^2 that depend on attr + for (int k = 0; k < ATTRIBUTES; ++k) + { + float a = v.a[k]; + + r += a * a * Q.w; + r -= 2 * a * (v.x * Q.gx[k] + v.y * Q.gy[k] + v.z * Q.gz[k] + Q.gw[k]); + } +#endif + float s = Q.w == 0.f ? 0.f : 1.f / Q.w; return fabsf(r) * s; @@ -504,6 +543,13 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo Q.b2 = c * dw; Q.c = d * dw; Q.w = w; + +#if ATTRIBUTES + memset(Q.gx, 0, sizeof(Q.gx)); + memset(Q.gy, 0, sizeof(Q.gy)); + memset(Q.gz, 0, sizeof(Q.gz)); + memset(Q.gw, 0, sizeof(Q.gw)); +#endif } static void quadricFromPoint(Quadric& Q, float x, float y, float z, float w) @@ -556,6 +602,84 @@ static void quadricFromTriangleEdge(Quadric& Q, const Vector3& p0, const Vector3 quadricFromPlane(Q, normal.x, normal.y, normal.z, -distance, length * weight); } +#if ATTRIBUTES +static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float w) +{ + // for each attribute we want to encode the following function into the quadric: + // (eval(pos) - attr)^2 + // where eval(pos) interpolates attribute across the triangle like so: + // eval(pos) = pos.x * gx + pos.y * gy + pos.z * gz + gw + // where gx/gy/gz/gw are gradients + Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z}; + Vector3 p20 = {p2.x - p0.x, p2.y - p0.y, p2.z - p0.z}; + + // we compute gradients using barycentric coordinates; barycentric coordinates can be computed as follows: + // v = (d11 * d20 - d01 * d21) / denom + // w = (d00 * d21 - d01 * d20) / denom + // u = 1 - v - w + // here v0, v1 are triangle edge vectors, v2 is a vector from point to triangle corner, and dij = dot(vi, vj) + const Vector3& v0 = p10; + const Vector3& v1 = p20; + float d00 = v0.x * v0.x + v0.y * v0.y + v0.z * v0.z; + float d01 = v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; + float d11 = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z; + float denom = d00 * d11 - d01 * d01; + float denomr = denom == 0 ? 0.f : 1.f / denom; + + // precompute gradient factors + // these are derived by directly computing derivative of eval(pos) = a0 * u + a1 * v + a2 * w and factoring out common factors that are shared between attributes + float gx1 = (d11 * v0.x - d01 * v1.x) * denomr; + float gx2 = (d00 * v1.x - d01 * v0.x) * denomr; + float gy1 = (d11 * v0.y - d01 * v1.y) * denomr; + float gy2 = (d00 * v1.y - d01 * v0.y) * denomr; + float gz1 = (d11 * v0.z - d01 * v1.z) * denomr; + float gz2 = (d00 * v1.z - d01 * v0.z) * denomr; + + for (int k = 0; k < ATTRIBUTES; ++k) + { + float a0 = p0.a[k], a1 = p1.a[k], a2 = p2.a[k]; + + // compute gradient of eval(pos) for x/y/z/w + // the formulas below are obtained by directly computing derivative of eval(pos) = a0 * u + a1 * v + a2 * w + float gx = gx1 * (a1 - a0) + gx2 * (a2 - a0); + float gy = gy1 * (a1 - a0) + gy2 * (a2 - a0); + float gz = gz1 * (a1 - a0) + gz2 * (a2 - a0); + float gw = a0 - p0.x * gx - p0.y * gy - p0.z * gz; + + // quadric encodes (eval(pos)-attr)^2; this means that the resulting expansion needs to compute, for example, pos.x * pos.y * K + // since quadrics already encode factors for pos.x * pos.y, we can accumulate almost everything in basic quadric fields + Q.a00 += w * (gx * gx); + Q.a11 += w * (gy * gy); + Q.a22 += w * (gz * gz); + + Q.a10 += w * (gy * gx); + Q.a20 += w * (gz * gx); + Q.a21 += w * (gz * gy); + + Q.b0 += w * (gx * gw); + Q.b1 += w * (gy * gw); + Q.b2 += w * (gz * gw); + + Q.c += w * (gw * gw); + + // the only remaining sum components are ones that depend on attr; these will be addded during error evaluation, see quadricError + Q.gx[k] = w * gx; + Q.gy[k] = w * gy; + Q.gz[k] = w * gz; + Q.gw[k] = w * gw; + +#if TRACE > 2 + printf("attr%d: %e %e %e\n", + k, + (gx * p0.x + gy * p0.y + gz * p0.z + gw - a0), + (gx * p1.x + gy * p1.y + gz * p1.z + gw - a1), + (gx * p2.x + gy * p2.y + gz * p2.z + gw - a2) + ); +#endif + } +} +#endif + static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) { for (size_t i = 0; i < index_count; i += 3) @@ -567,6 +691,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic Quadric Q; quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f); +#if ATTRIBUTES + quadricUpdateAttributes(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], Q.w); +#endif quadricAdd(vertex_quadrics[remap[i0]], Q); quadricAdd(vertex_quadrics[remap[i1]], Q); quadricAdd(vertex_quadrics[remap[i2]], Q); @@ -1038,7 +1165,7 @@ struct IdHasher struct TriangleHasher { - unsigned int* indices; + const unsigned int* indices; size_t hash(unsigned int i) const { @@ -1253,19 +1380,26 @@ static float interpolate(float y, float x0, float y0, float x1, float y1, float } // namespace meshopt #ifndef NDEBUG -unsigned char* meshopt_simplifyDebugKind = 0; -unsigned int* meshopt_simplifyDebugLoop = 0; -unsigned int* meshopt_simplifyDebugLoopBack = 0; +// Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds +MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = 0; +MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0; +MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0; #endif size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) { + return meshopt_simplifyWithAttributes(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, target_index_count, target_error, out_result_error, 0, 0, 0); +} + +size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_data, size_t vertex_count, size_t vertex_stride, size_t target_index_count, float target_error, float* out_result_error, const float* attributes, const float* attribute_weights, size_t attribute_count) +{ using namespace meshopt; assert(index_count % 3 == 0); - assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256); - assert(vertex_positions_stride % sizeof(float) == 0); + assert(vertex_stride > 0 && vertex_stride <= 256); + assert(vertex_stride % sizeof(float) == 0); assert(target_index_count <= index_count); + assert(attribute_count <= ATTRIBUTES); meshopt_Allocator allocator; @@ -1279,7 +1413,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, // build position remap that maps each vertex to the one with identical position unsigned int* remap = allocator.allocate<unsigned int>(vertex_count); unsigned int* wedge = allocator.allocate<unsigned int>(vertex_count); - buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, allocator); + buildPositionRemap(remap, wedge, vertex_data, vertex_count, vertex_stride, allocator); // classify vertices; vertex kind determines collapse rules, see kCanCollapse unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count); @@ -1303,7 +1437,21 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, #endif Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count); - rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride); + rescalePositions(vertex_positions, vertex_data, vertex_count, vertex_stride); + +#if ATTRIBUTES + for (size_t i = 0; i < vertex_count; ++i) + { + memset(vertex_positions[i].a, 0, sizeof(vertex_positions[i].a)); + + for (size_t k = 0; k < attribute_count; ++k) + { + float a = attributes[i * attribute_count + k]; + + vertex_positions[i].a[k] = a * attribute_weights[k]; + } + } +#endif Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count); memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric)); @@ -1395,7 +1543,9 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, // result_error is quadratic; we need to remap it back to linear if (out_result_error) + { *out_result_error = sqrtf(result_error); + } return result_count; } diff --git a/thirdparty/misc/patches/polypartition-godot-types.patch b/thirdparty/misc/patches/polypartition-godot-types.patch index 59fdb2707c..782f02e8dc 100644 --- a/thirdparty/misc/patches/polypartition-godot-types.patch +++ b/thirdparty/misc/patches/polypartition-godot-types.patch @@ -1,5 +1,5 @@ diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp -index 3a8a6efa8319..4f1b6dcb21d8 100644 +index 3a8a6efa83..5e94793b79 100644 --- a/thirdparty/misc/polypartition.cpp +++ b/thirdparty/misc/polypartition.cpp @@ -23,10 +23,7 @@ @@ -510,7 +510,7 @@ index 3a8a6efa8319..4f1b6dcb21d8 100644 - return 0; - } - numvertices += iter->GetNumPoints(); -+ for (iter = inpolys->front(); iter; iter++) { ++ for (iter = inpolys->front(); iter; iter = iter->next()) { + numvertices += iter->get().GetNumPoints(); } @@ -521,7 +521,7 @@ index 3a8a6efa8319..4f1b6dcb21d8 100644 polystartindex = 0; - for (iter = inpolys->begin(); iter != inpolys->end(); iter++) { - poly = &(*iter); -+ for (iter = inpolys->front(); iter; iter++) { ++ for (iter = inpolys->front(); iter; iter = iter->next()) { + poly = &(iter->get()); polyendindex = polystartindex + poly->GetNumPoints() - 1; for (i = 0; i < poly->GetNumPoints(); i++) { @@ -569,7 +569,7 @@ index 3a8a6efa8319..4f1b6dcb21d8 100644 newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if (edgeIter == edgeTree.begin()) { -+ if (edgeIter == edgeTree.front()) { ++ if (edgeIter == nullptr || edgeIter == edgeTree.front()) { error = true; break; } @@ -606,7 +606,7 @@ index 3a8a6efa8319..4f1b6dcb21d8 100644 newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if (edgeIter == edgeTree.begin()) { -+ if (edgeIter == edgeTree.front()) { ++ if (edgeIter == nullptr || edgeIter == edgeTree.front()) { error = true; break; } @@ -648,7 +648,7 @@ index 3a8a6efa8319..4f1b6dcb21d8 100644 newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if (edgeIter == edgeTree.begin()) { -+ if (edgeIter == edgeTree.front()) { ++ if (edgeIter == nullptr || edgeIter == edgeTree.front()) { error = true; break; } @@ -716,7 +716,7 @@ index 3a8a6efa8319..4f1b6dcb21d8 100644 } } diff --git a/thirdparty/misc/polypartition.h b/thirdparty/misc/polypartition.h -index f163f5d2173f..b2d905a3ef76 100644 +index f163f5d217..b2d905a3ef 100644 --- a/thirdparty/misc/polypartition.h +++ b/thirdparty/misc/polypartition.h @@ -24,8 +24,9 @@ diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp index 4f1b6dcb21..5e94793b79 100644 --- a/thirdparty/misc/polypartition.cpp +++ b/thirdparty/misc/polypartition.cpp @@ -1289,7 +1289,7 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto bool error = false; numvertices = 0; - for (iter = inpolys->front(); iter; iter++) { + for (iter = inpolys->front(); iter; iter = iter->next()) { numvertices += iter->get().GetNumPoints(); } @@ -1298,7 +1298,7 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto newnumvertices = numvertices; polystartindex = 0; - for (iter = inpolys->front(); iter; iter++) { + for (iter = inpolys->front(); iter; iter = iter->next()) { poly = &(iter->get()); polyendindex = polystartindex + poly->GetNumPoints() - 1; for (i = 0; i < poly->GetNumPoints(); i++) { @@ -1408,7 +1408,7 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto newedge.p1 = v->p; newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if (edgeIter == edgeTree.front()) { + if (edgeIter == nullptr || edgeIter == edgeTree.front()) { error = true; break; } @@ -1449,7 +1449,7 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto newedge.p1 = v->p; newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if (edgeIter == edgeTree.front()) { + if (edgeIter == nullptr || edgeIter == edgeTree.front()) { error = true; break; } @@ -1494,7 +1494,7 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto newedge.p1 = v->p; newedge.p2 = v->p; edgeIter = edgeTree.lower_bound(newedge); - if (edgeIter == edgeTree.front()) { + if (edgeIter == nullptr || edgeIter == edgeTree.front()) { error = true; break; } diff --git a/thirdparty/misc/smolv.cpp b/thirdparty/misc/smolv.cpp new file mode 100644 index 0000000000..26ed7294f9 --- /dev/null +++ b/thirdparty/misc/smolv.cpp @@ -0,0 +1,2108 @@ +// smol-v - public domain - https://github.com/aras-p/smol-v +// authored 2016-2020 by Aras Pranckevicius +// no warranty implied; use at your own risk +// See end of file for license information. + +#include "smolv.h" +#include <stdint.h> +#include <vector> +#include <algorithm> +#include <cstdio> +#include <cstring> + +#if !defined(_MSC_VER) && __cplusplus < 201103L +#define static_assert(x,y) +#endif + +#define _SMOLV_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +// -------------------------------------------------------------------------------------------- +// Metadata about known SPIR-V operations + +enum SpvOp +{ + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpVectorShuffleCompact = 13, // not in SPIR-V, added for SMOL-V! + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpGroupNonUniformElect = 333, + SpvOpGroupNonUniformAll = 334, + SpvOpGroupNonUniformAny = 335, + SpvOpGroupNonUniformAllEqual = 336, + SpvOpGroupNonUniformBroadcast = 337, + SpvOpGroupNonUniformBroadcastFirst = 338, + SpvOpGroupNonUniformBallot = 339, + SpvOpGroupNonUniformInverseBallot = 340, + SpvOpGroupNonUniformBallotBitExtract = 341, + SpvOpGroupNonUniformBallotBitCount = 342, + SpvOpGroupNonUniformBallotFindLSB = 343, + SpvOpGroupNonUniformBallotFindMSB = 344, + SpvOpGroupNonUniformShuffle = 345, + SpvOpGroupNonUniformShuffleXor = 346, + SpvOpGroupNonUniformShuffleUp = 347, + SpvOpGroupNonUniformShuffleDown = 348, + SpvOpGroupNonUniformIAdd = 349, + SpvOpGroupNonUniformFAdd = 350, + SpvOpGroupNonUniformIMul = 351, + SpvOpGroupNonUniformFMul = 352, + SpvOpGroupNonUniformSMin = 353, + SpvOpGroupNonUniformUMin = 354, + SpvOpGroupNonUniformFMin = 355, + SpvOpGroupNonUniformSMax = 356, + SpvOpGroupNonUniformUMax = 357, + SpvOpGroupNonUniformFMax = 358, + SpvOpGroupNonUniformBitwiseAnd = 359, + SpvOpGroupNonUniformBitwiseOr = 360, + SpvOpGroupNonUniformBitwiseXor = 361, + SpvOpGroupNonUniformLogicalAnd = 362, + SpvOpGroupNonUniformLogicalOr = 363, + SpvOpGroupNonUniformLogicalXor = 364, + SpvOpGroupNonUniformQuadBroadcast = 365, + SpvOpGroupNonUniformQuadSwap = 366, +}; +static const int kKnownOpsCount = SpvOpGroupNonUniformQuadSwap+1; + + +static const char* kSpirvOpNames[] = +{ + "Nop", + "Undef", + "SourceContinued", + "Source", + "SourceExtension", + "Name", + "MemberName", + "String", + "Line", + "#9", + "Extension", + "ExtInstImport", + "ExtInst", + "VectorShuffleCompact", + "MemoryModel", + "EntryPoint", + "ExecutionMode", + "Capability", + "#18", + "TypeVoid", + "TypeBool", + "TypeInt", + "TypeFloat", + "TypeVector", + "TypeMatrix", + "TypeImage", + "TypeSampler", + "TypeSampledImage", + "TypeArray", + "TypeRuntimeArray", + "TypeStruct", + "TypeOpaque", + "TypePointer", + "TypeFunction", + "TypeEvent", + "TypeDeviceEvent", + "TypeReserveId", + "TypeQueue", + "TypePipe", + "TypeForwardPointer", + "#40", + "ConstantTrue", + "ConstantFalse", + "Constant", + "ConstantComposite", + "ConstantSampler", + "ConstantNull", + "#47", + "SpecConstantTrue", + "SpecConstantFalse", + "SpecConstant", + "SpecConstantComposite", + "SpecConstantOp", + "#53", + "Function", + "FunctionParameter", + "FunctionEnd", + "FunctionCall", + "#58", + "Variable", + "ImageTexelPointer", + "Load", + "Store", + "CopyMemory", + "CopyMemorySized", + "AccessChain", + "InBoundsAccessChain", + "PtrAccessChain", + "ArrayLength", + "GenericPtrMemSemantics", + "InBoundsPtrAccessChain", + "Decorate", + "MemberDecorate", + "DecorationGroup", + "GroupDecorate", + "GroupMemberDecorate", + "#76", + "VectorExtractDynamic", + "VectorInsertDynamic", + "VectorShuffle", + "CompositeConstruct", + "CompositeExtract", + "CompositeInsert", + "CopyObject", + "Transpose", + "#85", + "SampledImage", + "ImageSampleImplicitLod", + "ImageSampleExplicitLod", + "ImageSampleDrefImplicitLod", + "ImageSampleDrefExplicitLod", + "ImageSampleProjImplicitLod", + "ImageSampleProjExplicitLod", + "ImageSampleProjDrefImplicitLod", + "ImageSampleProjDrefExplicitLod", + "ImageFetch", + "ImageGather", + "ImageDrefGather", + "ImageRead", + "ImageWrite", + "Image", + "ImageQueryFormat", + "ImageQueryOrder", + "ImageQuerySizeLod", + "ImageQuerySize", + "ImageQueryLod", + "ImageQueryLevels", + "ImageQuerySamples", + "#108", + "ConvertFToU", + "ConvertFToS", + "ConvertSToF", + "ConvertUToF", + "UConvert", + "SConvert", + "FConvert", + "QuantizeToF16", + "ConvertPtrToU", + "SatConvertSToU", + "SatConvertUToS", + "ConvertUToPtr", + "PtrCastToGeneric", + "GenericCastToPtr", + "GenericCastToPtrExplicit", + "Bitcast", + "#125", + "SNegate", + "FNegate", + "IAdd", + "FAdd", + "ISub", + "FSub", + "IMul", + "FMul", + "UDiv", + "SDiv", + "FDiv", + "UMod", + "SRem", + "SMod", + "FRem", + "FMod", + "VectorTimesScalar", + "MatrixTimesScalar", + "VectorTimesMatrix", + "MatrixTimesVector", + "MatrixTimesMatrix", + "OuterProduct", + "Dot", + "IAddCarry", + "ISubBorrow", + "UMulExtended", + "SMulExtended", + "#153", + "Any", + "All", + "IsNan", + "IsInf", + "IsFinite", + "IsNormal", + "SignBitSet", + "LessOrGreater", + "Ordered", + "Unordered", + "LogicalEqual", + "LogicalNotEqual", + "LogicalOr", + "LogicalAnd", + "LogicalNot", + "Select", + "IEqual", + "INotEqual", + "UGreaterThan", + "SGreaterThan", + "UGreaterThanEqual", + "SGreaterThanEqual", + "ULessThan", + "SLessThan", + "ULessThanEqual", + "SLessThanEqual", + "FOrdEqual", + "FUnordEqual", + "FOrdNotEqual", + "FUnordNotEqual", + "FOrdLessThan", + "FUnordLessThan", + "FOrdGreaterThan", + "FUnordGreaterThan", + "FOrdLessThanEqual", + "FUnordLessThanEqual", + "FOrdGreaterThanEqual", + "FUnordGreaterThanEqual", + "#192", + "#193", + "ShiftRightLogical", + "ShiftRightArithmetic", + "ShiftLeftLogical", + "BitwiseOr", + "BitwiseXor", + "BitwiseAnd", + "Not", + "BitFieldInsert", + "BitFieldSExtract", + "BitFieldUExtract", + "BitReverse", + "BitCount", + "#206", + "DPdx", + "DPdy", + "Fwidth", + "DPdxFine", + "DPdyFine", + "FwidthFine", + "DPdxCoarse", + "DPdyCoarse", + "FwidthCoarse", + "#216", + "#217", + "EmitVertex", + "EndPrimitive", + "EmitStreamVertex", + "EndStreamPrimitive", + "#222", + "#223", + "ControlBarrier", + "MemoryBarrier", + "#226", + "AtomicLoad", + "AtomicStore", + "AtomicExchange", + "AtomicCompareExchange", + "AtomicCompareExchangeWeak", + "AtomicIIncrement", + "AtomicIDecrement", + "AtomicIAdd", + "AtomicISub", + "AtomicSMin", + "AtomicUMin", + "AtomicSMax", + "AtomicUMax", + "AtomicAnd", + "AtomicOr", + "AtomicXor", + "#243", + "#244", + "Phi", + "LoopMerge", + "SelectionMerge", + "Label", + "Branch", + "BranchConditional", + "Switch", + "Kill", + "Return", + "ReturnValue", + "Unreachable", + "LifetimeStart", + "LifetimeStop", + "#258", + "GroupAsyncCopy", + "GroupWaitEvents", + "GroupAll", + "GroupAny", + "GroupBroadcast", + "GroupIAdd", + "GroupFAdd", + "GroupFMin", + "GroupUMin", + "GroupSMin", + "GroupFMax", + "GroupUMax", + "GroupSMax", + "#272", + "#273", + "ReadPipe", + "WritePipe", + "ReservedReadPipe", + "ReservedWritePipe", + "ReserveReadPipePackets", + "ReserveWritePipePackets", + "CommitReadPipe", + "CommitWritePipe", + "IsValidReserveId", + "GetNumPipePackets", + "GetMaxPipePackets", + "GroupReserveReadPipePackets", + "GroupReserveWritePipePackets", + "GroupCommitReadPipe", + "GroupCommitWritePipe", + "#289", + "#290", + "EnqueueMarker", + "EnqueueKernel", + "GetKernelNDrangeSubGroupCount", + "GetKernelNDrangeMaxSubGroupSize", + "GetKernelWorkGroupSize", + "GetKernelPreferredWorkGroupSizeMultiple", + "RetainEvent", + "ReleaseEvent", + "CreateUserEvent", + "IsValidEvent", + "SetUserEventStatus", + "CaptureEventProfilingInfo", + "GetDefaultQueue", + "BuildNDRange", + "ImageSparseSampleImplicitLod", + "ImageSparseSampleExplicitLod", + "ImageSparseSampleDrefImplicitLod", + "ImageSparseSampleDrefExplicitLod", + "ImageSparseSampleProjImplicitLod", + "ImageSparseSampleProjExplicitLod", + "ImageSparseSampleProjDrefImplicitLod", + "ImageSparseSampleProjDrefExplicitLod", + "ImageSparseFetch", + "ImageSparseGather", + "ImageSparseDrefGather", + "ImageSparseTexelsResident", + "NoLine", + "AtomicFlagTestAndSet", + "AtomicFlagClear", + "ImageSparseRead", + "SizeOf", + "TypePipeStorage", + "ConstantPipeStorage", + "CreatePipeFromPipeStorage", + "GetKernelLocalSizeForSubgroupCount", + "GetKernelMaxNumSubgroups", + "TypeNamedBarrier", + "NamedBarrierInitialize", + "MemoryNamedBarrier", + "ModuleProcessed", + "ExecutionModeId", + "DecorateId", + "GroupNonUniformElect", + "GroupNonUniformAll", + "GroupNonUniformAny", + "GroupNonUniformAllEqual", + "GroupNonUniformBroadcast", + "GroupNonUniformBroadcastFirst", + "GroupNonUniformBallot", + "GroupNonUniformInverseBallot", + "GroupNonUniformBallotBitExtract", + "GroupNonUniformBallotBitCount", + "GroupNonUniformBallotFindLSB", + "GroupNonUniformBallotFindMSB", + "GroupNonUniformShuffle", + "GroupNonUniformShuffleXor", + "GroupNonUniformShuffleUp", + "GroupNonUniformShuffleDown", + "GroupNonUniformIAdd", + "GroupNonUniformFAdd", + "GroupNonUniformIMul", + "GroupNonUniformFMul", + "GroupNonUniformSMin", + "GroupNonUniformUMin", + "GroupNonUniformFMin", + "GroupNonUniformSMax", + "GroupNonUniformUMax", + "GroupNonUniformFMax", + "GroupNonUniformBitwiseAnd", + "GroupNonUniformBitwiseOr", + "GroupNonUniformBitwiseXor", + "GroupNonUniformLogicalAnd", + "GroupNonUniformLogicalOr", + "GroupNonUniformLogicalXor", + "GroupNonUniformQuadBroadcast", + "GroupNonUniformQuadSwap", +}; +static_assert(_SMOLV_ARRAY_SIZE(kSpirvOpNames) == kKnownOpsCount, "kSpirvOpNames table mismatch with known SpvOps"); + + +struct OpData +{ + uint8_t hasResult; // does it have result ID? + uint8_t hasType; // does it have type ID? + uint8_t deltaFromResult; // How many words after (optional) type+result to write out as deltas from result? + uint8_t varrest; // should the rest of words be written in varint encoding? +}; +static const OpData kSpirvOpData[] = +{ + {0, 0, 0, 0}, // Nop + {1, 1, 0, 0}, // Undef + {0, 0, 0, 0}, // SourceContinued + {0, 0, 0, 1}, // Source + {0, 0, 0, 0}, // SourceExtension + {0, 0, 0, 0}, // Name + {0, 0, 0, 0}, // MemberName + {0, 0, 0, 0}, // String + {0, 0, 0, 1}, // Line + {1, 1, 0, 0}, // #9 + {0, 0, 0, 0}, // Extension + {1, 0, 0, 0}, // ExtInstImport + {1, 1, 0, 1}, // ExtInst + {1, 1, 2, 1}, // VectorShuffleCompact - new in SMOLV + {0, 0, 0, 1}, // MemoryModel + {0, 0, 0, 1}, // EntryPoint + {0, 0, 0, 1}, // ExecutionMode + {0, 0, 0, 1}, // Capability + {1, 1, 0, 0}, // #18 + {1, 0, 0, 1}, // TypeVoid + {1, 0, 0, 1}, // TypeBool + {1, 0, 0, 1}, // TypeInt + {1, 0, 0, 1}, // TypeFloat + {1, 0, 0, 1}, // TypeVector + {1, 0, 0, 1}, // TypeMatrix + {1, 0, 0, 1}, // TypeImage + {1, 0, 0, 1}, // TypeSampler + {1, 0, 0, 1}, // TypeSampledImage + {1, 0, 0, 1}, // TypeArray + {1, 0, 0, 1}, // TypeRuntimeArray + {1, 0, 0, 1}, // TypeStruct + {1, 0, 0, 1}, // TypeOpaque + {1, 0, 0, 1}, // TypePointer + {1, 0, 0, 1}, // TypeFunction + {1, 0, 0, 1}, // TypeEvent + {1, 0, 0, 1}, // TypeDeviceEvent + {1, 0, 0, 1}, // TypeReserveId + {1, 0, 0, 1}, // TypeQueue + {1, 0, 0, 1}, // TypePipe + {0, 0, 0, 1}, // TypeForwardPointer + {1, 1, 0, 0}, // #40 + {1, 1, 0, 0}, // ConstantTrue + {1, 1, 0, 0}, // ConstantFalse + {1, 1, 0, 0}, // Constant + {1, 1, 9, 0}, // ConstantComposite + {1, 1, 0, 1}, // ConstantSampler + {1, 1, 0, 0}, // ConstantNull + {1, 1, 0, 0}, // #47 + {1, 1, 0, 0}, // SpecConstantTrue + {1, 1, 0, 0}, // SpecConstantFalse + {1, 1, 0, 0}, // SpecConstant + {1, 1, 9, 0}, // SpecConstantComposite + {1, 1, 0, 0}, // SpecConstantOp + {1, 1, 0, 0}, // #53 + {1, 1, 0, 1}, // Function + {1, 1, 0, 0}, // FunctionParameter + {0, 0, 0, 0}, // FunctionEnd + {1, 1, 9, 0}, // FunctionCall + {1, 1, 0, 0}, // #58 + {1, 1, 0, 1}, // Variable + {1, 1, 0, 0}, // ImageTexelPointer + {1, 1, 1, 1}, // Load + {0, 0, 2, 1}, // Store + {0, 0, 0, 0}, // CopyMemory + {0, 0, 0, 0}, // CopyMemorySized + {1, 1, 0, 1}, // AccessChain + {1, 1, 0, 0}, // InBoundsAccessChain + {1, 1, 0, 0}, // PtrAccessChain + {1, 1, 0, 0}, // ArrayLength + {1, 1, 0, 0}, // GenericPtrMemSemantics + {1, 1, 0, 0}, // InBoundsPtrAccessChain + {0, 0, 0, 1}, // Decorate + {0, 0, 0, 1}, // MemberDecorate + {1, 0, 0, 0}, // DecorationGroup + {0, 0, 0, 0}, // GroupDecorate + {0, 0, 0, 0}, // GroupMemberDecorate + {1, 1, 0, 0}, // #76 + {1, 1, 1, 1}, // VectorExtractDynamic + {1, 1, 2, 1}, // VectorInsertDynamic + {1, 1, 2, 1}, // VectorShuffle + {1, 1, 9, 0}, // CompositeConstruct + {1, 1, 1, 1}, // CompositeExtract + {1, 1, 2, 1}, // CompositeInsert + {1, 1, 1, 0}, // CopyObject + {1, 1, 0, 0}, // Transpose + {1, 1, 0, 0}, // #85 + {1, 1, 0, 0}, // SampledImage + {1, 1, 2, 1}, // ImageSampleImplicitLod + {1, 1, 2, 1}, // ImageSampleExplicitLod + {1, 1, 3, 1}, // ImageSampleDrefImplicitLod + {1, 1, 3, 1}, // ImageSampleDrefExplicitLod + {1, 1, 2, 1}, // ImageSampleProjImplicitLod + {1, 1, 2, 1}, // ImageSampleProjExplicitLod + {1, 1, 3, 1}, // ImageSampleProjDrefImplicitLod + {1, 1, 3, 1}, // ImageSampleProjDrefExplicitLod + {1, 1, 2, 1}, // ImageFetch + {1, 1, 3, 1}, // ImageGather + {1, 1, 3, 1}, // ImageDrefGather + {1, 1, 2, 1}, // ImageRead + {0, 0, 3, 1}, // ImageWrite + {1, 1, 1, 0}, // Image + {1, 1, 1, 0}, // ImageQueryFormat + {1, 1, 1, 0}, // ImageQueryOrder + {1, 1, 2, 0}, // ImageQuerySizeLod + {1, 1, 1, 0}, // ImageQuerySize + {1, 1, 2, 0}, // ImageQueryLod + {1, 1, 1, 0}, // ImageQueryLevels + {1, 1, 1, 0}, // ImageQuerySamples + {1, 1, 0, 0}, // #108 + {1, 1, 1, 0}, // ConvertFToU + {1, 1, 1, 0}, // ConvertFToS + {1, 1, 1, 0}, // ConvertSToF + {1, 1, 1, 0}, // ConvertUToF + {1, 1, 1, 0}, // UConvert + {1, 1, 1, 0}, // SConvert + {1, 1, 1, 0}, // FConvert + {1, 1, 1, 0}, // QuantizeToF16 + {1, 1, 1, 0}, // ConvertPtrToU + {1, 1, 1, 0}, // SatConvertSToU + {1, 1, 1, 0}, // SatConvertUToS + {1, 1, 1, 0}, // ConvertUToPtr + {1, 1, 1, 0}, // PtrCastToGeneric + {1, 1, 1, 0}, // GenericCastToPtr + {1, 1, 1, 1}, // GenericCastToPtrExplicit + {1, 1, 1, 0}, // Bitcast + {1, 1, 0, 0}, // #125 + {1, 1, 1, 0}, // SNegate + {1, 1, 1, 0}, // FNegate + {1, 1, 2, 0}, // IAdd + {1, 1, 2, 0}, // FAdd + {1, 1, 2, 0}, // ISub + {1, 1, 2, 0}, // FSub + {1, 1, 2, 0}, // IMul + {1, 1, 2, 0}, // FMul + {1, 1, 2, 0}, // UDiv + {1, 1, 2, 0}, // SDiv + {1, 1, 2, 0}, // FDiv + {1, 1, 2, 0}, // UMod + {1, 1, 2, 0}, // SRem + {1, 1, 2, 0}, // SMod + {1, 1, 2, 0}, // FRem + {1, 1, 2, 0}, // FMod + {1, 1, 2, 0}, // VectorTimesScalar + {1, 1, 2, 0}, // MatrixTimesScalar + {1, 1, 2, 0}, // VectorTimesMatrix + {1, 1, 2, 0}, // MatrixTimesVector + {1, 1, 2, 0}, // MatrixTimesMatrix + {1, 1, 2, 0}, // OuterProduct + {1, 1, 2, 0}, // Dot + {1, 1, 2, 0}, // IAddCarry + {1, 1, 2, 0}, // ISubBorrow + {1, 1, 2, 0}, // UMulExtended + {1, 1, 2, 0}, // SMulExtended + {1, 1, 0, 0}, // #153 + {1, 1, 1, 0}, // Any + {1, 1, 1, 0}, // All + {1, 1, 1, 0}, // IsNan + {1, 1, 1, 0}, // IsInf + {1, 1, 1, 0}, // IsFinite + {1, 1, 1, 0}, // IsNormal + {1, 1, 1, 0}, // SignBitSet + {1, 1, 2, 0}, // LessOrGreater + {1, 1, 2, 0}, // Ordered + {1, 1, 2, 0}, // Unordered + {1, 1, 2, 0}, // LogicalEqual + {1, 1, 2, 0}, // LogicalNotEqual + {1, 1, 2, 0}, // LogicalOr + {1, 1, 2, 0}, // LogicalAnd + {1, 1, 1, 0}, // LogicalNot + {1, 1, 3, 0}, // Select + {1, 1, 2, 0}, // IEqual + {1, 1, 2, 0}, // INotEqual + {1, 1, 2, 0}, // UGreaterThan + {1, 1, 2, 0}, // SGreaterThan + {1, 1, 2, 0}, // UGreaterThanEqual + {1, 1, 2, 0}, // SGreaterThanEqual + {1, 1, 2, 0}, // ULessThan + {1, 1, 2, 0}, // SLessThan + {1, 1, 2, 0}, // ULessThanEqual + {1, 1, 2, 0}, // SLessThanEqual + {1, 1, 2, 0}, // FOrdEqual + {1, 1, 2, 0}, // FUnordEqual + {1, 1, 2, 0}, // FOrdNotEqual + {1, 1, 2, 0}, // FUnordNotEqual + {1, 1, 2, 0}, // FOrdLessThan + {1, 1, 2, 0}, // FUnordLessThan + {1, 1, 2, 0}, // FOrdGreaterThan + {1, 1, 2, 0}, // FUnordGreaterThan + {1, 1, 2, 0}, // FOrdLessThanEqual + {1, 1, 2, 0}, // FUnordLessThanEqual + {1, 1, 2, 0}, // FOrdGreaterThanEqual + {1, 1, 2, 0}, // FUnordGreaterThanEqual + {1, 1, 0, 0}, // #192 + {1, 1, 0, 0}, // #193 + {1, 1, 2, 0}, // ShiftRightLogical + {1, 1, 2, 0}, // ShiftRightArithmetic + {1, 1, 2, 0}, // ShiftLeftLogical + {1, 1, 2, 0}, // BitwiseOr + {1, 1, 2, 0}, // BitwiseXor + {1, 1, 2, 0}, // BitwiseAnd + {1, 1, 1, 0}, // Not + {1, 1, 4, 0}, // BitFieldInsert + {1, 1, 3, 0}, // BitFieldSExtract + {1, 1, 3, 0}, // BitFieldUExtract + {1, 1, 1, 0}, // BitReverse + {1, 1, 1, 0}, // BitCount + {1, 1, 0, 0}, // #206 + {1, 1, 0, 0}, // DPdx + {1, 1, 0, 0}, // DPdy + {1, 1, 0, 0}, // Fwidth + {1, 1, 0, 0}, // DPdxFine + {1, 1, 0, 0}, // DPdyFine + {1, 1, 0, 0}, // FwidthFine + {1, 1, 0, 0}, // DPdxCoarse + {1, 1, 0, 0}, // DPdyCoarse + {1, 1, 0, 0}, // FwidthCoarse + {1, 1, 0, 0}, // #216 + {1, 1, 0, 0}, // #217 + {0, 0, 0, 0}, // EmitVertex + {0, 0, 0, 0}, // EndPrimitive + {0, 0, 0, 0}, // EmitStreamVertex + {0, 0, 0, 0}, // EndStreamPrimitive + {1, 1, 0, 0}, // #222 + {1, 1, 0, 0}, // #223 + {0, 0, 3, 0}, // ControlBarrier + {0, 0, 2, 0}, // MemoryBarrier + {1, 1, 0, 0}, // #226 + {1, 1, 0, 0}, // AtomicLoad + {0, 0, 0, 0}, // AtomicStore + {1, 1, 0, 0}, // AtomicExchange + {1, 1, 0, 0}, // AtomicCompareExchange + {1, 1, 0, 0}, // AtomicCompareExchangeWeak + {1, 1, 0, 0}, // AtomicIIncrement + {1, 1, 0, 0}, // AtomicIDecrement + {1, 1, 0, 0}, // AtomicIAdd + {1, 1, 0, 0}, // AtomicISub + {1, 1, 0, 0}, // AtomicSMin + {1, 1, 0, 0}, // AtomicUMin + {1, 1, 0, 0}, // AtomicSMax + {1, 1, 0, 0}, // AtomicUMax + {1, 1, 0, 0}, // AtomicAnd + {1, 1, 0, 0}, // AtomicOr + {1, 1, 0, 0}, // AtomicXor + {1, 1, 0, 0}, // #243 + {1, 1, 0, 0}, // #244 + {1, 1, 0, 0}, // Phi + {0, 0, 2, 1}, // LoopMerge + {0, 0, 1, 1}, // SelectionMerge + {1, 0, 0, 0}, // Label + {0, 0, 1, 0}, // Branch + {0, 0, 3, 1}, // BranchConditional + {0, 0, 0, 0}, // Switch + {0, 0, 0, 0}, // Kill + {0, 0, 0, 0}, // Return + {0, 0, 0, 0}, // ReturnValue + {0, 0, 0, 0}, // Unreachable + {0, 0, 0, 0}, // LifetimeStart + {0, 0, 0, 0}, // LifetimeStop + {1, 1, 0, 0}, // #258 + {1, 1, 0, 0}, // GroupAsyncCopy + {0, 0, 0, 0}, // GroupWaitEvents + {1, 1, 0, 0}, // GroupAll + {1, 1, 0, 0}, // GroupAny + {1, 1, 0, 0}, // GroupBroadcast + {1, 1, 0, 0}, // GroupIAdd + {1, 1, 0, 0}, // GroupFAdd + {1, 1, 0, 0}, // GroupFMin + {1, 1, 0, 0}, // GroupUMin + {1, 1, 0, 0}, // GroupSMin + {1, 1, 0, 0}, // GroupFMax + {1, 1, 0, 0}, // GroupUMax + {1, 1, 0, 0}, // GroupSMax + {1, 1, 0, 0}, // #272 + {1, 1, 0, 0}, // #273 + {1, 1, 0, 0}, // ReadPipe + {1, 1, 0, 0}, // WritePipe + {1, 1, 0, 0}, // ReservedReadPipe + {1, 1, 0, 0}, // ReservedWritePipe + {1, 1, 0, 0}, // ReserveReadPipePackets + {1, 1, 0, 0}, // ReserveWritePipePackets + {0, 0, 0, 0}, // CommitReadPipe + {0, 0, 0, 0}, // CommitWritePipe + {1, 1, 0, 0}, // IsValidReserveId + {1, 1, 0, 0}, // GetNumPipePackets + {1, 1, 0, 0}, // GetMaxPipePackets + {1, 1, 0, 0}, // GroupReserveReadPipePackets + {1, 1, 0, 0}, // GroupReserveWritePipePackets + {0, 0, 0, 0}, // GroupCommitReadPipe + {0, 0, 0, 0}, // GroupCommitWritePipe + {1, 1, 0, 0}, // #289 + {1, 1, 0, 0}, // #290 + {1, 1, 0, 0}, // EnqueueMarker + {1, 1, 0, 0}, // EnqueueKernel + {1, 1, 0, 0}, // GetKernelNDrangeSubGroupCount + {1, 1, 0, 0}, // GetKernelNDrangeMaxSubGroupSize + {1, 1, 0, 0}, // GetKernelWorkGroupSize + {1, 1, 0, 0}, // GetKernelPreferredWorkGroupSizeMultiple + {0, 0, 0, 0}, // RetainEvent + {0, 0, 0, 0}, // ReleaseEvent + {1, 1, 0, 0}, // CreateUserEvent + {1, 1, 0, 0}, // IsValidEvent + {0, 0, 0, 0}, // SetUserEventStatus + {0, 0, 0, 0}, // CaptureEventProfilingInfo + {1, 1, 0, 0}, // GetDefaultQueue + {1, 1, 0, 0}, // BuildNDRange + {1, 1, 2, 1}, // ImageSparseSampleImplicitLod + {1, 1, 2, 1}, // ImageSparseSampleExplicitLod + {1, 1, 3, 1}, // ImageSparseSampleDrefImplicitLod + {1, 1, 3, 1}, // ImageSparseSampleDrefExplicitLod + {1, 1, 2, 1}, // ImageSparseSampleProjImplicitLod + {1, 1, 2, 1}, // ImageSparseSampleProjExplicitLod + {1, 1, 3, 1}, // ImageSparseSampleProjDrefImplicitLod + {1, 1, 3, 1}, // ImageSparseSampleProjDrefExplicitLod + {1, 1, 2, 1}, // ImageSparseFetch + {1, 1, 3, 1}, // ImageSparseGather + {1, 1, 3, 1}, // ImageSparseDrefGather + {1, 1, 1, 0}, // ImageSparseTexelsResident + {0, 0, 0, 0}, // NoLine + {1, 1, 0, 0}, // AtomicFlagTestAndSet + {0, 0, 0, 0}, // AtomicFlagClear + {1, 1, 0, 0}, // ImageSparseRead + {1, 1, 0, 0}, // SizeOf + {1, 1, 0, 0}, // TypePipeStorage + {1, 1, 0, 0}, // ConstantPipeStorage + {1, 1, 0, 0}, // CreatePipeFromPipeStorage + {1, 1, 0, 0}, // GetKernelLocalSizeForSubgroupCount + {1, 1, 0, 0}, // GetKernelMaxNumSubgroups + {1, 1, 0, 0}, // TypeNamedBarrier + {1, 1, 0, 1}, // NamedBarrierInitialize + {0, 0, 2, 1}, // MemoryNamedBarrier + {1, 1, 0, 0}, // ModuleProcessed + {0, 0, 0, 1}, // ExecutionModeId + {0, 0, 0, 1}, // DecorateId + {1, 1, 1, 1}, // GroupNonUniformElect + {1, 1, 1, 1}, // GroupNonUniformAll + {1, 1, 1, 1}, // GroupNonUniformAny + {1, 1, 1, 1}, // GroupNonUniformAllEqual + {1, 1, 1, 1}, // GroupNonUniformBroadcast + {1, 1, 1, 1}, // GroupNonUniformBroadcastFirst + {1, 1, 1, 1}, // GroupNonUniformBallot + {1, 1, 1, 1}, // GroupNonUniformInverseBallot + {1, 1, 1, 1}, // GroupNonUniformBallotBitExtract + {1, 1, 1, 1}, // GroupNonUniformBallotBitCount + {1, 1, 1, 1}, // GroupNonUniformBallotFindLSB + {1, 1, 1, 1}, // GroupNonUniformBallotFindMSB + {1, 1, 1, 1}, // GroupNonUniformShuffle + {1, 1, 1, 1}, // GroupNonUniformShuffleXor + {1, 1, 1, 1}, // GroupNonUniformShuffleUp + {1, 1, 1, 1}, // GroupNonUniformShuffleDown + {1, 1, 1, 1}, // GroupNonUniformIAdd + {1, 1, 1, 1}, // GroupNonUniformFAdd + {1, 1, 1, 1}, // GroupNonUniformIMul + {1, 1, 1, 1}, // GroupNonUniformFMul + {1, 1, 1, 1}, // GroupNonUniformSMin + {1, 1, 1, 1}, // GroupNonUniformUMin + {1, 1, 1, 1}, // GroupNonUniformFMin + {1, 1, 1, 1}, // GroupNonUniformSMax + {1, 1, 1, 1}, // GroupNonUniformUMax + {1, 1, 1, 1}, // GroupNonUniformFMax + {1, 1, 1, 1}, // GroupNonUniformBitwiseAnd + {1, 1, 1, 1}, // GroupNonUniformBitwiseOr + {1, 1, 1, 1}, // GroupNonUniformBitwiseXor + {1, 1, 1, 1}, // GroupNonUniformLogicalAnd + {1, 1, 1, 1}, // GroupNonUniformLogicalOr + {1, 1, 1, 1}, // GroupNonUniformLogicalXor + {1, 1, 1, 1}, // GroupNonUniformQuadBroadcast + {1, 1, 1, 1}, // GroupNonUniformQuadSwap +}; +static_assert(_SMOLV_ARRAY_SIZE(kSpirvOpData) == kKnownOpsCount, "kSpirvOpData table mismatch with known SpvOps"); + +// Instruction encoding depends on the table that describes the various SPIR-V opcodes. +// Whenever we change or expand the table, we need to bump up the SMOL-V version, and make +// sure that we can still decode files encoded by an older version. +static int smolv_GetKnownOpsCount(int version) +{ + if (version == 0) + return SpvOpModuleProcessed+1; + if (version == 1) // 2020 February, version 1 added ExecutionModeId..GroupNonUniformQuadSwap + return SpvOpGroupNonUniformQuadSwap+1; + return 0; +} + +static bool smolv_OpHasResult(SpvOp op, int opsCount) +{ + if (op < 0 || op >= opsCount) + return false; + return kSpirvOpData[op].hasResult != 0; +} + +static bool smolv_OpHasType(SpvOp op, int opsCount) +{ + if (op < 0 || op >= opsCount) + return false; + return kSpirvOpData[op].hasType != 0; +} + +static int smolv_OpDeltaFromResult(SpvOp op, int opsCount) +{ + if (op < 0 || op >= opsCount) + return 0; + return kSpirvOpData[op].deltaFromResult; +} + +static bool smolv_OpVarRest(SpvOp op, int opsCount) +{ + if (op < 0 || op >= opsCount) + return false; + return kSpirvOpData[op].varrest != 0; +} + +static bool smolv_OpDebugInfo(SpvOp op, int opsCount) +{ + return + op == SpvOpSourceContinued || + op == SpvOpSource || + op == SpvOpSourceExtension || + op == SpvOpName || + op == SpvOpMemberName || + op == SpvOpString || + op == SpvOpLine || + op == SpvOpNoLine || + op == SpvOpModuleProcessed; +} + + +static int smolv_DecorationExtraOps(int dec) +{ + if (dec == 0 || (dec >= 2 && dec <= 5)) // RelaxedPrecision, Block..ColMajor + return 0; + if (dec >= 29 && dec <= 37) // Stream..XfbStride + return 1; + return -1; // unknown, encode length +} + + +// -------------------------------------------------------------------------------------------- + + +static bool smolv_CheckGenericHeader(const uint32_t* words, size_t wordCount, uint32_t expectedMagic, uint32_t versionMask) +{ + if (!words) + return false; + if (wordCount < 5) + return false; + + uint32_t headerMagic = words[0]; + if (headerMagic != expectedMagic) + return false; + uint32_t headerVersion = words[1] & versionMask; + if (headerVersion < 0x00010000 || headerVersion > 0x00010500) + return false; // only support 1.0 through 1.5 + + return true; +} + +static const int kSpirVHeaderMagic = 0x07230203; +static const int kSmolHeaderMagic = 0x534D4F4C; // "SMOL" + +static const int kSmolCurrEncodingVersion = 1; + +static bool smolv_CheckSpirVHeader(const uint32_t* words, size_t wordCount) +{ + //@TODO: if SPIR-V header magic was reversed, that means the file got written + // in a "big endian" order. Need to byteswap all words then. + return smolv_CheckGenericHeader(words, wordCount, kSpirVHeaderMagic, 0xFFFFFFFF); +} +static bool smolv_CheckSmolHeader(const uint8_t* bytes, size_t byteCount) +{ + if (!smolv_CheckGenericHeader((const uint32_t*)bytes, byteCount/4, kSmolHeaderMagic, 0x00FFFFFF)) + return false; + if (byteCount < 24) // one more word past header to store decoded length + return false; + // SMOL-V version + int smolVersion = ((const uint32_t*)bytes)[1] >> 24; + if (smolVersion < 0 || smolVersion > kSmolCurrEncodingVersion) + return false; + return true; +} + + +static void smolv_Write4(smolv::ByteArray& arr, uint32_t v) +{ + arr.push_back(v & 0xFF); + arr.push_back((v >> 8) & 0xFF); + arr.push_back((v >> 16) & 0xFF); + arr.push_back(v >> 24); +} + +static void smolv_Write4(uint8_t*& buf, uint32_t v) +{ + memcpy(buf, &v, 4); + buf += 4; +} + + +static bool smolv_Read4(const uint8_t*& data, const uint8_t* dataEnd, uint32_t& outv) +{ + if (data + 4 > dataEnd) + return false; + outv = (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + data += 4; + return true; +} + + +// -------------------------------------------------------------------------------------------- + +// Variable-length integer encoding for unsigned integers. In each byte: +// - highest bit set if more bytes follow, cleared if this is last byte. +// - other 7 bits are the actual value payload. +// Takes 1-5 bytes to encode an integer (values between 0 and 127 take one byte, etc.). + +static void smolv_WriteVarint(smolv::ByteArray& arr, uint32_t v) +{ + while (v > 127) + { + arr.push_back((v & 127) | 128); + v >>= 7; + } + arr.push_back(v & 127); +} + +static bool smolv_ReadVarint(const uint8_t*& data, const uint8_t* dataEnd, uint32_t& outVal) +{ + uint32_t v = 0; + uint32_t shift = 0; + while (data < dataEnd) + { + uint8_t b = *data; + v |= (b & 127) << shift; + shift += 7; + data++; + if (!(b & 128)) + break; + } + outVal = v; + return true; //@TODO: report failures +} + +static uint32_t smolv_ZigEncode(int32_t i) +{ + return (uint32_t(i) << 1) ^ (i >> 31); +} + +static int32_t smolv_ZigDecode(uint32_t u) +{ + return (u & 1) ? ((u >> 1) ^ ~0) : (u >> 1); +} + + +// Remap most common Op codes (Load, Store, Decorate, VectorShuffle etc.) to be in < 16 range, for +// more compact varint encoding. This basically swaps rarely used op values that are < 16 with the +// ones that are common. + +static SpvOp smolv_RemapOp(SpvOp op) +{ +# define _SMOLV_SWAP_OP(op1,op2) if (op==op1) return op2; if (op==op2) return op1 + _SMOLV_SWAP_OP(SpvOpDecorate,SpvOpNop); // 0: 24% + _SMOLV_SWAP_OP(SpvOpLoad,SpvOpUndef); // 1: 17% + _SMOLV_SWAP_OP(SpvOpStore,SpvOpSourceContinued); // 2: 9% + _SMOLV_SWAP_OP(SpvOpAccessChain,SpvOpSource); // 3: 7.2% + _SMOLV_SWAP_OP(SpvOpVectorShuffle,SpvOpSourceExtension); // 4: 5.0% + // Name - already small enum value - 5: 4.4% + // MemberName - already small enum value - 6: 2.9% + _SMOLV_SWAP_OP(SpvOpMemberDecorate,SpvOpString); // 7: 4.0% + _SMOLV_SWAP_OP(SpvOpLabel,SpvOpLine); // 8: 0.9% + _SMOLV_SWAP_OP(SpvOpVariable,(SpvOp)9); // 9: 3.9% + _SMOLV_SWAP_OP(SpvOpFMul,SpvOpExtension); // 10: 3.9% + _SMOLV_SWAP_OP(SpvOpFAdd,SpvOpExtInstImport); // 11: 2.5% + // ExtInst - already small enum value - 12: 1.2% + // VectorShuffleCompact - already small enum value - used for compact shuffle encoding + _SMOLV_SWAP_OP(SpvOpTypePointer,SpvOpMemoryModel); // 14: 2.2% + _SMOLV_SWAP_OP(SpvOpFNegate,SpvOpEntryPoint); // 15: 1.1% +# undef _SMOLV_SWAP_OP + return op; +} + + +// For most compact varint encoding of common instructions, the instruction length should come out +// into 3 bits (be <8). SPIR-V instruction lengths are always at least 1, and for some other +// instructions they are guaranteed to be some other minimum length. Adjust the length before encoding, +// and after decoding accordingly. + +static uint32_t smolv_EncodeLen(SpvOp op, uint32_t len) +{ + len--; + if (op == SpvOpVectorShuffle) len -= 4; + if (op == SpvOpVectorShuffleCompact) len -= 4; + if (op == SpvOpDecorate) len -= 2; + if (op == SpvOpLoad) len -= 3; + if (op == SpvOpAccessChain) len -= 3; + return len; +} + +static uint32_t smolv_DecodeLen(SpvOp op, uint32_t len) +{ + len++; + if (op == SpvOpVectorShuffle) len += 4; + if (op == SpvOpVectorShuffleCompact) len += 4; + if (op == SpvOpDecorate) len += 2; + if (op == SpvOpLoad) len += 3; + if (op == SpvOpAccessChain) len += 3; + return len; +} + + +// Shuffling bits of length + opcode to be more compact in varint encoding in typical cases: +// 0x LLLL OOOO is how SPIR-V encodes it (L=length, O=op), we shuffle into: +// 0x LLLO OOLO, so that common case (op<16, len<8) is encoded into one byte. + +static bool smolv_WriteLengthOp(smolv::ByteArray& arr, uint32_t len, SpvOp op) +{ + len = smolv_EncodeLen(op, len); + // SPIR-V length field is 16 bits; if we get a larger value that means something + // was wrong, e.g. a vector shuffle instruction with less than 4 words (and our + // adjustment to common lengths in smolv_EncodeLen wrapped around) + if (len > 0xFFFF) + return false; + op = smolv_RemapOp(op); + uint32_t oplen = ((len >> 4) << 20) | ((op >> 4) << 8) | ((len & 0xF) << 4) | (op & 0xF); + smolv_WriteVarint(arr, oplen); + return true; +} + +static bool smolv_ReadLengthOp(const uint8_t*& data, const uint8_t* dataEnd, uint32_t& outLen, SpvOp& outOp) +{ + uint32_t val; + if (!smolv_ReadVarint(data, dataEnd, val)) + return false; + outLen = ((val >> 20) << 4) | ((val >> 4) & 0xF); + outOp = (SpvOp)(((val >> 4) & 0xFFF0) | (val & 0xF)); + + outOp = smolv_RemapOp(outOp); + outLen = smolv_DecodeLen(outOp, outLen); + return true; +} + + + +#define _SMOLV_READ_OP(len, words, op) \ + uint32_t len = words[0] >> 16; \ + if (len < 1) return false; /* malformed instruction, length needs to be at least 1 */ \ + if (words + len > wordsEnd) return false; /* malformed instruction, goes past end of data */ \ + SpvOp op = (SpvOp)(words[0] & 0xFFFF) + + +bool smolv::Encode(const void* spirvData, size_t spirvSize, ByteArray& outSmolv, uint32_t flags, StripOpNameFilterFunc stripFilter) +{ + const size_t wordCount = spirvSize / 4; + if (wordCount * 4 != spirvSize) + return false; + const uint32_t* words = (const uint32_t*)spirvData; + const uint32_t* wordsEnd = words + wordCount; + if (!smolv_CheckSpirVHeader(words, wordCount)) + return false; + + // reserve space in output (typical compression is to about 30%; reserve half of input space) + outSmolv.reserve(outSmolv.size() + spirvSize/2); + + // header (matches SPIR-V one, except different magic) + smolv_Write4(outSmolv, kSmolHeaderMagic); + smolv_Write4(outSmolv, (words[1] & 0x00FFFFFF) + (kSmolCurrEncodingVersion<<24)); // SPIR-V version (_XXX) + SMOL-V version (X___) + smolv_Write4(outSmolv, words[2]); // generator + smolv_Write4(outSmolv, words[3]); // bound + smolv_Write4(outSmolv, words[4]); // schema + + const size_t headerSpirvSizeOffset = outSmolv.size(); // size field may get updated later if stripping is enabled + smolv_Write4(outSmolv, (uint32_t)spirvSize); // space needed to decode (i.e. original SPIR-V size) + + size_t strippedSpirvWordCount = wordCount; + uint32_t prevResult = 0; + uint32_t prevDecorate = 0; + + const int knownOpsCount = smolv_GetKnownOpsCount(kSmolCurrEncodingVersion); + + words += 5; + while (words < wordsEnd) + { + _SMOLV_READ_OP(instrLen, words, op); + + if ((flags & kEncodeFlagStripDebugInfo) && smolv_OpDebugInfo(op, knownOpsCount)) + { + if (!stripFilter || op != SpvOpName || !stripFilter(reinterpret_cast<const char*>(&words[2]))) + { + strippedSpirvWordCount -= instrLen; + words += instrLen; + continue; + } + } + + // A usual case of vector shuffle, with less than 4 components, each with a value + // in [0..3] range: encode it in a more compact form, with the swizzle pattern in one byte. + // Turn this into a VectorShuffleCompact instruction, that takes up unused slot in Ops. + uint32_t swizzle = 0; + if (op == SpvOpVectorShuffle && instrLen <= 9) + { + uint32_t swz0 = instrLen > 5 ? words[5] : 0; + uint32_t swz1 = instrLen > 6 ? words[6] : 0; + uint32_t swz2 = instrLen > 7 ? words[7] : 0; + uint32_t swz3 = instrLen > 8 ? words[8] : 0; + if (swz0 < 4 && swz1 < 4 && swz2 < 4 && swz3 < 4) + { + op = SpvOpVectorShuffleCompact; + swizzle = (swz0 << 6) | (swz1 << 4) | (swz2 << 2) | (swz3); + } + } + + // length + opcode + if (!smolv_WriteLengthOp(outSmolv, instrLen, op)) + return false; + + size_t ioffs = 1; + // write type as varint, if we have it + if (smolv_OpHasType(op, knownOpsCount)) + { + if (ioffs >= instrLen) + return false; + smolv_WriteVarint(outSmolv, words[ioffs]); + ioffs++; + } + // write result as delta+zig+varint, if we have it + if (smolv_OpHasResult(op, knownOpsCount)) + { + if (ioffs >= instrLen) + return false; + uint32_t v = words[ioffs]; + smolv_WriteVarint(outSmolv, smolv_ZigEncode(v - prevResult)); // some deltas are negative, use zig + prevResult = v; + ioffs++; + } + + // Decorate & MemberDecorate: IDs relative to previous decorate + if (op == SpvOpDecorate || op == SpvOpMemberDecorate) + { + if (ioffs >= instrLen) + return false; + uint32_t v = words[ioffs]; + smolv_WriteVarint(outSmolv, smolv_ZigEncode(v - prevDecorate)); // spirv-remapped deltas often negative, use zig + prevDecorate = v; + ioffs++; + } + + // MemberDecorate special encoding: whole row of MemberDecorate instructions is often referring + // to the same type and linearly increasing member indices. Scan ahead to see how many we have, + // and encode whole bunch as one. + if (op == SpvOpMemberDecorate) + { + // scan ahead until we reach end, non-member-decoration or different type + const uint32_t decorationType = words[ioffs-1]; + const uint32_t* memberWords = words; + uint32_t prevIndex = 0; + uint32_t prevOffset = 0; + // write a byte on how many we have encoded as a bunch + size_t countLocation = outSmolv.size(); + outSmolv.push_back(0); + int count = 0; + while (memberWords < wordsEnd && count < 255) + { + _SMOLV_READ_OP(memberLen, memberWords, memberOp); + if (memberOp != SpvOpMemberDecorate) + break; + if (memberLen < 4) + return false; // invalid input + if (memberWords[1] != decorationType) + break; + + // write member index as delta from previous + uint32_t memberIndex = memberWords[2]; + smolv_WriteVarint(outSmolv, memberIndex - prevIndex); + prevIndex = memberIndex; + + // decoration (and length if not common/known) + uint32_t memberDec = memberWords[3]; + smolv_WriteVarint(outSmolv, memberDec); + const int knownExtraOps = smolv_DecorationExtraOps(memberDec); + if (knownExtraOps == -1) + smolv_WriteVarint(outSmolv, memberLen-4); + else if (unsigned(knownExtraOps) + 4 != memberLen) + return false; // invalid input + + // Offset decorations are most often linearly increasing, so encode as deltas + if (memberDec == 35) // Offset + { + if (memberLen != 5) + return false; + smolv_WriteVarint(outSmolv, memberWords[4]-prevOffset); + prevOffset = memberWords[4]; + } + else + { + // write rest of decorations as varint + for (uint32_t i = 4; i < memberLen; ++i) + smolv_WriteVarint(outSmolv, memberWords[i]); + } + + memberWords += memberLen; + ++count; + } + outSmolv[countLocation] = uint8_t(count); + words = memberWords; + continue; + } + + // Write out this many IDs, encoding them relative+zigzag to result ID + int relativeCount = smolv_OpDeltaFromResult(op, knownOpsCount); + for (int i = 0; i < relativeCount && ioffs < instrLen; ++i, ++ioffs) + { + if (ioffs >= instrLen) + return false; + uint32_t delta = prevResult - words[ioffs]; + // some deltas are negative (often on branches, or if program was processed by spirv-remap), + // so use zig encoding + smolv_WriteVarint(outSmolv, smolv_ZigEncode(delta)); + } + + if (op == SpvOpVectorShuffleCompact) + { + // compact vector shuffle, just write out single swizzle byte + outSmolv.push_back(uint8_t(swizzle)); + ioffs = instrLen; + } + else if (smolv_OpVarRest(op, knownOpsCount)) + { + // write out rest of words with variable encoding (expected to be small integers) + for (; ioffs < instrLen; ++ioffs) + smolv_WriteVarint(outSmolv, words[ioffs]); + } + else + { + // write out rest of words without any encoding + for (; ioffs < instrLen; ++ioffs) + smolv_Write4(outSmolv, words[ioffs]); + } + + words += instrLen; + } + + if (strippedSpirvWordCount != wordCount) + { + uint8_t* headerSpirvSize = &outSmolv[headerSpirvSizeOffset]; + smolv_Write4(headerSpirvSize, (uint32_t)strippedSpirvWordCount * 4); + } + + return true; +} + + +size_t smolv::GetDecodedBufferSize(const void* smolvData, size_t smolvSize) +{ + if (!smolv_CheckSmolHeader((const uint8_t*)smolvData, smolvSize)) + return 0; + const uint32_t* words = (const uint32_t*)smolvData; + return words[5]; +} + + +bool smolv::Decode(const void* smolvData, size_t smolvSize, void* spirvOutputBuffer, size_t spirvOutputBufferSize, uint32_t flags) +{ + // check header, and whether we have enough output buffer space + const size_t neededBufferSize = GetDecodedBufferSize(smolvData, smolvSize); + if (neededBufferSize == 0) + return false; // invalid SMOL-V + if (spirvOutputBufferSize < neededBufferSize) + return false; // not enough space in output buffer + if (spirvOutputBuffer == NULL) + return false; // output buffer is null + + const uint8_t* bytes = (const uint8_t*)smolvData; + const uint8_t* bytesEnd = bytes + smolvSize; + + uint8_t* outSpirv = (uint8_t*)spirvOutputBuffer; + + uint32_t val; + int smolVersion = 0; + + // header + smolv_Write4(outSpirv, kSpirVHeaderMagic); bytes += 4; + smolv_Read4(bytes, bytesEnd, val); smolVersion = val >> 24; val &= 0x00FFFFFF; smolv_Write4(outSpirv, val); // version + smolv_Read4(bytes, bytesEnd, val); smolv_Write4(outSpirv, val); // generator + smolv_Read4(bytes, bytesEnd, val); smolv_Write4(outSpirv, val); // bound + smolv_Read4(bytes, bytesEnd, val); smolv_Write4(outSpirv, val); // schema + bytes += 4; // decode buffer size + + // there are two SMOL-V encoding versions, both not indicating anything in their header version field: + // one that is called "before zero" here (2016-08-31 code). Support decoding that one only by presence + // of this special flag. + const bool beforeZeroVersion = smolVersion == 0 && (flags & kDecodeFlagUse20160831AsZeroVersion) != 0; + + const int knownOpsCount = smolv_GetKnownOpsCount(smolVersion); + + uint32_t prevResult = 0; + uint32_t prevDecorate = 0; + + while (bytes < bytesEnd) + { + // read length + opcode + uint32_t instrLen; + SpvOp op; + if (!smolv_ReadLengthOp(bytes, bytesEnd, instrLen, op)) + return false; + const bool wasSwizzle = (op == SpvOpVectorShuffleCompact); + if (wasSwizzle) + op = SpvOpVectorShuffle; + smolv_Write4(outSpirv, (instrLen << 16) | op); + + size_t ioffs = 1; + + // read type as varint, if we have it + if (smolv_OpHasType(op, knownOpsCount)) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + smolv_Write4(outSpirv, val); + ioffs++; + } + // read result as delta+varint, if we have it + if (smolv_OpHasResult(op, knownOpsCount)) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + val = prevResult + smolv_ZigDecode(val); + smolv_Write4(outSpirv, val); + prevResult = val; + ioffs++; + } + + // Decorate: IDs relative to previous decorate + if (op == SpvOpDecorate || op == SpvOpMemberDecorate) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + // "before zero" version did not use zig encoding for the value + val = prevDecorate + (beforeZeroVersion ? val : smolv_ZigDecode(val)); + smolv_Write4(outSpirv, val); + prevDecorate = val; + ioffs++; + } + + // MemberDecorate special decoding + if (op == SpvOpMemberDecorate && !beforeZeroVersion) + { + if (bytes >= bytesEnd) + return false; // broken input + int count = *bytes++; + int prevIndex = 0; + int prevOffset = 0; + for (int m = 0; m < count; ++m) + { + // read member index + uint32_t memberIndex; + if (!smolv_ReadVarint(bytes, bytesEnd, memberIndex)) return false; + memberIndex += prevIndex; + prevIndex = memberIndex; + + // decoration (and length if not common/known) + uint32_t memberDec; + if (!smolv_ReadVarint(bytes, bytesEnd, memberDec)) return false; + const int knownExtraOps = smolv_DecorationExtraOps(memberDec); + uint32_t memberLen; + if (knownExtraOps == -1) + { + if (!smolv_ReadVarint(bytes, bytesEnd, memberLen)) return false; + memberLen += 4; + } + else + memberLen = 4 + knownExtraOps; + + // write SPIR-V op+length (unless it's first member decoration, in which case it was written before) + if (m != 0) + { + smolv_Write4(outSpirv, (memberLen << 16) | op); + smolv_Write4(outSpirv, prevDecorate); + } + smolv_Write4(outSpirv, memberIndex); + smolv_Write4(outSpirv, memberDec); + // Special case for Offset decorations + if (memberDec == 35) // Offset + { + if (memberLen != 5) + return false; + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + val += prevOffset; + smolv_Write4(outSpirv, val); + prevOffset = val; + } + else + { + for (uint32_t i = 4; i < memberLen; ++i) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + smolv_Write4(outSpirv, val); + } + } + } + continue; + } + + // Read this many IDs, that are relative to result ID + int relativeCount = smolv_OpDeltaFromResult(op, knownOpsCount); + // "before zero" version only used zig encoding for IDs of several ops; after + // that ops got zig encoding for their IDs + bool zigDecodeVals = true; + if (beforeZeroVersion) + { + if (op != SpvOpControlBarrier && op != SpvOpMemoryBarrier && op != SpvOpLoopMerge && op != SpvOpSelectionMerge && op != SpvOpBranch && op != SpvOpBranchConditional && op != SpvOpMemoryNamedBarrier) + zigDecodeVals = false; + } + for (int i = 0; i < relativeCount && ioffs < instrLen; ++i, ++ioffs) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + if (zigDecodeVals) + val = smolv_ZigDecode(val); + smolv_Write4(outSpirv, prevResult - val); + } + + if (wasSwizzle && instrLen <= 9) + { + uint32_t swizzle = *bytes++; + if (instrLen > 5) smolv_Write4(outSpirv, (swizzle >> 6) & 3); + if (instrLen > 6) smolv_Write4(outSpirv, (swizzle >> 4) & 3); + if (instrLen > 7) smolv_Write4(outSpirv, (swizzle >> 2) & 3); + if (instrLen > 8) smolv_Write4(outSpirv, swizzle & 3); + } + else if (smolv_OpVarRest(op, knownOpsCount)) + { + // read rest of words with variable encoding + for (; ioffs < instrLen; ++ioffs) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + smolv_Write4(outSpirv, val); + } + } + else + { + // read rest of words without any encoding + for (; ioffs < instrLen; ++ioffs) + { + if (!smolv_Read4(bytes, bytesEnd, val)) return false; + smolv_Write4(outSpirv, val); + } + } + } + + if ((uint8_t*)spirvOutputBuffer + neededBufferSize != outSpirv) + return false; // something went wrong during decoding? we should have decoded to exact output size + + return true; +} + + + +// -------------------------------------------------------------------------------------------- +// Calculating instruction count / space stats on SPIR-V and SMOL-V + + +struct smolv::Stats +{ + Stats() { memset(this, 0, sizeof(*this)); } + size_t opCounts[kKnownOpsCount]; + size_t opSizes[kKnownOpsCount]; + size_t smolOpSizes[kKnownOpsCount]; + size_t varintCountsOp[6]; + size_t varintCountsType[6]; + size_t varintCountsRes[6]; + size_t varintCountsOther[6]; + size_t totalOps; + size_t totalSize; + size_t totalSizeSmol; + size_t inputCount; +}; + + +smolv::Stats* smolv::StatsCreate() +{ + return new Stats(); +} + +void smolv::StatsDelete(smolv::Stats *s) +{ + delete s; +} + + +bool smolv::StatsCalculate(smolv::Stats* stats, const void* spirvData, size_t spirvSize) +{ + if (!stats) + return false; + + const size_t wordCount = spirvSize / 4; + if (wordCount * 4 != spirvSize) + return false; + const uint32_t* words = (const uint32_t*)spirvData; + const uint32_t* wordsEnd = words + wordCount; + if (!smolv_CheckSpirVHeader(words, wordCount)) + return false; + words += 5; + + stats->inputCount++; + stats->totalSize += wordCount; + + while (words < wordsEnd) + { + _SMOLV_READ_OP(instrLen, words, op); + + if (op < kKnownOpsCount) + { + stats->opCounts[op]++; + stats->opSizes[op] += instrLen; + } + words += instrLen; + stats->totalOps++; + } + + return true; +} + + +bool smolv::StatsCalculateSmol(smolv::Stats* stats, const void* smolvData, size_t smolvSize) +{ + if (!stats) + return false; + + // debugging helper to dump all encoded bytes to stdout, keep at "if 0" +# if 0 +# define _SMOLV_DEBUG_PRINT_ENCODED_BYTES() { \ + printf("Op %-22s ", op < kKnownOpsCount ? kSpirvOpNames[op] : "???"); \ + for (const uint8_t* b = instrBegin; b < bytes; ++b) \ + printf("%02x ", *b); \ + printf("\n"); \ + } +# else +# define _SMOLV_DEBUG_PRINT_ENCODED_BYTES() {} +# endif + + const uint8_t* bytes = (const uint8_t*)smolvData; + const uint8_t* bytesEnd = bytes + smolvSize; + if (!smolv_CheckSmolHeader(bytes, smolvSize)) + return false; + + uint32_t val; + int smolVersion; + bytes += 4; + smolv_Read4(bytes, bytesEnd, val); smolVersion = val >> 24; + const int knownOpsCount = smolv_GetKnownOpsCount(smolVersion); + bytes += 16; + + stats->totalSizeSmol += smolvSize; + + while (bytes < bytesEnd) + { + const uint8_t* instrBegin = bytes; + const uint8_t* varBegin; + + // read length + opcode + uint32_t instrLen; + SpvOp op; + varBegin = bytes; + if (!smolv_ReadLengthOp(bytes, bytesEnd, instrLen, op)) + return false; + const bool wasSwizzle = (op == SpvOpVectorShuffleCompact); + if (wasSwizzle) + op = SpvOpVectorShuffle; + stats->varintCountsOp[bytes-varBegin]++; + + size_t ioffs = 1; + if (smolv_OpHasType(op, knownOpsCount)) + { + varBegin = bytes; + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + stats->varintCountsType[bytes-varBegin]++; + ioffs++; + } + if (smolv_OpHasResult(op, knownOpsCount)) + { + varBegin = bytes; + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + stats->varintCountsRes[bytes-varBegin]++; + ioffs++; + } + + if (op == SpvOpDecorate || op == SpvOpMemberDecorate) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + ioffs++; + } + // MemberDecorate special decoding + if (op == SpvOpMemberDecorate) + { + if (bytes >= bytesEnd) + return false; // broken input + int count = *bytes++; + for (int m = 0; m < count; ++m) + { + uint32_t memberIndex; + if (!smolv_ReadVarint(bytes, bytesEnd, memberIndex)) return false; + uint32_t memberDec; + if (!smolv_ReadVarint(bytes, bytesEnd, memberDec)) return false; + const int knownExtraOps = smolv_DecorationExtraOps(memberDec); + uint32_t memberLen; + if (knownExtraOps == -1) + { + if (!smolv_ReadVarint(bytes, bytesEnd, memberLen)) return false; + memberLen += 4; + } + else + memberLen = 4 + knownExtraOps; + for (uint32_t i = 4; i < memberLen; ++i) + { + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + } + } + stats->smolOpSizes[op] += bytes - instrBegin; + _SMOLV_DEBUG_PRINT_ENCODED_BYTES(); + continue; + } + + int relativeCount = smolv_OpDeltaFromResult(op, knownOpsCount); + for (int i = 0; i < relativeCount && ioffs < instrLen; ++i, ++ioffs) + { + varBegin = bytes; + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + stats->varintCountsRes[bytes-varBegin]++; + } + + if (wasSwizzle && instrLen <= 9) + { + bytes++; + } + else if (smolv_OpVarRest(op, knownOpsCount)) + { + for (; ioffs < instrLen; ++ioffs) + { + varBegin = bytes; + if (!smolv_ReadVarint(bytes, bytesEnd, val)) return false; + stats->varintCountsOther[bytes-varBegin]++; + } + } + else + { + for (; ioffs < instrLen; ++ioffs) + { + if (!smolv_Read4(bytes, bytesEnd, val)) return false; + } + } + + if (op < kKnownOpsCount) + { + stats->smolOpSizes[op] += bytes - instrBegin; + } + _SMOLV_DEBUG_PRINT_ENCODED_BYTES(); + } + + return true; +} + +static bool CompareOpCounters (std::pair<SpvOp,size_t> a, std::pair<SpvOp,size_t> b) +{ + return a.second > b.second; +} + +void smolv::StatsPrint(const Stats* stats) +{ + if (!stats) + return; + + typedef std::pair<SpvOp,size_t> OpCounter; + OpCounter counts[kKnownOpsCount]; + OpCounter sizes[kKnownOpsCount]; + OpCounter sizesSmol[kKnownOpsCount]; + for (int i = 0; i < kKnownOpsCount; ++i) + { + counts[i].first = (SpvOp)i; + counts[i].second = stats->opCounts[i]; + sizes[i].first = (SpvOp)i; + sizes[i].second = stats->opSizes[i]; + sizesSmol[i].first = (SpvOp)i; + sizesSmol[i].second = stats->smolOpSizes[i]; + } + std::sort(counts, counts + kKnownOpsCount, CompareOpCounters); + std::sort(sizes, sizes + kKnownOpsCount, CompareOpCounters); + std::sort(sizesSmol, sizesSmol + kKnownOpsCount, CompareOpCounters); + + printf("Stats for %i SPIR-V inputs, total size %i words (%.1fKB):\n", (int)stats->inputCount, (int)stats->totalSize, stats->totalSize * 4.0f / 1024.0f); + printf("Most occuring ops:\n"); + for (int i = 0; i < 30; ++i) + { + SpvOp op = counts[i].first; + printf(" #%2i: %4i %-20s %4i (%4.1f%%)\n", i, op, kSpirvOpNames[op], (int)counts[i].second, (float)counts[i].second / (float)stats->totalOps * 100.0f); + } + printf("Largest total size of ops:\n"); + for (int i = 0; i < 30; ++i) + { + SpvOp op = sizes[i].first; + printf(" #%2i: %-22s %6i (%4.1f%%) avg len %.1f\n", + i, + kSpirvOpNames[op], + (int)sizes[i].second*4, + (float)sizes[i].second / (float)stats->totalSize * 100.0f, + (float)sizes[i].second*4 / (float)stats->opCounts[op] + ); + } + printf("SMOL varint encoding counts per byte length:\n"); + printf(" B: %6s %6s %6s %6s\n", "Op", "Type", "Result", "Other"); + for (int i = 1; i < 6; ++i) + { + printf(" %i: %6i %6i %6i %6i\n", i, (int)stats->varintCountsOp[i], (int)stats->varintCountsType[i], (int)stats->varintCountsRes[i], (int)stats->varintCountsOther[i]); + } + printf("Largest total size of ops in SMOL:\n"); + for (int i = 0; i < 30; ++i) + { + SpvOp op = sizesSmol[i].first; + printf(" #%2i: %-22s %6i (%4.1f%%) avg len %.1f\n", + i, + kSpirvOpNames[op], + (int)sizesSmol[i].second, + (float)sizesSmol[i].second / (float)stats->totalSizeSmol * 100.0f, + (float)sizesSmol[i].second / (float)stats->opCounts[op] + ); + } +} + + +// ------------------------------------------------------------------------------ +// This software is available under 2 licenses -- choose whichever you prefer. +// ------------------------------------------------------------------------------ +// ALTERNATIVE A - MIT License +// Copyright (c) 2016-2020 Aras Pranckevicius +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// ------------------------------------------------------------------------------ +// ALTERNATIVE B - Public Domain (www.unlicense.org) +// This is free and unencumbered software released into the public domain. +// Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +// software, either in source code form or as a compiled binary, for any purpose, +// commercial or non-commercial, and by any means. +// In jurisdictions that recognize copyright laws, the author or authors of this +// software dedicate any and all copyright interest in the software to the public +// domain. We make this dedication for the benefit of the public at large and to +// the detriment of our heirs and successors. We intend this dedication to be an +// overt act of relinquishment in perpetuity of all present and future rights to +// this software under copyright law. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ------------------------------------------------------------------------------ diff --git a/thirdparty/misc/smolv.h b/thirdparty/misc/smolv.h new file mode 100644 index 0000000000..798ee4126f --- /dev/null +++ b/thirdparty/misc/smolv.h @@ -0,0 +1,169 @@ +// smol-v - public domain - https://github.com/aras-p/smol-v +// authored 2016-2020 by Aras Pranckevicius +// no warranty implied; use at your own risk +// See end of file for license information. +// +// +// ### OVERVIEW: +// +// SMOL-V encodes Vulkan/Khronos SPIR-V format programs into a form that is smaller, and is more +// compressible. Normally no changes to the programs are done; they decode +// into exactly same program as what was encoded. Optionally, debug information +// can be removed too. +// +// SPIR-V is a very verbose format, several times larger than same programs expressed in other +// shader formats (e.g. DX11 bytecode, GLSL, DX9 bytecode etc.). The SSA-form with ever increasing +// IDs is not very appreciated by regular data compressors either. SMOL-V does several things +// to improve this: +// - Many words, especially ones that most often have small values, are encoded using +// "varint" scheme (1-5 bytes per word, with just one byte for values in 0..127 range). +// See https://developers.google.com/protocol-buffers/docs/encoding +// - Some IDs used in the program are delta-encoded, relative to previously seen IDs (e.g. Result +// IDs). Often instructions reference things that were computed just before, so this results in +// small deltas. These values are also encoded using "varint" scheme. +// - Reordering instruction opcodes so that the most common ones are the smallest values, for smaller +// varint encoding. +// - Encoding several instructions in a more compact form, e.g. the "typical <=4 component swizzle" +// shape of a VectorShuffle instruction, or sequences of MemberDecorate instructions. +// +// A somewhat similar utility is spirv-remap from glslang, see +// https://github.com/KhronosGroup/glslang/blob/master/README-spirv-remap.txt +// +// +// ### USAGE: +// +// Add source/smolv.h and source/smolv.cpp to your C++ project build. +// Currently it might require C++11 or somesuch; I only tested with Visual Studio 2017/2019, Mac Xcode 11 and Gcc 5.4. +// +// smolv::Encode and smolv::Decode is the basic functionality. +// +// Other functions are for development/statistics purposes, to figure out frequencies and +// distributions of the instructions. +// +// There's a test + compression benchmarking suite in testing/testmain.cpp; using that needs adding +// other files under testing/external to the build too (3rd party code: glslang remapper, Zstd, LZ4). +// +// +// ### LIMITATIONS / TODO: +// +// - SPIR-V where the words got stored in big-endian layout is not supported yet. +// - The whole thing might not work on Big-Endian CPUs. It might, but I'm not 100% sure. +// - Not much prevention is done against malformed/corrupted inputs, TODO. +// - Out of memory cases are not handled. The code will either throw exception +// or crash, depending on your compilation flags. + +#pragma once + +#include <stdint.h> +#include <vector> +#include <cstddef> + +namespace smolv +{ + typedef std::vector<uint8_t> ByteArray; + + enum EncodeFlags + { + kEncodeFlagNone = 0, + kEncodeFlagStripDebugInfo = (1<<0), // Strip all optional SPIR-V instructions (debug names etc.) + }; + enum DecodeFlags + { + kDecodeFlagNone = 0, + kDecodeFlagUse20160831AsZeroVersion = (1 << 0), // For "version zero" of SMOL-V encoding, use 2016 08 31 code path (this is what happens to be used by Unity 2017-2020) + }; + + // Preserve *some* OpName debug names. + // Return true to preserve, false to strip. + // This is really only used to implement a workaround for problems with some Vulkan drivers. + typedef bool(*StripOpNameFilterFunc)(const char* name); + + // ------------------------------------------------------------------- + // Encoding / Decoding + + // Encode SPIR-V into SMOL-V. + // + // Resulting data is appended to outSmolv array (the array is not cleared). + // + // flags is bitset of EncodeFlags values. + // + // Returns false on malformed SPIR-V input; if that happens the output array might get + // partial/broken SMOL-V program. + bool Encode(const void* spirvData, size_t spirvSize, ByteArray& outSmolv, uint32_t flags = kEncodeFlagNone, StripOpNameFilterFunc stripFilter = 0); + + + // Decode SMOL-V into SPIR-V. + // + // Resulting data is written into the passed buffer. Get required buffer space with + // GetDecodeBufferSize; this is the size of decoded SPIR-V program. + // + // flags is bitset of DecodeFlags values. + + // Decoding does no memory allocations. + // + // Returns false on malformed input; if that happens the output buffer might be only partially + // written to. + bool Decode(const void* smolvData, size_t smolvSize, void* spirvOutputBuffer, size_t spirvOutputBufferSize, uint32_t flags = kDecodeFlagNone); + + + // Given a SMOL-V program, get size of the decoded SPIR-V program. + // This is the buffer size that Decode expects. + // + // Returns zero on malformed input (just checks the header, not the full input). + size_t GetDecodedBufferSize(const void* smolvData, size_t smolvSize); + + + // ------------------------------------------------------------------- + // Computing instruction statistics on SPIR-V/SMOL-V programs + + struct Stats; + + Stats* StatsCreate(); + void StatsDelete(Stats* s); + + bool StatsCalculate(Stats* stats, const void* spirvData, size_t spirvSize); + bool StatsCalculateSmol(Stats* stats, const void* smolvData, size_t smolvSize); + void StatsPrint(const Stats* stats); + +} // namespace smolv + + +// ------------------------------------------------------------------------------ +// This software is available under 2 licenses -- choose whichever you prefer. +// ------------------------------------------------------------------------------ +// ALTERNATIVE A - MIT License +// Copyright (c) 2016-2020 Aras Pranckevicius +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// ------------------------------------------------------------------------------ +// ALTERNATIVE B - Public Domain (www.unlicense.org) +// This is free and unencumbered software released into the public domain. +// Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +// software, either in source code form or as a compiled binary, for any purpose, +// commercial or non-commercial, and by any means. +// In jurisdictions that recognize copyright laws, the author or authors of this +// software dedicate any and all copyright interest in the software to the public +// domain. We make this dedication for the benefit of the public at large and to +// the detriment of our heirs and successors. We intend this dedication to be an +// overt act of relinquishment in perpetuity of all present and future rights to +// this software under copyright law. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ------------------------------------------------------------------------------ |